summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-08-05 15:15:46 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-08-05 15:15:46 +0000
commitab0df696d09f6b53b33345d207f8aead63a6fcab (patch)
treee446f792382e49b1169482837cd842a82fb2350b /c/src/lib/libcpu
parentFixed name of Buffer so this would compile. (diff)
downloadrtems-ab0df696d09f6b53b33345d207f8aead63a6fcab.tar.bz2
Automatic CPU type detection code from Eric Valette <valette@crf.canon.fr>.
Enabled on the pc386.
Diffstat (limited to 'c/src/lib/libcpu')
-rw-r--r--c/src/lib/libcpu/i386/Makefile.in6
-rw-r--r--c/src/lib/libcpu/i386/cpu.h9
-rw-r--r--c/src/lib/libcpu/i386/cpuModel.S255
-rw-r--r--c/src/lib/libcpu/i386/cpuModel.h32
-rw-r--r--c/src/lib/libcpu/i386/displayCpu.c209
-rw-r--r--c/src/lib/libcpu/i386/registers.h159
6 files changed, 664 insertions, 6 deletions
diff --git a/c/src/lib/libcpu/i386/Makefile.in b/c/src/lib/libcpu/i386/Makefile.in
index 8a1c6f0951..b1282e2b55 100644
--- a/c/src/lib/libcpu/i386/Makefile.in
+++ b/c/src/lib/libcpu/i386/Makefile.in
@@ -11,14 +11,14 @@ PROJECT_ROOT = @PROJECT_ROOT@
PGM=${ARCH}/libcpu.rel
# C source names, if any, go here -- minus the .c
-C_PIECES=cpu
+C_PIECES=cpu displayCpu
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
-H_FILES=$(srcdir)/cpu.h
+H_FILES=$(srcdir)/cpu.h $(srcdir)/registers.h $(srcdir)/cpuModel.h
# Assembly source names, if any, go here -- minus the .s
-S_PIECES=cpu_asm
+S_PIECES=cpu_asm cpuModel
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
diff --git a/c/src/lib/libcpu/i386/cpu.h b/c/src/lib/libcpu/i386/cpu.h
index cded552740..be25929a0e 100644
--- a/c/src/lib/libcpu/i386/cpu.h
+++ b/c/src/lib/libcpu/i386/cpu.h
@@ -18,8 +18,11 @@
* $Id$
*/
-#ifndef _i386_CPU_H
-#define _i386_CPU_H
+#ifndef _LIBCPU_i386_CPU_H
+#define _LIBCPU_i386_CPU_H
+
+#include <libcpu/registers.h>
+
#ifndef ASM
@@ -63,7 +66,7 @@
: "=r" ((_eflags)) : "0" ((_eflags)) \
); \
\
- _level = (_eflags & 0x0200) ? 0 : 1; \
+ _level = (_eflags & EFLAGS_INTR_ENABLE) ? 0 : 1; \
} while (0)
#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
diff --git a/c/src/lib/libcpu/i386/cpuModel.S b/c/src/lib/libcpu/i386/cpuModel.S
new file mode 100644
index 0000000000..aaace8af9f
--- /dev/null
+++ b/c/src/lib/libcpu/i386/cpuModel.S
@@ -0,0 +1,255 @@
+/* cpuModel.S
+ *
+ * This file contains all assembly code for the Intel Cpu identification.
+ * It is based on linux cpu detection code.
+ *
+ * Intel also provides public similar code in the book
+ * called :
+ *
+ * Pentium Processor Family
+ * Developer Family
+ * Volume 3 : Architecture and Programming Manual
+ *
+ * At the following place :
+ *
+ * Chapter 5 : Feature determination
+ * Chapter 25: CPUID instruction
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <asm.h>
+#include <libcpu/registers.h>
+
+BEGIN_CODE
+ PUBLIC(checkCPUtypeSetCr0);
+/*
+ * check Processor type: 386, 486, 6x86(L) or CPUID capable processor
+ */
+
+SYM (checkCPUtypeSetCr0):
+ /*
+ * Assume 386 for now
+ */
+ movl $3, SYM (x86)
+ /*
+ * Start using the EFAGS AC bit determination method described in
+ * the book mentionned above page 5.1. If this bit can be set we
+ * have a 486 or above.
+ */
+ pushfl /* save EFLAGS */
+
+ pushfl /* Get EFLAGS in EAX */
+ popl eax
+
+ movl eax,ecx /* save original EFLAGS in ECX */
+ xorl $EFLAGS_ALIGN_CHECK,eax /* flip AC bit in EAX */
+ pushl eax /* set EAX as EFLAGS */
+ popfl
+ pushfl /* Get new EFLAGS in EAX */
+ popl eax
+
+ xorl ecx,eax /* check if AC bit changed */
+ andl $EFLAGS_ALIGN_CHECK,eax
+ je is386 /* If not : we have a 386 */
+ /*
+ * Assume 486 for now
+ */
+ movl $4,SYM (x86)
+ movl ecx,eax /* Restore orig EFLAGS in EAX */
+ xorl $EFLAGS_ID,eax /* flip ID flag */
+ pushl eax /* set EAX as EFLAGS */
+ popfl
+ pushfl /* Get new EFLAGS in EAX */
+ popl eax
+
+ xorl ecx,eax /* check if ID bit changed */
+ andl $EFLAGS_ID,eax
+
+ /*
+ * if we are on a straight 486DX,
+ * SX, or 487SX we can't change it
+ * OTOH 6x86MXs and MIIs check OK
+ * Also if we are on a Cyrix 6x86(L)
+ */
+ je is486x
+
+isnew:
+ /*
+ * restore original EFLAGS
+ */
+ popfl
+ incl SYM(have_cpuid) /* we have CPUID instruction */
+
+ /* use it to get :
+ * processor type,
+ * processor model,
+ * processor mask,
+ * by using it with EAX = 1
+ */
+ movl $1, eax
+ cpuid
+
+ movb al, cl /* save reg for future use */
+
+ andb $0x0f,ah /* mask processor family */
+ movb ah,SYM (x86) /* put result in x86 var */
+
+ andb $0xf0, al /* get model */
+ shrb $4, al
+ movb al,SYM (x86_model) /* store it in x86_model */
+
+ andb $0x0f, cl /* get mask revision */
+ movb cl,SYM (x86_mask) /* store it in x86_mask */
+
+ movl edx,SYM(x86_capability) /* store feature flags in x86_capability */
+
+ /* get vendor info by using CPUID with EXA = 0 */
+ xorl eax, eax
+ cpuid
+
+ /*
+ * store results contained in ebx, edx, ecx in
+ * x86_vendor_id variable.
+ */
+ movl ebx,SYM(x86_vendor_id)
+ movl edx,SYM(x86_vendor_id)+4
+ movl ecx,SYM(x86_vendor_id)+8
+
+ movl cr0,eax /* 486+ */
+ andl $(CR0_PAGING | CR0_PROTECTION_ENABLE | CR0_EXTENSION_TYPE), eax
+ orl $(CR0_ALIGMENT_MASK | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR | CR0_MONITOR_COPROC),eax
+ jmp 2f
+
+/* Now we test if we have a Cyrix 6x86(L). We didn't test before to avoid
+ * clobbering the new BX chipset used with the Pentium II, which has a register
+ * at the same addresses as those used to access the Cyrix special configuration
+ * registers (CCRs).
+ */
+ /*
+ * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2
+ * (and it _must_ be 5 divided by 2) while other CPUs change
+ * them in undefined ways. We need to know this since we may
+ * need to enable the CPUID instruction at least.
+ * We couldn't use this test before since the PPro and PII behave
+ * like Cyrix chips in this respect.
+ */
+is486x: xor ax,ax
+ sahf
+ movb $5,ax
+ movb $2,bx
+ div bl
+ lahf
+ cmpb $2,ah
+ jne ncyrix
+ /*
+ * N.B. The pattern of accesses to 0x22 and 0x23 is *essential*
+ * so do not try to "optimize" it! For the same reason we
+ * do all this with interrupts off.
+ */
+#define setCx86(reg, val) \
+ movb reg,ax; \
+ outb ax,$0x22; \
+ movb val,ax; \
+ outb ax,$0x23
+
+#define getCx86(reg) \
+ movb reg,ax; \
+ outb ax,$0x22; \
+ inb $0x23,ax
+
+ cli
+ getCx86($0xc3) /* get CCR3 */
+ movb ax,cx /* Save old value */
+ movb ax,bx
+ andb $0x0f,bx /* Enable access to all config registers */
+ orb $0x10,bx /* by setting bit 4 */
+ setCx86($0xc3,bx)
+
+ getCx86($0xe8) /* now we can get CCR4 */
+ orb $0x80,ax /* and set bit 7 (CPUIDEN) */
+ movb ax,bx /* to enable CPUID execution */
+ setCx86($0xe8,bx)
+
+ getCx86($0xfe) /* DIR0 : let's check this is a 6x86(L) */
+ andb $0xf0,ax /* should be 3xh */
+ cmpb $0x30,ax
+ jne n6x86
+ getCx86($0xe9) /* CCR5 : we reset the SLOP bit */
+ andb $0xfd,ax /* so that udelay calculation */
+ movb ax,bx /* is correct on 6x86(L) CPUs */
+ setCx86($0xe9,bx)
+ setCx86($0xc3,cx) /* Restore old CCR3 */
+ sti
+ jmp isnew /* We enabled CPUID now */
+
+n6x86: setCx86($0xc3,cx) /* Restore old CCR3 */
+ sti
+ncyrix: /* restore original EFLAGS */
+ popfl
+ movl cr0,eax /* 486 */
+ andl $(CR0_PAGING | CR0_EXTENSION_TYPE | CR0_PROTECTION_ENABLE),eax /* Save PG,PE,ET */
+ orl $(CR0_ALIGMENT_MASK | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR | CR0_MONITOR_COPROC),eax /* set AM, WP, NE and MP */
+ jmp 2f
+is386: /* restore original EFLAGS */
+ popfl
+ movl cr0,eax /* 386 */
+ andl $(CR0_PAGING | CR0_EXTENSION_TYPE | CR0_PROTECTION_ENABLE),eax /* Save PG,PE,ET */
+ orl $CR0_MONITOR_COPROC,eax /* set MP */
+2: movl eax,cr0
+ call check_x87
+ ret
+
+
+/*
+ * We depend on ET to be correct. This checks for 287/387.
+ */
+check_x87:
+ movb $0,SYM(hard_math)
+ clts
+ fninit
+ fstsw ax
+ cmpb $0,al
+ je 1f
+ movl cr0,eax /* no coprocessor: have to set bits */
+ xorl $4,eax /* set EM */
+ movl eax,cr0
+ ret
+ .align 16
+1: movb $1,SYM(hard_math)
+ .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */
+ ret
+
+END_CODE
+
+BEGIN_DATA
+ PUBLIC(x86)
+ PUBLIC(have_cpuid)
+ PUBLIC(x86_model)
+ PUBLIC(x86_mask)
+ PUBLIC(x86_capability)
+ PUBLIC(x86_vendor_id)
+ PUBLIC(hard_math)
+
+SYM(x86):
+ .byte 0
+SYM(have_cpuid):
+ .long 0
+SYM(x86_model):
+ .byte 0
+SYM(x86_mask):
+ .byte 0
+SYM(x86_capability):
+ .long 0
+SYM(x86_vendor_id):
+ .zero 13
+SYM(hard_math):
+ .byte 0
+END_DATA
+
diff --git a/c/src/lib/libcpu/i386/cpuModel.h b/c/src/lib/libcpu/i386/cpuModel.h
new file mode 100644
index 0000000000..5d7301aab4
--- /dev/null
+++ b/c/src/lib/libcpu/i386/cpuModel.h
@@ -0,0 +1,32 @@
+/* cpuModel.h
+ *
+ * This file contains declaration for variables and code
+ * that may be used to get the Intel Cpu identification
+ * that has been performed by checkCPUtypeSetCr0 function.
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+/*
+ * Tell us the machine setup..
+ */
+#include <stdio.h>
+#include <libcpu/cpu.h>
+#include <string.h>
+
+extern char hard_math; /* flotting point coprocessor present indicator */
+extern char x86; /* type of cpu (3 = 386, 4 =486, ...) */
+extern char x86_model;
+extern char x86_mask;
+extern int x86_capability;
+extern char x86_vendor_id[13];
+extern int have_cpuid;
+extern unsigned char Cx86_step; /* cyrix processor identification */
+
+extern voidget_cpuinfo(); /* Display this information in ascii form */
diff --git a/c/src/lib/libcpu/i386/displayCpu.c b/c/src/lib/libcpu/i386/displayCpu.c
new file mode 100644
index 0000000000..3220b1151f
--- /dev/null
+++ b/c/src/lib/libcpu/i386/displayCpu.c
@@ -0,0 +1,209 @@
+/* displayCpu.c
+ *
+ * This file contains code for displaying the Intel Cpu identification
+ * that has been performed by checkCPUtypeSetCr0 function.
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+/*
+ * Tell us the machine setup..
+ */
+#include <stdio.h>
+#include <libcpu/cpu.h>
+#include <string.h>
+#include <libcpu/cpuModel.h>
+
+extern void printk(const char*, ...);
+
+unsigned char Cx86_step = 0;
+static const char *Cx86_type[] = {
+ "unknown", "1.3", "1.4", "1.5", "1.6", "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2"
+ };
+
+static const char * i486model(unsigned int nr)
+{
+ static const char *model[] = {
+ "0","DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB",
+ "10","11","12","13","Am5x86-WT","Am5x86-WB"
+ };
+ if (nr < sizeof(model)/sizeof(char *))
+ return model[nr];
+ return NULL;
+}
+
+static const char * i586model(unsigned int nr)
+{
+ static const char *model[] = {
+ "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83",
+ "Pentium MMX", NULL, NULL, "Mobile Pentium 75+",
+ "Mobile Pentium MMX"
+ };
+ if (nr < sizeof(model)/sizeof(char *))
+ return model[nr];
+ return NULL;
+}
+
+static const char * Cx86model(void)
+{
+ unsigned char nr6x86 = 0;
+ static const char *model[] = {
+ "unknown", "6x86", "6x86L", "6x86MX", "MII"
+ };
+ switch (x86) {
+ case 5:
+ nr6x86 = ((x86_capability & (1 << 8)) ? 2 : 1); /* cx8 flag only on 6x86L */
+ break;
+ case 6:
+ nr6x86 = 3;
+ break;
+ default:
+ nr6x86 = 0;
+ }
+
+ /* We must get the stepping number by reading DIR1 */
+ i386_outport_byte(0x22,0xff) ; i386_inport_byte(0x23, x86_mask);
+ switch (x86_mask) {
+ case 0x03:
+ Cx86_step = 1; /* 6x86MX Rev 1.3 */
+ break;
+ case 0x04:
+ Cx86_step = 2; /* 6x86MX Rev 1.4 */
+ break;
+ case 0x05:
+ Cx86_step = 3; /* 6x86MX Rev 1.5 */
+ break;
+ case 0x06:
+ Cx86_step = 4; /* 6x86MX Rev 1.6 */
+ break;
+ case 0x14:
+ Cx86_step = 5; /* 6x86 Rev 2.4 */
+ break;
+ case 0x15:
+ Cx86_step = 6; /* 6x86 Rev 2.5 */
+ break;
+ case 0x16:
+ Cx86_step = 7; /* 6x86 Rev 2.6 */
+ break;
+ case 0x17:
+ Cx86_step = 8; /* 6x86 Rev 2.7 or 3.7 */
+ break;
+ case 0x22:
+ Cx86_step = 9; /* 6x86L Rev 4.2 */
+ break;
+ default:
+ Cx86_step = 0;
+ }
+ return model[nr6x86];
+}
+
+static const char * i686model(unsigned int nr)
+{
+ static const char *model[] = {
+ "PPro A-step", "Pentium Pro"
+ };
+ if (nr < sizeof(model)/sizeof(char *))
+ return model[nr];
+ return NULL;
+}
+
+struct cpu_model_info {
+ int x86;
+ char *model_names[16];
+};
+
+static struct cpu_model_info amd_models[] = {
+ { 4,
+ { NULL, NULL, NULL, "DX/2", NULL, NULL, NULL, "DX/2-WB", "DX/4",
+ "DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" }},
+ { 5,
+ { "K5/SSA5 (PR-75, PR-90, PR-100)", "K5 (PR-120, PR-133)",
+ "K5 (PR-166)", "K5 (PR-200)", NULL, NULL,
+ "K6 (166 - 266)", "K6 (166 - 300)", "K6-2 (200 - 450)",
+ "K6-3D-Plus (200 - 450)", NULL, NULL, NULL, NULL, NULL, NULL }},
+};
+
+static const char * AMDmodel(void)
+{
+ const char *p=NULL;
+ int i;
+
+ if (x86_model < 16)
+ for (i=0; i<sizeof(amd_models)/sizeof(struct cpu_model_info); i++)
+ if (amd_models[i].x86 == x86) {
+ p = amd_models[i].model_names[(int)x86_model];
+ break;
+ }
+ return p;
+}
+
+static const char * getmodel(int x86, int model)
+{
+ const char *p = NULL;
+ static char nbuf[12];
+ if (strncmp(x86_vendor_id, "Cyrix", 5) == 0)
+ p = Cx86model();
+ else if(strcmp(x86_vendor_id, "AuthenticAMD")==0)
+ p = AMDmodel();
+ else {
+ switch (x86) {
+ case 4:
+ p = i486model(model);
+ break;
+ case 5:
+ p = i586model(model);
+ break;
+ case 6:
+ p = i686model(model);
+ break;
+ }
+ }
+ if (p)
+ return p;
+
+ sprintf(nbuf, "%d", model);
+ return nbuf;
+}
+
+void printCpuInfo()
+{
+ int i, len = 0;
+ static const char *x86_cap_flags[] = {
+ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+ "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov",
+ "16", "17", "18", "19", "20", "21", "22", "mmx",
+ "24", "25", "26", "27", "28", "29", "30", "31"
+ };
+
+ printk("cpu\t\t\t: %c86\n", x86+'0');
+ printk("model\t\t: %s\n",
+ have_cpuid ? getmodel(x86, x86_model) : "unknown");
+ if (x86_vendor_id [0] == '\0')
+ strcpy(x86_vendor_id, "unknown");
+ printk("vendor_id\t: %s\n", x86_vendor_id);
+
+ if (x86_mask)
+ if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) {
+ printk("stepping\t: %d\n", x86_mask);
+ }
+ else { /* we have a Cyrix */
+ printk("stepping\t: %s\n", Cx86_type[Cx86_step]);
+ }
+ else
+ printk("stepping\t: unknown\n");
+
+ printk("fpu\t\t\t: %s\n", (hard_math ? "yes" : "no"));
+ printk("cpuid\t\t: %s\n", (have_cpuid ? "yes" : "no"));
+ printk("flags\t\t:");
+ for ( i = 0 ; i < 32 ; i++ ) {
+ if ( x86_capability & (1 << i) ) {
+ printk(" %s", x86_cap_flags[i]);
+ }
+ }
+}
diff --git a/c/src/lib/libcpu/i386/registers.h b/c/src/lib/libcpu/i386/registers.h
new file mode 100644
index 0000000000..142516ca94
--- /dev/null
+++ b/c/src/lib/libcpu/i386/registers.h
@@ -0,0 +1,159 @@
+/* registers.h
+ *
+ * This file contains definition and constants related to Intel Cpu
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef _LIBCPU_i386_REGISTERS_H
+#define _LIBCPU_i386_REGISTERS_H
+
+/*
+ * definition related to EFLAGS
+ */
+#define EFLAGS_CARRY 0x1
+#define EFLAGS_PARITY 0x4
+
+#define EFLAGS_AUX_CARRY 0x10
+#define EFLAGS_ZERO 0x40
+#define EFLAGS_SIGN 0x80
+
+#define EFLAGS_TRAP 0x100
+#define EFLAGS_INTR_ENABLE 0x200
+#define EFLAGS_DIRECTION 0x400
+#define EFLAGS_OVERFLOW 0x800
+
+#define EFLAGS_IOPL_MASK 0x3000
+#define EFLAGS_NESTED_TASK 0x8000
+
+#define EFLAGS_RESUME 0x10000
+#define EFLAGS_VIRTUAL_MODE 0x20000
+#define EFLAGS_ALIGN_CHECK 0x40000
+#define EFLAGS_VIRTUAL_INTR 0x80000
+
+#define EFLAGS_VIRTUAL_INTR_PEND 0x100000
+#define EFLAGS_ID 0x200000
+
+/*
+ * definitions related to CR0
+ */
+#define CR0_PROTECTION_ENABLE 0x1
+#define CR0_MONITOR_COPROC 0x2
+#define CR0_COPROC_SOFT_EMUL 0x4
+#define CR0_FLOATING_INSTR_EXCEPTION 0x8
+
+#define CR0_EXTENSION_TYPE 0x10
+#define CR0_NUMERIC_ERROR 0x20
+
+#define CR0_WRITE_PROTECT 0x10000
+#define CR0_ALIGMENT_MASK 0x40000
+
+#define CR0_NO_WRITE_THROUGH 0x20000000
+#define CR0_PAGE_LEVEL_CACHE_DISABLE 0x40000000
+#define CR0_PAGING 0x80000000
+
+#ifndef ASM
+
+/*
+ * definition of eflags registers has a bit field structure
+ */
+typedef struct {
+ /*
+ * fist byte : bits 0->7
+ */
+ unsigned int carry : 1;
+ unsigned int : 1;
+ unsigned int parity : 1;
+ unsigned int : 1;
+
+ unsigned int auxiliary_carry : 1;
+ unsigned int : 1;
+ unsigned int zero : 1; /* result is zero */
+ unsigned int sign : 1; /* result is less than zero */
+ /*
+ * Second byte : bits 7->15
+ */
+ unsigned int trap : 1;
+ unsigned int intr_enable : 1; /* set => intr on */
+ unsigned int direction : 1; /* set => autodecrement */
+ unsigned int overflow : 1;
+
+ unsigned int IO_privilege : 2;
+ unsigned int nested_task : 1;
+ unsigned int : 1;
+ /*
+ * Third byte : bits 15->23
+ */
+ unsigned int resume : 1;
+ unsigned int virtual_mode : 1;
+ unsigned int aligment_check : 1;
+ unsigned int virtual_intr : 1;
+
+ unsigned int virtual_intr_pending : 1;
+ unsigned int id : 1;
+ unsigned int : 2;
+
+ /*
+ * fourth byte : bits 24->31 : UNUSED
+ */
+ unsigned int : 8;
+}eflags_bits;
+
+typedef union {
+ eflags_bits eflags;
+ unsigned int i;
+}eflags;
+/*
+ * definition of eflags registers has a bit field structure
+ */
+typedef struct {
+ /*
+ * fist byte : bits 0->7
+ */
+ unsigned int protection_enable : 1;
+ unsigned int monitor_coproc : 1;
+ unsigned int coproc_soft_emul : 1;
+ unsigned int floating_instr_except : 1;
+
+ unsigned int extension_type : 1;
+ unsigned int numeric_error : 1;
+ unsigned int : 2;
+ /*
+ * second byte 8->15 : UNUSED
+ */
+ unsigned int : 8;
+ /*
+ * third byte 16->23
+ */
+ unsigned int write_protect : 1;
+ unsigned int : 1;
+ unsigned int aligment_mask : 1;
+ unsigned int : 1;
+
+ unsigned int : 4;
+ /*
+ * fourth byte 24->31
+ */
+ unsigned int : 4;
+
+ unsigned int : 1;
+ unsigned int no_write_through : 1;
+ unsigned int page_level_cache_disable : 1;
+ unsigned int paging : 1;
+}cr0_bits;
+
+typedef union {
+ cr0_bits cr0;
+ unsigned int i;
+}cr0;
+
+#endif
+
+#endif
+