fix filenames
[AROS.git] / arch / i386-pc / cpu / checkcpu.c
blob36cade69194450630bbe19717064d7a04b35cfef
1 #/*
2 # Copyright © 2000, The AROS Development Team. All rights reserved.
3 # $Id$
5 # Desc: i386 compatable CPU detection routine
6 # Lang: english
7 #*/
9 #include <aros/asmcall.h>
10 #include "cpu_intern.h"
12 unsigned long unused;
13 UBYTE cpu_ready=0;
15 #define i386_getcr0(currcr0) asm volatile ( "movl %%cr0,%0" : "=r" (currcr0) :);
16 #define i386_setcr0(newcr0) asm volatile ( "movl %0,%%cr0" :: "r" (newcr0) );
18 UWORD i386_CheckCPU_FPU( void );
20 /**
22 THIS FUNCTION IS CALLED A> BY THE BOOT CPU DURING EXEC INIT, AND B> BY SECONDARY PROCESSORS IN THEIR INIT PHASE
24 N.B
26 This code is run in a supervisor state - and as such cant contain kprinf output.
27 also -
29 **/
31 void i386_CheckCPU_Type( struct i386_compat_intern *CPU_intern )
33 unsigned long maxi,eax,ebx,ecx,edx,newcr0;
34 BOOL CRxSet = FALSE;
35 int i;
36 char *strVendor = NULL;
38 CPU_intern->x86_cpuid = -1;
39 CPU_intern->x86 = 3;
41 /* TODO: code the EFLAGS-> AC Bit check */
42 if ( TRUE ) /* Can we set EFLAGS-> AC Bit? */
44 CPU_intern->x86 = 4; /* Ok we have something better than a 386.. */
46 /* TODO: code the ID flag check */
47 if ( TRUE ) /* Try to change ID flag -if we can CPUID is implemented */
49 /* Ok we CPUID!! Hurray!.. */
50 i386_cpuid( 0,maxi,unused,unused,unused );
51 maxi &= 0xffff; /* The high-order word is non-zero on some Cyrix CPUs */
53 i386_cpuid( 0,unused,ebx,ecx,edx ); /* Max CPUID level supported & Vendor Name */
55 strVendor = (char *)&CPU_intern->x86_vendor_id;
57 for(i=0;i<4;i++) strVendor[i] = ( ebx >> (8*i) );
58 for(i=0;i<4;i++) strVendor[4+i] = ( edx >> (8*i) );
59 for(i=0;i<4;i++) strVendor[8+i] = ( ecx >> (8*i) );
61 if ( maxi >= 1 ) /* Is more available? Do standard stuff */
63 i386_cpuid(1,eax,ebx,unused,edx);
65 CPU_intern->x86_mask = eax & 0xf; /* cpu stepping */
66 CPU_intern->x86_model = (eax >> 4) & 0xf; /* cpu model */
67 CPU_intern->x86_vendor = (eax >> 8) & 0xf; /* cpu family */
68 CPU_intern->x86_reserved = eax >> 12;
70 CPU_intern->x86_capability = edx;
74 CRxSet = TRUE;
76 /* */
78 i386_getcr0(newcr0);
80 if ( CRxSet == TRUE )
82 /* Update CR0 register */
83 /* Save PG,PE,ET */
84 /* Set AM,WP,NE and MP */
85 newcr0 &= 0x80000011;
86 newcr0 |= 0x00050022;
88 else
90 /* Update CR0 reg. i386 version */
91 /* Save PG,PE,ET */
92 /* Set MP */
93 newcr0 &= 0x80000011;
94 newcr0 |= 0x2;
97 /* TODO: Next line disabled due to problems .. (setcr0) */
98 i386_setcr0(newcr0);
100 CPU_intern->x86_hard_math = i386_CheckCPU_FPU();
103 cpu_ready += 1;
105 /* TODO: Next line disabled due to problems .. (invalidate LDT etc,) */
106 /* Invalidate LDT */
107 /* Clear D flag as needed by AROS and gcc */
109 asm volatile( " xorl %%eax,%%eax\n\t"
110 " lldt %%ax\n\t"
111 " cld"
112 :: "m" (unused) : "eax","ax","memory" );
114 if ( cpu_ready > 1 )
116 /* We have been called as the start of the cpu init routine for a secondary processor
117 so call the initialise routine now*/
119 //initialise_secondary(); /*call the initialise secondary MP function!*/
120 //THIS NEVER RETURNS!
124 UWORD i386_CheckCPU_FPU( void ) /* This checks for 287/387. */
126 UWORD RetVAL;
127 UBYTE fpu;
128 int loop;
130 RetVAL = 0;
132 asm volatile( " clts\n\t"
133 " fninit\n\t"
134 " fstsw %%ax\n\t"
135 " movb %%al,%0"
136 : "=r" (fpu) : "m" (unused) : "%0", "ax", "al", "memory" );
138 //kprintf(" tested ..");
139 for (loop = 0; loop < 100000000; loop++)
140 loop = loop;
142 if (fpu!=0)
144 asm volatile( " movl %%cr0,%%eax\n\t" /* no coprocessor: have to set bits */
145 " xorl $4,%%eax\n\t" /* set EM */
146 " movl %%eax,%%cr0"
147 :: "m" (unused) : "eax","memory" );
149 else
151 RetVAL = 1;
152 asm volatile( ".byte 0xDB,0xE4" ); /* fsetpm for 287, ignored by 387 */
154 return RetVAL;