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 Gleixnerstatic inline void load_ucode_bsp(void) { } load_ucode_ap(void)23148f9bb8SPaul Gortmakerstatic inline void load_ucode_ap(void) { } microcode_bsp_resume(void)24f9e14dbbSBorislav Petkovstatic 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 Gleixnerstatic 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 Gleixnerstatic 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 Gleixnerstatic __always_inline bool microcode_nmi_handler_enabled(void) 847eb314a2SThomas Gleixner { 857eb314a2SThomas Gleixner return static_branch_unlikely(µcode_nmi_handler_enable); 867eb314a2SThomas Gleixner } 877eb314a2SThomas Gleixner #else microcode_nmi_handler_enabled(void)887eb314a2SThomas Gleixnerstatic __always_inline bool microcode_nmi_handler_enabled(void) { return false; } 897eb314a2SThomas Gleixner #endif 907eb314a2SThomas Gleixner 911965aae3SH. Peter Anvin #endif /* _ASM_X86_MICROCODE_H */ 92