added CPUID code from rbench and get_cpl to be used by the
[dosdemo] / src / cpuid_s.asm
1         section .text
2 ; foo_ are watcom functions, _foo are djgpp functions
3
4 F_ID equ 0x200000
5
6         global read_cpuid
7         global _read_cpuid
8         global read_cpuid_
9 read_cpuid_:
10         push eax
11         call check_cpuid
12         pop eax
13         jnc read_cpuid_nocheck
14         mov eax, -1
15         ret
16
17 _read_cpuid:
18 read_cpuid:
19         call check_cpuid
20         mov eax, [esp + 4]
21         jnc read_cpuid_nocheck
22         mov eax, -1
23         ret
24
25         ; determine if cpuid is available. avail: cf=0, not avail: cf=1
26 check_cpuid:
27         pushf
28         pop eax
29         mov edx, eax    ; keep a copy of the original eflags in edx
30         xor eax, F_ID
31         push eax
32         popf
33         pushf
34         pop eax
35         clc
36         cmp eax, edx
37         jnz .noerr
38         stc
39 .noerr: ret
40
41         ; enter with the cpuid_info structure pointer in eax
42 read_cpuid_nocheck:
43         push ebp
44         mov ebp, esp
45         push ebx
46         push edi
47         push esi
48         push eax        ; save the original struct pointer
49         sub esp, 8
50         mov edi, eax    ; struct pointer -> edi
51
52         ; clear struct
53         cld
54         push edi
55         mov ecx, (32+48)/4
56         xor eax, eax
57         rep stosd
58         pop edi
59
60         xor eax, eax
61         mov [esp], eax  ; current index
62         cpuid
63
64         mov [edi], eax          ; maxidx
65         ; clamp to the size of our cpuid_info structure
66         cmp eax, 1
67         jbe .skipclamp
68         mov eax, 1
69 .skipclamp:
70         mov [esp + 4], eax      ; maximum index
71
72         mov [edi + 4], ebx      ; vendor name
73         mov [edi + 8], edx
74         mov [edi + 12], ecx
75         add edi, 16
76
77 .loop:  mov eax, [esp]
78         inc eax
79         cmp eax, [esp + 4]
80         ja .loopend
81         mov [esp], eax
82         cpuid
83         mov [edi], eax
84         mov [edi + 4], ebx
85         mov [edi + 8], edx
86         mov [edi + 12], ecx
87         add edi, 16
88         jmp .loop
89 .loopend:
90         ; try to retrieve the brand string (avail on P4 or newer)
91         mov eax, 80000000h
92         cpuid
93         test eax, 80000000h
94         jz .done        ; no extended cpuid functions
95         cmp eax, 80000004h
96         jb .done        ; no brand string available
97
98         ; brand string available
99         mov esi, esp            ; save esp to esi
100         mov esp, [esp + 8]      ; esp <- original struct pointer
101         add esp, 32+48          ; offset to end of brandstr
102         mov eax, 80000004h
103         cpuid
104         push edx
105         push ecx
106         push ebx
107         push eax
108         mov eax, 80000003h
109         cpuid
110         push edx
111         push ecx
112         push ebx
113         push eax
114         mov eax, 80000002h
115         cpuid
116         push edx
117         push ecx
118         push ebx
119         push eax
120         mov esp, esi    ; done restore esp
121
122 .done:  add esp, 8
123         pop eax
124         pop esi
125         pop edi
126         pop ebx
127         pop ebp
128         xor eax, eax
129         ret
130         
131 ; vi:ft=nasm: