AMD cpuid feature flags for i386

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

AMD cpuid feature flags for i386

Jonathan Gray
The following lets i386 print out AMD specific feature flags
(ie NXE, LONG) similiar to what we already do on amd64.

The Cyrix 3DNOW flag is removed as it should show up
in the AMD specific flags in addition to the Intel ones.

Index: i386/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v
retrieving revision 1.140
diff -u -p -r1.140 locore.s
--- i386/locore.s 12 Oct 2011 18:30:09 -0000 1.140
+++ i386/locore.s 28 Oct 2011 09:42:38 -0000
@@ -156,6 +156,7 @@
  .globl _C_LABEL(cpuid_level)
  .globl _C_LABEL(cpu_miscinfo)
  .globl _C_LABEL(cpu_feature), _C_LABEL(cpu_ecxfeature)
+ .globl _C_LABEL(cpu_amdfeature)
  .globl _C_LABEL(cpu_cache_eax), _C_LABEL(cpu_cache_ebx)
  .globl _C_LABEL(cpu_cache_ecx), _C_LABEL(cpu_cache_edx)
  .globl _C_LABEL(cold), _C_LABEL(cnvmem), _C_LABEL(extmem)
@@ -193,6 +194,7 @@ _C_LABEL(cpu): .long 0 # are we 386, 38
 _C_LABEL(cpu_id): .long 0 # saved from 'cpuid' instruction
 _C_LABEL(cpu_miscinfo): .long 0 # misc info (apic/brand id) from 'cpuid'
 _C_LABEL(cpu_feature): .long 0 # feature flags from 'cpuid' instruction
+_C_LABEL(cpu_amdfeature): .long 0 # AMD feature flags from 'cpuid'
 _C_LABEL(cpu_ecxfeature):.long 0 # extended feature flags from 'cpuid'
 _C_LABEL(cpuid_level): .long -1 # max. lvl accepted by 'cpuid' insn
 _C_LABEL(cpu_cache_eax):.long 0
@@ -407,6 +409,9 @@ try586: /* Use the `cpuid' instruction.
  cpuid
  cmpl $0x80000000,%eax
  jbe 2f
+ movl $0x80000001,%eax
+ cpuid
+ movl %edx,RELOC(_C_LABEL(cpu_amdfeature))
  movl $0x80000002,%eax
  cpuid
  movl %eax,RELOC(_C_LABEL(cpu_brandstr))
Index: i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.505
diff -u -p -r1.505 machdep.c
--- i386/machdep.c 5 Jul 2011 04:48:01 -0000 1.505
+++ i386/machdep.c 28 Oct 2011 09:42:40 -0000
@@ -983,8 +983,17 @@ const struct cpu_cpuid_feature i386_cpui
  { CPUID_SS, "SS" },
  { CPUID_HTT, "HTT" },
  { CPUID_TM, "TM" },
- { CPUID_SBF, "SBF" },
- { CPUID_3DNOW, "3DNOW" },
+ { CPUID_SBF, "SBF" }
+};
+
+const struct cpu_cpuid_feature i386_cpuid_amdfeatures[] = {
+ { CPUID_MPC, "MPC" },
+ { CPUID_NXE, "NXE" },
+ { CPUID_MMXX, "MMXX" },
+ { CPUID_FFXSR, "FFXSR" },
+ { CPUID_LONG, "LONG" },
+ { CPUID_3DNOW2, "3DNOW2" },
+ { CPUID_3DNOW, "3DNOW" }
 };
 
 const struct cpu_cpuid_feature i386_cpuid_ecxfeatures[] = {
@@ -1826,6 +1835,14 @@ identifycpu(struct cpu_info *ci)
     i386_cpuid_features[i].feature_bit) {
  printf("%s%s", (numbits == 0 ? "" : ","),
     i386_cpuid_features[i].feature_name);
+ numbits++;
+ }
+ }
+ for (i = 0; i < nitems(i386_cpuid_amdfeatures); i++) {
+ if (cpu_amdfeature &
+    i386_cpuid_amdfeatures[i].feature_bit) {
+ printf("%s%s", (numbits == 0 ? "" : ","),
+    i386_cpuid_amdfeatures[i].feature_name);
  numbits++;
  }
  }
Index: include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.120
diff -u -p -r1.120 cpu.h
--- include/cpu.h 23 May 2011 09:54:20 -0000 1.120
+++ include/cpu.h 28 Oct 2011 09:42:41 -0000
@@ -311,6 +311,7 @@ extern char cpu_brandstr[];
 extern int cpuid_level;
 extern int cpu_miscinfo;
 extern int cpu_feature;
+extern int cpu_amdfeature;
 extern int cpu_ecxfeature;
 extern int cpu_cache_eax;
 extern int cpu_cache_ebx;
Index: include/specialreg.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/specialreg.h,v
retrieving revision 1.39
diff -u -p -r1.39 specialreg.h
--- include/specialreg.h 29 Apr 2010 17:00:48 -0000 1.39
+++ include/specialreg.h 28 Oct 2011 09:42:42 -0000
@@ -122,15 +122,6 @@
 #define CPUID_B30 0x40000000 /* reserved */
 #define CPUID_SBF 0x80000000 /* signal break on FERR */
 
-/*
- * Note: The 3DNOW flag does not really belong in this feature set since it is
- * returned by the cpuid instruction when called with 0x80000001 in eax rather
- * than 0x00000001, but cyrix3_cpu_setup() moves it to a reserved bit of the
- * feature set for simplicity
- */
-#define CPUID_3DNOW 0x40000000 /* has 3DNow! instructions (AMD) */
-#define CPUID_LONG 0x20000000 /* long mode (AMD64, ext cpuid) */
-
 #define CPUIDECX_SSE3 0x00000001 /* has SSE3 instructions */
 #define CPUIDECX_PCLMUL 0x00000002 /* Carryless Multiplication */
 #define CPUIDECX_MWAIT 0x00000008 /* Monitor/Mwait */
@@ -155,6 +146,18 @@
 #define CPUIDECX_XSAVE 0x04000000 /* XSAVE/XSTOR States */
 #define CPUIDECX_OSXSAVE 0x08000000 /* OSXSAVE */
 #define CPUIDECX_AVX 0x10000000 /* Advanced Vector Extensions */
+
+/*
+ * AMD/VIA processor specific flags.
+ */
+
+#define CPUID_MPC 0x00080000 /* Multiprocessing Capable */
+#define CPUID_NXE 0x00100000 /* No-Execute Extension */
+#define CPUID_MMXX 0x00400000 /* AMD MMX Extensions */
+#define CPUID_FFXSR 0x02000000 /* fast FP/MMX save/restore */
+#define CPUID_LONG 0x20000000 /* long mode */
+#define CPUID_3DNOW2 0x40000000 /* 3DNow! Instruction Extension */
+#define CPUID_3DNOW 0x80000000 /* 3DNow! Instructions */
 
 /*
  * Model-specific registers for the i386 family

Reply | Threaded
Open this post in threaded view
|

Re: AMD cpuid feature flags for i386

Mark Kettenis
> Date: Fri, 28 Oct 2011 20:54:48 +1100
> From: Jonathan Gray <[hidden email]>
>
> The following lets i386 print out AMD specific feature flags
> (ie NXE, LONG) similiar to what we already do on amd64.
>
> The Cyrix 3DNOW flag is removed as it should show up
> in the AMD specific flags in addition to the Intel ones.

I like thise, but:

> Index: i386/machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
> retrieving revision 1.505
> diff -u -p -r1.505 machdep.c
> --- i386/machdep.c 5 Jul 2011 04:48:01 -0000 1.505
> +++ i386/machdep.c 28 Oct 2011 09:42:40 -0000
> @@ -983,8 +983,17 @@ const struct cpu_cpuid_feature i386_cpui
>   { CPUID_SS, "SS" },
>   { CPUID_HTT, "HTT" },
>   { CPUID_TM, "TM" },
> - { CPUID_SBF, "SBF" },
> - { CPUID_3DNOW, "3DNOW" },
> + { CPUID_SBF, "SBF" }
> +};
> +
> +const struct cpu_cpuid_feature i386_cpuid_amdfeatures[] = {

The amd64 code calls this cpu_ecpuid_features.  Perhaps it is better
to use the same name or at least a similar name?  Also, these seem to
be relevant to Intel CPUs as well isn't it?

> + { CPUID_MPC, "MPC" },
> + { CPUID_NXE, "NXE" },
> + { CPUID_MMXX, "MMXX" },
> + { CPUID_FFXSR, "FFXSR" },
> + { CPUID_LONG, "LONG" },
> + { CPUID_3DNOW2, "3DNOW2" },
> + { CPUID_3DNOW, "3DNOW" }
>  };

Reply | Threaded
Open this post in threaded view
|

Re: AMD cpuid feature flags for i386

Jonathan Gray
On Fri, Oct 28, 2011 at 03:01:42PM +0200, Mark Kettenis wrote:

> > Date: Fri, 28 Oct 2011 20:54:48 +1100
> > From: Jonathan Gray <[hidden email]>
> >
> > The following lets i386 print out AMD specific feature flags
> > (ie NXE, LONG) similiar to what we already do on amd64.
> >
> > The Cyrix 3DNOW flag is removed as it should show up
> > in the AMD specific flags in addition to the Intel ones.
>
> I like thise, but:
>
> The amd64 code calls this cpu_ecpuid_features.  Perhaps it is better
> to use the same name or at least a similar name?  Also, these seem to
> be relevant to Intel CPUs as well isn't it?

The comments refer to ecx as extended as well, and I
am under the perhaps mistaken impression that AMD defines
these cpuid values, especially as many values duplicate those
found in the default results. But as the intel and amd documents
both refer to them as extended how about the following, now
with some 8000_0001 ecx flags as well.


Index: i386/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v
retrieving revision 1.140
diff -u -p -r1.140 locore.s
--- i386/locore.s 12 Oct 2011 18:30:09 -0000 1.140
+++ i386/locore.s 28 Oct 2011 13:51:36 -0000
@@ -156,6 +156,7 @@
  .globl _C_LABEL(cpuid_level)
  .globl _C_LABEL(cpu_miscinfo)
  .globl _C_LABEL(cpu_feature), _C_LABEL(cpu_ecxfeature)
+ .globl _C_LABEL(ecpu_feature), _C_LABEL(ecpu_ecxfeature)
  .globl _C_LABEL(cpu_cache_eax), _C_LABEL(cpu_cache_ebx)
  .globl _C_LABEL(cpu_cache_ecx), _C_LABEL(cpu_cache_edx)
  .globl _C_LABEL(cold), _C_LABEL(cnvmem), _C_LABEL(extmem)
@@ -193,7 +194,9 @@ _C_LABEL(cpu): .long 0 # are we 386, 38
 _C_LABEL(cpu_id): .long 0 # saved from 'cpuid' instruction
 _C_LABEL(cpu_miscinfo): .long 0 # misc info (apic/brand id) from 'cpuid'
 _C_LABEL(cpu_feature): .long 0 # feature flags from 'cpuid' instruction
-_C_LABEL(cpu_ecxfeature):.long 0 # extended feature flags from 'cpuid'
+_C_LABEL(ecpu_feature): .long 0 # extended feature flags from 'cpuid'
+_C_LABEL(cpu_ecxfeature):.long 0 # ecx feature flags from 'cpuid'
+_C_LABEL(ecpu_ecxfeature): .long 0 # extended ecx feature flags
 _C_LABEL(cpuid_level): .long -1 # max. lvl accepted by 'cpuid' insn
 _C_LABEL(cpu_cache_eax):.long 0
 _C_LABEL(cpu_cache_ebx):.long 0
@@ -407,6 +410,10 @@ try586: /* Use the `cpuid' instruction.
  cpuid
  cmpl $0x80000000,%eax
  jbe 2f
+ movl $0x80000001,%eax
+ cpuid
+ movl %edx,RELOC(_C_LABEL(ecpu_feature))
+ movl %ecx,RELOC(_C_LABEL(ecpu_ecxfeature))
  movl $0x80000002,%eax
  cpuid
  movl %eax,RELOC(_C_LABEL(cpu_brandstr))
Index: i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.505
diff -u -p -r1.505 machdep.c
--- i386/machdep.c 5 Jul 2011 04:48:01 -0000 1.505
+++ i386/machdep.c 28 Oct 2011 13:51:38 -0000
@@ -983,8 +983,17 @@ const struct cpu_cpuid_feature i386_cpui
  { CPUID_SS, "SS" },
  { CPUID_HTT, "HTT" },
  { CPUID_TM, "TM" },
- { CPUID_SBF, "SBF" },
- { CPUID_3DNOW, "3DNOW" },
+ { CPUID_SBF, "SBF" }
+};
+
+const struct cpu_cpuid_feature i386_ecpuid_features[] = {
+ { CPUID_MPC, "MPC" },
+ { CPUID_NXE, "NXE" },
+ { CPUID_MMXX, "MMXX" },
+ { CPUID_FFXSR, "FFXSR" },
+ { CPUID_LONG, "LONG" },
+ { CPUID_3DNOW2, "3DNOW2" },
+ { CPUID_3DNOW, "3DNOW" }
 };
 
 const struct cpu_cpuid_feature i386_cpuid_ecxfeatures[] = {
@@ -1014,6 +1023,16 @@ const struct cpu_cpuid_feature i386_cpui
  { CPUIDECX_AVX, "AVX" },
 };
 
+const struct cpu_cpuid_feature i386_ecpuid_ecxfeatures[] = {
+ { CPUIDECX_LAHF, "LAHF" },
+ { CPUIDECX_SVM, "SVM" },
+ { CPUIDECX_ABM, "ABM" },
+ { CPUIDECX_SSE4A, "SSE4A" },
+ { CPUIDECX_XOP, "XOP" },
+ { CPUIDECX_WDT, "WDT" },
+ { CPUIDECX_FMA4, "FMA4" }
+};
+
 void
 winchip_cpu_setup(struct cpu_info *ci)
 {
@@ -1829,6 +1848,14 @@ identifycpu(struct cpu_info *ci)
  numbits++;
  }
  }
+ for (i = 0; i < nitems(i386_ecpuid_features); i++) {
+ if (ecpu_feature &
+    i386_ecpuid_features[i].feature_bit) {
+ printf("%s%s", (numbits == 0 ? "" : ","),
+    i386_ecpuid_features[i].feature_name);
+ numbits++;
+ }
+ }
  max = sizeof(i386_cpuid_ecxfeatures)
  / sizeof(i386_cpuid_ecxfeatures[0]);
  for (i = 0; i < max; i++) {
@@ -1836,6 +1863,14 @@ identifycpu(struct cpu_info *ci)
     i386_cpuid_ecxfeatures[i].feature_bit) {
  printf("%s%s", (numbits == 0 ? "" : ","),
     i386_cpuid_ecxfeatures[i].feature_name);
+ numbits++;
+ }
+ }
+ for (i = 0; i < nitems(i386_ecpuid_ecxfeatures); i++) {
+ if (ecpu_ecxfeature &
+    i386_ecpuid_ecxfeatures[i].feature_bit) {
+ printf("%s%s", (numbits == 0 ? "" : ","),
+    i386_ecpuid_ecxfeatures[i].feature_name);
  numbits++;
  }
  }
Index: include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.120
diff -u -p -r1.120 cpu.h
--- include/cpu.h 23 May 2011 09:54:20 -0000 1.120
+++ include/cpu.h 28 Oct 2011 13:51:40 -0000
@@ -311,7 +311,9 @@ extern char cpu_brandstr[];
 extern int cpuid_level;
 extern int cpu_miscinfo;
 extern int cpu_feature;
+extern int ecpu_feature;
 extern int cpu_ecxfeature;
+extern int ecpu_ecxfeature;
 extern int cpu_cache_eax;
 extern int cpu_cache_ebx;
 extern int cpu_cache_ecx;
Index: include/specialreg.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/specialreg.h,v
retrieving revision 1.39
diff -u -p -r1.39 specialreg.h
--- include/specialreg.h 29 Apr 2010 17:00:48 -0000 1.39
+++ include/specialreg.h 28 Oct 2011 13:51:40 -0000
@@ -122,15 +122,6 @@
 #define CPUID_B30 0x40000000 /* reserved */
 #define CPUID_SBF 0x80000000 /* signal break on FERR */
 
-/*
- * Note: The 3DNOW flag does not really belong in this feature set since it is
- * returned by the cpuid instruction when called with 0x80000001 in eax rather
- * than 0x00000001, but cyrix3_cpu_setup() moves it to a reserved bit of the
- * feature set for simplicity
- */
-#define CPUID_3DNOW 0x40000000 /* has 3DNow! instructions (AMD) */
-#define CPUID_LONG 0x20000000 /* long mode (AMD64, ext cpuid) */
-
 #define CPUIDECX_SSE3 0x00000001 /* has SSE3 instructions */
 #define CPUIDECX_PCLMUL 0x00000002 /* Carryless Multiplication */
 #define CPUIDECX_MWAIT 0x00000008 /* Monitor/Mwait */
@@ -155,6 +146,26 @@
 #define CPUIDECX_XSAVE 0x04000000 /* XSAVE/XSTOR States */
 #define CPUIDECX_OSXSAVE 0x08000000 /* OSXSAVE */
 #define CPUIDECX_AVX 0x10000000 /* Advanced Vector Extensions */
+
+/*
+ * AMD/VIA processor specific flags.
+ */
+
+#define CPUID_MPC 0x00080000 /* Multiprocessing Capable */
+#define CPUID_NXE 0x00100000 /* No-Execute Extension */
+#define CPUID_MMXX 0x00400000 /* AMD MMX Extensions */
+#define CPUID_FFXSR 0x02000000 /* fast FP/MMX save/restore */
+#define CPUID_LONG 0x20000000 /* long mode */
+#define CPUID_3DNOW2 0x40000000 /* 3DNow! Instruction Extension */
+#define CPUID_3DNOW 0x80000000 /* 3DNow! Instructions */
+
+#define CPUIDECX_LAHF 0x00000001 /* LAHF and SAHF instructions */
+#define CPUIDECX_SVM 0x00000004 /* Secure Virtual Machine */
+#define CPUIDECX_ABM 0x00000020 /* LZCNT instruction */
+#define CPUIDECX_SSE4A 0x00000040 /* SSE4-A instruction set */
+#define CPUIDECX_XOP 0x00000800 /* extended operating support */
+#define CPUIDECX_WDT 0x00002000 /* watchdog timer */
+#define CPUIDECX_FMA4 0x00010000 /* 4-operand FMA instructions */
 
 /*
  * Model-specific registers for the i386 family