|
2 | 2 | #ifndef _ASM_X86_MICROCODE_H |
3 | 3 | #define _ASM_X86_MICROCODE_H |
4 | 4 |
|
5 | | -#include <linux/earlycpio.h> |
6 | | -#include <linux/initrd.h> |
7 | | - |
8 | | -#include <asm/cpu.h> |
9 | | -#include <asm/microcode_amd.h> |
10 | | -#include <asm/microcode_intel.h> |
11 | | - |
12 | | -struct ucode_patch { |
13 | | - struct list_head plist; |
14 | | - void *data; /* Intel uses only this one */ |
15 | | - unsigned int size; |
16 | | - u32 patch_id; |
17 | | - u16 equiv_cpu; |
18 | | -}; |
19 | | - |
20 | | -extern struct list_head microcode_cache; |
21 | | - |
22 | 5 | struct cpu_signature { |
23 | 6 | unsigned int sig; |
24 | 7 | unsigned int pf; |
25 | 8 | unsigned int rev; |
26 | 9 | }; |
27 | 10 |
|
28 | | -struct device; |
29 | | - |
30 | | -enum ucode_state { |
31 | | - UCODE_OK = 0, |
32 | | - UCODE_NEW, |
33 | | - UCODE_UPDATED, |
34 | | - UCODE_NFOUND, |
35 | | - UCODE_ERROR, |
36 | | -}; |
37 | | - |
38 | | -struct microcode_ops { |
39 | | - enum ucode_state (*request_microcode_fw) (int cpu, struct device *); |
40 | | - |
41 | | - void (*microcode_fini_cpu) (int cpu); |
42 | | - |
43 | | - /* |
44 | | - * The generic 'microcode_core' part guarantees that |
45 | | - * the callbacks below run on a target cpu when they |
46 | | - * are being called. |
47 | | - * See also the "Synchronization" section in microcode_core.c. |
48 | | - */ |
49 | | - enum ucode_state (*apply_microcode) (int cpu); |
50 | | - int (*collect_cpu_info) (int cpu, struct cpu_signature *csig); |
51 | | -}; |
52 | | - |
53 | 11 | struct ucode_cpu_info { |
54 | 12 | struct cpu_signature cpu_sig; |
55 | 13 | void *mc; |
56 | 14 | }; |
57 | | -extern struct ucode_cpu_info ucode_cpu_info[]; |
58 | | -struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa); |
59 | 15 |
|
60 | | -#ifdef CONFIG_CPU_SUP_INTEL |
61 | | -extern struct microcode_ops * __init init_intel_microcode(void); |
62 | | -#else |
63 | | -static inline struct microcode_ops * __init init_intel_microcode(void) |
64 | | -{ |
65 | | - return NULL; |
66 | | -} |
67 | | -#endif /* CONFIG_CPU_SUP_INTEL */ |
68 | | - |
69 | | -#ifdef CONFIG_CPU_SUP_AMD |
70 | | -extern struct microcode_ops * __init init_amd_microcode(void); |
71 | | -extern void __exit exit_amd_microcode(void); |
| 16 | +#ifdef CONFIG_MICROCODE |
| 17 | +void load_ucode_bsp(void); |
| 18 | +void load_ucode_ap(void); |
| 19 | +void microcode_bsp_resume(void); |
72 | 20 | #else |
73 | | -static inline struct microcode_ops * __init init_amd_microcode(void) |
74 | | -{ |
75 | | - return NULL; |
76 | | -} |
77 | | -static inline void __exit exit_amd_microcode(void) {} |
| 21 | +static inline void load_ucode_bsp(void) { } |
| 22 | +static inline void load_ucode_ap(void) { } |
| 23 | +static inline void microcode_bsp_resume(void) { } |
78 | 24 | #endif |
79 | 25 |
|
80 | | -#define MAX_UCODE_COUNT 128 |
| 26 | +#ifdef CONFIG_CPU_SUP_INTEL |
| 27 | +/* Intel specific microcode defines. Public for IFS */ |
| 28 | +struct microcode_header_intel { |
| 29 | + unsigned int hdrver; |
| 30 | + unsigned int rev; |
| 31 | + unsigned int date; |
| 32 | + unsigned int sig; |
| 33 | + unsigned int cksum; |
| 34 | + unsigned int ldrver; |
| 35 | + unsigned int pf; |
| 36 | + unsigned int datasize; |
| 37 | + unsigned int totalsize; |
| 38 | + unsigned int metasize; |
| 39 | + unsigned int reserved[2]; |
| 40 | +}; |
81 | 41 |
|
82 | | -#define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) |
83 | | -#define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u') |
84 | | -#define CPUID_INTEL2 QCHAR('i', 'n', 'e', 'I') |
85 | | -#define CPUID_INTEL3 QCHAR('n', 't', 'e', 'l') |
86 | | -#define CPUID_AMD1 QCHAR('A', 'u', 't', 'h') |
87 | | -#define CPUID_AMD2 QCHAR('e', 'n', 't', 'i') |
88 | | -#define CPUID_AMD3 QCHAR('c', 'A', 'M', 'D') |
| 42 | +struct microcode_intel { |
| 43 | + struct microcode_header_intel hdr; |
| 44 | + unsigned int bits[]; |
| 45 | +}; |
89 | 46 |
|
90 | | -#define CPUID_IS(a, b, c, ebx, ecx, edx) \ |
91 | | - (!((ebx ^ (a))|(edx ^ (b))|(ecx ^ (c)))) |
| 47 | +#define DEFAULT_UCODE_DATASIZE (2000) |
| 48 | +#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) |
| 49 | +#define MC_HEADER_TYPE_MICROCODE 1 |
| 50 | +#define MC_HEADER_TYPE_IFS 2 |
92 | 51 |
|
93 | | -/* |
94 | | - * In early loading microcode phase on BSP, boot_cpu_data is not set up yet. |
95 | | - * x86_cpuid_vendor() gets vendor id for BSP. |
96 | | - * |
97 | | - * In 32 bit AP case, accessing boot_cpu_data needs linear address. To simplify |
98 | | - * coding, we still use x86_cpuid_vendor() to get vendor id for AP. |
99 | | - * |
100 | | - * x86_cpuid_vendor() gets vendor information directly from CPUID. |
101 | | - */ |
102 | | -static inline int x86_cpuid_vendor(void) |
| 52 | +static inline int intel_microcode_get_datasize(struct microcode_header_intel *hdr) |
103 | 53 | { |
104 | | - u32 eax = 0x00000000; |
105 | | - u32 ebx, ecx = 0, edx; |
106 | | - |
107 | | - native_cpuid(&eax, &ebx, &ecx, &edx); |
108 | | - |
109 | | - if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) |
110 | | - return X86_VENDOR_INTEL; |
111 | | - |
112 | | - if (CPUID_IS(CPUID_AMD1, CPUID_AMD2, CPUID_AMD3, ebx, ecx, edx)) |
113 | | - return X86_VENDOR_AMD; |
114 | | - |
115 | | - return X86_VENDOR_UNKNOWN; |
| 54 | + return hdr->datasize ? : DEFAULT_UCODE_DATASIZE; |
116 | 55 | } |
117 | 56 |
|
118 | | -static inline unsigned int x86_cpuid_family(void) |
| 57 | +static inline u32 intel_get_microcode_revision(void) |
119 | 58 | { |
120 | | - u32 eax = 0x00000001; |
121 | | - u32 ebx, ecx = 0, edx; |
| 59 | + u32 rev, dummy; |
| 60 | + |
| 61 | + native_wrmsrl(MSR_IA32_UCODE_REV, 0); |
122 | 62 |
|
123 | | - native_cpuid(&eax, &ebx, &ecx, &edx); |
| 63 | + /* As documented in the SDM: Do a CPUID 1 here */ |
| 64 | + native_cpuid_eax(1); |
124 | 65 |
|
125 | | - return x86_family(eax); |
| 66 | + /* get the current revision from MSR 0x8B */ |
| 67 | + native_rdmsr(MSR_IA32_UCODE_REV, dummy, rev); |
| 68 | + |
| 69 | + return rev; |
126 | 70 | } |
127 | 71 |
|
128 | | -#ifdef CONFIG_MICROCODE |
129 | | -extern void __init load_ucode_bsp(void); |
130 | | -extern void load_ucode_ap(void); |
131 | | -extern bool initrd_gone; |
132 | | -void microcode_bsp_resume(void); |
133 | | -#else |
134 | | -static inline void __init load_ucode_bsp(void) { } |
135 | | -static inline void load_ucode_ap(void) { } |
136 | | -static inline void microcode_bsp_resume(void) { } |
137 | | -#endif |
| 72 | +void show_ucode_info_early(void); |
| 73 | + |
| 74 | +#else /* CONFIG_CPU_SUP_INTEL */ |
| 75 | +static inline void show_ucode_info_early(void) { } |
| 76 | +#endif /* !CONFIG_CPU_SUP_INTEL */ |
138 | 77 |
|
139 | 78 | #endif /* _ASM_X86_MICROCODE_H */ |
0 commit comments