<p>Marshall Dawson has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25458">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/amd: Add agesa_HeapRebase callout<br><br>One of AGESA's optional callout functions allows it to use a heap area<br>managed by coreboot.  Add the function here; note that AGESA does not<br>yet call out to agesa_HeapRebase.<br><br>AGESA treats the heap as follows:<br> * It assumes an initial heap base address of 4 MB.  An abstracted call<br>   to AgesaHeapRebase is made for an opportunity to override the base.<br> * If necessary, AGESA programs a variable MTRR in order to keep its<br>   heap in CAR.<br> * At the end of AmdInitPost, AGESA migrates the heap to 0xb0000 (temp<br>   mem) and removes blocks that will not be used later.<br> * After AmdInitPost, coreboot initializes cbmem and uses a region there<br>   for requested heap space.<br> * During AmdInitEnv, AGESA migrates its heap information from temp mem<br>   to the cbmem region (main ram).<br><br>To support this callout, define a region that may be used while CAR is<br>still present.  The heap base may then either be in CAR or cbmem.  Make<br>the default cbmem (i.e. for postcar, ramstage).  Add a function that<br>can indicate the base should be in CAR instead.  This currently needs<br>to be called before an AGESA Entry Point call in bootblock and romstage.<br>(Only a single one will be required once AGESA moves out of bootblock.)<br>Add a call from EmptyHeap that switches the heap base to cbmem.<br><br>Future work may include:<br> * The AMD standard CAR setup code doesn't allow enough space to use a<br>   a CAR_GLOBAL variable.  Consider redoing the AMD CAR setup and<br>   teardown functionality, and use a CAR_GLOBAL region instead.<br> * Move the heap migration and reduction from the AGESA blob into<br>   coreboot (eliminate the concept of temp ram).<br><br>BUG=b:74518368<br>TEST=Boot Kahlee with experimental PI blob<br><br>Change-Id: Ieda202a6064302b21707bd7ddfabc132cd85ed45<br>Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com><br>---<br>M src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h<br>M src/soc/amd/common/block/include/amdblocks/agesawrapper.h<br>M src/soc/amd/common/block/pi/Kconfig<br>M src/soc/amd/common/block/pi/def_callouts.c<br>M src/soc/amd/common/block/pi/heapmanager.c<br>M src/soc/amd/stoneyridge/bootblock/bootblock.c<br>M src/soc/amd/stoneyridge/include/soc/cpu.h<br>M src/soc/amd/stoneyridge/romstage.c<br>8 files changed, 86 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/25458/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h</span><br><span>index 34131cf..d317c66 100644</span><br><span>--- a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h</span><br><span>+++ b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h</span><br><span>@@ -33,6 +33,7 @@</span><br><span>         UINT32 NextNodeOffset;</span><br><span> } BIOS_BUFFER_NODE;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AGESA_STATUS agesa_HeapRebase(UINT32 Func, UINTN Data, VOID *ConfigPtr);</span><br><span> AGESA_STATUS agesa_AllocateBuffer(UINT32 Func, UINTN Data, VOID *ConfigPtr);</span><br><span> AGESA_STATUS agesa_DeallocateBuffer(UINT32 Func, UINTN Data, VOID *ConfigPtr);</span><br><span> AGESA_STATUS agesa_LocateBuffer(UINT32 Func, UINTN Data, VOID *ConfigPtr);</span><br><span>diff --git a/src/soc/amd/common/block/include/amdblocks/agesawrapper.h b/src/soc/amd/common/block/include/amdblocks/agesawrapper.h</span><br><span>index 986d6f8..00452dd4 100644</span><br><span>--- a/src/soc/amd/common/block/include/amdblocks/agesawrapper.h</span><br><span>+++ b/src/soc/amd/common/block/include/amdblocks/agesawrapper.h</span><br><span>@@ -63,4 +63,8 @@</span><br><span> void SetFchMidParams(FCH_INTERFACE *params);</span><br><span> void SetNbMidParams(GNB_MID_CONFIGURATION *params);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define AGESA_HEAP_IN_CAR 1</span><br><span style="color: hsl(120, 100%, 40%);">+#define AGESA_HEAP_IN_DRAM 0</span><br><span style="color: hsl(120, 100%, 40%);">+void set_agesa_heap_loc(int premem);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* __AGESAWRAPPER_H__ */</span><br><span>diff --git a/src/soc/amd/common/block/pi/Kconfig b/src/soc/amd/common/block/pi/Kconfig</span><br><span>index bd5926f..5c4a00b 100644</span><br><span>--- a/src/soc/amd/common/block/pi/Kconfig</span><br><span>+++ b/src/soc/amd/common/block/pi/Kconfig</span><br><span>@@ -4,3 +4,32 @@</span><br><span>       default n</span><br><span>    help</span><br><span>           This option builds functions that interface AMD's AGESA.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if SOC_AMD_COMMON_BLOCK_PI</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config PI_AGESA_CAR_HEAP_BASE</span><br><span style="color: hsl(120, 100%, 40%);">+ hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x400000</span><br><span style="color: hsl(120, 100%, 40%);">+      help</span><br><span style="color: hsl(120, 100%, 40%);">+    The AGESA PI blob may be built to allow an optional callout for</span><br><span style="color: hsl(120, 100%, 40%);">+       AgesaHeapRebase.  If called, this option determines the location</span><br><span style="color: hsl(120, 100%, 40%);">+      for the heap prior to DRAM availability.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config PI_AGESA_CAR_HEAP_SIZE</span><br><span style="color: hsl(120, 100%, 40%);">+   hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x20000</span><br><span style="color: hsl(120, 100%, 40%);">+       help</span><br><span style="color: hsl(120, 100%, 40%);">+    This option determines the amount of space allowed for AGESA heap</span><br><span style="color: hsl(120, 100%, 40%);">+     prior to DRAM availability.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config PI_AGESA_HEAP_SET_MTRR</span><br><span style="color: hsl(120, 100%, 40%);">+        bool</span><br><span style="color: hsl(120, 100%, 40%);">+  default n if PI_AGESA_CAR_HEAP_BASE = 0x400000</span><br><span style="color: hsl(120, 100%, 40%);">+        default y</span><br><span style="color: hsl(120, 100%, 40%);">+     help</span><br><span style="color: hsl(120, 100%, 40%);">+    AGESA is compiled with a default pre-DRAM heap base of 4 MB.  It</span><br><span style="color: hsl(120, 100%, 40%);">+      will set a variable MTRR for this range if not overridden by</span><br><span style="color: hsl(120, 100%, 40%);">+          coreboot.  If coreboot indicates a heap base of 4MB, AGESA can't</span><br><span style="color: hsl(120, 100%, 40%);">+          detect the override and will still program an MTRR.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span>diff --git a/src/soc/amd/common/block/pi/def_callouts.c b/src/soc/amd/common/block/pi/def_callouts.c</span><br><span>index beb2d18..bc8a2f6 100644</span><br><span>--- a/src/soc/amd/common/block/pi/def_callouts.c</span><br><span>+++ b/src/soc/amd/common/block/pi/def_callouts.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span>      { AGESA_DO_RESET,                 agesa_Reset },</span><br><span>     { AGESA_FCH_OEM_CALLOUT,          agesa_fch_initreset },</span><br><span>     { AGESA_HALT_THIS_AP,             agesa_HaltThisAp },</span><br><span style="color: hsl(120, 100%, 40%);">+ { AGESA_HEAP_REBASE,              agesa_HeapRebase },</span><br><span>        { AGESA_GNB_PCIE_SLOT_RESET,      agesa_PcieSlotResetControl }</span><br><span> };</span><br><span> #else</span><br><span>@@ -49,6 +50,7 @@</span><br><span> #endif /* ENV_RAMSTAGE */</span><br><span> </span><br><span>   /* Optional callouts */</span><br><span style="color: hsl(120, 100%, 40%);">+       { AGESA_HEAP_REBASE,                   agesa_HeapRebase },</span><br><span>   { AGESA_GET_IDS_INIT_DATA,             agesa_EmptyIdsInitData },</span><br><span>     //AgesaHeapRebase - Hook ID?</span><br><span>         { AGESA_HOOKBEFORE_DRAM_INIT,          agesa_NoopUnsupported },</span><br><span>diff --git a/src/soc/amd/common/block/pi/heapmanager.c b/src/soc/amd/common/block/pi/heapmanager.c</span><br><span>index a469a45..5545b00 100644</span><br><span>--- a/src/soc/amd/common/block/pi/heapmanager.c</span><br><span>+++ b/src/soc/amd/common/block/pi/heapmanager.c</span><br><span>@@ -11,7 +11,10 @@</span><br><span>  * GNU General Public License for more details.</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/early_variables.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/mtrr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/cpu.h></span><br><span> #include <amdblocks/agesawrapper.h></span><br><span> #include <amdlib.h></span><br><span> #include <arch/acpi.h></span><br><span>@@ -19,13 +22,38 @@</span><br><span> #include <cbmem.h></span><br><span> #include <string.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int use_pre_cbmem_heap CAR_GLOBAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void *agesa_heap_base(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  return cbmem_add(CBMEM_ID_RESUME_SCRATCH, BIOS_HEAP_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* todo: remove ENV_BOOTBLOCK when AGESA is out of bootblock */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ENV_BOOTBLOCK || car_get_var(use_pre_cbmem_heap))</span><br><span style="color: hsl(120, 100%, 40%);">+         return (void *)CONFIG_PI_AGESA_CAR_HEAP_BASE;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+          return cbmem_add(CBMEM_ID_RESUME_SCRATCH, BIOS_HEAP_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Setting is 0 automatically. No need to initialize with AGESA_HEAP_IN_DRAM. */</span><br><span style="color: hsl(120, 100%, 40%);">+void set_agesa_heap_loc(int loc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);</span><br><span style="color: hsl(120, 100%, 40%);">+ int mtrr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   car_set_var(use_pre_cbmem_heap, loc);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (loc == AGESA_HEAP_IN_DRAM)</span><br><span style="color: hsl(120, 100%, 40%);">+                return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!IS_ENABLED(CONFIG_PI_AGESA_HEAP_SET_MTRR))</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_AGESA_HEAP;</span><br><span style="color: hsl(120, 100%, 40%);">+        set_var_mtrr(mtrr, CONFIG_PI_AGESA_CAR_HEAP_BASE,</span><br><span style="color: hsl(120, 100%, 40%);">+                     CONFIG_PI_AGESA_CAR_HEAP_SIZE, MTRR_TYPE_WRBACK);</span><br><span> }</span><br><span> </span><br><span> static void EmptyHeap(int unused)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  set_agesa_heap_loc(AGESA_HEAP_IN_DRAM);</span><br><span>      void *BiosManagerPtr = agesa_heap_base();</span><br><span>    memset(BiosManagerPtr, 0, BIOS_HEAP_SIZE);</span><br><span> }</span><br><span>@@ -35,6 +63,21 @@</span><br><span> #endif</span><br><span> ROMSTAGE_CBMEM_INIT_HOOK(EmptyHeap)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AGESA_STATUS agesa_HeapRebase(UINT32 Func, UINTN Data, VOID *ConfigPtr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ AGESA_REBASE_PARAMS *RebaseParams;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  RebaseParams = (AGESA_REBASE_PARAMS *)ConfigPtr;</span><br><span style="color: hsl(120, 100%, 40%);">+      RebaseParams->HeapAddress = (UINTN)agesa_heap_base();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (RebaseParams->HeapAddress) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return AGESA_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_ERR, "Error: AGESA heap has no base\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return AGESA_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AGESA_STATUS agesa_AllocateBuffer (UINT32 Func, UINTN Data, VOID *ConfigPtr)</span><br><span> {</span><br><span>  UINT32              AvailableHeapSize;</span><br><span>diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c</span><br><span>index db5c9b6..6fa9239 100644</span><br><span>--- a/src/soc/amd/stoneyridge/bootblock/bootblock.c</span><br><span>+++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c</span><br><span>@@ -121,6 +121,8 @@</span><br><span>        if (boot_cpu() && IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW))</span><br><span>          load_smu_fw1();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   set_agesa_heap_loc(AGESA_HEAP_IN_CAR);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     post_code(0x37);</span><br><span>     do_agesawrapper(agesawrapper_amdinitreset, "amdinitreset");</span><br><span> </span><br><span>diff --git a/src/soc/amd/stoneyridge/include/soc/cpu.h b/src/soc/amd/stoneyridge/include/soc/cpu.h</span><br><span>index bf8ed49..d4acae7 100644</span><br><span>--- a/src/soc/amd/stoneyridge/include/soc/cpu.h</span><br><span>+++ b/src/soc/amd/stoneyridge/include/soc/cpu.h</span><br><span>@@ -26,6 +26,7 @@</span><br><span>  *  todo: Revisit this once AGESA no longer programs MTRRs.</span><br><span>  */</span><br><span> #define SOC_EARLY_VMTRR_FLASH 2</span><br><span style="color: hsl(120, 100%, 40%);">+#define SOC_EARLY_VMTRR_AGESA_HEAP 1</span><br><span> </span><br><span> void stoney_init_cpus(struct device *dev);</span><br><span> </span><br><span>diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c</span><br><span>index 490fd9e..fc50d98 100644</span><br><span>--- a/src/soc/amd/stoneyridge/romstage.c</span><br><span>+++ b/src/soc/amd/stoneyridge/romstage.c</span><br><span>@@ -47,6 +47,8 @@</span><br><span> </span><br><span>     console_init();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   set_agesa_heap_loc(AGESA_HEAP_IN_CAR); /* Re-init for romstage */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (!s3_resume) {</span><br><span>            post_code(0x40);</span><br><span>             do_agesawrapper(agesawrapper_amdinitpost, "amdinitpost");</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25458">change 25458</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/25458"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ieda202a6064302b21707bd7ddfabc132cd85ed45 </div>
<div style="display:none"> Gerrit-Change-Number: 25458 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Marshall Dawson <marshalldawson3rd@gmail.com> </div>