xref: /linux-6.15/arch/x86/include/asm/microcode.h (revision 5214a9f6)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21965aae3SH. Peter Anvin #ifndef _ASM_X86_MICROCODE_H
31965aae3SH. Peter Anvin #define _ASM_X86_MICROCODE_H
4bb898558SAl Viro 
5bb898558SAl Viro struct cpu_signature {
6bb898558SAl Viro 	unsigned int sig;
7bb898558SAl Viro 	unsigned int pf;
8bb898558SAl Viro 	unsigned int rev;
9bb898558SAl Viro };
10bb898558SAl Viro 
11bb898558SAl Viro struct ucode_cpu_info {
12bb898558SAl Viro 	struct cpu_signature	cpu_sig;
13bb898558SAl Viro 	void			*mc;
14bb898558SAl Viro };
1558ce8d6dSBorislav Petkov 
16fe055896SBorislav Petkov #ifdef CONFIG_MICROCODE
17d02a0efdSThomas Gleixner void load_ucode_bsp(void);
18d02a0efdSThomas Gleixner void load_ucode_ap(void);
19f9e14dbbSBorislav Petkov void microcode_bsp_resume(void);
20*5214a9f6SBorislav Petkov (AMD) bool __init microcode_loader_disabled(void);
21a8ebf6d1SFenghua Yu #else
load_ucode_bsp(void)22d02a0efdSThomas Gleixner static inline void load_ucode_bsp(void)	{ }
load_ucode_ap(void)23148f9bb8SPaul Gortmaker static inline void load_ucode_ap(void) { }
microcode_bsp_resume(void)24f9e14dbbSBorislav Petkov static inline void microcode_bsp_resume(void) { }
microcode_loader_disabled(void)25*5214a9f6SBorislav Petkov (AMD) static inline bool __init microcode_loader_disabled(void) { return false; }
26a8ebf6d1SFenghua Yu #endif
275f9c01aaSBorislav Petkov 
284c585af7SThomas Gleixner extern unsigned long initrd_start_early;
294c585af7SThomas Gleixner 
30d02a0efdSThomas Gleixner #ifdef CONFIG_CPU_SUP_INTEL
31d02a0efdSThomas Gleixner /* Intel specific microcode defines. Public for IFS */
32d02a0efdSThomas Gleixner struct microcode_header_intel {
33d02a0efdSThomas Gleixner 	unsigned int	hdrver;
34d02a0efdSThomas Gleixner 	unsigned int	rev;
35d02a0efdSThomas Gleixner 	unsigned int	date;
36d02a0efdSThomas Gleixner 	unsigned int	sig;
37d02a0efdSThomas Gleixner 	unsigned int	cksum;
38d02a0efdSThomas Gleixner 	unsigned int	ldrver;
39d02a0efdSThomas Gleixner 	unsigned int	pf;
40d02a0efdSThomas Gleixner 	unsigned int	datasize;
41d02a0efdSThomas Gleixner 	unsigned int	totalsize;
42d02a0efdSThomas Gleixner 	unsigned int	metasize;
43cf5ab01cSAshok Raj 	unsigned int	min_req_ver;
44cf5ab01cSAshok Raj 	unsigned int	reserved;
45d02a0efdSThomas Gleixner };
46d02a0efdSThomas Gleixner 
47d02a0efdSThomas Gleixner struct microcode_intel {
48d02a0efdSThomas Gleixner 	struct microcode_header_intel	hdr;
49d02a0efdSThomas Gleixner 	unsigned int			bits[];
50d02a0efdSThomas Gleixner };
51d02a0efdSThomas Gleixner 
52d02a0efdSThomas Gleixner #define DEFAULT_UCODE_DATASIZE		(2000)
53d02a0efdSThomas Gleixner #define MC_HEADER_SIZE			(sizeof(struct microcode_header_intel))
54d02a0efdSThomas Gleixner #define MC_HEADER_TYPE_MICROCODE	1
55d02a0efdSThomas Gleixner #define MC_HEADER_TYPE_IFS		2
56d02a0efdSThomas Gleixner 
intel_microcode_get_datasize(struct microcode_header_intel * hdr)57d02a0efdSThomas Gleixner static inline int intel_microcode_get_datasize(struct microcode_header_intel *hdr)
58d02a0efdSThomas Gleixner {
59d02a0efdSThomas Gleixner 	return hdr->datasize ? : DEFAULT_UCODE_DATASIZE;
60d02a0efdSThomas Gleixner }
61d02a0efdSThomas Gleixner 
intel_get_microcode_revision(void)62d02a0efdSThomas Gleixner static inline u32 intel_get_microcode_revision(void)
63d02a0efdSThomas Gleixner {
64d02a0efdSThomas Gleixner 	u32 rev, dummy;
65d02a0efdSThomas Gleixner 
66d02a0efdSThomas Gleixner 	native_wrmsrl(MSR_IA32_UCODE_REV, 0);
67d02a0efdSThomas Gleixner 
68d02a0efdSThomas Gleixner 	/* As documented in the SDM: Do a CPUID 1 here */
69d02a0efdSThomas Gleixner 	native_cpuid_eax(1);
70d02a0efdSThomas Gleixner 
71d02a0efdSThomas Gleixner 	/* get the current revision from MSR 0x8B */
72d02a0efdSThomas Gleixner 	native_rdmsr(MSR_IA32_UCODE_REV, dummy, rev);
73d02a0efdSThomas Gleixner 
74d02a0efdSThomas Gleixner 	return rev;
75d02a0efdSThomas Gleixner }
76d02a0efdSThomas Gleixner #endif /* !CONFIG_CPU_SUP_INTEL */
77d02a0efdSThomas Gleixner 
787eb314a2SThomas Gleixner bool microcode_nmi_handler(void);
798f849ff6SThomas Gleixner void microcode_offline_nmi_handler(void);
807eb314a2SThomas Gleixner 
817eb314a2SThomas Gleixner #ifdef CONFIG_MICROCODE_LATE_LOADING
827eb314a2SThomas Gleixner DECLARE_STATIC_KEY_FALSE(microcode_nmi_handler_enable);
microcode_nmi_handler_enabled(void)837eb314a2SThomas Gleixner static __always_inline bool microcode_nmi_handler_enabled(void)
847eb314a2SThomas Gleixner {
857eb314a2SThomas Gleixner 	return static_branch_unlikely(&microcode_nmi_handler_enable);
867eb314a2SThomas Gleixner }
877eb314a2SThomas Gleixner #else
microcode_nmi_handler_enabled(void)887eb314a2SThomas Gleixner static __always_inline bool microcode_nmi_handler_enabled(void) { return false; }
897eb314a2SThomas Gleixner #endif
907eb314a2SThomas Gleixner 
911965aae3SH. Peter Anvin #endif /* _ASM_X86_MICROCODE_H */
92