52 lines
2.7 KiB
C
52 lines
2.7 KiB
C
#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_CPUID4_H_
|
|
#define COSMOPOLITAN_LIBC_NEXGEN32E_CPUID4_H_
|
|
#include "libc/nexgen32e/kcpuids.h"
|
|
|
|
#define CPUID4_KEY (eax & 0xff)
|
|
#define CPUID4_CACHE_TYPE (((eax & 0x0000001fu) >> 000) + 0)
|
|
#define CPUID4_CACHE_LEVEL (((eax & 0x000000e0u) >> 005) + 0)
|
|
#define CPUID4_IS_FULLY_ASSOCIATIVE (!!(eax & (1u << 9)))
|
|
#define CPUID4_IS_SELF_INITIALIZING_LEVEL (!!(eax & (1u << 8)))
|
|
#define CPUID4_MAX_THREADS_SHARING_CACHE (((eax & 0x03ffc000u) >> 016) + 1)
|
|
#define CPUID4_MAX_CORES_IN_PHYSICAL_CPU (((eax & 0xfc000000u) >> 032) + 1)
|
|
#define CPUID4_SYSTEM_COHERENCY_LINE_SIZE (((Ebx & 0x00000fffu) >> 000) + 1)
|
|
#define CPUID4_PHYSICAL_LINE_PARTITIONS (((Ebx & 0x003ff000u) >> 014) + 1)
|
|
#define CPUID4_WAYS_OF_ASSOCIATIVITY (((Ebx & 0xffc00000u) >> 026) + 1)
|
|
#define CPUID4_NUMBER_OF_SETS (Ecx + 1u)
|
|
#define CPUID4_WBINVD_INVD_BEHAVIOR (!!(Edx & (1u << 0)))
|
|
#define CPUID4_INCLUSIVE_OF_LOWER_LEVELS (!!(Edx & (1u << 1)))
|
|
#define CPUID4_COMPLEX_INDEXING (!!(Edx & (1u << 2)))
|
|
#define CPUID4_CACHE_SIZE_IN_BYTES \
|
|
(CPUID4_WAYS_OF_ASSOCIATIVITY * CPUID4_PHYSICAL_LINE_PARTITIONS * \
|
|
CPUID4_SYSTEM_COHERENCY_LINE_SIZE * CPUID4_NUMBER_OF_SETS)
|
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
#define CPUID4_ITERATE(I, FORM) \
|
|
do { \
|
|
uint32_t eax, Ebx, Ecx, Edx; \
|
|
if (KCPUIDS(0H, EAX) >= 4) { \
|
|
for (I = 0;; ++I) { \
|
|
asm("push\t%%rbx\n\t" \
|
|
"cpuid\n\t" \
|
|
"mov\t%%ebx,%1\n\t" \
|
|
"pop\t%%rbx" \
|
|
: "=a"(eax), "=rm"(Ebx), "=c"(Ecx), "=d"(Edx) \
|
|
: "0"(4), "2"(I)); \
|
|
(void)Ebx; \
|
|
(void)Ecx; \
|
|
(void)Edx; \
|
|
if (CPUID4_CACHE_TYPE) { \
|
|
FORM; \
|
|
} else { \
|
|
break; \
|
|
} \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_CPUID4_H_ */
|