Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/74873 )
Change subject: cpu/intel/microcode: Implement microcode info caching inside cbmem ......................................................................
cpu/intel/microcode: Implement microcode info caching inside cbmem
This patch implements microcode info caching inside cbmem to avoid boot time penalty.
Currently, locating ucode from cbfs is a continuous process in every boot hence, there are boot time penalties knowing typically `cpu_microcode_blob.bin` is consists of multiple microcodes as per different CPU steppings.
Adding more microcode into `cpu_microcode_blob.bin` would increase the boot time cost. Hence, this patch enables caching of microcode related information inside cbmem that can be used to avoid microcode searching time during the warm resets.
Additionally, use a tab to align `CBMEM_ID_CSE_PARTITION_VERSION` with other CBMEM ID macros.
TEST=Build and boot google/rex with this patch which saves 11ms of boot time.
Without this patch during warm reset:
cbmem -c | grep microcode CBFS: Found 'cpu_microcode_blob.bin' @0x1e180 size 0x35400 in mcache @0x76add080 microcode: sig=0x906a4 pf=0x80 revision=0x423 microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date
boot time: 954:calling FspSiliconInit 788,614 (5,414) 955:returning from FspSiliconInit 823,803 (35,188)
With this patch during warm reset:
cbmem -c | grep microcode microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date microcode: Update skipped, already up-to-date
boot time: 954:calling FspSiliconInit 786,475 (5,390) 955:returning from FspSiliconInit 811,083 (24,608)
Change-Id: I208a2e0e1dce96b2d4d63f882e8aaf4c25f77e3f Signed-off-by: Subrata Banik subratabanik@google.com --- M src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h M src/cpu/intel/microcode/microcode.c M src/include/cpu/intel/microcode.h 3 files changed, 96 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/73/74873/1
diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h index 4162d84..11bfc5a 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h @@ -85,7 +85,8 @@ #define CBMEM_ID_MEM_CHIP_INFO 0x5048434D #define CBMEM_ID_AMD_STB 0x5f425453 #define CBMEM_ID_AMD_MP2 0x5f32504d -#define CBMEM_ID_CSE_PARTITION_VERSION 0x43535056 +#define CBMEM_ID_CSE_PARTITION_VERSION 0x43535056 +#define CBMEM_ID_MICROCODE_INFO 0x55434f44
#define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ @@ -165,5 +166,6 @@ { CBMEM_ID_MEM_CHIP_INFO, "MEM CHIP INFO"},\ { CBMEM_ID_AMD_STB, "AMD STB"},\ { CBMEM_ID_AMD_MP2, "AMD MP2 BUFFER"},\ - { CBMEM_ID_CSE_PARTITION_VERSION, "CSE PARTITION VERSION"} + { CBMEM_ID_CSE_PARTITION_VERSION, "CSE PARTITION VERSION"}, \ + { CBMEM_ID_MICROCODE_INFO, "MICROCODE INFO"} #endif /* _CBMEM_ID_H_ */ diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c index 6f6e2f1..87f122a 100644 --- a/src/cpu/intel/microcode/microcode.c +++ b/src/cpu/intel/microcode/microcode.c @@ -233,16 +233,21 @@ { static bool microcode_checked; static const void *ucode_update; + struct microcode_info *info;
if (microcode_checked) return ucode_update;
+ info = cbmem_find(CBMEM_ID_MICROCODE_INFO); + if (info) + ucode_update = (void *)info->microcode_ptr; /* * Since this function caches the found microcode (NULL or a valid * microcode pointer), it is expected to be run from BSP before starting * any other APs. This sequence is not multithread safe otherwise. */ - ucode_update = find_cbfs_microcode(); + else + ucode_update = find_cbfs_microcode(); microcode_checked = true;
return ucode_update; @@ -284,3 +289,18 @@ return 0; } #endif + +static void microcode_setup_cbmem_cache(int unused) +{ + struct microcode_info *info; + uint32_t cpu_id = cpu_get_cpuid(); + + info = cbmem_add(CBMEM_ID_MICROCODE_INFO, sizeof(struct microcode_info)); + if (info->cpu_id != cpu_id) { + info->cpu_id = cpu_id; + info->microcode_rev = get_current_microcode_rev(); + info->microcode_ptr = (uintptr_t)find_cbfs_microcode(); + } +} + +RAMSTAGE_CBMEM_INIT_HOOK(microcode_setup_cbmem_cache) diff --git a/src/include/cpu/intel/microcode.h b/src/include/cpu/intel/microcode.h index 5a6c27e..99de2f7 100644 --- a/src/include/cpu/intel/microcode.h +++ b/src/include/cpu/intel/microcode.h @@ -4,6 +4,12 @@
#include <stdint.h>
+struct microcode_info { + uint32_t cpu_id; + uint32_t microcode_rev; + uintptr_t microcode_ptr; +} __packed; + /* Find the microcode and reload the microcode if SoC has RELOAD_MICROCODE_PATCH * config selected. */ void intel_reload_microcode(void);