From 484e39c0680d8129ef0b1a591340e731eab25097 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 24 Jan 2026 10:37:51 +0100 Subject: [PATCH] mp_init: Pass microcode size to MPinit Extend get_microcode_info() to return the microcode size. This is being used in the following commit which uses the size to copy the microcode update to RAM in order to speed up MPinit. Depending on the SPI flash interface speed, the microcode size and the number of APs this can improve boot time by seconds. Since microcode size isn't used yet this is not a functional change. Change-Id: I1385e04c56e1411f0847a1c201c17e460c957477 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90894 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/cpu/intel/haswell/haswell_init.c | 12 +++++++----- src/cpu/intel/model_1067x/mp_init.c | 8 ++++++-- src/cpu/intel/model_2065x/model_2065x_init.c | 8 ++++++-- src/cpu/intel/model_206ax/model_206ax_init.c | 8 ++++++-- src/cpu/intel/model_f2x/mp_init.c | 8 ++++++-- src/cpu/x86/mp_init.c | 3 +++ src/include/cpu/x86/mp.h | 2 +- src/soc/intel/apollolake/cpu.c | 8 ++++++-- src/soc/intel/baytrail/cpu.c | 8 ++++++-- src/soc/intel/braswell/cpu.c | 8 ++++++-- src/soc/intel/common/block/cpu/mp_init.c | 8 ++++++-- .../intel/common/block/include/intelblocks/mp_init.h | 2 +- src/soc/intel/xeon_sp/cpx/cpu.c | 8 ++++++-- src/soc/intel/xeon_sp/gnr/cpu.c | 8 ++++++-- src/soc/intel/xeon_sp/skx/cpu.c | 9 +++++++-- src/soc/intel/xeon_sp/spr/cpu.c | 8 ++++++-- 16 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index a54a01ad8f..bd8932a039 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -502,8 +502,6 @@ static void cpu_core_init(struct device *cpu) } /* MP initialization support. */ -static const void *microcode_patch; - static void pre_mp_init(void) { /* Setup MTRRs based on physical address size. */ @@ -534,10 +532,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - microcode_patch = intel_microcode_find(); - *microcode = microcode_patch; + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } @@ -547,6 +548,7 @@ static void per_cpu_smm_trigger(void) smm_relocate(); /* After SMM relocation a 2nd microcode load is required. */ + const void *microcode_patch = intel_microcode_find(); intel_microcode_load_unlocked(microcode_patch); } diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index def136e689..f2a702c2ca 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -30,9 +30,13 @@ static int get_cpu_count(void) return cores; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c index d02c70bdfa..f8fb589159 100644 --- a/src/cpu/intel/model_2065x/model_2065x_init.c +++ b/src/cpu/intel/model_2065x/model_2065x_init.c @@ -129,9 +129,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c index 162c674e0f..0fdbacbe8d 100644 --- a/src/cpu/intel/model_206ax/model_206ax_init.c +++ b/src/cpu/intel/model_206ax/model_206ax_init.c @@ -509,9 +509,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_f2x/mp_init.c b/src/cpu/intel/model_f2x/mp_init.c index c8d38c59ff..010b1770c1 100644 --- a/src/cpu/intel/model_f2x/mp_init.c +++ b/src/cpu/intel/model_f2x/mp_init.c @@ -27,9 +27,13 @@ static int get_cpu_count(void) return CONFIG_MAX_CPUS; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 23880c74c8..ed2005e91e 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -77,6 +77,7 @@ struct mp_params { int num_cpus; /* Total cpus include BSP */ int parallel_microcode_load; const void *microcode_pointer; + size_t microcode_size; /* Flight plan for APs and BSP. */ struct mp_flight_record *flight_plan; int num_records; @@ -1145,9 +1146,11 @@ static enum cb_err do_mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops printk(BIOS_INFO, "Will perform SMM setup.\n"); mp_params.num_cpus = mp_state.cpu_count; + /* Gather microcode information. */ if (mp_state.ops.get_microcode_info != NULL) mp_state.ops.get_microcode_info(&mp_params.microcode_pointer, + &mp_params.microcode_size, &mp_params.parallel_microcode_load); mp_params.flight_plan = &mp_steps[0]; mp_params.num_records = ARRAY_SIZE(mp_steps); diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h index dd86dce2c5..ec4297e105 100644 --- a/src/include/cpu/x86/mp.h +++ b/src/include/cpu/x86/mp.h @@ -47,7 +47,7 @@ struct mp_ops { * Optionally fill in pointer to microcode and indicate if the APs * can load the microcode in parallel. */ - void (*get_microcode_info)(const void **microcode, int *parallel); + void (*get_microcode_info)(const void **microcode, size_t *size, int *parallel); /* * Optionally provide a callback prior to the APs starting SMM * relocation or CPU driver initialization. However, note that diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index 67450b2d5d..ee003805fd 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -193,9 +193,13 @@ int get_cpu_count(void) return num_virt_cores; } -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } #endif diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 2a4616cec3..7408eb7c64 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -146,11 +146,15 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { const struct pattrs *pattrs = pattrs_get(); + const struct microcode *microcode_file = pattrs->microcode_patch; - *microcode = pattrs->microcode_patch; + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/soc/intel/braswell/cpu.c b/src/soc/intel/braswell/cpu.c index 23663c3c71..f5e985396b 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -146,11 +146,15 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { const struct pattrs *pattrs = pattrs_get(); + const struct microcode *microcode_file = pattrs->microcode_patch; - *microcode = pattrs->microcode_patch; + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index dd8a31592e..12d9b95cbd 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -137,9 +137,13 @@ int get_cpu_count(void) * sets the argument *parallel to 1, which allows microcode loading in all * APs to occur in parallel during MP Init. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } diff --git a/src/soc/intel/common/block/include/intelblocks/mp_init.h b/src/soc/intel/common/block/include/intelblocks/mp_init.h index 0dd2109e4a..a0579b7db2 100644 --- a/src/soc/intel/common/block/include/intelblocks/mp_init.h +++ b/src/soc/intel/common/block/include/intelblocks/mp_init.h @@ -21,7 +21,7 @@ int get_cpu_count(void); * sets the argument *parallel to 1, which allows microcode loading in all * APs to occur in parallel during MP Init. */ -void get_microcode_info(const void **microcode, int *parallel); +void get_microcode_info(const void **microcode, size_t *size, int *parallel); /* * Perform BSP and AP initialization diff --git a/src/soc/intel/xeon_sp/cpx/cpu.c b/src/soc/intel/xeon_sp/cpx/cpu.c index c6375ecfdb..57f9ea9a29 100644 --- a/src/soc/intel/xeon_sp/cpx/cpu.c +++ b/src/soc/intel/xeon_sp/cpx/cpu.c @@ -66,9 +66,13 @@ static void xeon_configure_mca(void) * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases * so do it serialized. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } diff --git a/src/soc/intel/xeon_sp/gnr/cpu.c b/src/soc/intel/xeon_sp/gnr/cpu.c index 2e645a53d7..9969287b3c 100644 --- a/src/soc/intel/xeon_sp/gnr/cpu.c +++ b/src/soc/intel/xeon_sp/gnr/cpu.c @@ -21,9 +21,13 @@ bool cpu_soc_is_in_untrusted_mode(void) return false; } -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } diff --git a/src/soc/intel/xeon_sp/skx/cpu.c b/src/soc/intel/xeon_sp/skx/cpu.c index 48054baada..ddb509bfb4 100644 --- a/src/soc/intel/xeon_sp/skx/cpu.c +++ b/src/soc/intel/xeon_sp/skx/cpu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -70,9 +71,13 @@ static void xeon_configure_mca(void) * FSP-S updates microcodes serialized, so do the same. * */ -static void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } diff --git a/src/soc/intel/xeon_sp/spr/cpu.c b/src/soc/intel/xeon_sp/spr/cpu.c index feaac904a2..55568cc8ff 100644 --- a/src/soc/intel/xeon_sp/spr/cpu.c +++ b/src/soc/intel/xeon_sp/spr/cpu.c @@ -56,9 +56,13 @@ static void xeon_configure_mca(void) * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases * so do it serialized. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; }