_cpuid() - full cpuid instruction wrapper
- the prototype changes to _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx) - this makes possible to use all the features of the cpuid instruction as described in the Intel specs
This commit is contained in:
parent
45eabea285
commit
80d671aea7
5 changed files with 50 additions and 45 deletions
|
@ -18,6 +18,9 @@
|
|||
#define _CPUF_I386_SSE4_1 11
|
||||
#define _CPUF_I386_SSE4_2 12
|
||||
|
||||
#define _CPUF_I386_HTT 13 /* Supports HTT */
|
||||
#define _CPUF_I386_HTT_MAX_NUM 14 /* Maximal num of threads */
|
||||
|
||||
_PROTOTYPE(int _cpufeature, (int featureno));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,7 @@ _PROTOTYPE(void std_err, (char *_s));
|
|||
_PROTOTYPE(void prints, (const char *_s, ...));
|
||||
_PROTOTYPE(int fsversion, (char *_dev, char *_prog));
|
||||
_PROTOTYPE(int getprocessor, (void));
|
||||
_PROTOTYPE(void _cpuid, (u32_t eax_in, u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx));
|
||||
_PROTOTYPE(void _cpuid, (u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx));
|
||||
_PROTOTYPE(int load_mtab, (char *_prog_name));
|
||||
_PROTOTYPE(int rewrite_mtab, (char *_prog_name));
|
||||
_PROTOTYPE(int get_mtab_entry, (char *_s1, char *_s2, char *_s3, char *_s4));
|
||||
|
|
|
@ -75,6 +75,7 @@ sys/vm_i386.h
|
|||
#define CPUID1_EDX_PGE (1L << 13) /* Page Global (bit) Enable */
|
||||
#define CPUID1_EDX_APIC_ON_CHIP (1L << 9) /* APIC is present on the chip */
|
||||
#define CPUID1_EDX_TSC (1L << 4) /* Timestamp counter present */
|
||||
#define CPUID1_EDX_HTT (1L << 28) /* Supports HTT */
|
||||
#define CPUID1_EDX_FXSR (1L << 24)
|
||||
#define CPUID1_EDX_SSE (1L << 25)
|
||||
#define CPUID1_EDX_SSE2 (1L << 26)
|
||||
|
|
|
@ -6,57 +6,61 @@
|
|||
|
||||
int _cpufeature(int cpufeature)
|
||||
{
|
||||
u32_t cpuid_feature_edx = 0;
|
||||
u32_t cpuid_feature_ecx = 0;
|
||||
u32_t eax, ebx, ecx, edx;
|
||||
int proc;
|
||||
|
||||
eax = ebx = ecx = edx = 0;
|
||||
proc = getprocessor();
|
||||
|
||||
/* If processor supports CPUID and its CPUID supports enough
|
||||
* parameters, retrieve EDX feature flags to test against.
|
||||
*/
|
||||
if(proc >= 586) {
|
||||
u32_t params, a, b, c, d;
|
||||
_cpuid(0, ¶ms, &b, &c, &d);
|
||||
if(params > 0) {
|
||||
_cpuid(1, &a, &b, &cpuid_feature_ecx,
|
||||
&cpuid_feature_edx);
|
||||
eax = 0;
|
||||
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
if(eax > 0) {
|
||||
eax = 1;
|
||||
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
}
|
||||
}
|
||||
|
||||
switch(cpufeature) {
|
||||
case _CPUF_I386_PSE:
|
||||
return cpuid_feature_edx & CPUID1_EDX_PSE;
|
||||
return edx & CPUID1_EDX_PSE;
|
||||
case _CPUF_I386_PGE:
|
||||
return cpuid_feature_edx & CPUID1_EDX_PGE;
|
||||
return edx & CPUID1_EDX_PGE;
|
||||
case _CPUF_I386_APIC_ON_CHIP:
|
||||
return cpuid_feature_edx & CPUID1_EDX_APIC_ON_CHIP;
|
||||
return edx & CPUID1_EDX_APIC_ON_CHIP;
|
||||
case _CPUF_I386_TSC:
|
||||
return cpuid_feature_edx & CPUID1_EDX_TSC;
|
||||
return edx & CPUID1_EDX_TSC;
|
||||
case _CPUF_I386_FPU:
|
||||
return cpuid_feature_edx & CPUID1_EDX_FPU;
|
||||
return edx & CPUID1_EDX_FPU;
|
||||
case _CPUF_I386_SSEx:
|
||||
return (cpuid_feature_edx & (CPUID1_EDX_FXSR |
|
||||
return (edx & (CPUID1_EDX_FXSR |
|
||||
CPUID1_EDX_SSE |
|
||||
CPUID1_EDX_SSE2)) &&
|
||||
(cpuid_feature_ecx & (CPUID1_ECX_SSE3 |
|
||||
(ecx & (CPUID1_ECX_SSE3 |
|
||||
CPUID1_ECX_SSSE3 |
|
||||
CPUID1_ECX_SSE4_1 |
|
||||
CPUID1_ECX_SSE4_2));
|
||||
case _CPUF_I386_FXSR:
|
||||
return cpuid_feature_edx & CPUID1_EDX_FXSR;
|
||||
return edx & CPUID1_EDX_FXSR;
|
||||
case _CPUF_I386_SSE:
|
||||
return cpuid_feature_edx & CPUID1_EDX_SSE;
|
||||
return edx & CPUID1_EDX_SSE;
|
||||
case _CPUF_I386_SSE2:
|
||||
return cpuid_feature_edx & CPUID1_EDX_SSE2;
|
||||
return edx & CPUID1_EDX_SSE2;
|
||||
case _CPUF_I386_SSE3:
|
||||
return cpuid_feature_ecx & CPUID1_ECX_SSE3;
|
||||
return ecx & CPUID1_ECX_SSE3;
|
||||
case _CPUF_I386_SSSE3:
|
||||
return cpuid_feature_ecx & CPUID1_ECX_SSSE3;
|
||||
return ecx & CPUID1_ECX_SSSE3;
|
||||
case _CPUF_I386_SSE4_1:
|
||||
return cpuid_feature_ecx & CPUID1_ECX_SSE4_1;
|
||||
return ecx & CPUID1_ECX_SSE4_1;
|
||||
case _CPUF_I386_SSE4_2:
|
||||
return cpuid_feature_ecx & CPUID1_ECX_SSE4_2;
|
||||
return ecx & CPUID1_ECX_SSE4_2;
|
||||
case _CPUF_I386_HTT:
|
||||
return edx & CPUID1_EDX_HTT;
|
||||
case _CPUF_I386_HTT_MAX_NUM:
|
||||
return (ebx >> 16) & 0xff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -3,41 +3,38 @@
|
|||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||
.sect .text
|
||||
|
||||
! void _cpuid(u32_t eax, u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx);
|
||||
! void _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx);
|
||||
|
||||
.define __cpuid
|
||||
|
||||
__cpuid:
|
||||
! save registers
|
||||
push ebp
|
||||
|
||||
mov ebp, esp
|
||||
|
||||
! save work registers
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
! set eax parameter to cpuid and execute cpuid
|
||||
mov eax, 24(esp)
|
||||
! set parameters to cpuid and execute cpuid
|
||||
mov ebp, 12(esp)
|
||||
mov eax, (ebp)
|
||||
mov ebp, 16(esp)
|
||||
mov ebx, (ebp)
|
||||
mov ebp, 20(esp)
|
||||
mov ecx, (ebp)
|
||||
mov ebp, 24(esp)
|
||||
mov edx, (ebp)
|
||||
.data1 0x0F, 0xA2 ! CPUID
|
||||
|
||||
! store results in pointer arguments
|
||||
mov ebp, 28(esp)
|
||||
mov ebp, 12(esp)
|
||||
mov (ebp), eax
|
||||
mov ebp, 32(esp)
|
||||
mov ebp, 16(esp)
|
||||
mov (ebp), ebx
|
||||
mov ebp, 36(esp)
|
||||
mov ebp, 20(esp)
|
||||
mov (ebp), ecx
|
||||
mov ebp, 40(esp)
|
||||
mov ebp, 24(esp)
|
||||
mov (ebp), edx
|
||||
|
||||
! restore registers
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
|
|
Loading…
Reference in a new issue