[coreboot-gerrit] Change in coreboot[master]: soc/amd: Add agesa_HeapRebase callout

Marshall Dawson (Code Review) gerrit at coreboot.org
Thu Mar 29 22:14:53 CEST 2018


Marshall Dawson has uploaded this change for review. ( https://review.coreboot.org/25458


Change subject: soc/amd: Add agesa_HeapRebase callout
......................................................................

soc/amd: Add agesa_HeapRebase callout

One of AGESA's optional callout functions allows it to use a heap area
managed by coreboot.  Add the function here; note that AGESA does not
yet call out to agesa_HeapRebase.

AGESA treats the heap as follows:
 * It assumes an initial heap base address of 4 MB.  An abstracted call
   to AgesaHeapRebase is made for an opportunity to override the base.
 * If necessary, AGESA programs a variable MTRR in order to keep its
   heap in CAR.
 * At the end of AmdInitPost, AGESA migrates the heap to 0xb0000 (temp
   mem) and removes blocks that will not be used later.
 * After AmdInitPost, coreboot initializes cbmem and uses a region there
   for requested heap space.
 * During AmdInitEnv, AGESA migrates its heap information from temp mem
   to the cbmem region (main ram).

To support this callout, define a region that may be used while CAR is
still present.  The heap base may then either be in CAR or cbmem.  Make
the default cbmem (i.e. for postcar, ramstage).  Add a function that
can indicate the base should be in CAR instead.  This currently needs
to be called before an AGESA Entry Point call in bootblock and romstage.
(Only a single one will be required once AGESA moves out of bootblock.)
Add a call from EmptyHeap that switches the heap base to cbmem.

Future work may include:
 * The AMD standard CAR setup code doesn't allow enough space to use a
   a CAR_GLOBAL variable.  Consider redoing the AMD CAR setup and
   teardown functionality, and use a CAR_GLOBAL region instead.
 * Move the heap migration and reduction from the AGESA blob into
   coreboot (eliminate the concept of temp ram).

BUG=b:74518368
TEST=Boot Kahlee with experimental PI blob

Change-Id: Ieda202a6064302b21707bd7ddfabc132cd85ed45
Signed-off-by: Marshall Dawson <marshalldawson3rd at gmail.com>
---
M src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
M src/soc/amd/common/block/include/amdblocks/agesawrapper.h
M src/soc/amd/common/block/pi/Kconfig
M src/soc/amd/common/block/pi/def_callouts.c
M src/soc/amd/common/block/pi/heapmanager.c
M src/soc/amd/stoneyridge/bootblock/bootblock.c
M src/soc/amd/stoneyridge/include/soc/cpu.h
M src/soc/amd/stoneyridge/romstage.c
8 files changed, 86 insertions(+), 2 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/25458/1

diff --git a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
index 34131cf..d317c66 100644
--- a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
+++ b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
@@ -33,6 +33,7 @@
 	UINT32 NextNodeOffset;
 } BIOS_BUFFER_NODE;
 
+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);
 AGESA_STATUS agesa_LocateBuffer(UINT32 Func, UINTN Data, VOID *ConfigPtr);
diff --git a/src/soc/amd/common/block/include/amdblocks/agesawrapper.h b/src/soc/amd/common/block/include/amdblocks/agesawrapper.h
index 986d6f8..00452dd4 100644
--- a/src/soc/amd/common/block/include/amdblocks/agesawrapper.h
+++ b/src/soc/amd/common/block/include/amdblocks/agesawrapper.h
@@ -63,4 +63,8 @@
 void SetFchMidParams(FCH_INTERFACE *params);
 void SetNbMidParams(GNB_MID_CONFIGURATION *params);
 
+#define AGESA_HEAP_IN_CAR 1
+#define AGESA_HEAP_IN_DRAM 0
+void set_agesa_heap_loc(int premem);
+
 #endif /* __AGESAWRAPPER_H__ */
diff --git a/src/soc/amd/common/block/pi/Kconfig b/src/soc/amd/common/block/pi/Kconfig
index bd5926f..5c4a00b 100644
--- a/src/soc/amd/common/block/pi/Kconfig
+++ b/src/soc/amd/common/block/pi/Kconfig
@@ -4,3 +4,32 @@
 	default n
 	help
 	  This option builds functions that interface AMD's AGESA.
+
+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 called, this option determines the location
+	  for the heap prior to DRAM availability.
+
+config PI_AGESA_CAR_HEAP_SIZE
+	hex
+	default 0x20000
+	help
+	  This option determines the amount of space allowed for AGESA heap
+	  prior to DRAM availability.
+
+config PI_AGESA_HEAP_SET_MTRR
+	bool
+	default n if PI_AGESA_CAR_HEAP_BASE = 0x400000
+	default y
+	help
+	  AGESA is compiled with a default pre-DRAM heap base of 4 MB.  It
+	  will set a variable MTRR for this range if not overridden by
+	  coreboot.  If coreboot indicates a heap base of 4MB, AGESA can't
+	  detect the override and will still program an MTRR.
+
+endif
diff --git a/src/soc/amd/common/block/pi/def_callouts.c b/src/soc/amd/common/block/pi/def_callouts.c
index beb2d18..bc8a2f6 100644
--- a/src/soc/amd/common/block/pi/def_callouts.c
+++ b/src/soc/amd/common/block/pi/def_callouts.c
@@ -30,6 +30,7 @@
 	{ 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
@@ -49,6 +50,7 @@
 #endif /* ENV_RAMSTAGE */
 
 	/* Optional callouts */
+	{ AGESA_HEAP_REBASE,                   agesa_HeapRebase },
 	{ AGESA_GET_IDS_INIT_DATA,             agesa_EmptyIdsInitData },
 	//AgesaHeapRebase - Hook ID?
 	{ AGESA_HOOKBEFORE_DRAM_INIT,          agesa_NoopUnsupported },
diff --git a/src/soc/amd/common/block/pi/heapmanager.c b/src/soc/amd/common/block/pi/heapmanager.c
index a469a45..5545b00 100644
--- a/src/soc/amd/common/block/pi/heapmanager.c
+++ b/src/soc/amd/common/block/pi/heapmanager.c
@@ -11,7 +11,10 @@
  * GNU General Public License for more details.
  */
 
-
+#include <arch/early_variables.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <soc/cpu.h>
 #include <amdblocks/agesawrapper.h>
 #include <amdlib.h>
 #include <arch/acpi.h>
@@ -19,13 +22,38 @@
 #include <cbmem.h>
 #include <string.h>
 
+static int use_pre_cbmem_heap CAR_GLOBAL;
+
 static void *agesa_heap_base(void)
 {
-	return cbmem_add(CBMEM_ID_RESUME_SCRATCH, BIOS_HEAP_SIZE);
+	/* todo: remove ENV_BOOTBLOCK when AGESA is out of bootblock */
+	if (ENV_BOOTBLOCK || car_get_var(use_pre_cbmem_heap))
+		return (void *)CONFIG_PI_AGESA_CAR_HEAP_BASE;
+	else
+		return cbmem_add(CBMEM_ID_RESUME_SCRATCH, BIOS_HEAP_SIZE);
+}
+
+/* Setting is 0 automatically. No need to initialize with AGESA_HEAP_IN_DRAM. */
+void set_agesa_heap_loc(int loc)
+{
+	msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
+	int mtrr;
+
+	car_set_var(use_pre_cbmem_heap, loc);
+	if (loc == AGESA_HEAP_IN_DRAM)
+		return;
+
+	if (!IS_ENABLED(CONFIG_PI_AGESA_HEAP_SET_MTRR))
+		return;
+
+	mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_AGESA_HEAP;
+	set_var_mtrr(mtrr, CONFIG_PI_AGESA_CAR_HEAP_BASE,
+			CONFIG_PI_AGESA_CAR_HEAP_SIZE, MTRR_TYPE_WRBACK);
 }
 
 static void EmptyHeap(int unused)
 {
+	set_agesa_heap_loc(AGESA_HEAP_IN_DRAM);
 	void *BiosManagerPtr = agesa_heap_base();
 	memset(BiosManagerPtr, 0, BIOS_HEAP_SIZE);
 }
@@ -35,6 +63,21 @@
 #endif
 ROMSTAGE_CBMEM_INIT_HOOK(EmptyHeap)
 
+AGESA_STATUS agesa_HeapRebase(UINT32 Func, UINTN Data, VOID *ConfigPtr)
+{
+	AGESA_REBASE_PARAMS *RebaseParams;
+
+	RebaseParams = (AGESA_REBASE_PARAMS *)ConfigPtr;
+	RebaseParams->HeapAddress = (UINTN)agesa_heap_base();
+
+	if (RebaseParams->HeapAddress) {
+		return AGESA_SUCCESS;
+	} else {
+		printk(BIOS_ERR, "Error: AGESA heap has no base\n");
+		return AGESA_ERROR;
+	}
+}
+
 AGESA_STATUS agesa_AllocateBuffer (UINT32 Func, UINTN Data, VOID *ConfigPtr)
 {
 	UINT32              AvailableHeapSize;
diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c
index db5c9b6..6fa9239 100644
--- a/src/soc/amd/stoneyridge/bootblock/bootblock.c
+++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c
@@ -121,6 +121,8 @@
 	if (boot_cpu() && IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW))
 		load_smu_fw1();
 
+	set_agesa_heap_loc(AGESA_HEAP_IN_CAR);
+
 	post_code(0x37);
 	do_agesawrapper(agesawrapper_amdinitreset, "amdinitreset");
 
diff --git a/src/soc/amd/stoneyridge/include/soc/cpu.h b/src/soc/amd/stoneyridge/include/soc/cpu.h
index bf8ed49..d4acae7 100644
--- a/src/soc/amd/stoneyridge/include/soc/cpu.h
+++ b/src/soc/amd/stoneyridge/include/soc/cpu.h
@@ -26,6 +26,7 @@
  *  todo: Revisit this once AGESA no longer programs MTRRs.
  */
 #define SOC_EARLY_VMTRR_FLASH 2
+#define SOC_EARLY_VMTRR_AGESA_HEAP 1
 
 void stoney_init_cpus(struct device *dev);
 
diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c
index 490fd9e..fc50d98 100644
--- a/src/soc/amd/stoneyridge/romstage.c
+++ b/src/soc/amd/stoneyridge/romstage.c
@@ -47,6 +47,8 @@
 
 	console_init();
 
+	set_agesa_heap_loc(AGESA_HEAP_IN_CAR); /* Re-init for romstage */
+
 	if (!s3_resume) {
 		post_code(0x40);
 		do_agesawrapper(agesawrapper_amdinitpost, "amdinitpost");

-- 
To view, visit https://review.coreboot.org/25458
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ieda202a6064302b21707bd7ddfabc132cd85ed45
Gerrit-Change-Number: 25458
Gerrit-PatchSet: 1
Gerrit-Owner: Marshall Dawson <marshalldawson3rd at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180329/243d222c/attachment-0001.html>


More information about the coreboot-gerrit mailing list