1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* Microcode update for Intel PIII and later CPUs */
6 #include <console/console.h>
8 #include <cpu/intel/microcode.h>
9 #include <cpu/x86/msr.h>
10 #include <smp/spinlock.h>
14 DECLARE_SPIN_LOCK(microcode_lock
)
17 u32 hdrver
; /* Header Version */
18 u32 rev
; /* Update Revision */
20 u32 sig
; /* Processor Signature */
22 u32 cksum
; /* Checksum */
23 u32 ldrver
; /* Loader Revision */
24 u32 pf
; /* Processor Flags */
26 u32 data_size
; /* Data Size */
27 u32 total_size
; /* Total Size */
32 struct ext_sig_table
{
38 struct ext_sig_entry
{
44 static inline u32
read_microcode_rev(void)
46 /* Some Intel CPUs can be very finicky about the
47 * CPUID sequence used. So this is implemented in
48 * assembly so that it works reliably.
52 "xorl %%eax, %%eax\n\t"
53 "xorl %%edx, %%edx\n\t"
54 "movl $0x8b, %%ecx\n\t"
56 "movl $0x01, %%eax\n\t"
58 "movl $0x08b, %%ecx\n\t"
61 "=a" (msr
.lo
), "=d" (msr
.hi
)
69 #define MICROCODE_CBFS_FILE "cpu_microcode_blob.bin"
71 static int load_microcode(const struct microcode
*ucode_patch
)
76 msr
.lo
= (unsigned long)ucode_patch
+ sizeof(struct microcode
);
78 wrmsr(IA32_BIOS_UPDT_TRIG
, msr
);
80 current_rev
= read_microcode_rev();
81 if (current_rev
== ucode_patch
->rev
) {
82 printk(BIOS_INFO
, "microcode: updated to revision "
83 "0x%x date=%04x-%02x-%02x\n", read_microcode_rev(),
84 ucode_patch
->date
& 0xffff, (ucode_patch
->date
>> 24) & 0xff,
85 (ucode_patch
->date
>> 16) & 0xff);
92 void intel_microcode_load_unlocked(const void *microcode_patch
)
95 const struct microcode
*m
= microcode_patch
;
98 printk(BIOS_WARNING
, "microcode: failed because no ucode was found\n");
102 current_rev
= read_microcode_rev();
104 /* No use loading the same revision. */
105 if (current_rev
== m
->rev
) {
106 printk(BIOS_INFO
, "microcode: Update skipped, already up-to-date\n");
111 /*SoC specific check to update microcode*/
112 if (soc_skip_ucode_update(current_rev
, m
->rev
)) {
113 printk(BIOS_DEBUG
, "Skip microcode update\n");
118 printk(BIOS_INFO
, "microcode: load microcode patch\n");
119 if (load_microcode(m
) < 0)
120 printk(BIOS_ERR
, "microcode: Update failed\n");
123 uint32_t get_current_microcode_rev(void)
125 return read_microcode_rev();
128 uint32_t get_microcode_rev(const void *microcode
)
130 return ((struct microcode
*)microcode
)->rev
;
133 uint32_t get_microcode_size(const void *microcode
)
135 return ((struct microcode
*)microcode
)->total_size
;
138 uint32_t get_microcode_checksum(const void *microcode
)
140 return ((struct microcode
*)microcode
)->cksum
;
144 static struct ext_sig_table
*ucode_get_ext_sig_table(const struct microcode
*ucode
)
146 struct ext_sig_table
*ext_tbl
;
147 /* header + ucode data blob size */
148 u32 size
= ucode
->data_size
+ sizeof(struct microcode
);
150 ssize_t ext_tbl_len
= ucode
->total_size
- size
;
152 if (ext_tbl_len
< (ssize_t
)sizeof(struct ext_sig_table
))
155 ext_tbl
= (struct ext_sig_table
*)((uintptr_t)ucode
+ size
);
157 if (ext_tbl_len
< (sizeof(struct ext_sig_table
) +
158 ext_tbl
->ext_sig_cnt
* sizeof(struct ext_sig_entry
)))
164 static const void *find_cbfs_microcode(void)
166 const struct microcode
*ucode_updates
;
167 struct ext_sig_table
*ext_tbl
;
168 size_t microcode_len
;
170 u32 pf
, rev
, sig
, update_size
;
172 struct cpuinfo_x86 c
;
174 rev
= read_microcode_rev();
180 if ((c
.x86_model
>= 5) || (c
.x86
> 6)) {
181 msr
= rdmsr(IA32_PLATFORM_ID
);
182 pf
= 1 << ((msr
.hi
>> 18) & 7);
185 printk(BIOS_DEBUG
, "microcode: sig=0x%x pf=0x%x revision=0x%x\n",
188 if (CONFIG(CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS
)) {
189 char cbfs_filename
[25];
190 snprintf(cbfs_filename
, sizeof(cbfs_filename
), "cpu_microcode_%x.bin", sig
);
191 ucode_updates
= cbfs_map(cbfs_filename
, µcode_len
);
193 ucode_updates
= cbfs_map(MICROCODE_CBFS_FILE
, µcode_len
);
195 if (ucode_updates
== NULL
)
198 while (microcode_len
>= sizeof(*ucode_updates
)) {
199 /* Newer microcode updates include a size field, whereas older
200 * containers set it at 0 and are exactly 2048 bytes long */
201 if (ucode_updates
->total_size
) {
202 update_size
= ucode_updates
->total_size
;
204 printk(BIOS_SPEW
, "Microcode size field is 0\n");
208 /* Checkpoint 1: The microcode update falls within CBFS */
209 if (update_size
> microcode_len
) {
210 printk(BIOS_WARNING
, "Microcode header corrupted!\n");
214 if ((ucode_updates
->sig
== sig
) && (ucode_updates
->pf
& pf
))
215 return ucode_updates
;
218 /* Check if there is extended signature table */
219 ext_tbl
= ucode_get_ext_sig_table(ucode_updates
);
221 if (ext_tbl
!= NULL
) {
223 struct ext_sig_entry
*entry
= (struct ext_sig_entry
*)(ext_tbl
+ 1);
225 for (i
= 0; i
< ext_tbl
->ext_sig_cnt
; i
++, entry
++) {
226 if ((sig
== entry
->sig
) && (pf
& entry
->pf
)) {
227 return ucode_updates
;
232 ucode_updates
= (void *)((char *)ucode_updates
+ update_size
);
233 microcode_len
-= update_size
;
239 const void *intel_microcode_find(void)
241 static bool microcode_checked
;
242 static const void *ucode_update
;
244 if (ENV_CACHE_AS_RAM
) {
245 printk(BIOS_ERR
, "Microcode Error: Early microcode patching is not supported due"
246 "to NEM limitation\n");
250 if (microcode_checked
)
254 * Since this function caches the found microcode (NULL or a valid
255 * microcode pointer), it is expected to be run from BSP before starting
256 * any other APs. This sequence is not multithread safe otherwise.
258 ucode_update
= find_cbfs_microcode();
259 microcode_checked
= true;
264 void intel_update_microcode_from_cbfs(void)
266 const void *patch
= intel_microcode_find();
268 spin_lock(µcode_lock
);
270 intel_microcode_load_unlocked(patch
);
272 spin_unlock(µcode_lock
);
275 void intel_reload_microcode(void)
277 if (!CONFIG(RELOAD_MICROCODE_PATCH
))
280 const struct microcode
*m
= intel_microcode_find();
283 printk(BIOS_WARNING
, "microcode: failed because no ucode was found\n");
287 printk(BIOS_INFO
, "microcode: Re-load microcode patch\n");
289 if (load_microcode(m
) < 0)
290 printk(BIOS_ERR
, "microcode: Re-load failed\n");
294 __weak
int soc_skip_ucode_update(u32 current_patch_id
,