diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/usr/vpd/vpd_if.H | 11 | ||||
-rw-r--r-- | src/usr/fsi/fsipres.C | 15 | ||||
-rw-r--r-- | src/usr/isteps/istep06/host_discover_targets.C | 11 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/target_types_hb.xml | 1 | ||||
-rw-r--r-- | src/usr/vpd/dvpd.C | 15 | ||||
-rw-r--r-- | src/usr/vpd/pvpd.C | 18 | ||||
-rwxr-xr-x | src/usr/vpd/vpd.C | 128 |
7 files changed, 176 insertions, 23 deletions
diff --git a/src/include/usr/vpd/vpd_if.H b/src/include/usr/vpd/vpd_if.H index e6f32dcc6..c34a465a4 100644 --- a/src/include/usr/vpd/vpd_if.H +++ b/src/include/usr/vpd/vpd_if.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -105,6 +105,15 @@ namespace VPD errlHndl_t invalidatePnorCache ( TARGETING::Target * i_target ); /** + * @brief This function validates targets sharing PNOR::CENTAUR_VPD cache. + * Invalidate sections where all of the targets sharing a VPD_REC_NUM + * are invalid. Keep the section if any target is valid. + * @return errlHndl_t - NULL if successful, otherwise a pointer to the + * error log. + */ + errlHndl_t validateSharedPnorCache( ); + + /** * @brief This function invalidates all of the VPD data in the PNOR cache. * @param[in] i_setHwOnly - Also set vars to not access VPD cache * @return errlHndl_t - NULL if successful, otherwise a pointer to the diff --git a/src/usr/fsi/fsipres.C b/src/usr/fsi/fsipres.C index 038e952b3..5798bde02 100644 --- a/src/usr/fsi/fsipres.C +++ b/src/usr/fsi/fsipres.C @@ -299,13 +299,14 @@ errlHndl_t membPresenceDetect(DeviceFW::OperationType i_opType, } else { - // FSI is not present, invalidate MVPD in the PNOR - l_errl = VPD::invalidatePnorCache(i_target); - if (l_errl) - { - TRACFCOMP( g_trac_fsi, "Error invalidating MVPD in PNOR" ); - errlCommit( l_errl, FSI_COMP_ID ); - } + // Defer invalidating CVPD in the PNOR in case another target might be + // sharing this VPD_REC_NUM. Check all targets sharing this + // VPD_REC_NUM after target discovery in VPD::validateSharedPnorCache. + // Ensure the VPD_SWITCHES cache valid bit is invalid at this point. + TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = + i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); + vpdSwitches.pnorCacheValid = 0; + i_target->setAttr<TARGETING::ATTR_VPD_SWITCHES>( vpdSwitches ); } #endif diff --git a/src/usr/isteps/istep06/host_discover_targets.C b/src/usr/isteps/istep06/host_discover_targets.C index 6ed27ce31..b13c6f529 100644 --- a/src/usr/isteps/istep06/host_discover_targets.C +++ b/src/usr/isteps/istep06/host_discover_targets.C @@ -42,6 +42,7 @@ #include <hwas/common/hwasCommon.H> #include <hwas/common/hwas_reasoncodes.H> #include <hwas/hwasPlat.H> +#include <vpd/vpd_if.H> namespace ISTEP_06 { @@ -75,6 +76,16 @@ void* host_discover_targets( void *io_pArgs ) l_err = HWAS::discoverTargets(); } +#if (defined(CONFIG_MEMVPD_READ_FROM_HW)&&defined(CONFIG_MEMVPD_READ_FROM_PNOR)) + // Now that all targets have completed presence detect and vpd access, + // invalidate PNOR::CENTAUR_VPD sections where all the targets sharing a + // VPD_REC_NUM are invalid. + if (NULL == l_err) //discoverTargets worked + { + l_err = VPD::validateSharedPnorCache(); + } +#endif + if (l_err) { // Create IStep error log and cross reference occurred error diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index 1304931c3..022ed0037 100755 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -225,6 +225,7 @@ <targetTypeExtension> <id>unit-mcs-nimbus</id> <attribute><id>HB_TARGET_SCOMABLE</id></attribute> + <attribute><id>VPD_SWITCHES</id></attribute> </targetTypeExtension> <targetType> diff --git a/src/usr/vpd/dvpd.C b/src/usr/vpd/dvpd.C index b8c49a8ed..9ce09990f 100644 --- a/src/usr/vpd/dvpd.C +++ b/src/usr/vpd/dvpd.C @@ -265,13 +265,14 @@ errlHndl_t directMemoryPresenceDetect(DeviceFW::OperationType i_opType, TRACFCOMP(g_trac_vpd, ERR_MRK "directMemoryPresenceDetect> failed presence detect"); - // Invalidate DVPD in the PNOR - l_errl = VPD::invalidatePnorCache(i_target); - if (l_errl) - { - TRACFCOMP( g_trac_vpd, "Error invalidating DVPD in PNOR" ); - errlCommit( l_errl, VPD_COMP_ID ); - } + // Defer invalidating DVPD in the PNOR in case another target might be + // sharing this VPD_REC_NUM. Check all targets sharing this + // VPD_REC_NUM after target discovery in VPD::validateSharedPnorCache. + // Ensure the VPD_SWITCHES cache valid bit is invalid at this point. + TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = + i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); + vpdSwitches.pnorCacheValid = 0; + i_target->setAttr<TARGETING::ATTR_VPD_SWITCHES>( vpdSwitches ); } #endif diff --git a/src/usr/vpd/pvpd.C b/src/usr/vpd/pvpd.C index 3acde7831..8017776b9 100644 --- a/src/usr/vpd/pvpd.C +++ b/src/usr/vpd/pvpd.C @@ -262,14 +262,16 @@ errlHndl_t nodePresenceDetect(DeviceFW::OperationType i_opType, TRACFCOMP(g_trac_vpd, ERR_MRK "nodePresenceDetect> failed presence detect"); - // Invalidate PVPD in the PNOR - l_errl = VPD::invalidatePnorCache(i_target); - if (l_errl) - { - TRACFCOMP( g_trac_vpd, "Error invalidating PVPD in PNOR" ); - errlCommit( l_errl, VPD_COMP_ID ); - } - pvpd_present = true; + // Defer invalidating PVPD in the PNOR in case another target might be + // sharing this VPD_REC_NUM. Check all targets sharing this + // VPD_REC_NUM after target discovery in VPD::validateSharedPnorCache. + // Ensure the VPD_SWITCHES cache valid bit is invalid at this point. + TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = + i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); + vpdSwitches.pnorCacheValid = 0; + i_target->setAttr<TARGETING::ATTR_VPD_SWITCHES>( vpdSwitches ); + + pvpd_present = true; //node PVDP always returns present } #endif diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C index b39361b45..ebda849d4 100755 --- a/src/usr/vpd/vpd.C +++ b/src/usr/vpd/vpd.C @@ -37,6 +37,7 @@ #include "pvpd.H" #include "spd.H" #include "ipvpd.H" +#include <map> // ---------------------------------------------- // Trace - defined in vpd_common @@ -833,5 +834,132 @@ errlHndl_t invalidateAllPnorCaches ( bool i_setHwOnly ) return l_err; } +typedef std::pair<TARGETING::Target *, bool> targetValidPair_t; +typedef std::map<TARGETING::ATTR_VPD_REC_NUM_type, + targetValidPair_t> numRecValidMap_t; + +// For each target in list, either add a map entry for this VPD_REC_NUM +// or OR in the cache valid bit if VPD_REC_NUM is already in the map. +void addListToMap(numRecValidMap_t & i_recNumMap, + const TARGETING::TargetHandleList & i_targetList) +{ + for (TARGETING::TargetHandleList::const_iterator + targItr = i_targetList.begin(); + targItr != i_targetList.end(); + ++targItr) + { + TARGETING::Target * l_pTarg = *targItr; + TARGETING::ATTR_VPD_REC_NUM_type l_recNum = + l_pTarg->getAttr<TARGETING::ATTR_VPD_REC_NUM>(); + TARGETING::ATTR_VPD_SWITCHES_type l_switches = + l_pTarg->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); + + numRecValidMap_t::iterator itr = i_recNumMap.find(l_recNum); + if( itr != i_recNumMap.end() ) + { + TRACDCOMP( g_trac_vpd, "addListToMap() " + "OR in %d for VPD_REC_NUM %d HUID %.8X", + l_switches.pnorCacheValid, + l_recNum, + TARGETING::get_huid(l_pTarg)); + + itr->second.second |= l_switches.pnorCacheValid; + } + else + { + TRACDCOMP( g_trac_vpd, "addListToMap() " + "Set %d for VPD_REC_NUM %d HUID %.8X", + l_switches.pnorCacheValid, + l_recNum, + TARGETING::get_huid(l_pTarg)); + + i_recNumMap[l_recNum] = + targetValidPair_t(l_pTarg,l_switches.pnorCacheValid); + } + } +} + +// -------------------------------------------------------- +// This function validates targets sharing the PNOR::CENTAUR_VPD cache. +// Invalidate sections where all of the targets sharing a VPD_REC_NUM +// are invalid. Keep the section if any target is valid. +//--------------------------------------------------------- +errlHndl_t validateSharedPnorCache() +{ + errlHndl_t errl = NULL; + std::map<TARGETING::ATTR_VPD_REC_NUM_type,targetValidPair_t> l_recNumMap; + + TRACDCOMP( g_trac_vpd, ENTER_MRK"validateSharedPnorCache()"); + + do + { +#if defined(CONFIG_PVPD_READ_FROM_HW) && defined(CONFIG_PVPD_READ_FROM_PNOR) + // Add cache status for the node + TARGETING::TargetHandleList l_nodeList; + getEncResources(l_nodeList, + TARGETING::TYPE_NODE, + TARGETING::UTIL_FILTER_ALL); + addListToMap( l_recNumMap, l_nodeList); +#endif + + // If this system has mem bufs, then gather all mem bufs. + // If there are no mem bufs, then gather the MCSs for direct memory. + TARGETING::TargetHandleList l_memBufList; + getChipResources(l_memBufList, + TARGETING::TYPE_MEMBUF, + TARGETING::UTIL_FILTER_ALL); + if (l_memBufList.size()) // system has mem bufs + { + addListToMap( l_recNumMap, l_memBufList); + } + else // Add cache status for all MCSs for direct memory + { + TARGETING::TargetHandleList l_mcsList; + getChipletResources(l_mcsList, + TARGETING::TYPE_MCS, + TARGETING::UTIL_FILTER_ALL); + addListToMap( l_recNumMap, l_mcsList); + } + + // check for any section that is invalid for all that share it + for (numRecValidMap_t::iterator itr = l_recNumMap.begin(); + itr != l_recNumMap.end(); ++itr) + { + // The second.second is the accumulation of all pnorCacheValid + // bits. If true, then at least one target is using this + // VPD_REC_NUM section. Keep it. + if (itr->second.second) + { + TRACDCOMP( g_trac_vpd, "validateSharedPnorCache() " + "valid is %d for VPD_REC_NUM %d HUID %.8X " + "keep this section", + itr->second.second, + itr->first, + TARGETING::get_huid(itr->second.first)); + } + // if false, then all that share this section, none are valid. + // Invalidate this section. + else + { + TRACFCOMP( g_trac_vpd, "validateSharedPnorCache() " + "valid is %d for VPD_REC_NUM %d HUID %.8X " + "invalidate this section", + itr->second.second, + itr->first, + TARGETING::get_huid(itr->second.first)); + + // invalidate cache section for this VPD_REC_NUM + errl = VPD::invalidatePnorCache(itr->second.first); + if (errl) + { + // Just commit the log and move on. No need to terminate IPL + errlCommit( errl, VPD_COMP_ID ); + } + } + } + } while (0); + + return errl; +} }; //end VPD namespace |