diff usr/src/uts/i86pc/os/cpuid.c @ 13905:b151bd260b71

3414 Need a new word of AT_SUN_HWCAP bits 3415 Add isainfo support for f16c and rdrand 3416 Need disassembler support for rdrand and f16c Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com> Approved by: Garrett D'Amore <garrett@damore.org>
author Robert Mustacchi <rm@joyent.com>
date Thu, 13 Dec 2012 11:29:00 -0800
parents 73253247f9e5
children 0291cd939b43
line wrap: on
line diff
--- a/usr/src/uts/i86pc/os/cpuid.c	Thu Dec 13 11:25:45 2012 -0800
+++ b/usr/src/uts/i86pc/os/cpuid.c	Thu Dec 13 11:29:00 2012 -0800
@@ -161,7 +161,9 @@
 	"avx",
 	"vmx",
 	"svm",
-	"topoext"
+	"topoext",
+	"f16c",
+	"rdrand"
 };
 
 boolean_t
@@ -1155,6 +1157,7 @@
 	if (xsave_force_disable) {
 		mask_ecx &= ~CPUID_INTC_ECX_XSAVE;
 		mask_ecx &= ~CPUID_INTC_ECX_AVX;
+		mask_ecx &= ~CPUID_INTC_ECX_F16C;
 	}
 
 	/*
@@ -1255,10 +1258,15 @@
 
 		if (cp->cp_ecx & CPUID_INTC_ECX_XSAVE) {
 			add_x86_feature(featureset, X86FSET_XSAVE);
+
 			/* We only test AVX when there is XSAVE */
 			if (cp->cp_ecx & CPUID_INTC_ECX_AVX) {
 				add_x86_feature(featureset,
 				    X86FSET_AVX);
+
+				if (cp->cp_ecx & CPUID_INTC_ECX_F16C)
+					add_x86_feature(featureset,
+					    X86FSET_F16C);
 			}
 		}
 	}
@@ -1294,6 +1302,9 @@
 		add_x86_feature(featureset, X86FSET_VMX);
 	}
 
+	if (cp->cp_ecx & CPUID_INTC_ECX_RDRAND)
+		add_x86_feature(featureset, X86FSET_RDRAND);
+
 	/*
 	 * Only need it first time, rest of the cpus would follow suit.
 	 * we only capture this for the bootcpu.
@@ -1897,6 +1908,7 @@
 				remove_x86_feature(x86_featureset, X86FSET_AVX);
 				CPI_FEATURES_ECX(cpi) &= ~CPUID_INTC_ECX_XSAVE;
 				CPI_FEATURES_ECX(cpi) &= ~CPUID_INTC_ECX_AVX;
+				CPI_FEATURES_ECX(cpi) &= ~CPUID_INTC_ECX_F16C;
 				xsave_force_disable = B_TRUE;
 			}
 		}
@@ -2518,11 +2530,11 @@
  * the hardware feature support and kernel support for those features into
  * what we're actually going to tell applications via the aux vector.
  */
-uint_t
-cpuid_pass4(cpu_t *cpu)
+void
+cpuid_pass4(cpu_t *cpu, uint_t *hwcap_out)
 {
 	struct cpuid_info *cpi;
-	uint_t hwcap_flags = 0;
+	uint_t hwcap_flags = 0, hwcap_flags_2 = 0;
 
 	if (cpu == NULL)
 		cpu = CPU;
@@ -2569,6 +2581,8 @@
 			    CPUID_INTC_ECX_OSXSAVE);
 		if (!is_x86_feature(x86_featureset, X86FSET_AVX))
 			*ecx &= ~CPUID_INTC_ECX_AVX;
+		if (!is_x86_feature(x86_featureset, X86FSET_F16C))
+			*ecx &= ~CPUID_INTC_ECX_F16C;
 
 		/*
 		 * [no explicit support required beyond x87 fp context]
@@ -2604,8 +2618,11 @@
 		    (*ecx & CPUID_INTC_ECX_OSXSAVE)) {
 			hwcap_flags |= AV_386_XSAVE;
 
-			if (*ecx & CPUID_INTC_ECX_AVX)
+			if (*ecx & CPUID_INTC_ECX_AVX) {
 				hwcap_flags |= AV_386_AVX;
+				if (*ecx & CPUID_INTC_ECX_F16C)
+					hwcap_flags_2 |= AV_386_2_F16C;
+			}
 		}
 		if (*ecx & CPUID_INTC_ECX_VMX)
 			hwcap_flags |= AV_386_VMX;
@@ -2624,6 +2641,9 @@
 			hwcap_flags |= AV_386_CMOV;
 		if (*ecx & CPUID_INTC_ECX_CX16)
 			hwcap_flags |= AV_386_CX16;
+
+		if (*ecx & CPUID_INTC_ECX_RDRAND)
+			hwcap_flags_2 |= AV_386_2_RDRAND;
 	}
 
 	if (cpi->cpi_xmaxeax < 0x80000001)
@@ -2739,7 +2759,10 @@
 
 pass4_done:
 	cpi->cpi_pass = 4;
-	return (hwcap_flags);
+	if (hwcap_out != NULL) {
+		hwcap_out[0] = hwcap_flags;
+		hwcap_out[1] = hwcap_flags_2;
+	}
 }