Commit 43d86e3c authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/cpu: Provide cpuid_read() et al.



Provide a few helper functions to read CPUID leafs or individual registers
into a data structure without requiring unions.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarJuergen Gross <jgross@suse.com>
Tested-by: default avatarSohil Mehta <sohil.mehta@intel.com>
Tested-by: default avatarMichael Kelley <mhklinux@outlook.com>
Tested-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: default avatarZhang Rui <rui.zhang@intel.com>
Tested-by: default avatarWang Wendy <wendy.wang@intel.com>
Tested-by: default avatarK Prateek Nayak <kprateek.nayak@amd.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/878r3mg570.ffs@tglx
parent 841c3516
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -127,6 +127,42 @@ static inline unsigned int cpuid_edx(unsigned int op)
	return edx;
}

static inline void __cpuid_read(unsigned int leaf, unsigned int subleaf, u32 *regs)
{
	regs[CPUID_EAX] = leaf;
	regs[CPUID_ECX] = subleaf;
	__cpuid(regs + CPUID_EAX, regs + CPUID_EBX, regs + CPUID_ECX, regs + CPUID_EDX);
}

#define cpuid_subleaf(leaf, subleaf, regs) {		\
	static_assert(sizeof(*(regs)) == 16);		\
	__cpuid_read(leaf, subleaf, (u32 *)(regs));	\
}

#define cpuid_leaf(leaf, regs) {			\
	static_assert(sizeof(*(regs)) == 16);		\
	__cpuid_read(leaf, 0, (u32 *)(regs));		\
}

static inline void __cpuid_read_reg(unsigned int leaf, unsigned int subleaf,
				    enum cpuid_regs_idx regidx, u32 *reg)
{
	u32 regs[4];

	__cpuid_read(leaf, subleaf, regs);
	*reg = regs[regidx];
}

#define cpuid_subleaf_reg(leaf, subleaf, regidx, reg) {		\
	static_assert(sizeof(*(reg)) == 4);			\
	__cpuid_read_reg(leaf, subleaf, regidx, (u32 *)(reg));	\
}

#define cpuid_leaf_reg(leaf, regidx, reg) {			\
	static_assert(sizeof(*(reg)) == 4);			\
	__cpuid_read_reg(leaf, 0, regidx, (u32 *)(reg));	\
}

static __always_inline bool cpuid_function_is_indexed(u32 function)
{
	switch (function) {