diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig index 5da70f4e0b..b58e45398e 100644 --- a/src/soc/amd/cezanne/Kconfig +++ b/src/soc/amd/cezanne/Kconfig @@ -31,6 +31,7 @@ config SOC_SPECIFIC_OPTIONS select IDT_IN_EVERY_STAGE select IOAPIC select PARALLEL_MP_AP_WORK + select PAYLOAD_PRELOAD select PLATFORM_USES_FSP2_0 select PROVIDES_ROM_SHARING select RESET_VECTOR_IN_RAM diff --git a/src/soc/amd/cezanne/fsp_s_params.c b/src/soc/amd/cezanne/fsp_s_params.c index 96dc61bf80..60f3942802 100644 --- a/src/soc/amd/cezanne/fsp_s_params.c +++ b/src/soc/amd/cezanne/fsp_s_params.c @@ -1,8 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include +#include static void fsp_assign_vbios_upds(FSP_S_CONFIG *scfg) { @@ -22,4 +24,18 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) * no SPI operations, we can read the APOB while FSP-S executes. */ start_apob_cache_read(); + /* + * We enqueue the payload to be loaded after the APOB. This might cause a bit of + * bus contention when loading uCode and OPROMs, but since those calls happen at + * different points in the boot state machine it's a little harder to sequence all the + * async loading correctly. So in order to keep the complexity down, we enqueue the + * payload preload here. The end goal will be to add uCode and OPROM preloading + * before the payload so that the sequencing is correct. + * + * While FSP-S is executing, it's not currently possible to enqueue other transactions + * because FSP-S doesn't call `thread_yield()`. So the payload will start loading + * right after FSP-S completes. + */ + if (!acpi_is_wakeup_s3()) + payload_preload(); } diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig index 79e011fadd..11b6c8ccdb 100644 --- a/src/soc/amd/common/block/cpu/Kconfig +++ b/src/soc/amd/common/block/cpu/Kconfig @@ -24,6 +24,16 @@ config MEMLAYOUT_LD_FILE string default "src/soc/amd/common/block/cpu/noncar/memlayout.ld" +config PAYLOAD_PRELOAD_CACHE_SIZE + hex + default 0x30000 + depends on PAYLOAD_PRELOAD + help + This config sets the size of the payload_preload_cache memory region. + It is used as the destination for the raw payload. This space is only + populated during non-S3, so it doesn't need to be reserved in the + EARLY_RESERVED_DRAM region. + endif # SOC_AMD_COMMON_BLOCK_NONCAR config SOC_AMD_COMMON_BLOCK_MCA_COMMON diff --git a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld index e5044e6d43..59631f3ada 100644 --- a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld +++ b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld @@ -97,6 +97,16 @@ SECTIONS EARLY_RESERVED_DRAM_END(.) +#if CONFIG(PAYLOAD_PRELOAD) + /* + * This section is outside the early_reserved_dram section. We only read + * the payload on non-S3 boots, so we don't need to reserve it from the + * OS. The 64 byte alignment is required by the SPI DMA controller. + */ + . = ALIGN(64); + REGION(payload_preload_cache, ., CONFIG_PAYLOAD_PRELOAD_CACHE_SIZE, 64) +#endif + RAMSTAGE(CONFIG_RAMBASE, 8M) }