From 80d671aea75369ac538037f43727588d7973ce5d Mon Sep 17 00:00:00 2001 From: Tomas Hruby Date: Fri, 15 Jan 2010 15:23:57 +0000 Subject: [PATCH] _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 --- include/minix/cpufeature.h | 3 ++ include/minix/minlib.h | 2 +- include/sys/vm_i386.h | 1 + lib/i386/misc/_cpufeature.c | 56 ++++++++++++++++++++----------------- lib/i386/misc/_cpuid.s | 33 ++++++++++------------ 5 files changed, 50 insertions(+), 45 deletions(-) diff --git a/include/minix/cpufeature.h b/include/minix/cpufeature.h index 94e77f81a..0eea544d9 100644 --- a/include/minix/cpufeature.h +++ b/include/minix/cpufeature.h @@ -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 diff --git a/include/minix/minlib.h b/include/minix/minlib.h index dd3ca040c..3fe63fb28 100644 --- a/include/minix/minlib.h +++ b/include/minix/minlib.h @@ -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)); diff --git a/include/sys/vm_i386.h b/include/sys/vm_i386.h index a864a078a..0124db54f 100644 --- a/include/sys/vm_i386.h +++ b/include/sys/vm_i386.h @@ -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) diff --git a/lib/i386/misc/_cpufeature.c b/lib/i386/misc/_cpufeature.c index 84642bd44..90f48166d 100644 --- a/lib/i386/misc/_cpufeature.c +++ b/lib/i386/misc/_cpufeature.c @@ -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 | - CPUID1_EDX_SSE | - CPUID1_EDX_SSE2)) && - (cpuid_feature_ecx & (CPUID1_ECX_SSE3 | - CPUID1_ECX_SSSE3 | - CPUID1_ECX_SSE4_1 | - CPUID1_ECX_SSE4_2)); + return (edx & (CPUID1_EDX_FXSR | + CPUID1_EDX_SSE | + CPUID1_EDX_SSE2)) && + (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; diff --git a/lib/i386/misc/_cpuid.s b/lib/i386/misc/_cpuid.s index 7be01bf53..c967fe0fb 100644 --- a/lib/i386/misc/_cpuid.s +++ b/lib/i386/misc/_cpuid.s @@ -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 -- 2.44.0