Rev 2 | 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) |
||
65 | |||
66 | SYMBOL_NAME_LABEL(X86_is386) |
||
67 | pushfl |
||
68 | popl %eax |
||
69 | movl %eax, %ecx |
||
70 | xorl $0x40000, %eax |
||
71 | pushl %eax |
||
72 | popfl |
||
73 | pushfl |
||
74 | popl %eax |
||
75 | cmp %ecx, %eax |
||
76 | jz is386 |
||
77 | |||
78 | pushl %ecx |
||
79 | popfl |
||
80 | movl $0, %eax |
||
81 | ret |
||
82 | is386: |
||
83 | movl $1, %eax |
||
84 | ret |
||
85 | |||
86 | SYMBOL_NAME_LABEL(X86_hasCPUID) |
||
87 | pushfl |
||
88 | popl %eax |
||
89 | movl %eax, %ecx |
||
90 | xorl $0x200000, %eax |
||
91 | pushl %eax |
||
92 | popfl |
||
93 | pushfl |
||
94 | popl %eax |
||
95 | xorl %ecx, %eax |
||
96 | je noCPUID |
||
97 | |||
98 | pushl %ecx /* Restore the old EFLAG value... */ |
||
99 | popfl |
||
100 | movl $1, %eax |
||
101 | ret |
||
102 | noCPUID: |
||
103 | movl $0, %eax |
||
104 | ret |
||
105 | |||
106 | SYMBOL_NAME_LABEL(X86_isCyrix) |
||
107 | xorw %ax, %ax |
||
108 | sahf |
||
109 | mov $5, %ax |
||
110 | mov $2, %bx |
||
111 | divb %bl |
||
112 | lahf |
||
113 | cmpb $2, %ah |
||
114 | jne noCyrix |
||
115 | movl $1, %eax |
||
116 | ret |
||
117 | noCyrix: |
||
118 | movl $0, %eax |
||
119 | ret |
||
120 | |||
121 | SYMBOL_NAME_LABEL(X86_get_FPU) |
||
122 | /* First of all, set the FPU type to 0... */ |
||
123 | movb $0, SYMBOL_NAME(X86_fpu) |
||
124 | fninit |
||
125 | /* Let's give some time to the FPU... |
||
126 | * We cannot use WAIT 'cause we don't know if an FPU is present... |
||
127 | */ |
||
128 | movl $2, %ecx |
||
129 | here: |
||
130 | loop here |
||
131 | movw $0x5a5a, fpu_status |
||
132 | fnstsw fpu_status |
||
133 | /* Guys, I really don't know when to wai and when not... |
||
134 | */ |
||
135 | movl $2, %ecx |
||
136 | here1: |
||
137 | loop here1 |
||
138 | movw fpu_status, %ax |
||
139 | |||
140 | cmpb $0, %al |
||
141 | jne endFPUProc |
||
142 | |||
143 | chkCW: |
||
144 | /* OK, if we are here, we have some kind of FPU... */ |
||
145 | fnstcw fpu_status |
||
146 | |||
147 | /* Guys, I really don't know when to wai and when not... |
||
148 | */ |
||
149 | movl $2, %ecx |
||
150 | here2: |
||
151 | loop here2 |
||
152 | |||
153 | movw fpu_status, %ax |
||
154 | andw $0x103f, %ax |
||
155 | cmpw $0x03F, %ax |
||
156 | jne endFPUProc |
||
157 | /* ... Err... I was wrong :(. Here we are sure to have an FPU */ |
||
158 | movb $1, SYMBOL_NAME(X86_fpu) |
||
159 | |||
160 | chkInf: |
||
161 | /* Well... I assume that if we arrive to X86_get_FPU, we are running on a |
||
162 | * 386+ processor... Hence, the following is a complete nonsense!!! |
||
163 | * I'm commenting it out, we will see... |
||
164 | */ |
||
165 | #if 0 |
||
166 | /* Um... If we have a -386, end of the story! */ |
||
167 | cmpb $3, SYMBOL_NAME(X86_cpu) |
||
168 | jle endFPUProc |
||
169 | movb $2, SYMBOL_NAME(X86_fpu) |
||
170 | fld1 |
||
171 | fldz |
||
172 | fdivp |
||
173 | fld %st |
||
174 | fchs |
||
175 | fcompp |
||
176 | fstsw fpu_status |
||
177 | wait |
||
178 | sahf |
||
179 | jz endFPUProc |
||
180 | movb $3, SYMBOL_NAME(X86_fpu) |
||
181 | #else |
||
182 | movb $3, SYMBOL_NAME(X86_fpu) |
||
183 | #endif |
||
184 | endFPUProc: |
||
185 | ret |