_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_1 11
|
||||||
#define _CPUF_I386_SSE4_2 12
|
#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));
|
_PROTOTYPE(int _cpufeature, (int featureno));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,7 +15,7 @@ _PROTOTYPE(void std_err, (char *_s));
|
||||||
_PROTOTYPE(void prints, (const char *_s, ...));
|
_PROTOTYPE(void prints, (const char *_s, ...));
|
||||||
_PROTOTYPE(int fsversion, (char *_dev, char *_prog));
|
_PROTOTYPE(int fsversion, (char *_dev, char *_prog));
|
||||||
_PROTOTYPE(int getprocessor, (void));
|
_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 load_mtab, (char *_prog_name));
|
||||||
_PROTOTYPE(int rewrite_mtab, (char *_prog_name));
|
_PROTOTYPE(int rewrite_mtab, (char *_prog_name));
|
||||||
_PROTOTYPE(int get_mtab_entry, (char *_s1, char *_s2, char *_s3, char *_s4));
|
_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_PGE (1L << 13) /* Page Global (bit) Enable */
|
||||||
#define CPUID1_EDX_APIC_ON_CHIP (1L << 9) /* APIC is present on the chip */
|
#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_TSC (1L << 4) /* Timestamp counter present */
|
||||||
|
#define CPUID1_EDX_HTT (1L << 28) /* Supports HTT */
|
||||||
#define CPUID1_EDX_FXSR (1L << 24)
|
#define CPUID1_EDX_FXSR (1L << 24)
|
||||||
#define CPUID1_EDX_SSE (1L << 25)
|
#define CPUID1_EDX_SSE (1L << 25)
|
||||||
#define CPUID1_EDX_SSE2 (1L << 26)
|
#define CPUID1_EDX_SSE2 (1L << 26)
|
||||||
|
|
|
@ -6,57 +6,61 @@
|
||||||
|
|
||||||
int _cpufeature(int cpufeature)
|
int _cpufeature(int cpufeature)
|
||||||
{
|
{
|
||||||
u32_t cpuid_feature_edx = 0;
|
u32_t eax, ebx, ecx, edx;
|
||||||
u32_t cpuid_feature_ecx = 0;
|
|
||||||
int proc;
|
int proc;
|
||||||
|
|
||||||
|
eax = ebx = ecx = edx = 0;
|
||||||
proc = getprocessor();
|
proc = getprocessor();
|
||||||
|
|
||||||
/* If processor supports CPUID and its CPUID supports enough
|
/* If processor supports CPUID and its CPUID supports enough
|
||||||
* parameters, retrieve EDX feature flags to test against.
|
* parameters, retrieve EDX feature flags to test against.
|
||||||
*/
|
*/
|
||||||
if(proc >= 586) {
|
if(proc >= 586) {
|
||||||
u32_t params, a, b, c, d;
|
eax = 0;
|
||||||
_cpuid(0, ¶ms, &b, &c, &d);
|
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
if(params > 0) {
|
if(eax > 0) {
|
||||||
_cpuid(1, &a, &b, &cpuid_feature_ecx,
|
eax = 1;
|
||||||
&cpuid_feature_edx);
|
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(cpufeature) {
|
switch(cpufeature) {
|
||||||
case _CPUF_I386_PSE:
|
case _CPUF_I386_PSE:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_PSE;
|
return edx & CPUID1_EDX_PSE;
|
||||||
case _CPUF_I386_PGE:
|
case _CPUF_I386_PGE:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_PGE;
|
return edx & CPUID1_EDX_PGE;
|
||||||
case _CPUF_I386_APIC_ON_CHIP:
|
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:
|
case _CPUF_I386_TSC:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_TSC;
|
return edx & CPUID1_EDX_TSC;
|
||||||
case _CPUF_I386_FPU:
|
case _CPUF_I386_FPU:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_FPU;
|
return edx & CPUID1_EDX_FPU;
|
||||||
case _CPUF_I386_SSEx:
|
case _CPUF_I386_SSEx:
|
||||||
return (cpuid_feature_edx & (CPUID1_EDX_FXSR |
|
return (edx & (CPUID1_EDX_FXSR |
|
||||||
CPUID1_EDX_SSE |
|
CPUID1_EDX_SSE |
|
||||||
CPUID1_EDX_SSE2)) &&
|
CPUID1_EDX_SSE2)) &&
|
||||||
(cpuid_feature_ecx & (CPUID1_ECX_SSE3 |
|
(ecx & (CPUID1_ECX_SSE3 |
|
||||||
CPUID1_ECX_SSSE3 |
|
CPUID1_ECX_SSSE3 |
|
||||||
CPUID1_ECX_SSE4_1 |
|
CPUID1_ECX_SSE4_1 |
|
||||||
CPUID1_ECX_SSE4_2));
|
CPUID1_ECX_SSE4_2));
|
||||||
case _CPUF_I386_FXSR:
|
case _CPUF_I386_FXSR:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_FXSR;
|
return edx & CPUID1_EDX_FXSR;
|
||||||
case _CPUF_I386_SSE:
|
case _CPUF_I386_SSE:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_SSE;
|
return edx & CPUID1_EDX_SSE;
|
||||||
case _CPUF_I386_SSE2:
|
case _CPUF_I386_SSE2:
|
||||||
return cpuid_feature_edx & CPUID1_EDX_SSE2;
|
return edx & CPUID1_EDX_SSE2;
|
||||||
case _CPUF_I386_SSE3:
|
case _CPUF_I386_SSE3:
|
||||||
return cpuid_feature_ecx & CPUID1_ECX_SSE3;
|
return ecx & CPUID1_ECX_SSE3;
|
||||||
case _CPUF_I386_SSSE3:
|
case _CPUF_I386_SSSE3:
|
||||||
return cpuid_feature_ecx & CPUID1_ECX_SSSE3;
|
return ecx & CPUID1_ECX_SSSE3;
|
||||||
case _CPUF_I386_SSE4_1:
|
case _CPUF_I386_SSE4_1:
|
||||||
return cpuid_feature_ecx & CPUID1_ECX_SSE4_1;
|
return ecx & CPUID1_ECX_SSE4_1;
|
||||||
case _CPUF_I386_SSE4_2:
|
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;
|
return 0;
|
||||||
|
|
|
@ -3,41 +3,38 @@
|
||||||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
.sect .text
|
.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
|
.define __cpuid
|
||||||
|
|
||||||
__cpuid:
|
__cpuid:
|
||||||
|
! save registers
|
||||||
push ebp
|
push ebp
|
||||||
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
! save work registers
|
|
||||||
push eax
|
|
||||||
push ebx
|
push ebx
|
||||||
push ecx
|
|
||||||
push edx
|
|
||||||
|
|
||||||
! set eax parameter to cpuid and execute cpuid
|
! set parameters to cpuid and execute cpuid
|
||||||
mov eax, 24(esp)
|
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
|
.data1 0x0F, 0xA2 ! CPUID
|
||||||
|
|
||||||
! store results in pointer arguments
|
! store results in pointer arguments
|
||||||
mov ebp, 28(esp)
|
mov ebp, 12(esp)
|
||||||
mov (ebp), eax
|
mov (ebp), eax
|
||||||
mov ebp, 32(esp)
|
mov ebp, 16(esp)
|
||||||
mov (ebp), ebx
|
mov (ebp), ebx
|
||||||
mov ebp, 36(esp)
|
mov ebp, 20(esp)
|
||||||
mov (ebp), ecx
|
mov (ebp), ecx
|
||||||
mov ebp, 40(esp)
|
mov ebp, 24(esp)
|
||||||
mov (ebp), edx
|
mov (ebp), edx
|
||||||
|
|
||||||
! restore registers
|
! restore registers
|
||||||
pop edx
|
|
||||||
pop ecx
|
|
||||||
pop ebx
|
pop ebx
|
||||||
pop eax
|
|
||||||
|
|
||||||
pop ebp
|
pop ebp
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
Loading…
Reference in a new issue