Watt-32 tcp/ip  2.2 dev-rel.10
cpumodel.h
Go to the documentation of this file.
1 
4 /*
5  * This file contains declaration for variables and code
6  * that may be used to get the Intel Cpu identification
7  * that has been performed by CheckCpuType() function.
8  *
9  * COPYRIGHT (c) 1998 valette@crf.canon.fr
10  *
11  * The license and distribution terms for this file may be
12  * found in the file LICENSE in this distribution or at
13  * http://www.OARcorp.com/rtems/license.html.
14  *
15  * $Id: cpumodel.h,v 1.2 1998/08/05 16:51:39 joel Exp $
16  */
17 
18 #if !defined(_w32_CPUMODEL_H) && (DOSX) /* Only for DOSX/Win32 targets */
19 #define _w32_CPUMODEL_H
20 
21 #if defined(CPU_TEST) || defined(__LCC__)
22  #undef CONST
23  #define CONST
24 #else
25  #define CONST const
26 #endif
27 
28 #if defined(__DMC__)
29  #define SYSCALL __syscall /* no underscore prefix */
30 #else
31  #define SYSCALL
32 #endif
33 
34 #if defined(__GNUC__) || defined(_MSC_VER)
35  #define DATA_DECL
36 #else
37  #define DATA_DECL cdecl
38 #endif
39 
40 extern CONST char DATA_DECL x86_type; /* type of CPU (3=386, 4=486, ...) */
41 extern CONST char DATA_DECL x86_model;
42 extern CONST char DATA_DECL x86_mask;
43 extern CONST int DATA_DECL x86_hard_math; /* FPU present */
44 extern CONST DWORD DATA_DECL x86_capability;
45 extern CONST int DATA_DECL x86_have_cpuid;
46 extern CONST char DATA_DECL x86_vendor_id[13];
47 
48 /* x86_capability bits
49  */
50 #define X86_CAPA_FPU (1UL << 0) /* Floating Point processor */
51 #define X86_CAPA_VME (1UL << 1) /* V86 Mode Extensions */
52 #define X86_CAPA_DE (1UL << 2) /* Debug Extensions */
53 #define X86_CAPA_PSE (1UL << 3) /* Page Size Extensions */
54 #define X86_CAPA_TSC (1UL << 4) /* Time Stamp Counter */
55 #define X86_CAPA_MSR (1UL << 5) /* Model Specific Registers */
56 #define X86_CAPA_PAE (1UL << 6) /* Physical Address Extensions */
57 #define X86_CAPA_MCE (1UL << 7) /* Machine Check Exception */
58 #define X86_CAPA_CX8 (1UL << 8) /* CMPXCHG8B instruction available */
59 #define X86_CAPA_APIC (1UL << 9) /* APIC present (multiproc support) */
60 #define X86_CAPA_FSC (1UL << 10) /* Fast System Call (AMD K6/Cyrix) */
61 #define X86_CAPA_SEP (1UL << 11) /* Fast system call (SYSENTER/SYSEXIT) */
62 #define X86_CAPA_MTRR (1UL << 12) /* Memory Type Range Registers */
63 #define X86_CAPA_PGE (1UL << 13) /* Page Global Enable */
64 #define X86_CAPA_MCA (1UL << 14) /* Machine Check Architecture */
65 #define X86_CAPA_CMOV (1UL << 15) /* Conditional MOVe instructions */
66 #define X86_CAPA_PAT (1UL << 16) /* Page Attribute Table */
67 #define X86_CAPA_PSE36 (1UL << 17) /* 36 bit Page Size Extenions */
68 #define X86_CAPA_PSN (1UL << 18) /* Processor Serial Number */
69 #define X86_CAPA_CFLSH (1UL << 19) /* Cache Flush */
70 #define X86_CAPA_RSRV_20 (1UL << 20) /* Reserved */
71 #define X86_CAPA_DTES (1UL << 21) /* Debug Trace Store */
72 #define X86_CAPA_ACPI (1UL << 22) /* ACPI support */
73 #define X86_CAPA_MMX (1UL << 23) /* MultiMedia Extensions */
74 #define X86_CAPA_FXSR (1UL << 24) /* FXSAVE/FXRSTOR instructions */
75 #define X86_CAPA_SSE (1UL << 25) /* SSE instructions */
76 #define X86_CAPA_SSE2 (1UL << 26) /* SSE2 instructions */
77 #define X86_CAPA_SSNOOP (1UL << 27) /* SELFSNOOP */
78 #define X86_CAPA_RSRV_28 (1UL << 28) /* Reserved */
79 #define X86_CAPA_ACC (1UL << 29) /* Automatic Clock Control */
80 #define X86_CAPA_IA64 (1UL << 30) /* IA64 instructions */
81 #define X86_CAPA_RSRV_31 (1UL << 31) /* Reserved */
82 
83 /* CR4 register bits.
84  */
85 #define CR4_TS_DISABLE 0x004
86 #define CR4_OSFXSR 0x100 /* ?? OS does FXSAVE/FXRSTOR on task switch */
87 
88 #if !defined(__LCC__)
89  #define CheckCpuType W32_NAMESPACE (CheckCpuType)
90  #define MY_CS W32_NAMESPACE (MY_CS)
91  #define MY_DS W32_NAMESPACE (MY_DS)
92  #define MY_ES W32_NAMESPACE (MY_ES)
93  #define MY_SS W32_NAMESPACE (MY_SS)
94  #define asm_ffs W32_NAMESPACE (asm_ffs)
95  #define Get_CR4 W32_NAMESPACE (Get_CR4)
96  #define SelWriteable W32_NAMESPACE (SelWriteable)
97  #define SelReadable W32_NAMESPACE (SelReadable)
98  #define get_cpuid W32_NAMESPACE (get_cpuid)
99  #define get_rdtsc W32_NAMESPACE (get_rdtsc)
100  #define get_rdtsc2 W32_NAMESPACE (get_rdtsc2)
101 
102  extern void SYSCALL cdecl CheckCpuType (void);
103  extern int SYSCALL cdecl asm_ffs (int val);
104 
105  extern WORD SYSCALL cdecl MY_CS (void);
106  extern WORD SYSCALL cdecl MY_DS (void);
107  extern WORD SYSCALL cdecl MY_ES (void);
108  extern WORD SYSCALL cdecl MY_SS (void);
109  extern DWORD SYSCALL cdecl Get_CR4 (void);
110 
111  extern BOOL SYSCALL cdecl SelWriteable(WORD sel);
112  extern BOOL SYSCALL cdecl SelReadable (WORD sel);
113 #endif
114 
115 #if defined(__WATCOMC__) && 0 /* no more need for this */
116  #pragma aux x86_type "*"
117  #pragma aux x86_model "*"
118  #pragma aux x86_mask "*"
119  #pragma aux x86_hard_math "*"
120  #pragma aux x86_capability "*"
121  #pragma aux x86_vendor_id "*"
122  #pragma aux x86_have_cpuid "*"
123 
124  #pragma aux (__cdecl) _w32_CheckCpuType "*"
125  #pragma aux (__cdecl) _w32_MY_CS "*"
126  #pragma aux (__cdecl) _w32_MY_DS "*"
127  #pragma aux (__cdecl) _w32_MY_ES "*"
128  #pragma aux (__cdecl) _w32_MY_SS "*"
129  #pragma aux (__cdecl) _w32_asm_ffs "*"
130  #pragma aux (__cdecl) _w32_Get_CR4 "*"
131  #pragma aux (__cdecl) _w32_SelWriteable "*"
132  #pragma aux (__cdecl) _w32_SelReadable "*"
133 
134 #elif defined(__HIGHC__)
135  #pragma alias (x86_type, "x86_type")
136  #pragma alias (x86_model, "x86_model")
137  #pragma alias (x86_mask, "x86_mask")
138  #pragma alias (x86_hard_math, "x86_hard_math")
139  #pragma alias (x86_capability, "x86_capability")
140  #pragma alias (x86_vendor_id, "x86_vendor_id")
141  #pragma alias (x86_have_cpuid, "x86_have_cpuid")
142 
143  #pragma alias (_w32_CheckCpuType,"_w32_CheckCpuType")
144  #pragma alias (_w32_MY_CS, "_w32_MY_CS")
145  #pragma alias (_w32_MY_DS, "_w32_MY_DS")
146  #pragma alias (_w32_MY_ES, "_w32_MY_ES")
147  #pragma alias (_w32_MY_SS, "_w32_MY_SS")
148  #pragma alias (_w32_asm_ffs, "_w32_asm_ffs")
149  #pragma alias (_w32_Get_CR4, "_w32_Get_CR4")
150  #pragma alias (_w32_SelWriteable,"_w32_SelWriteable")
151  #pragma alias (_w32_SelReadable, "_w32_SelReadable")
152 #endif
153 
154 
155 #if defined(__GNUC__) && defined(__i386__)
156  /*
157  * Call this only if x86_have_cpuid == TRUE.
158  */
159  /*@unused@*/ extern __inline__ void get_cpuid (DWORD val, DWORD *eax,
160  DWORD *ebx,DWORD *ecx,
161  DWORD *edx)
162  {
163  __asm__ __volatile__ (
164  ".byte 0x0F,0xA2;" /* cpuid opcode */
165  : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
166  : "0" (val));
167  ARGSUSED (val); /* for lint */
168  ARGSUSED (eax);
169  ARGSUSED (ebx);
170  ARGSUSED (ecx);
171  ARGSUSED (edx);
172  }
173 
174  /*
175  * Return CPU timestamp value. Don't call unless 'has_rdtsc'
176  * is TRUE. This code is originally by
177  * Tom Burgess <Tom_Burgess@bc.sympatico.ca> and
178  * Douglas Eleveld <deleveld@dds.nl>
179  */
180  extern __inline__ uint64 get_rdtsc (void)
181  {
182  register uint64 tsc;
183  __asm__ __volatile__ (
184  ".byte 0x0F, 0x31;" /* rdtsc opcode */
185  : "=A" (tsc) );
186  return (tsc);
187  }
188 
189  extern __inline__ void get_rdtsc2 (struct ulong_long *tsc)
190  {
191  __asm__ __volatile__ (
192  ".byte 0x0F, 0x31;"
193  : "=a" (tsc->lo), "=d" (tsc->hi) : );
194  }
195 
196 #elif defined(__GNUC__) && defined(__x86_64__)
197  /*
198  * Call this only if x86_have_cpuid == TRUE.
199  */
200  /*@unused@*/ extern __inline__ void get_cpuid (DWORD val, DWORD *r1,
201  DWORD *r2, DWORD *r3,
202  DWORD *r4)
203  {
204  __asm__ __volatile__ (
205  "cpuid"
206  : "=a" (*r1), "=b" (*r2), "=c" (*r3), "=d" (*r4)
207  : "a" (val));
208  ARGSUSED (val); /* for lint */
209  ARGSUSED (r1);
210  ARGSUSED (r2);
211  ARGSUSED (r3);
212  ARGSUSED (r4);
213  }
214 
215 #elif defined(WATCOM386)
216  /*
217  * Call this only if x86_have_cpuid == TRUE.
218  */
219  extern void get_cpuid (DWORD val, DWORD *eax, DWORD *ebx, DWORD *ecx, DWORD *edx);
220  #pragma aux _w32_get_cpuid = \
221  ".586" \
222  "push eax" \
223  "push ebx" \
224  "push ecx" \
225  "push edx" \
226  "mov eax, esi" \
227  "cpuid" \
228  "mov esi, [esp]" \
229  "mov [esi], edx" \
230  "mov esi, [esp+4]" \
231  "mov [esi], ecx" \
232  "mov esi, [esp+8]" \
233  "mov [esi], ebx" \
234  "mov esi, [esp+12]" \
235  "mov [esi], eax" \
236  "add esp, 16" \
237  parm [esi] [eax] [ebx] [ecx] [edx] \
238  modify [esi eax ebx ecx edx];
239 
240  extern uint64 get_rdtsc (void);
241  #pragma aux _w32_get_rdtsc = \
242  ".586" \
243  "db 0Fh, 31h" \
244  "cld" \
245  "nop" \
246  "nop" \
247  "nop" \
248  "nop" \
249  modify [eax edx];
250 
251 #elif defined(__LCC__)
252  #undef get_rdtsc
253  #define get_rdtsc() _rdtsc() /* in <intrinsics.h> */
254 
255 #else
256  /*
257  * No inlining for other targets
258  */
259  extern void SYSCALL cdecl get_cpuid (DWORD val, DWORD *_eax,
260  DWORD *_ebx, DWORD *_ecx,
261  DWORD *_edx);
262  #ifdef HAVE_UINT64
263  extern uint64 cdecl get_rdtsc (void);
264  #endif
265 #endif
266 
267 #if (DOSX) && !defined(__GNUC__)
268  extern void cdecl get_rdtsc2 (struct ulong_long *);
269 #endif
270 
271 #if defined(__HIGHC__)
272  #pragma alias (get_cpuid, "_w32_get_cpuid")
273  #pragma alias (get_rdtsc, "_w32_get_rdtsc")
274  #pragma alias (get_rdtsc2, "_w32_get_rdtsc2")
275 #endif
276 
277 #if defined(WIN32)
278  // extern uint64 win_get_rdtsc (void);
279  // #define GET_RDTSC() win_get_rdtsc()
280  #define GET_RDTSC() UNIMPLEMENTED()
281 #else
282  #define GET_RDTSC() get_rdtsc()
283 #endif
284 
285 
286 #if 0 && (defined(__BORLANDC__) || defined(__DMC__)) && \
287  (defined(__SMALL__) || defined(__LARGE__)) && defined(__SMALL32__)
288 /*
289  * Save FPU state.
290  */
291 static void pkt_save_fpu (char far *state)
292 {
293  __asm les bx, state
294  __asm fnstcw es:[bx] /* save IEM bit status */
295  __asm nop /* delay while control word saved */
296  __asm fndisi /* disable BUSY signal */
297  __asm mov ax, es:[bx] /* get original control word in AX */
298  __asm fsave es:[bx] /* save FPU state */
299  __asm fwait /* wait for save to complete */
300  __asm mov es:[bx],ax /* put original control word in saved state */
301 }
302 
303 /*
304  * Restore FPU state.
305  */
306 static void pkt_restore_fpu (char far *state)
307 {
308  __asm les bx, state
309  __asm frstor es:[bx]
310 }
311 #endif
312 
313 #undef SYSCALL
314 #undef DATA_DECL
315 
316 /*
317  * Check if a CPUID instruction is available on this CPU.
318  * Not used at the moment. See cpumodel.asm instead.
319  */
320 #if defined(__GNUC__) && defined(__x86_64__)
321 extern __inline__ BOOL have_cpuid (void)
322 {
323  return (TRUE);
324 }
325 
326 #elif defined(__GNUC__) && defined(__i386__)
327 extern __inline__ BOOL have_cpuid (void)
328 {
329  int result = -1;
330 
331  /* We're checking if the bit #21 of EFLAGS
332  * can be toggled. If yes = CPUID is available.
333  */
334  __asm__ __volatile__ (
335  "pushf\n"
336  "popl %%eax\n"
337  "xorl $0x200000, %%eax\n"
338  "movl %%eax, %%ecx\n"
339  "andl $0x200000, %%ecx\n"
340  "pushl %%eax\n"
341  "popf\n"
342  "pushf\n"
343  "popl %%eax\n"
344  "andl $0x200000, %%eax\n"
345  "xorl %%eax, %%ecx\n"
346  "movl %%ecx, %0\n"
347  : "=r" (result) : : "eax", "ecx");
348  return (result == 0);
349 }
350 
351 #elif defined(_MSC_VER) || defined(__POCC__)
352 __declspec(naked) static BOOL have_cpuid (void)
353 {
354  _asm {
355  pushfd
356  pop eax
357  mov ecx, eax
358  xor eax, 1 << 21
359  push eax
360  popfd
361  pushfd
362  pop eax
363  xor eax, ecx
364  bt eax, 21
365  jnc no_cpuid
366  mov eax, 1
367  ret
368 no_cpuid:
369  mov eax, 0
370  ret
371  }
372 }
373 #endif
374 
375 #endif /* !_w32_CPUMODEL_H && DOSX */
376 
unsigned long long uint64
our unsigned "long long" type
Definition: wattcp.h:60