Rev 1618 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* Project: OSLib |
2 | * Description: The OS Construction Kit |
||
3 | * Date: 1.6.2000 |
||
4 | * Idea by: Luca Abeni & Gerardo Lamastra |
||
5 | * |
||
6 | * OSLib is an SO project aimed at developing a common, easy-to-use |
||
7 | * low-level infrastructure for developing OS kernels and Embedded |
||
8 | * Applications; it partially derives from the HARTIK project but it |
||
9 | * currently is independently developed. |
||
10 | * |
||
11 | * OSLib is distributed under GPL License, and some of its code has |
||
12 | * been derived from the Linux kernel source; also some important |
||
13 | * ideas come from studying the DJGPP go32 extender. |
||
14 | * |
||
15 | * We acknowledge the Linux Community, Free Software Foundation, |
||
16 | * D.J. Delorie and all the other developers who believe in the |
||
17 | * freedom of software and ideas. |
||
18 | * |
||
19 | * For legalese, check out the included GPL license. |
||
20 | */ |
||
21 | |||
22 | /* CPU detection code */ |
||
23 | |||
24 | .title "CPU2.S" |
||
25 | |||
26 | #include <ll/i386/linkage.h> |
||
27 | #include <ll/i386/defs.h> |
||
28 | |||
29 | /* |
||
30 | * The following code has been extracted by Intel AP-485 |
||
31 | * Application Note: Intel Processor Identification with CPUID instruction |
||
32 | */ |
||
33 | |||
34 | .data |
||
35 | |||
36 | ASMFILE(CPU2) |
||
37 | |||
38 | .globl SYMBOL_NAME(X86_fpu) |
||
39 | |||
40 | SYMBOL_NAME_LABEL(X86_fpu) .byte 0 |
||
41 | SYMBOL_NAME_LABEL(X86_cpu) .byte 0 |
||
42 | fpu_status: .word 0 |
||
43 | |||
44 | /* |
||
45 | struct CPU { |
||
46 | DWORD X86_cpu; 0 |
||
47 | DWORD X86_cpuIdFlag; 4 |
||
48 | DWORD X86_vendor_1; 8 |
||
49 | DWORD X86_vendor_2; 12 |
||
50 | DWORD X86_vendor_3; 16 |
||
51 | DWORD X86_signature; 20 |
||
52 | DWORD X86_IntelFeature_1; 24 |
||
53 | DWORD X86_IntelFeature_2; 28 |
||
54 | DWORD X86_StandardFeature; 32 |
||
55 | } |
||
56 | */ |
||
57 | |||
58 | .text |
||
59 | |||
60 | .globl SYMBOL_NAME(X86_get_CPU) |
||
61 | .globl SYMBOL_NAME(X86_get_FPU) |
||
62 | .globl SYMBOL_NAME(X86_is386) |
||
63 | .globl SYMBOL_NAME(X86_isCyrix) |
||
64 | .globl SYMBOL_NAME(X86_hasCPUID) |
||
787 | giacomo | 65 | .globl SYMBOL_NAME(X86_enable_cyrix_cpuid) |
2 | pj | 66 | |
67 | SYMBOL_NAME_LABEL(X86_is386) |
||
68 | pushfl |
||
69 | popl %eax |
||
70 | movl %eax, %ecx |
||
71 | xorl $0x40000, %eax |
||
72 | pushl %eax |
||
73 | popfl |
||
74 | pushfl |
||
75 | popl %eax |
||
76 | cmp %ecx, %eax |
||
77 | jz is386 |
||
78 | |||
79 | pushl %ecx |
||
80 | popfl |
||
81 | movl $0, %eax |
||
82 | ret |
||
83 | is386: |
||
84 | movl $1, %eax |
||
85 | ret |
||
86 | |||
787 | giacomo | 87 | SYMBOL_NAME_LABEL(X86_enable_cyrix_cpuid) |
88 | |||
89 | pushfl |
||
90 | cli |
||
91 | /* Get Cyrix reg c3h */ |
||
92 | movb $0xc3,%al |
||
93 | outb %al,$0x22 |
||
94 | inb $0x23,%al |
||
95 | /* Enable config access */ |
||
96 | movb %al,%cl |
||
97 | movb %al,%bl |
||
98 | andb $0xf,%bl |
||
99 | orb $0x10,%bl |
||
100 | /* Set Cyrix reg c3h */ |
||
101 | movb $0xc3,%al |
||
102 | outb %al,$0x22 |
||
103 | movb %bl,%al |
||
104 | outb %al,$0x23 |
||
105 | /* Get Cyrix reg e8 */ |
||
106 | movb $0xe8,%al |
||
107 | outb %al,$0x22 |
||
108 | inb $0x23,%al |
||
109 | /* Set "CPUID" bit */ |
||
110 | orb $0x80,%al |
||
111 | movb %al,%bl |
||
112 | /* Set Cyrix reg e8 */ |
||
113 | movb $0xe8,%al |
||
114 | outb %al,$0x22 |
||
115 | movb %bl,%al |
||
116 | outb %al,$0x23 |
||
117 | /* Get Cyrix reg fe */ |
||
118 | movb $0xfe,%al |
||
119 | outb %al,$0x22 |
||
120 | inb $0x23,%al |
||
121 | /* Is CPU a 6x86(L)? */ |
||
122 | andb $0xf0,%al |
||
123 | cmpb $0x30,%al |
||
124 | jne not6x86 |
||
125 | /* Get Cyrix reg e9 */ |
||
126 | movb $0xe9,%al |
||
127 | outb %al,$0x22 |
||
128 | inb $0x23,%al |
||
129 | /* Fix 6x86 SLOP bug */ |
||
130 | andb $0xfd,%al |
||
131 | movb %al,%bl |
||
132 | /* Set Cyrix reg e9 */ |
||
133 | movb $0xe9,%al |
||
134 | outb %al,$0x22 |
||
135 | movb %bl,%al |
||
136 | outb %al,$0x23 |
||
137 | not6x86: |
||
138 | /* Set Cyrix reg c3 */ |
||
139 | movb $0xc3,%al |
||
140 | outb %al,$0x22 |
||
141 | movb %cl,%al |
||
142 | outb %al,$0x23 |
||
791 | giacomo | 143 | |
144 | /* Disable suspended mode */ |
||
145 | movb $0xc2,%al |
||
146 | outb %al,$0x22 |
||
147 | inb $0x23,%al |
||
148 | andb $0x7F,%al |
||
149 | movb %al,%bl |
||
150 | movb $0xc2,%al |
||
151 | outb %al,$0x22 |
||
152 | movb %bl,%al |
||
153 | outb %al,$0x23 |
||
154 | |||
787 | giacomo | 155 | popfl |
156 | ret |
||
157 | |||
2 | pj | 158 | SYMBOL_NAME_LABEL(X86_hasCPUID) |
159 | pushfl |
||
160 | popl %eax |
||
161 | movl %eax, %ecx |
||
162 | xorl $0x200000, %eax |
||
163 | pushl %eax |
||
164 | popfl |
||
165 | pushfl |
||
166 | popl %eax |
||
167 | xorl %ecx, %eax |
||
168 | je noCPUID |
||
169 | |||
170 | pushl %ecx /* Restore the old EFLAG value... */ |
||
171 | popfl |
||
172 | movl $1, %eax |
||
173 | ret |
||
174 | noCPUID: |
||
175 | movl $0, %eax |
||
176 | ret |
||
177 | |||
178 | SYMBOL_NAME_LABEL(X86_isCyrix) |
||
179 | xorw %ax, %ax |
||
180 | sahf |
||
181 | mov $5, %ax |
||
182 | mov $2, %bx |
||
183 | divb %bl |
||
184 | lahf |
||
185 | cmpb $2, %ah |
||
186 | jne noCyrix |
||
187 | movl $1, %eax |
||
188 | ret |
||
189 | noCyrix: |
||
190 | movl $0, %eax |
||
191 | ret |
||
192 | |||
193 | SYMBOL_NAME_LABEL(X86_get_FPU) |
||
194 | /* First of all, set the FPU type to 0... */ |
||
195 | movb $0, SYMBOL_NAME(X86_fpu) |
||
196 | fninit |
||
197 | /* Let's give some time to the FPU... |
||
198 | * We cannot use WAIT 'cause we don't know if an FPU is present... |
||
199 | */ |
||
200 | movl $2, %ecx |
||
201 | here: |
||
202 | loop here |
||
203 | movw $0x5a5a, fpu_status |
||
204 | fnstsw fpu_status |
||
205 | /* Guys, I really don't know when to wai and when not... |
||
206 | */ |
||
207 | movl $2, %ecx |
||
208 | here1: |
||
209 | loop here1 |
||
210 | movw fpu_status, %ax |
||
211 | |||
212 | cmpb $0, %al |
||
213 | jne endFPUProc |
||
214 | |||
215 | chkCW: |
||
216 | /* OK, if we are here, we have some kind of FPU... */ |
||
217 | fnstcw fpu_status |
||
218 | |||
219 | /* Guys, I really don't know when to wai and when not... |
||
220 | */ |
||
221 | movl $2, %ecx |
||
222 | here2: |
||
223 | loop here2 |
||
224 | |||
225 | movw fpu_status, %ax |
||
226 | andw $0x103f, %ax |
||
227 | cmpw $0x03F, %ax |
||
228 | jne endFPUProc |
||
229 | /* ... Err... I was wrong :(. Here we are sure to have an FPU */ |
||
230 | movb $1, SYMBOL_NAME(X86_fpu) |
||
231 | |||
232 | chkInf: |
||
233 | /* Well... I assume that if we arrive to X86_get_FPU, we are running on a |
||
234 | * 386+ processor... Hence, the following is a complete nonsense!!! |
||
235 | * I'm commenting it out, we will see... |
||
236 | */ |
||
237 | #if 0 |
||
238 | /* Um... If we have a -386, end of the story! */ |
||
239 | cmpb $3, SYMBOL_NAME(X86_cpu) |
||
240 | jle endFPUProc |
||
241 | movb $2, SYMBOL_NAME(X86_fpu) |
||
242 | fld1 |
||
243 | fldz |
||
244 | fdivp |
||
245 | fld %st |
||
246 | fchs |
||
247 | fcompp |
||
248 | fstsw fpu_status |
||
249 | wait |
||
250 | sahf |
||
251 | jz endFPUProc |
||
252 | movb $3, SYMBOL_NAME(X86_fpu) |
||
253 | #else |
||
254 | movb $3, SYMBOL_NAME(X86_fpu) |
||
255 | #endif |
||
256 | endFPUProc: |
||
257 | ret |