summaryrefslogtreecommitdiffstats
path: root/c
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
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')
-rw-r--r--c/src/exec/score/cpu/i386/asm.h1
-rw-r--r--c/src/exec/score/tools/hppa1.1/Makefile.in6
-rw-r--r--c/src/lib/libbsp/i386/force386/include/bsp.h7
-rw-r--r--c/src/lib/libbsp/i386/force386/startup/setvec.c2
-rw-r--r--c/src/lib/libbsp/i386/i386ex/include/bsp.h7
-rw-r--r--c/src/lib/libbsp/i386/i386ex/startup/setvec.c8
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console.c6
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.s13
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c6
-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
15 files changed, 696 insertions, 30 deletions
diff --git a/c/src/exec/score/cpu/i386/asm.h b/c/src/exec/score/cpu/i386/asm.h
index 53a4ea7e5a..9fe867c04c 100644
--- a/c/src/exec/score/cpu/i386/asm.h
+++ b/c/src/exec/score/cpu/i386/asm.h
@@ -92,6 +92,7 @@
#define edi REG (edi)
#define esp REG (esp)
#define ebp REG (ebp)
+#define cr0 REG (cr0)
#define ax REG (ax)
#define bx REG (bx)
diff --git a/c/src/exec/score/tools/hppa1.1/Makefile.in b/c/src/exec/score/tools/hppa1.1/Makefile.in
index 4a8be52b11..0ef6de8843 100644
--- a/c/src/exec/score/tools/hppa1.1/Makefile.in
+++ b/c/src/exec/score/tools/hppa1.1/Makefile.in
@@ -50,12 +50,14 @@ CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
all: ${ARCH} $(SRCS) preinstall $(PGMS)
- $(INSTALL) $(INSTBINFLAGS) ${PGMS} ${PROJECT_RELEASE}/bin
# Hack
# we are #including files that haven't been installed yet.
# Make sure they are available.
-preinstall: FORCEIT
+preinstall: ${ARCH} headers $(SRCS) $(PGMS)
+ $(INSTALL) $(INSTBINFLAGS) ${PGMS} ${PROJECT_RELEASE}/bin
+
+headers: FORCE
cd $(CPU_DIR); $(MAKE) install-headers
# Install the program(s), appending _g or _p as appropriate.
diff --git a/c/src/lib/libbsp/i386/force386/include/bsp.h b/c/src/lib/libbsp/i386/force386/include/bsp.h
index 125e53ec88..63e06e2326 100644
--- a/c/src/lib/libbsp/i386/force386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/force386/include/bsp.h
@@ -146,8 +146,11 @@ extern "C" {
extern rtems_configuration_table BSP_Configuration;
-extern i386_IDT_slot Interrupt_descriptor_table[ 256 ];
-extern i386_GDT_slot Global_descriptor_table[ 8192 ];
+#define IDT_SIZE 256
+#define GDT_SIZE 8192
+
+extern interrupt_gate_descriptor Interrupt_descriptor_table[IDT_SIZE];
+extern segment_descriptors Global_descriptor_table [GDT_SIZE];
BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */
BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */
diff --git a/c/src/lib/libbsp/i386/force386/startup/setvec.c b/c/src/lib/libbsp/i386/force386/startup/setvec.c
index 62b9494ab8..eb2cf51e42 100644
--- a/c/src/lib/libbsp/i386/force386/startup/setvec.c
+++ b/c/src/lib/libbsp/i386/force386/startup/setvec.c
@@ -32,7 +32,7 @@ i386_isr_entry set_vector( /* returns old vector */
)
{
i386_isr_entry previous_isr;
- i386_IDT_slot idt;
+ interrupt_gate_descriptor idt;
if ( type )
rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr );
diff --git a/c/src/lib/libbsp/i386/i386ex/include/bsp.h b/c/src/lib/libbsp/i386/i386ex/include/bsp.h
index 896f4e5cc3..9c37d8248e 100644
--- a/c/src/lib/libbsp/i386/i386ex/include/bsp.h
+++ b/c/src/lib/libbsp/i386/i386ex/include/bsp.h
@@ -116,8 +116,11 @@ extern "C" {
extern rtems_configuration_table BSP_Configuration;
-extern i386_IDT_slot Interrupt_descriptor_table[ 256 ];
-extern i386_GDT_slot Global_descriptor_table[ 8192 ];
+#define IDT_SIZE 256
+#define GDT_SIZE 8192
+
+extern interrupt_gate_descriptor Interrupt_descriptor_table[IDT_SIZE];
+extern segment_descriptors Global_descriptor_table [GDT_SIZE];
BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */
BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */
diff --git a/c/src/lib/libbsp/i386/i386ex/startup/setvec.c b/c/src/lib/libbsp/i386/i386ex/startup/setvec.c
index 62b9494ab8..9e7a0e758d 100644
--- a/c/src/lib/libbsp/i386/i386ex/startup/setvec.c
+++ b/c/src/lib/libbsp/i386/i386ex/startup/setvec.c
@@ -32,7 +32,7 @@ i386_isr_entry set_vector( /* returns old vector */
)
{
i386_isr_entry previous_isr;
- i386_IDT_slot idt;
+ interrupt_gate_descriptor idt;
if ( type )
rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr );
@@ -45,11 +45,7 @@ i386_isr_entry set_vector( /* returns old vector */
((idt.offset_16_31 << 16) | idt.offset_0_15);
/* build the IDT entry */
- idt.offset_0_15 = ((rtems_unsigned32) handler) & 0xffff;
- idt.segment_selector = get_cs();
- idt.reserved = 0x00;
- idt.p_dpl = 0x8e; /* present, ISR */
- idt.offset_16_31 = ((rtems_unsigned32) handler) >> 16;
+ create_interrupt_gate_descriptor( &idt, handler );
/* install the IDT entry */
Interrupt_descriptor_table[ vector ] = idt;
diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c
index c8d9a2c4f4..fb711ef578 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console.c
@@ -232,7 +232,11 @@ console_initialize(rtems_device_major_number major,
printk("Initialized console on port COM2 9600-8-N-1\n\n");
}
}
-
+#define DISPLAY_CPU_INFO
+#ifdef DISPLAY_CPU_INFO
+ printCpuInfo();
+#endif
+
return RTEMS_SUCCESSFUL;
} /* console_initialize */
diff --git a/c/src/lib/libbsp/i386/pc386/start/start.s b/c/src/lib/libbsp/i386/pc386/start/start.s
index 36fad8153c..5ff92f3134 100644
--- a/c/src/lib/libbsp/i386/pc386/start/start.s
+++ b/c/src/lib/libbsp/i386/pc386/start/start.s
@@ -64,6 +64,8 @@ BEGIN_CODE
EXTERN (_return_to_monitor)
EXTERN (_IBMPC_initVideo)
EXTERN (debugPollingGetChar)
+ EXTERN (checkCPUtypeSetCr0)
+
/*
* In case this crashes on your machine and this is not due
@@ -87,8 +89,8 @@ speakl: jmp speakl # and SPIN!!!
nop
cli # DISABLE INTERRUPTS!!!
-#ifdef DEBUG_EARLY_START
cld
+#ifdef DEBUG_EARLY_START
/*
* Must get video attribute to have a working printk.
* Note that the following code assume we already have
@@ -149,14 +151,9 @@ SYM (zero_bss):
stosl # clear a long in the bss
/*---------------------------------------------------------------------+
-| Initialize the i387.
-|
-| Using the NO WAIT form of the instruction insures that if it is not
-| present the board will not lock up or get an exception.
+| Check CPU type. Enable Cache and init coprocessor if needed.
+---------------------------------------------------------------------*/
-
- fninit # MUST USE NO-WAIT FORM
-
+ call checkCPUtypeSetCr0
/*---------------------------------------------------------------------+
| Transfer control to User's Board Support Package
+---------------------------------------------------------------------*/
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index 744808b3be..24303b36a7 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -37,7 +37,8 @@
#include <bsp.h>
#include <libcsupport.h>
#include <rtems/libio.h>
-
+#include <libcpu/cpuModel.h>
+
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
@@ -58,6 +59,7 @@ extern rtems_configuration_table Configuration;
rtems_cpu_table Cpu_table; /* CPU configuration table. */
char *rtems_progname; /* Program name - from main(). */
+extern void debugPollingGetChar();
/*-------------------------------------------------------------------------+
| External Prototypes
@@ -130,7 +132,7 @@ void bsp_start( void )
console_reserve_resources(&BSP_Configuration);
/*
- * Init trems_interrupt_management
+ * Init rtems_interrupt_management
*/
rtems_irq_mngt_init();
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
+