-
Notifications
You must be signed in to change notification settings - Fork 0
/
CPUID.asm
86 lines (60 loc) · 1.89 KB
/
CPUID.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
bits 16
global CheckCPUID
global CheckLongMode
extern PrintString
segment .text
CheckCPUID:
; Check if CPUID is supported by attempting to flip the ID bit (bit 21) in
; the FLAGS register. If we can flip it, CPUID is available.
; Copy FLAGS in to EAX via stack
pushfd
pop eax
; Copy to ECX as well for comparing later on
mov ecx, eax
; Flip the ID bit
xor eax, 1 << 21
; Copy EAX to FLAGS via the stack
push eax
popfd
; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported)
pushfd
pop eax
; Restore FLAGS from the old version stored in ECX (i.e. flipping the ID bit
; back if it was ever flipped).
push ecx
popfd
; Compare EAX and ECX. If they are equal then that means the bit wasn't
; flipped, and CPUID isn't supported.
xor eax, ecx
jz NoCPUID
; Check if CPUID supprots long ode check
mov eax, 0x80000000 ; Set the A-register to 0x80000000.
cpuid ; CPU identification.
cmp eax, 0x80000001 ; Compare the A-register with 0x80000001.
jb NoLongModeCheck ; It is less, there is no long mode.
ret
CheckLongMode:
mov eax, 0x80000001 ; Set the A-register to 0x80000001.
cpuid ; CPU identification.
test edx, 1 << 29 ; Test if the LM-bit, which is bit 29, is set in the D-register.
jz NoLongModeSupport
ret
NoCPUID:
mov bx, CPUIDFail
call PrintString
hlt
NoLongModeCheck:
mov bx, NoLongModeCheckString
call PrintString
hlt
NoLongModeSupport:
mov bx, NoLongMode
call PrintString
hlt
segment .data
CPUIDFail:
db 'No CPUID', 0xa, 0xd, 0
NoLongModeCheckString:
db 'No long mode check supported', 0xa, 0xd, 0
NoLongMode:
db 'Long Mode is not supported', 0xa, 0xd, 0