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 <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90894
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Patrick Rudolph 2026-01-24 10:37:51 +01:00 committed by Matt DeVillier
commit 484e39c068
16 changed files with 85 additions and 31 deletions

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -13,6 +13,7 @@
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/em64t101_save_state.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/mp_init.h>
#include <intelpch/lockdown.h>
#include <soc/msr.h>
#include <soc/pm.h>
@ -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;
}

View file

@ -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;
}