summaryrefslogtreecommitdiffstats
path: root/src/usr/runtime
diff options
context:
space:
mode:
authorMatt Derksen <mderkse1@us.ibm.com>2018-07-19 16:41:22 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-08-02 14:35:13 -0500
commit847e8ef1fbeb1c87cc2ff9d7dfe7ad3a8d4d9895 (patch)
tree9b6b6569bd31eff4c5325ac61448f2925c2cc05a /src/usr/runtime
parent4dfcdd4a9e59308aa24a94673d5d16341b383dea (diff)
downloadtalos-hostboot-847e8ef1fbeb1c87cc2ff9d7dfe7ad3a8d4d9895.tar.gz
talos-hostboot-847e8ef1fbeb1c87cc2ff9d7dfe7ad3a8d4d9895.zip
Add hostboot reserved memory mirroring support
Adding this support to avoid losing runtime functions (PRD, OCC/PM Complex management) to a mirroring-enabled system when a memory channel failure happens to the first piece of memory in a drawer. Basically just need to change where we physically map hostboot reserved memory to be the new mirrored spot. Change-Id: I85aa8c6033a47e4598eb1130e0b3d06c360ea479 CQ:SW437433 CMVC-Prereq: 1063550 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/63034 Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: ILYA SMIRNOV <ismirno@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/runtime')
-rw-r--r--src/usr/runtime/populate_hbruntime.C70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 28fab3e7d..5450319e9 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -92,7 +92,7 @@ const uint8_t BITS_PER_BYTE = 8;
const uint8_t HDAT_INVALID_NODE = 0xFF;
// The upper limit of the hostboot reserved memory. Only applies to PHYP.
-// The lower limit is Hostboot HRMOR + 64MB;
+// The lower limit is Hostboot HRMOR + 64MB (if not mirroring)
const uint64_t HB_RES_MEM_UPPER_LIMIT = 256*MEGABYTE;
// The lower limit of the hostboot reserved memory. Do not allow to reserve
@@ -197,7 +197,7 @@ errlHndl_t getNextRhbAddrRange(hdatMsVpdRhbAddrRange_t* & o_rngPtr)
TARGETING::Target * l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget( l_sys );
- assert(l_sys != nullptr);
+ assert(l_sys != nullptr,"getNextRhbAddrRange:top level target nullptr");
uint32_t l_nextSection =
@@ -345,6 +345,34 @@ errlHndl_t checkHbResMemLimit(const uint64_t i_addr, const uint64_t i_size)
uint64_t l_lowerLimit = HB_RES_MEM_LOWER_LIMIT + l_hbAddr;
uint64_t l_upperLimit = HB_RES_MEM_UPPER_LIMIT + l_hbAddr;
+ // Update address limits for mirroring
+ if(TARGETING::is_phyp_load())
+ {
+ // Change address start to mirror address, if mirror enabled
+ TARGETING::Target* l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ assert( l_sys != nullptr,"checkHbResMemLimit:top level target nullptr");
+
+ auto l_mirrored =
+ l_sys->getAttr<TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM>();
+ if (l_mirrored)
+ {
+ TARGETING::ATTR_MIRROR_BASE_ADDRESS_type l_mirrorBase = 0;
+ l_mirrorBase =
+ l_sys->getAttr<TARGETING::ATTR_MIRROR_BASE_ADDRESS>();
+
+ TRACFCOMP( g_trac_runtime,
+ "checkHbResMemLimit> Adding mirror base %p so "
+ "new start address at %p",
+ reinterpret_cast<void*>(l_mirrorBase),
+ reinterpret_cast<void*>(l_lowerLimit + l_mirrorBase) );
+
+ // update address to new mirror address
+ l_lowerLimit += l_mirrorBase;
+ l_upperLimit += l_mirrorBase;
+ }
+ }
+
TRACDCOMP(g_trac_runtime, "l_hbAddr 0x%.16llX, i_addr 0x%.16llX, l_lowerLimit 0x%.16llX",
l_hbAddr, i_addr, l_lowerLimit);
TRACDCOMP(g_trac_runtime, "i_size = 0x%.16llX, l_upperLimit = 0x%.16llX",
@@ -420,7 +448,7 @@ errlHndl_t setNextHbRsvMemEntry(const HDAT::hdatMsVpdRhbAddrRangeType i_type,
assert(l_rngPtr != nullptr, "getNextRhbAddrRange returned nullptr");
// Determine starting address
- // Logical OR staring adddress with enum FORCE_PHYS_ADDR to
+ // Logical OR starting address with enum FORCE_PHYS_ADDR to
// ignore the HRMOR bit
uint64_t l_startAddr = i_startAddr | VmmManager::FORCE_PHYS_ADDR;
@@ -1090,11 +1118,37 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node)
TARGETING::TYPE_PROC,
true);
+ TARGETING::ATTR_MIRROR_BASE_ADDRESS_type l_mirrorBase = 0;
if(TARGETING::is_phyp_load())
{
// First phyp entry is for the entire 256M HB space
- uint64_t l_hbAddr = cpu_spr_value(CPU_SPR_HRMOR)
- - VMM_HRMOR_OFFSET;
+ uint64_t l_hbAddr = cpu_spr_value(CPU_SPR_HRMOR) - VMM_HRMOR_OFFSET;
+
+ // If mirroring enabled,
+ // change address start to be at its mirrored address equivalent
+ TARGETING::Target* l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ assert( l_sys != nullptr,
+ "populate_HbRsvMem: top level target nullptr" );
+
+ auto l_mirrored =
+ l_sys->getAttr<TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM>();
+ if (l_mirrored)
+ {
+ l_mirrorBase =
+ l_sys->getAttr<TARGETING::ATTR_MIRROR_BASE_ADDRESS>();
+
+ TRACFCOMP( g_trac_runtime,
+ "populate_HbRsvMem> Adding mirror base %p so "
+ "new start address at %p",
+ reinterpret_cast<void*>(l_mirrorBase),
+ reinterpret_cast<void*>(l_hbAddr + l_mirrorBase) );
+
+ // l_mirrorBase is basically a new floor/zero that we want to
+ // orient everything against. Therefore we just add it onto
+ // the address we would normally use.
+ l_hbAddr += l_mirrorBase;
+ }
l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_PRIMARY,
i_nodeId,
l_hbAddr,
@@ -1210,7 +1264,9 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node)
{
TARGETING::Target * l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget( l_sys );
- assert(l_sys != nullptr);
+ assert( l_sys != nullptr,
+ "populate_HbRsvMem:CONFIG_START_OCC_DURING_BOOT - "
+ "top level target nullptr" );
uint64_t l_occCommonAddr = l_sys->getAttr
<TARGETING::ATTR_OCC_COMMON_AREA_PHYS_ADDR>();
l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HOMER_OCC,
@@ -1244,7 +1300,7 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node)
if(TARGETING::is_phyp_load())
{
l_startAddr = cpu_spr_value(CPU_SPR_HRMOR)
- + VMM_HB_DATA_TOC_START_OFFSET;
+ + l_mirrorBase + VMM_HB_DATA_TOC_START_OFFSET;
}
else if(TARGETING::is_sapphire_load())
{
OpenPOWER on IntegriCloud