From c150a57d2989699198358e6066913f7e4dc8abc6 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Mon, 30 Apr 2018 17:59:27 -0600 Subject: [PATCH] amd/pi: Add AgesaHeapRebase callout Implement an optional callout for AgesaHeapRebase which allows AGESA to override any internal hardcoded heap addresses. Designate a region in CAR that may be used for pre-mem heap and return that address before DRAM is configured. After DRAM is up, the address in cbmem is returned. TEST=Boot grunt with patchstack and experimental blob BUG=b:74518368 Change-Id: Ieda202a6064302b21707bd7ddfabc132cd85ed45 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/25458 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- .../block/include/amdblocks/BiosCallOuts.h | 1 + src/soc/amd/common/block/pi/Kconfig | 8 +++++ src/soc/amd/common/block/pi/def_callouts.c | 2 ++ src/soc/amd/common/block/pi/heapmanager.c | 33 +++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h index 53d565576f..97bf2082d3 100644 --- a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h +++ b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h @@ -34,6 +34,7 @@ typedef struct _BIOS_BUFFER_NODE { } BIOS_BUFFER_NODE; AGESA_STATUS agesa_GetTempHeapBase(UINT32 Func, UINTN Data, VOID *ConfigPtr); +AGESA_STATUS agesa_HeapRebase(UINT32 Func, UINTN Data, VOID *ConfigPtr); AGESA_STATUS agesa_AllocateBuffer(UINT32 Func, UINTN Data, VOID *ConfigPtr); AGESA_STATUS agesa_DeallocateBuffer(UINT32 Func, UINTN Data, VOID *ConfigPtr); diff --git a/src/soc/amd/common/block/pi/Kconfig b/src/soc/amd/common/block/pi/Kconfig index 547232ef66..f0917bb767 100644 --- a/src/soc/amd/common/block/pi/Kconfig +++ b/src/soc/amd/common/block/pi/Kconfig @@ -7,6 +7,14 @@ config SOC_AMD_COMMON_BLOCK_PI if SOC_AMD_COMMON_BLOCK_PI +config PI_AGESA_CAR_HEAP_BASE + hex + default 0x400000 + help + The AGESA PI blob may be built to allow an optional callout for + AgesaHeapRebase. If AGESA calls AgesaHeapRebase, this option + determines the location of the heap prior to DRAM availability. + config PI_AGESA_TEMP_RAM_BASE hex default 0x100000 diff --git a/src/soc/amd/common/block/pi/def_callouts.c b/src/soc/amd/common/block/pi/def_callouts.c index 0adff7d8b2..54b1ede72a 100644 --- a/src/soc/amd/common/block/pi/def_callouts.c +++ b/src/soc/amd/common/block/pi/def_callouts.c @@ -31,6 +31,7 @@ const BIOS_CALLOUT_STRUCT BiosCallouts[] = { { AGESA_DO_RESET, agesa_Reset }, { AGESA_FCH_OEM_CALLOUT, agesa_fch_initreset }, { AGESA_HALT_THIS_AP, agesa_HaltThisAp }, + { AGESA_HEAP_REBASE, agesa_HeapRebase }, { AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl } }; #else @@ -46,6 +47,7 @@ const BIOS_CALLOUT_STRUCT BiosCallouts[] = { { AGESA_READ_SPD, agesa_ReadSpd }, { AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl }, { AGESA_GET_TEMP_HEAP_BASE, agesa_GetTempHeapBase }, + { AGESA_HEAP_REBASE, agesa_HeapRebase }, #if ENV_RAMSTAGE { AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp }, { AGESA_RUNFUNC_ON_ALL_APS, agesa_RunFcnOnAllAps }, diff --git a/src/soc/amd/common/block/pi/heapmanager.c b/src/soc/amd/common/block/pi/heapmanager.c index 98a8ce14e2..54b0cbc0bb 100644 --- a/src/soc/amd/common/block/pi/heapmanager.c +++ b/src/soc/amd/common/block/pi/heapmanager.c @@ -55,6 +55,39 @@ AGESA_STATUS agesa_GetTempHeapBase(UINT32 Func, UINTN Data, VOID *ConfigPtr) return AGESA_SUCCESS; } +/* + * Name agesa_HeapRebase + * Brief description AGESA may use internal hardcoded locations for its + * heap. Modern implementations allow the base to be + * overridden by calling agesa_HeapRebase. + * Input parameters + * Func Unused + * Data Unused + * ConfigPtr Pointer to type AGESA_REBASE_PARAMS + * Output parameters + * Status Indicates whether HeapAddress was successfully + * set. + */ +AGESA_STATUS agesa_HeapRebase(UINT32 Func, UINTN Data, VOID *ConfigPtr) +{ + AGESA_REBASE_PARAMS *Rebase; + + Rebase = (AGESA_REBASE_PARAMS *)ConfigPtr; + if (ENV_BOOTBLOCK) { + Rebase->HeapAddress = CONFIG_PI_AGESA_CAR_HEAP_BASE; + } else { + /* + * todo: remove the if() above and keep the assignment here + * once all AGESA functions are removed from bootblock. + */ + Rebase->HeapAddress = (UINTN)agesa_heap_base(); + if (!Rebase->HeapAddress) + Rebase->HeapAddress = CONFIG_PI_AGESA_CAR_HEAP_BASE; + } + + return AGESA_SUCCESS; +} + /* * Name FindAllocatedNode * Brief description Find an allocated node that matches the handle.