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(a)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(a)gmail.com>
Marshall Dawson has uploaded this change for review. ( https://review.coreboot.org/25456
Change subject: vc/amd/stoneyridge: Add definition for AGESA heap rebase
......................................................................
vc/amd/stoneyridge: Add definition for AGESA heap rebase
AgesaHeapRebase is an optional callout that allows AGESA to use a
coreboot-managed heap base address. Its internal default location
is determined by AMD_HEAP_START_ADDRESS which is defined as 4 MB.
Add a #define that AGESA may use once the feature is available.
BUG=b:74518368
Change-Id: Id23455779b1c8c4931ad1a3122587e09ad237ecc
Signed-off-by: Marshall Dawson <marshalldawson3rd(a)gmail.com>
---
M src/vendorcode/amd/pi/00670F00/AGESA.h
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/56/25456/1
diff --git a/src/vendorcode/amd/pi/00670F00/AGESA.h b/src/vendorcode/amd/pi/00670F00/AGESA.h
index 2b2a8b6..ba1e505 100644
--- a/src/vendorcode/amd/pi/00670F00/AGESA.h
+++ b/src/vendorcode/amd/pi/00670F00/AGESA.h
@@ -68,6 +68,7 @@
#define AGESA_IDLE_AN_AP 0x00028107ul
#define AGESA_WAIT_FOR_ALL_APS 0x00028108ul
#define AGESA_HALT_THIS_AP 0x00028109ul
+#define AGESA_HEAP_REBASE 0x0002810aul
// AGESA ADVANCED CALLOUTS, Memory
#define AGESA_READ_SPD 0x00028140ul
--
To view, visit https://review.coreboot.org/25456
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: Id23455779b1c8c4931ad1a3122587e09ad237ecc
Gerrit-Change-Number: 25456
Gerrit-PatchSet: 1
Gerrit-Owner: Marshall Dawson <marshalldawson3rd(a)gmail.com>
Marshall Dawson has uploaded this change for review. ( https://review.coreboot.org/25455
Change subject: amd/stoneyridge: Use defined value for SPI flash MTRR
......................................................................
amd/stoneyridge: Use defined value for SPI flash MTRR
Replace an absolute value with a #define value in bootblock. This is
in preparation for using an additional MTRR in a subsequent patch.
Change-Id: I006c7cfa0057b3ed4a21359fc8367caf6ec5baf3
Signed-off-by: Marshall Dawson <marshalldawson3rd(a)gmail.com>
---
M src/soc/amd/stoneyridge/bootblock/bootblock.c
M src/soc/amd/stoneyridge/include/soc/cpu.h
2 files changed, 13 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/25455/1
diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c
index fafaf07..db5c9b6 100644
--- a/src/soc/amd/stoneyridge/bootblock/bootblock.c
+++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c
@@ -25,6 +25,7 @@
#include <amdblocks/agesawrapper.h>
#include <amdblocks/agesawrapper_call.h>
#include <soc/pci_devs.h>
+#include <soc/cpu.h>
#include <soc/northbridge.h>
#include <soc/southbridge.h>
#include <amdblocks/psp.h>
@@ -61,7 +62,7 @@
* todo: AGESA currently writes variable MTRRs. Once that is
* corrected, un-hardcode this MTRR.
*/
- mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - 2;
+ mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_FLASH;
set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
}
diff --git a/src/soc/amd/stoneyridge/include/soc/cpu.h b/src/soc/amd/stoneyridge/include/soc/cpu.h
index d2c412f..bf8ed49 100644
--- a/src/soc/amd/stoneyridge/include/soc/cpu.h
+++ b/src/soc/amd/stoneyridge/include/soc/cpu.h
@@ -16,6 +16,17 @@
#ifndef __STONEYRIDGE_CPU_H__
#define __STONEYRIDGE_CPU_H__
+#include <device/device.h>
+
+/*
+ * Set a variable MTRR in bootblock and/or romstage. AGESA will use the lowest
+ * numbered registers. Any values defined below are subtracted from the
+ * highest numbered registers.
+ *
+ * todo: Revisit this once AGESA no longer programs MTRRs.
+ */
+#define SOC_EARLY_VMTRR_FLASH 2
+
void stoney_init_cpus(struct device *dev);
#endif /* __STONEYRIDGE_CPU_H__ */
--
To view, visit https://review.coreboot.org/25455
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: I006c7cfa0057b3ed4a21359fc8367caf6ec5baf3
Gerrit-Change-Number: 25455
Gerrit-PatchSet: 1
Gerrit-Owner: Marshall Dawson <marshalldawson3rd(a)gmail.com>