| 1 | ! getprocessor() - determine processor type Author: Kees J. Bot
|
|---|
| 2 | ! 26 Jan 1994
|
|---|
| 3 |
|
|---|
| 4 | .text
|
|---|
| 5 |
|
|---|
| 6 | o32 = 0x66 ! 32 bit operand size prefix
|
|---|
| 7 |
|
|---|
| 8 | ! int getprocessor(void);
|
|---|
| 9 | ! Return 86, 186, 286, 386, 486, 586, ...
|
|---|
| 10 |
|
|---|
| 11 | .define _getprocessor
|
|---|
| 12 |
|
|---|
| 13 | _getprocessor:
|
|---|
| 14 | push bp
|
|---|
| 15 | mov bp, sp
|
|---|
| 16 | push sp ! see if pushed sp == sp
|
|---|
| 17 | pop ax
|
|---|
| 18 | cmp ax, sp
|
|---|
| 19 | jz new_processor
|
|---|
| 20 | mov cx, #0x0120 ! see if shifts are mod 32
|
|---|
| 21 | shlb ch, cl ! zero tells if 86
|
|---|
| 22 | mov ax, #86
|
|---|
| 23 | jz got_processor
|
|---|
| 24 | mov ax, #186
|
|---|
| 25 | jmp got_processor
|
|---|
| 26 |
|
|---|
| 27 | new_processor: ! see if high bits are set in saved IDT
|
|---|
| 28 | sub sp, #6 ! space for IDT ptr
|
|---|
| 29 | sidt -6(bp) ! save 3 word IDT ptr
|
|---|
| 30 | cmpb -1(bp), #0xFF ! top byte of IDT ptr is always FF on 286
|
|---|
| 31 | mov ax, #286
|
|---|
| 32 | je got_processor
|
|---|
| 33 |
|
|---|
| 34 | ! 386, 486, 586
|
|---|
| 35 | and sp, #0xFFFC ! Align stack to avoid AC fault (needed?)
|
|---|
| 36 | mov cx, #0x0004 ! Try to flip the AC bit introduced on the 486
|
|---|
| 37 | call flip
|
|---|
| 38 | mov ax, #386 ! 386 if it didn't react to "flipping"
|
|---|
| 39 | jz got_processor
|
|---|
| 40 | mov cx, #0x0020 ! Try to flip the ID bit introduced on the 586
|
|---|
| 41 | call flip
|
|---|
| 42 | mov ax, #486 ! 486 if it didn't react
|
|---|
| 43 | jz got_processor
|
|---|
| 44 | .data1 o32
|
|---|
| 45 | pushf
|
|---|
| 46 | .data1 o32
|
|---|
| 47 | pusha ! Save the world
|
|---|
| 48 | .data1 o32
|
|---|
| 49 | xor ax, ax
|
|---|
| 50 | inc ax ! eax = 1
|
|---|
| 51 | .data1 0x0F, 0xA2 ! CPUID instruction tells the processor type
|
|---|
| 52 | andb ah, #0x0F ! Extract the family (5, 6, ...)
|
|---|
| 53 | movb al, ah
|
|---|
| 54 | movb ah, #100
|
|---|
| 55 | mulb ah ! 500, 600, ...
|
|---|
| 56 | add ax, #86 ! 586, 686, ...
|
|---|
| 57 | mov bx, sp
|
|---|
| 58 | mov 7*4(bx), ax ! Pass ax through
|
|---|
| 59 | .data1 o32
|
|---|
| 60 | popa
|
|---|
| 61 | .data1 o32
|
|---|
| 62 | popf
|
|---|
| 63 |
|
|---|
| 64 | got_processor:
|
|---|
| 65 | mov sp, bp
|
|---|
| 66 | pop bp
|
|---|
| 67 | ret
|
|---|
| 68 |
|
|---|
| 69 | flip:
|
|---|
| 70 | push bx ! Save bx and realign stack to multiple of 4
|
|---|
| 71 | .data1 o32 ! About to operate on a 32 bit object
|
|---|
| 72 | pushf ! Push eflags
|
|---|
| 73 | pop ax
|
|---|
| 74 | pop dx ! dx:ax = eflags
|
|---|
| 75 | mov bx, dx ! Save original eflags (high word only)
|
|---|
| 76 | xor dx, cx ! Flip the bit to test
|
|---|
| 77 | push dx
|
|---|
| 78 | push ax ! Push modified eflags value
|
|---|
| 79 | .data1 o32
|
|---|
| 80 | popf ! Load modified eflags register
|
|---|
| 81 | .data1 o32
|
|---|
| 82 | pushf
|
|---|
| 83 | pop ax
|
|---|
| 84 | pop dx ! Get it again
|
|---|
| 85 | push bx
|
|---|
| 86 | push ax
|
|---|
| 87 | .data1 o32
|
|---|
| 88 | popf ! Restore original eflags register
|
|---|
| 89 | xor dx, bx ! See if the bit changed
|
|---|
| 90 | test dx, cx
|
|---|
| 91 | pop bx ! Restore bx
|
|---|
| 92 | ret
|
|---|