summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorwhs <whs@us.ibm.com>2016-03-14 16:31:27 -0500
committerStephen Cprek <smcprek@us.ibm.com>2016-04-21 13:51:47 -0500
commit9dee05c3d4c801d74972216a8c501e5c1c3fc2b6 (patch)
tree4acaf595a78857f595acdd9b17f03fd118411079 /src
parent25bc87d9fc30db27f8c78019858f832c92d69097 (diff)
downloadblackbird-hostboot-9dee05c3d4c801d74972216a8c501e5c1c3fc2b6.tar.gz
blackbird-hostboot-9dee05c3d4c801d74972216a8c501e5c1c3fc2b6.zip
VPD Caching broken on multiple socket, single CVPD systems (Barreleye)
Invalidate Centaur Pnor sections if the section is invalid for all targets that share that section. Keep a section if any target sharing the section finds the section valid. Fixes: open-power/hostboot#29 Change-Id: I14302e38f1d39f3bb4e1857267e1547d1a06302b Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22047 Tested-by: Jenkins Server Reviewed-by: A. P. Williams III <iawillia@us.ibm.com> Reviewed-by: Matthew A. Ploetz <maploetz@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22153 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/vpd/vpd_if.H11
-rw-r--r--src/usr/fsi/fsipres.C15
-rw-r--r--src/usr/isteps/istep06/host_discover_targets.C11
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/target_types_hb.xml1
-rw-r--r--src/usr/vpd/dvpd.C15
-rw-r--r--src/usr/vpd/pvpd.C18
-rwxr-xr-xsrc/usr/vpd/vpd.C128
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
OpenPOWER on IntegriCloud