Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jun 2004 16:12:32 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 54116 for review
Message-ID:  <200406032312.i53NCWLq055737@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=54116

Change 54116 by peter@peter_daintree on 2004/06/03 16:11:34

	slight reorg.  promote features bits to public interfaces, test cpuid
	for the NX bits and turn on EFER_NXE etc.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/identcpu.c#31 edit
.. //depot/projects/hammer/sys/amd64/amd64/initcpu.c#9 edit
.. //depot/projects/hammer/sys/amd64/amd64/machdep.c#87 edit
.. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#61 edit
.. //depot/projects/hammer/sys/amd64/amd64/mpboot.S#11 edit
.. //depot/projects/hammer/sys/amd64/amd64/pmap.c#71 edit
.. //depot/projects/hammer/sys/amd64/include/md_var.h#26 edit
.. //depot/projects/hammer/sys/amd64/include/pmap.h#33 edit
.. //depot/projects/hammer/sys/amd64/include/specialreg.h#15 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/identcpu.c#31 (text+ko) ====

@@ -69,13 +69,10 @@
 void earlysetcpuclass(void);
 void panicifcpuunsupported(void);
 
-static void print_AMD_features(void);
 static void print_AMD_info(void);
 static void print_AMD_assoc(int i);
 
-int	cpu_feature2;		/* XXX change cpu_feature to long? */
 int	cpu_class;
-u_int	cpu_exthigh;		/* Highest arg to extended CPUID */
 char machine[] = "amd64";
 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, 
     machine, 0, "Machine class");
@@ -109,26 +106,18 @@
 	strncpy(cpu_model, amd64_cpus[cpu].cpu_name, sizeof (cpu_model));
 
 	/* Check for extended CPUID information and a processor name. */
-	if (cpu_high > 0 &&
-	    (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
-	    strcmp(cpu_vendor, "AuthenticAMD") == 0)) {
-		do_cpuid(0x80000000, regs);
-		if (regs[0] >= 0x80000000) {
-			cpu_exthigh = regs[0];
-			if (cpu_exthigh >= 0x80000004) {
-				brand = cpu_brand;
-				for (i = 0x80000002; i < 0x80000005; i++) {
-					do_cpuid(i, regs);
-					memcpy(brand, regs, sizeof(regs));
-					brand += sizeof(regs);
-				}
-			}
+	if (cpu_exthigh >= 0x80000004) {
+		brand = cpu_brand;
+		for (i = 0x80000002; i < 0x80000005; i++) {
+			do_cpuid(i, regs);
+			memcpy(brand, regs, sizeof(regs));
+			brand += sizeof(regs);
 		}
 	}
 
 	if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
-		/* Better late than never I suppose.. */
-		strcat(cpu_model, "IA-32e");
+		/* Please make up your mind folks! */
+		strcat(cpu_model, "EM64T");
 	} else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
 		/*
 		 * Values taken from AMD Processor Recognition
@@ -259,6 +248,43 @@
 				"\040<b31>"
 				);
 			}
+			if (amd_feature != 0) {
+				printf("\n  AMD Features=0x%b", amd_feature,
+					"\020"		/* in hex */
+					"\001FPU"	/* Integral FPU */
+					"\002VME"	/* Extended VM86 mode support */
+					"\003DE"	/* Debug extensions */
+					"\004PSE"	/* 4MByte page tables */
+					"\005TSC"	/* Timestamp counter */
+					"\006MSR"	/* Machine specific registers */
+					"\007PAE"	/* Physical address extension */
+					"\010MCE"	/* Machine Check support */
+					"\011CX8"	/* CMPEXCH8 instruction */
+					"\012APIC"	/* SMP local APIC */
+					"\013<b10>"
+					"\014SYSCALL"	/* SYSENTER/SYSEXIT instructions */
+					"\015MTRR"	/* Memory Type Range Registers */
+					"\016PGE"	/* PG_G (global bit) support */
+					"\017MCA"	/* Machine Check Architecture */
+					"\020CMOV"	/* CMOV instruction */
+					"\021PAT"	/* Page attributes table */
+					"\022PGE36"	/* 36 bit address space support */
+					"\023RSVD"	/* Reserved, unknown */
+					"\024MP"	/* Multiprocessor Capable */
+					"\025NX"	/* Has EFER.NXE, NX (no execute pte bit) */
+					"\026<b21>"
+					"\027MMX+"	/* AMD MMX Instruction Extensions */
+					"\030MMX"
+					"\031FXSAVE"	/* FXSAVE/FXRSTOR */
+					"\032<b25>"
+					"\033<b26>"
+					"\034<b27>"
+					"\035<b28>"
+					"\036LM"	/* Long mode */
+					"\0373DNow!+"	/* AMD 3DNow! Instruction Extensions */
+					"\0403DNow!"	/* AMD 3DNow! Instructions */
+					);
+			}
 
 			/*
 			 * If this CPU supports hyperthreading then mention
@@ -269,8 +295,6 @@
 				printf("\n  Hyperthreading: %d logical CPUs",
 				    (cpu_procinfo & CPUID_HTT_CORES) >> 16);
 		}
-		if (cpu_exthigh >= 0x80000001)
-			print_AMD_features();
 	}
 	/* Avoid ugly blank lines: only print newline when we have to. */
 	if (*cpu_vendor || cpu_id)
@@ -327,6 +351,16 @@
 	cpu_feature = regs[3];
 	cpu_feature2 = regs[2];
 
+	if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
+	    strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		do_cpuid(0x80000000, regs);
+		cpu_exthigh = regs[0];
+	}
+	if (cpu_exthigh >= 0x80000001) {
+		do_cpuid(0x80000001, regs);
+		amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+	}
+
 	/* XXX */
 	cpu = CPU_CLAWHAMMER;
 }
@@ -358,111 +392,64 @@
 static void
 print_AMD_info(void)
 {
+	u_int regs[4];
 
-	if (cpu_exthigh >= 0x80000005) {
-		u_int regs[4];
+	if (cpu_exthigh < 0x80000005)
+		return;
 
-		do_cpuid(0x80000005, regs);
-		printf("L1 2MB data TLB: %d entries", (regs[0] >> 16) & 0xff);
-		print_AMD_assoc(regs[0] >> 24);
+	do_cpuid(0x80000005, regs);
+	printf("L1 2MB data TLB: %d entries", (regs[0] >> 16) & 0xff);
+	print_AMD_assoc(regs[0] >> 24);
 
-		printf("L1 2MB instruction TLB: %d entries", regs[0] & 0xff);
-		print_AMD_assoc((regs[0] >> 8) & 0xff);
+	printf("L1 2MB instruction TLB: %d entries", regs[0] & 0xff);
+	print_AMD_assoc((regs[0] >> 8) & 0xff);
 
-		printf("L1 4KB data TLB: %d entries", (regs[1] >> 16) & 0xff);
-		print_AMD_assoc(regs[1] >> 24);
+	printf("L1 4KB data TLB: %d entries", (regs[1] >> 16) & 0xff);
+	print_AMD_assoc(regs[1] >> 24);
 
-		printf("L1 4KB instruction TLB: %d entries", regs[1] & 0xff);
-		print_AMD_assoc((regs[1] >> 8) & 0xff);
+	printf("L1 4KB instruction TLB: %d entries", regs[1] & 0xff);
+	print_AMD_assoc((regs[1] >> 8) & 0xff);
 
-		printf("L1 data cache: %d kbytes", regs[2] >> 24);
-		printf(", %d bytes/line", regs[2] & 0xff);
-		printf(", %d lines/tag", (regs[2] >> 8) & 0xff);
-		print_AMD_assoc((regs[2] >> 16) & 0xff);
+	printf("L1 data cache: %d kbytes", regs[2] >> 24);
+	printf(", %d bytes/line", regs[2] & 0xff);
+	printf(", %d lines/tag", (regs[2] >> 8) & 0xff);
+	print_AMD_assoc((regs[2] >> 16) & 0xff);
 
-		printf("L1 instruction cache: %d kbytes", regs[3] >> 24);
-		printf(", %d bytes/line", regs[3] & 0xff);
-		printf(", %d lines/tag", (regs[3] >> 8) & 0xff);
-		print_AMD_assoc((regs[3] >> 16) & 0xff);
+	printf("L1 instruction cache: %d kbytes", regs[3] >> 24);
+	printf(", %d bytes/line", regs[3] & 0xff);
+	printf(", %d lines/tag", (regs[3] >> 8) & 0xff);
+	print_AMD_assoc((regs[3] >> 16) & 0xff);
 
-		if (cpu_exthigh >= 0x80000006) {
-			do_cpuid(0x80000006, regs);
-			if ((regs[0] >> 16) != 0) {
-				printf("L2 2MB data TLB: %d entries",
-				    (regs[0] >> 16) & 0xfff);
-				print_AMD_l2_assoc(regs[0] >> 28);
-				printf("L2 2MB instruction TLB: %d entries",
-				    regs[0] & 0xfff);
-				print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
-			} else {
-				printf("L2 2MB unified TLB: %d entries",
-				    regs[0] & 0xfff);
-				print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
-			}
-			if ((regs[1] >> 16) != 0) {
-				printf("L2 4KB data TLB: %d entries",
-				    (regs[1] >> 16) & 0xfff);
-				print_AMD_l2_assoc(regs[1] >> 28);
+	if (cpu_exthigh >= 0x80000006) {
+		do_cpuid(0x80000006, regs);
+		if ((regs[0] >> 16) != 0) {
+			printf("L2 2MB data TLB: %d entries",
+			    (regs[0] >> 16) & 0xfff);
+			print_AMD_l2_assoc(regs[0] >> 28);
+			printf("L2 2MB instruction TLB: %d entries",
+			    regs[0] & 0xfff);
+			print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
+		} else {
+			printf("L2 2MB unified TLB: %d entries",
+			    regs[0] & 0xfff);
+			print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
+		}
+		if ((regs[1] >> 16) != 0) {
+			printf("L2 4KB data TLB: %d entries",
+			    (regs[1] >> 16) & 0xfff);
+			print_AMD_l2_assoc(regs[1] >> 28);
 
-				printf("L2 4KB instruction TLB: %d entries",
-				    (regs[1] >> 16) & 0xfff);
-				print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
-			} else {
-				printf("L2 4KB unified TLB: %d entries",
-				    (regs[1] >> 16) & 0xfff);
-				print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
-			}
-			printf("L2 unified cache: %d kbytes", regs[2] >> 16);
-			printf(", %d bytes/line", regs[2] & 0xff);
-			printf(", %d lines/tag", (regs[2] >> 8) & 0x0f);
-			print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);	
+			printf("L2 4KB instruction TLB: %d entries",
+			    (regs[1] >> 16) & 0xfff);
+			print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
+		} else {
+			printf("L2 4KB unified TLB: %d entries",
+			    (regs[1] >> 16) & 0xfff);
+			print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
 		}
+		printf("L2 unified cache: %d kbytes", regs[2] >> 16);
+		printf(", %d bytes/line", regs[2] & 0xff);
+		printf(", %d lines/tag", (regs[2] >> 8) & 0x0f);
+		print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);	
 	}
 }
-
-static void
-print_AMD_features(void)
-{
-	u_int regs[4];
-
-	/*
-	 * Values taken from AMD Processor Recognition
-	 * http://www.amd.com/products/cpg/athlon/techdocs/pdf/20734.pdf
-	 */
-	do_cpuid(0x80000001, regs);
-	printf("\n  AMD Features=0x%b", regs[3] & ~(cpu_feature & 0x0183f3ff),
-		"\020"		/* in hex */
-		"\001FPU"	/* Integral FPU */
-		"\002VME"	/* Extended VM86 mode support */
-		"\003DE"	/* Debug extensions */
-		"\004PSE"	/* 4MByte page tables */
-		"\005TSC"	/* Timestamp counter */
-		"\006MSR"	/* Machine specific registers */
-		"\007PAE"	/* Physical address extension */
-		"\010MCE"	/* Machine Check support */
-		"\011CX8"	/* CMPEXCH8 instruction */
-		"\012APIC"	/* SMP local APIC */
-		"\013<b10>"
-		"\014SYSCALL"	/* SYSENTER/SYSEXIT instructions */
-		"\015MTRR"	/* Memory Type Range Registers */
-		"\016PGE"	/* PG_G (global bit) support */
-		"\017MCA"	/* Machine Check Architecture */
-		"\020CMOV"	/* CMOV instruction */
-		"\021PAT"	/* Page attributes table */
-		"\022PGE36"	/* 36 bit address space support */
-		"\023RSVD"	/* Reserved, unknown */
-		"\024MP"	/* Multiprocessor Capable */
-		"\025NX"	/* Has EFER.NXE, NX (no execute pte bit) */
-		"\026<b21>"
-		"\027MMX+"	/* AMD MMX Instruction Extensions */
-		"\030MMX"
-		"\031FXSAVE"	/* FXSAVE/FXRSTOR */
-		"\032<b25>"
-		"\033<b26>"
-		"\034<b27>"
-		"\035<b28>"
-		"\036LM"	/* Long mode */
-		"\0373DNow!+"	/* AMD 3DNow! Instruction Extensions */
-		"\0403DNow!"	/* AMD 3DNow! Instructions */
-		);
-}

==== //depot/projects/hammer/sys/amd64/amd64/initcpu.c#9 (text+ko) ====

@@ -41,7 +41,8 @@
 #include <machine/md_var.h>
 #include <machine/specialreg.h>
 
-void initializecpu(void);
+#include <vm/vm.h>
+#include <vm/pmap.h>
 
 static int	hw_instruction_sse;
 SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
@@ -49,31 +50,30 @@
 
 int	cpu;			/* Are we 386, 386sx, 486, etc? */
 u_int	cpu_feature;		/* Feature flags */
+u_int	cpu_feature2;		/* Feature flags */
+u_int	amd_feature;		/* Feature flags */
 u_int	cpu_high;		/* Highest arg to CPUID */
+u_int	cpu_exthigh;		/* Highest arg to extended CPUID */
 u_int	cpu_id;			/* Stepping ID */
 u_int	cpu_procinfo;		/* HyperThreading Info / Brand Index / CLFUSH */
 char	cpu_vendor[20];		/* CPU Origin code */
 u_int	cpu_fxsr;		/* SSE enabled */
 
 /*
- * Initialize CR4 (Control register 4) to enable SSE instructions.
+ * Initialize CPU control registers
  */
 void
-enable_sse(void)
+initializecpu(void)
 {
+	uint64_t msr;
+
 	if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) {
 		load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
 		cpu_fxsr = hw_instruction_sse = 1;
 	}
-}
-
-void
-initializecpu(void)
-{
-
-	switch (cpu) {
-	default:
-		break;
+	if ((amd_feature & AMDID_NX) != 0) {
+		msr = rdmsr(MSR_EFER) | EFER_NXE;
+		wrmsr(MSR_EFER, msr);
+		pg_nx = PG_NX;
 	}
-	enable_sse();
 }

==== //depot/projects/hammer/sys/amd64/amd64/machdep.c#87 (text+ko) ====

@@ -130,7 +130,6 @@
 extern void printcpuinfo(void);	/* XXX header file */
 extern void identify_cpu(void);
 extern void panicifcpuunsupported(void);
-extern void initializecpu(void);
 
 #define	CS_SECURE(cs)		(ISPL(cs) == SEL_UPL)
 #define	EFL_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
@@ -1108,12 +1107,6 @@
 #error "have you forgotten the isa device?";
 #endif
 
-#if 0	/* Not till we test the features bit */
-	/* Turn on PTE NX (no execute) bit */
-	msr = rdmsr(MSR_EFER) | EFER_NXE;
-	wrmsr(MSR_EFER, msr);
-#endif
-
 	proc0.p_uarea = (struct user *)(physfree + KERNBASE);
 	bzero(proc0.p_uarea, UAREA_PAGES * PAGE_SIZE);
 	physfree += UAREA_PAGES * PAGE_SIZE;

==== //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#61 (text+ko) ====

@@ -432,8 +432,8 @@
 	/* set up FPU state on the AP */
 	fpuinit();
 
-	/* set up SSE registers */
-	enable_sse();
+	/* set up SSE/NX registers */
+	initializecpu();
 
 	/* A quick check from sanity claus */
 	if (PCPU_GET(apic_id) != lapic_id()) {

==== //depot/projects/hammer/sys/amd64/amd64/mpboot.S#11 (text+ko) ====

@@ -102,11 +102,7 @@
 	 */
 	movl	$MSR_EFER, %ecx
 	rdmsr
-#if 0	/* not till we test the NX cpuid bits */
-	orl	$EFER_LME | EFER_SCE | EFER_NXE, %eax
-#else
 	orl	$EFER_LME | EFER_SCE, %eax
-#endif
 	wrmsr
 
 	/*

==== //depot/projects/hammer/sys/amd64/amd64/pmap.c#71 (text+ko) ====

@@ -174,6 +174,7 @@
 static int ndmpdp;
 static vm_paddr_t dmaplimit;
 vm_offset_t kernel_vm_end;
+pt_entry_t	pg_nx;
 
 static u_int64_t	KPTphys;	/* phys addr of kernel level 1 */
 static u_int64_t	KPDphys;	/* phys addr of kernel level 2 */
@@ -1944,10 +1945,8 @@
 	newpte = (pt_entry_t)(pa | PG_V);
 	if ((prot & VM_PROT_WRITE) != 0)
 		newpte |= PG_RW;
-#ifdef PG_NX
 	if ((prot & VM_PROT_EXECUTE) == 0)
-		newpte |= PG_NX;
-#endif
+		newpte |= pg_nx;
 	if (wired)
 		newpte |= PG_W;
 	if (va < VM_MAXUSER_ADDRESS)

==== //depot/projects/hammer/sys/amd64/include/md_var.h#26 (text+ko) ====

@@ -42,6 +42,8 @@
 extern	int	busdma_swi_pending;
 extern	u_int	cpu_exthigh;
 extern	u_int	cpu_feature;
+extern	u_int	cpu_feature2;
+extern	u_int	amd_feature;
 extern	u_int	cpu_fxsr;
 extern	u_int	cpu_high;
 extern	u_int	cpu_id;
@@ -63,7 +65,7 @@
 void	cpu_setregs(void);
 void	doreti_iret(void) __asm(__STRING(doreti_iret));
 void	doreti_iret_fault(void) __asm(__STRING(doreti_iret_fault));
-void	enable_sse(void);
+void	initializecpu(void);
 void	fillw(int /*u_short*/ pat, void *base, size_t cnt);
 void	fpstate_drop(struct thread *td);
 int	is_physical_memory(vm_paddr_t addr);

==== //depot/projects/hammer/sys/amd64/include/pmap.h#33 (text+ko) ====

@@ -62,6 +62,7 @@
 #define	PG_AVAIL1	0x200	/*    /	Available for system	*/
 #define	PG_AVAIL2	0x400	/*   <	programmers use		*/
 #define	PG_AVAIL3	0x800	/*    \				*/
+#define	PG_NX		(1ul<<63) /* No-execute */
 
 
 /* Our various interpretations of the above */
@@ -202,6 +203,8 @@
 
 #define	pde_store(pdep, pde)	pte_store((pdep), (pde))
 
+extern pt_entry_t pg_nx;
+
 #endif /* _KERNEL */
 
 /*

==== //depot/projects/hammer/sys/amd64/include/specialreg.h#15 (text+ko) ====

@@ -112,6 +112,22 @@
 #define	CPUID_B30	0x40000000
 #define	CPUID_PBE	0x80000000
 
+#define CPUID2_SSE3	0x00000001
+#define CPUID2_MON	0x00000008
+#define CPUID2_DS_CPL	0x00000010
+#define CPUID2_EST	0x00000080
+#define CPUID2_TM2	0x00000100
+#define CPUID2_CNTXID	0x00000400
+#define CPUID2_CX16	0x00002000
+
+/*
+ * Important bits in the AMD extended cpuid flags
+ */
+#define AMDID_SYSCALL	0x00000800
+#define AMDID_MP	0x00080000
+#define AMDID_NX	0x00100000
+#define AMDID_LM	0x20000000
+
 /*
  * CPUID instruction 1 ebx info
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406032312.i53NCWLq055737>