2 # Copyright © 2000, The AROS Development Team. All rights reserved.
5 # Desc: i386 compatable CPU detection routine
9 #include <aros/asmcall.h>
10 #include "cpu_intern.h"
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 );
22 THIS FUNCTION IS CALLED A> BY THE BOOT CPU DURING EXEC INIT, AND B> BY SECONDARY PROCESSORS IN THEIR INIT PHASE
26 This code is run in a supervisor state - and as such cant contain kprinf output.
31 void i386_CheckCPU_Type( struct i386_compat_intern
*CPU_intern
)
33 unsigned long li
,maxi
,maxei
,eax
,ebx
,ecx
,edx
,newcr0
;
38 CPU_intern
->x86_cpuid
= -1;
41 #warning 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 #warning 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
= &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
;
82 /* Update CR0 register */
84 /* Set AM,WP,NE and MP */
90 /* Update CR0 reg. i386 version */
97 #warning TODO: Next line disabled due to problems .. (setcr0)
100 CPU_intern
->x86_hard_math
= i386_CheckCPU_FPU();
105 #warning TODO: Next line disabled due to problems .. (invalidate LDT etc,)
107 /* Clear D flag as needed by AROS and gcc */
109 asm volatile( " xorl %%eax,%%eax\n\t"
112 :: "m" (unused
) : "eax","ax","memory" );
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. */
132 asm volatile( " clts\n\t"
136 : "=r" (fpu
) : "m" (unused
) : "%0", "ax", "al", "memory" );
138 //kprintf(" tested ..");
139 for (loop
= 0; loop
< 100000000; loop
++)
144 asm volatile( " movl %%cr0,%%eax\n\t" /* no coprocessor: have to set bits */
145 " xorl $4,%%eax\n\t" /* set EM */
147 :: "m" (unused
) : "eax","memory" );
152 asm volatile( ".byte 0xDB,0xE4" ); /* fsetpm for 287, ignored by 387 */