Skip to content

Commit

Permalink
Redo cpuid feature detection
Browse files Browse the repository at this point in the history
We already have a proper cpuid feature API used in
userland, but Linux took it out for KERNEL use, to
plug into the Linux API. We do not have a kernel API to
use, so we might as well use the userland one.

This makes it nice and consistent, and more easy to read.

Signed-off-by: Jorgen Lundman <[email protected]>
  • Loading branch information
lundman committed Mar 16, 2024
1 parent 63f438a commit d16e19a
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 318 deletions.
64 changes: 47 additions & 17 deletions include/os/windows/spl/sys/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,52 @@ extern uint32_t getcpuid();

typedef int processorid_t;

#define CPUID_FEATURE_PCLMULQDQ (1<<1)
#define CPUID_FEATURE_MOVBE (1<<22)
#define CPUID_FEATURE_AES (1<<25)
#define CPUID_FEATURE_XSAVE (1<<26)
#define CPUID_FEATURE_OSXSAVE (1<<27)
#define CPUID_FEATURE_AVX1_0 (1<<28)

#define CPUID_FEATURE_SSE (1<<25)
#define CPUID_FEATURE_SSE2 (1<<26)
#define CPUID_FEATURE_SSE3 (1<<0)
#define CPUID_FEATURE_SSSE3 (1<<9)
#define CPUID_FEATURE_SSE4_2 (1<<20)
#define CPUID_FEATURE_SSE4_1 (1<<19)

#define CPUID_LEAF7_FEATURE_AVX2 (1<<5)
#define CPUID_LEAF7_FEATURE_AVX512F (1<<16)
#define CPUID_LEAF7_FEATURE_SHA_NI (1<<29)
#if defined(__amd64__) || defined(__x86_64__)

extern int __cpuid_count(unsigned int __level, unsigned int __sublevel,
unsigned int __eax, unsigned int __ebx,
unsigned int __ecx, unsigned int __edx);

#define __cpuid_count(level, count, a, b, c, d) \
__asm__("xchg{l}\t{%%}ebx, %1\n\t" \
"cpuid\n\t" \
"xchg{l}\t{%%}ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))

#define __cpuid(level, a, b, c, d) \
__asm__("xchg{l}\t{%%}ebx, %1\n\t" \
"cpuid\n\t" \
"xchg{l}\t{%%}ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level))

static inline unsigned int
__get_cpuid_max(unsigned int __ext, unsigned int *__sig)
{
unsigned int __eax, __ebx, __ecx, __edx;
__cpuid(__ext, __eax, __ebx, __ecx, __edx);
if (__sig)
*__sig = __ebx;
return (__eax);
}

/* macOS does have do_cpuid() macro */
static inline int
__get_cpuid(unsigned int __level,
unsigned int *__eax, unsigned int *__ebx,
unsigned int *__ecx, unsigned int *__edx)
{
unsigned int __ext = __level & 0x80000000;
if (__get_cpuid_max(__ext, 0) < __level)
return (0);
__cpuid(__level, *__eax, *__ebx, *__ecx, *__edx);
return (1);
}

#endif // x86

typedef int processorid_t;
extern int spl_processor_init(void);

#endif /* _SPL_PROCESSOR_H */
Loading

0 comments on commit d16e19a

Please sign in to comment.