summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2019-07-16 15:51:06 -0500
committerDaniel M Crowell <dcrowell@us.ibm.com>2019-08-05 15:33:09 -0500
commit7a758c4ef4c69abf1510271e437d250e4691f1ac (patch)
tree3b271dcbfe48d4ff0d02304675275434dc634b8a /src
parent4ced775921eb599a0579e98c2f3f19ab08b53ed3 (diff)
downloadtalos-hostboot-7a758c4ef4c69abf1510271e437d250e4691f1ac.tar.gz
talos-hostboot-7a758c4ef4c69abf1510271e437d250e4691f1ac.zip
Handle processor swap between slots to 1-socket system
If a processor was booted in the second slot, it will be programmed to use the memory for that slot. When it is installed in the first slot it will then get reprogrammed to use the data for slot0. However, if the new system only contains data for that 1 slot, we won't be able to find a match to do the initial part of the boot. This change will force some values into good enough shape to get the boot far enough to do the SBE update to reprogram the memory map. Change-Id: I9b88d4181272104a8c680e9b5e84c4d204fdea05 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/80680 Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Christian R Geddes <crgeddes@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')
-rw-r--r--src/include/arch/memorymap.H25
-rw-r--r--src/include/usr/isteps/istep_reasoncodes.H2
-rw-r--r--src/usr/isteps/istep06/host_discover_targets.C65
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/attribute_types_hb.xml33
-rw-r--r--src/usr/targeting/common/xmltohb/target_types_hb.xml3
-rwxr-xr-xsrc/usr/targeting/targetservicestart.C73
6 files changed, 190 insertions, 11 deletions
diff --git a/src/include/arch/memorymap.H b/src/include/arch/memorymap.H
index 7b75f6363..1ea479d8c 100644
--- a/src/include/arch/memorymap.H
+++ b/src/include/arch/memorymap.H
@@ -39,8 +39,13 @@ constexpr uint64_t MMIO_OFFSET_PER_CHIP = (4*TERABYTE); //0x40000000000
constexpr uint64_t MMIO_OFFSET_PER_GROUP = (32*TERABYTE); //0x200000000000
constexpr uint64_t MMIO_BASE = 0x6000000000000;
+
/**
* @brief Compute MMIO value for a given chip and base value
+ * @param[in] i_baseAddr group0-chip0 address
+ * @param[in] i_group Fabric Group ID to compute address for
+ * @param[in] i_chip Fabric Chip ID to compute address for
+ * @return Fully qualified memory address
*/
inline uint64_t computeMemoryMapOffset( uint64_t i_baseAddr,
uint8_t i_group,
@@ -52,6 +57,26 @@ inline uint64_t computeMemoryMapOffset( uint64_t i_baseAddr,
};
/**
+ * @brief Determine fabric id from a MMIO address
+ * @param[in] i_addr position-specific memory address
+ * @param[out] i_group Fabric Group ID to compute address for
+ * @param[out] i_chip Fabric Chip ID to compute address for
+ */
+inline void getFabricIdFromAddr( uint64_t i_addr,
+ uint8_t& o_group,
+ uint8_t& o_chip )
+{
+ // chop off any high-order offset
+ uint64_t l_addr = i_addr % MMIO_BASE;
+ // use integer math to get the group id
+ o_group = l_addr / MMIO_OFFSET_PER_GROUP;
+ // chop off the group
+ l_addr = l_addr % MMIO_OFFSET_PER_GROUP;
+ // use integer math to get the chip id
+ o_chip = l_addr % MMIO_OFFSET_PER_CHIP;
+};
+
+/**
* @brief A few default values that will need to be known
* by low-level code
*/
diff --git a/src/include/usr/isteps/istep_reasoncodes.H b/src/include/usr/isteps/istep_reasoncodes.H
index 36c1e8e39..2199d75c8 100644
--- a/src/include/usr/isteps/istep_reasoncodes.H
+++ b/src/include/usr/isteps/istep_reasoncodes.H
@@ -69,6 +69,7 @@ namespace ISTEP
MOD_CALL_UPDATE_UCD_FLASH = 0x26,
MOD_LOAD_HCODE = 0x27,
MOD_GET_OMI_FREQ = 0x28,
+ MOD_DISCOVER_TARGETS = 0x29,
};
/**
@@ -144,6 +145,7 @@ namespace ISTEP
RC_UCD_IMG_NOT_IN_CONTAINER = ISTEP_COMP_ID | 0x4F,
RC_MM_UNMAP_FAILED = ISTEP_COMP_ID | 0x50,
RC_OMI_FREQ_MISMATCH = ISTEP_COMP_ID | 0x51,
+ RC_CANNOT_BOOT_WITH_MISMATCHED_BARS = ISTEP_COMP_ID | 0x52,
};
};
diff --git a/src/usr/isteps/istep06/host_discover_targets.C b/src/usr/isteps/istep06/host_discover_targets.C
index 89e0dd8dd..7884056c1 100644
--- a/src/usr/isteps/istep06/host_discover_targets.C
+++ b/src/usr/isteps/istep06/host_discover_targets.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -59,6 +59,7 @@
//SBE interfacing
#include <sbeio/sbeioif.H>
#include <sys/misc.h>
+#include <sbe/sbeif.H>
#include <p9_query_core_access_state.H>
#include <p9_setup_sbe_config.H>
@@ -618,13 +619,71 @@ void* host_discover_targets( void *io_pArgs )
errlCommit (l_err, ISTEP_COMP_ID);
}
} // end if (l_pMasterProcChip)
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "host_discover_targets exit" );
#ifdef CONFIG_PRINT_SYSTEM_INFO
print_system_info();
#endif
+ // Handle the case where we don't have a valid memory map swap victim due
+ // to a module swap - See TARGETING::adjustMemoryMap()
+ if( l_pTopLevel->getAttr<TARGETING::ATTR_FORCE_SBE_UPDATE>()
+ == TARGETING::FORCE_SBE_UPDATE_BAR_MISMATCH )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Forcing SBE update to handle swapped memory map" );
+ l_err = SBE::updateProcessorSbeSeeproms();
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "host_discover_targets: Error calling updateProcessorSbeSeeproms");
+ l_stepError.addErrorDetails( l_err );
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+
+ // We should never get here, if we do that means the SBE update didn't
+ // actually happen. That is a problem since we're currently running
+ // with mismatched BAR data
+ TARGETING::ATTR_XSCOM_BASE_ADDRESS_type l_xscom =
+ l_pMasterProcChip->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
+ TARGETING::ATTR_PROC_EFF_FABRIC_GROUP_ID_type l_group =
+ l_pMasterProcChip->getAttr<TARGETING::ATTR_PROC_EFF_FABRIC_GROUP_ID>();
+ TARGETING::ATTR_PROC_EFF_FABRIC_CHIP_ID_type l_chip =
+ l_pMasterProcChip->getAttr<TARGETING::ATTR_PROC_EFF_FABRIC_CHIP_ID>();
+ /*@
+ * @errortype
+ * @moduleid ISTEP::MOD_DISCOVER_TARGETS
+ * @reasoncode ISTEP::RC_CANNOT_BOOT_WITH_MISMATCHED_BARS
+ * @userdata1 Current XSCOM BAR
+ * @userdata2[0-31] Desired ATTR_PROC_EFF_FABRIC_GROUP_ID
+ * @userdata2[32:63] Desired ATTR_PROC_EFF_FABRIC_GROUP_ID
+ * @devdesc Not able to update the SBE to correct the BAR mismatch
+ * @custdesc Required module update failed
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ ISTEP::MOD_DISCOVER_TARGETS,
+ ISTEP::RC_CANNOT_BOOT_WITH_MISMATCHED_BARS,
+ l_xscom,
+ TWO_UINT32_TO_UINT64(
+ l_group,
+ l_chip));
+
+ l_err->addHwCallout( l_pMasterProcChip,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ l_err->collectTrace(TARG_COMP_NAME);
+ l_err->collectTrace(SBE_COMP_NAME);
+ l_err->collectTrace("ISTEPS_TRACE",256);
+
+ // Create IStep error log and cross ref error that occurred
+ l_stepError.addErrorDetails( l_err );
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "host_discover_targets exit" );
+
return l_stepError.getErrorHandle();
}
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index 491e9667b..2ca3f0494 100755
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -230,6 +230,39 @@
<readable/>
</attribute>
+ <enumerationType>
+ <description>
+ Enumeration specifying a target's CEC degraded mode domain
+ </description>
+ <default>NO</default>
+ <enumerator>
+ <name>NO</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>BAR_MISMATCH</name>
+ <value>1</value>
+ </enumerator>
+ <id>FORCE_SBE_UPDATE</id>
+ </enumerationType>
+
+ <attribute>
+ <id>FORCE_SBE_UPDATE</id>
+ <description>
+ Set to non-zero to force a SBE update at various places in the IPL.
+ </description>
+ <simpleType>
+ <enumeration>
+ <id>FORCE_SBE_UPDATE</id>
+ <default>NO</default>
+ </enumeration>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hbOnly/>
+ </attribute>
+
<attribute>
<!-- Need to add this explicitly to handle the Axone case -->
<id>FREQ_MCA_MHZ</id>
diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml
index 1f7421305..4b3599cef 100644
--- a/src/usr/targeting/common/xmltohb/target_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml
@@ -276,6 +276,9 @@
<attribute>
<id>FORCE_PRE_PAYLOAD_DRTM</id>
</attribute>
+ <attribute>
+ <id>FORCE_SBE_UPDATE</id>
+ </attribute>
<!-- Need to add this explicitly to handle the Axone case -->
<attribute>
<id>FREQ_MCA_MHZ</id>
diff --git a/src/usr/targeting/targetservicestart.C b/src/usr/targeting/targetservicestart.C
index 0cce34319..d16d8b75c 100755
--- a/src/usr/targeting/targetservicestart.C
+++ b/src/usr/targeting/targetservicestart.C
@@ -74,6 +74,7 @@
#include <sbeio/sbeioif.H>
#include <sys/mm.h>
#include "../runtime/hdatstructs.H"
+#include <console/consoleif.H>
#ifdef CONFIG_BMC_IPMI
#include <ipmi/ipmiif.H>
@@ -968,11 +969,65 @@ static void adjustMemoryMap( TargetService& i_targetService )
// Set the rest of the BARs...
}
- // We must have found a match somewhere
- TARG_ASSERT( l_swapVictim != nullptr, "No swap match found" );
+ // We should have found a match, but if a processor was swapped
+ // between different systems we could end up with a non-match
+ if( l_swapVictim == nullptr )
+ {
+ TARG_INF( "No swap victim was found, forcing master proc to use calculated proc0 values" );
+
+ // figure out what fabric id we actually booted with
+ uint8_t l_bootGroup = 0;
+ uint8_t l_bootChip = 0;
+ getFabricIdFromAddr( l_curXscomBAR, l_bootGroup, l_bootChip );
+ CONSOLE::displayf( NULL, "Module swap detected - handling memory remap from g%d:c%d\n", l_bootGroup, l_bootChip );
+
+ // now adjust the attributes that our early code is going to consume
+ // to match the fabric id we're currently using
+ ATTR_XSCOM_BASE_ADDRESS_type l_xscomBAR =
+ computeMemoryMapOffset( l_xscomBase, l_bootGroup, l_bootChip );
+ l_pMasterProcChip->setAttr<ATTR_XSCOM_BASE_ADDRESS>(l_xscomBAR);
+
+ ATTR_LPC_BUS_ADDR_type l_lpcBAR =
+ computeMemoryMapOffset( l_lpcBase, l_bootGroup, l_bootChip );
+ l_pMasterProcChip->setAttr<ATTR_LPC_BUS_ADDR>(l_lpcBAR);
+
+ ATTR_PSI_BRIDGE_BASE_ADDR_type l_psiBridgeBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_PSI_BRIDGE_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_PSI_BRIDGE_BASE_ADDR>(l_psiBridgeBAR);
+
+ ATTR_XIVE_CONTROLLER_BAR_ADDR_type l_xiveCtrlBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_XIVE_CONTROLLER_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_XIVE_CONTROLLER_BAR_ADDR>(l_xiveCtrlBAR);
+ ATTR_XIVE_THREAD_MGMT1_BAR_ADDR_type l_xiveThreadMgmtBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_XIVE_THREAD_MGMT1_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ TARG_INF( " XIVE_THREAD_MGMT1_BAR =%.16llX", l_xiveThreadMgmtBAR );
+ l_pMasterProcChip->setAttr<ATTR_XIVE_THREAD_MGMT1_BAR_ADDR>(l_xiveThreadMgmtBAR);
+
+ ATTR_PSI_HB_ESB_ADDR_type l_psiHbEsbBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_PSI_HB_ESB_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_PSI_HB_ESB_ADDR>(l_psiHbEsbBAR);
+
+ ATTR_INTP_BASE_ADDR_type l_intpBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_INTP_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_INTP_BASE_ADDR>(l_intpBAR);
+
+ // Set the attribute to force a SBE update later
+ l_pTopLevel->setAttr<TARGETING::ATTR_FORCE_SBE_UPDATE>
+ (TARGETING::FORCE_SBE_UPDATE_BAR_MISMATCH);
+ }
// Now swap the BARs between the master and the victim if needed
- if( l_swapVictim != l_pMasterProcChip )
+ else if( l_swapVictim != l_pMasterProcChip )
{
// Walk through all of the attributes we cached above
SWAP_ATTRIBUTE( ATTR_PROC_EFF_FABRIC_GROUP_ID, l_pMasterProcChip,
@@ -999,17 +1054,19 @@ static void adjustMemoryMap( TargetService& i_targetService )
// Cross-check that what we ended up setting in the attributes
// matches the non-TARGETING values that the XSCOM and LPC
- // drivers computed
- if( l_pMasterProcChip->getAttr<ATTR_LPC_BUS_ADDR>()
- != LPC::get_lpc_bar() )
+ // drivers computed (only if we found a swap victim)
+ if( l_swapVictim &&
+ (l_pMasterProcChip->getAttr<ATTR_LPC_BUS_ADDR>()
+ != LPC::get_lpc_bar()) )
{
TARG_ERR( "LPC attribute=%.16llX, live=%.16llX",
l_pMasterProcChip->getAttr<ATTR_LPC_BUS_ADDR>(),
LPC::get_lpc_bar() );
TARG_ASSERT( false, "LPC BARs are inconsistent" );
}
- if( l_pMasterProcChip->getAttr<ATTR_XSCOM_BASE_ADDRESS>()
- != XSCOM::get_master_bar() )
+ if( l_swapVictim &&
+ (l_pMasterProcChip->getAttr<ATTR_XSCOM_BASE_ADDRESS>()
+ != XSCOM::get_master_bar()) )
{
TARG_ERR( "XSCOM attribute=%.16llX, live=%.16llX",
l_pMasterProcChip->getAttr<ATTR_XSCOM_BASE_ADDRESS>(),
OpenPOWER on IntegriCloud