Skip to content

Commit

Permalink
Handle processor swap between slots to 1-socket system
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dcrowell77 committed Aug 5, 2019
1 parent 4ced775 commit 7a758c4
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 11 deletions.
25 changes: 25 additions & 0 deletions src/include/arch/memorymap.H
Expand Up @@ -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,
Expand All @@ -51,6 +56,26 @@ inline uint64_t computeMemoryMapOffset( uint64_t i_baseAddr,
(MMIO_OFFSET_PER_CHIP * i_chip));
};

/**
* @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
Expand Down
2 changes: 2 additions & 0 deletions src/include/usr/isteps/istep_reasoncodes.H
Expand Up @@ -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,
};

/**
Expand Down Expand Up @@ -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,
};

};
Expand Down
65 changes: 62 additions & 3 deletions src/usr/isteps/istep06/host_discover_targets.C
Expand Up @@ -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. */
/* */
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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();
}

Expand Down
33 changes: 33 additions & 0 deletions src/usr/targeting/common/xmltohb/attribute_types_hb.xml
Expand Up @@ -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>
Expand Down
3 changes: 3 additions & 0 deletions src/usr/targeting/common/xmltohb/target_types_hb.xml
Expand Up @@ -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>
Expand Down
73 changes: 65 additions & 8 deletions src/usr/targeting/targetservicestart.C
Expand Up @@ -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>
Expand Down Expand Up @@ -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,
Expand All @@ -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>(),
Expand Down

0 comments on commit 7a758c4

Please sign in to comment.