src/intel/microcode: Add support for extended signature table
Microcode header supports advertising support for only one CPU signature and processor flags. If there are multiple processor families supported by this microcode blob, they are mentioned in the extended signature table. Add support to parse the extended processor signature table to determine if the microcode blob supports the currently running CPU. BUG=b:182234962 TEST=Booted ADL brya system with a processor whose signature/pf are in the extended signature table of a microcode patch. Was able to match and load the patch appropriately. Signed-off-by: Rizwan Qureshi <rizwan.qureshi@intel.com> Change-Id: I1466caf4a4ba1f9a0214bdde19cce57dd65dacbd Reviewed-on: https://review.coreboot.org/c/coreboot/+/54734 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
078448296c
commit
1aa60a95bd
|
@ -29,6 +29,18 @@ struct microcode {
|
||||||
u32 reserved[3];
|
u32 reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ext_sig_table {
|
||||||
|
u32 ext_sig_cnt;
|
||||||
|
u32 ext_tbl_chksm;
|
||||||
|
u32 res[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ext_sig_entry {
|
||||||
|
u32 sig;
|
||||||
|
u32 pf;
|
||||||
|
u32 chksm;
|
||||||
|
};
|
||||||
|
|
||||||
static inline u32 read_microcode_rev(void)
|
static inline u32 read_microcode_rev(void)
|
||||||
{
|
{
|
||||||
/* Some Intel CPUs can be very finicky about the
|
/* Some Intel CPUs can be very finicky about the
|
||||||
|
@ -117,9 +129,31 @@ uint32_t get_microcode_checksum(const void *microcode)
|
||||||
return ((struct microcode *)microcode)->cksum;
|
return ((struct microcode *)microcode)->cksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct ext_sig_table *ucode_get_ext_sig_table(const struct microcode *ucode)
|
||||||
|
{
|
||||||
|
struct ext_sig_table *ext_tbl;
|
||||||
|
/* header + ucode data blob size */
|
||||||
|
u32 size = ucode->data_size + sizeof(struct microcode);
|
||||||
|
|
||||||
|
size_t ext_tbl_len = ucode->total_size - size;
|
||||||
|
|
||||||
|
if (ext_tbl_len < sizeof(struct ext_sig_table))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ext_tbl = (struct ext_sig_table *)((uintptr_t)ucode + size);
|
||||||
|
|
||||||
|
if (ext_tbl_len < (sizeof(struct ext_sig_table) +
|
||||||
|
ext_tbl->ext_sig_cnt * sizeof(struct ext_sig_entry)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return ext_tbl;
|
||||||
|
}
|
||||||
|
|
||||||
static const void *find_cbfs_microcode(void)
|
static const void *find_cbfs_microcode(void)
|
||||||
{
|
{
|
||||||
const struct microcode *ucode_updates;
|
const struct microcode *ucode_updates;
|
||||||
|
struct ext_sig_table *ext_tbl;
|
||||||
size_t microcode_len;
|
size_t microcode_len;
|
||||||
u32 eax;
|
u32 eax;
|
||||||
u32 pf, rev, sig, update_size;
|
u32 pf, rev, sig, update_size;
|
||||||
|
@ -163,6 +197,22 @@ static const void *find_cbfs_microcode(void)
|
||||||
if ((ucode_updates->sig == sig) && (ucode_updates->pf & pf))
|
if ((ucode_updates->sig == sig) && (ucode_updates->pf & pf))
|
||||||
return ucode_updates;
|
return ucode_updates;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if there is extended signature table */
|
||||||
|
ext_tbl = ucode_get_ext_sig_table(ucode_updates);
|
||||||
|
|
||||||
|
if (ext_tbl != NULL) {
|
||||||
|
int i;
|
||||||
|
struct ext_sig_entry *entry = (struct ext_sig_entry *)(ext_tbl + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < ext_tbl->ext_sig_cnt; i++, entry++) {
|
||||||
|
|
||||||
|
if ((sig == entry->sig) && (pf & entry->pf)) {
|
||||||
|
return ucode_updates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ucode_updates = (void *)((char *)ucode_updates + update_size);
|
ucode_updates = (void *)((char *)ucode_updates + update_size);
|
||||||
microcode_len -= update_size;
|
microcode_len -= update_size;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue