2010-03-03 15:27:30 +01:00
|
|
|
/* getprocessor() - determine processor type Author: Kees J. Bot */
|
|
|
|
/* 26 Jan 1994 */
|
2010-08-17 18:44:07 +02:00
|
|
|
#include <machine/asm.h>
|
2010-03-03 15:27:30 +01:00
|
|
|
|
|
|
|
/* int getprocessor(void); */
|
|
|
|
/* Return 386, 486, 586, ... */
|
2010-08-17 18:44:07 +02:00
|
|
|
ENTRY(getprocessor)
|
2010-03-03 15:27:30 +01:00
|
|
|
push %ebp
|
|
|
|
movl %esp, %ebp
|
|
|
|
andl $0xFFFFFFFC, %esp /* Align stack to avoid AC fault */
|
|
|
|
movl $0x00040000, %ecx /* Try to flip the AC bit introduced on the 486 */
|
|
|
|
call flip
|
|
|
|
movl $386, %eax /* 386 if it didn't react to "flipping" */
|
|
|
|
je gotprocessor
|
|
|
|
movl $0x00200000, %ecx /* Try to flip the ID bit introduced on the 586 */
|
|
|
|
call flip
|
|
|
|
movl $486, %eax /* 486 if it didn't react */
|
|
|
|
je gotprocessor
|
|
|
|
pushf
|
|
|
|
pusha /* Save the world */
|
|
|
|
movl $1, %eax
|
|
|
|
.byte 0x0F, 0xA2 /* CPUID instruction tells the processor type */
|
|
|
|
andb $0x0F, %ah /* Extract the family (5, 6, ...) */
|
|
|
|
movzbl %ah, %eax
|
|
|
|
cmpl $15, %eax /* 15: extended family */
|
|
|
|
jne direct
|
|
|
|
movl $6, %eax /* Make it 686 */
|
|
|
|
direct:
|
|
|
|
imull $100, %eax /* 500, 600, ... */
|
|
|
|
addl $86, %eax /* 586, 686, ... */
|
|
|
|
movl %eax, 7*4(%esp) /* Pass eax through */
|
|
|
|
popa
|
|
|
|
popf
|
|
|
|
gotprocessor:
|
|
|
|
leave
|
|
|
|
ret
|
|
|
|
|
|
|
|
flip:
|
|
|
|
pushf /* Push eflags */
|
|
|
|
pop %eax /* eax = eflags */
|
|
|
|
movl %eax, %edx /* Save original eflags */
|
|
|
|
xorl %ecx, %eax /* Flip the bit to test */
|
|
|
|
push %eax /* Push modified eflags value */
|
|
|
|
popf /* Load modified eflags register */
|
|
|
|
pushf
|
|
|
|
pop %eax /* Get it again */
|
|
|
|
push %edx
|
|
|
|
popf /* Restore original eflags register */
|
|
|
|
xorl %edx, %eax /* See if the bit changed */
|
|
|
|
testl %ecx, %eax
|
|
|
|
ret
|