summaryrefslogtreecommitdiffstats
path: root/src/usr/scom
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2017-11-21 15:45:35 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-01-09 10:37:55 -0500
commit7f8aa4b7a01721e52c0c0b4d4d54c6ba8738c11c (patch)
tree9097fe9d68881e9ec568d83340468c5413a7f111 /src/usr/scom
parent9ea9546db73d86d46871fcbb94cc93d3f2fb31a1 (diff)
downloadtalos-hostboot-7f8aa4b7a01721e52c0c0b4d4d54c6ba8738c11c.tar.gz
talos-hostboot-7f8aa4b7a01721e52c0c0b4d4d54c6ba8738c11c.zip
Tweaks to multicast scom workaround
Added a mode to avoid a pile of FFDC collection for the case where we expect errors could happen. Also added a couple new flags to control which chiplets get accessed as part of the workaround, one to avoid access to slave cores before they are running and the other to avoid access to the memory chiplets before they have clocks enabled. Without these changes, the code is still functionally correct but the traces get filled with pointless non-errors which makes real problems harder to find and also increases boot time. Change-Id: I834781261d16748cbbfd8511d9649ec19de53d81 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50503 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@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: Corey V. Swenson <cswenson@us.ibm.com> Reviewed-by: Prachi Gupta <pragupta@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/scom')
-rw-r--r--src/usr/scom/scom.C79
1 files changed, 77 insertions, 2 deletions
diff --git a/src/usr/scom/scom.C b/src/usr/scom/scom.C
index e6d1a9135..5c35dfdd2 100644
--- a/src/usr/scom/scom.C
+++ b/src/usr/scom/scom.C
@@ -48,7 +48,7 @@
#include <hw_access_def.H>
#include <p9_scom_addr.H>
#include <targeting/common/utilFilter.H>
-
+#include <targeting/namedtarget.H>
// Trace definition
@@ -58,6 +58,31 @@ TRAC_INIT(&g_trac_scom, SCOM_COMP_NAME, KILOBYTE, TRACE::BUFFER_SLOW); //1K
namespace SCOM
{
+#ifndef __HOSTBOOT_RUNTIME
+/**
+ * Keep track of system state to handle the multicast workaround
+ * more cleanly
+ */
+bool g_useSlaveCores = false;
+bool g_useMemChiplets = false;
+
+/**
+ * @brief Enable scoms to all cores for multicast workaround
+ */
+void enableSlaveCoreMulticast( void )
+{
+ g_useSlaveCores = true;
+};
+
+/**
+ * @brief Enable scoms to the memory chiplets for multicast workaround
+ */
+void enableMemChipletMulticast( void )
+{
+ g_useMemChiplets = true;
+};
+#endif
+
/**
* @brief Add any additional FFDC for this specific type of scom
*
@@ -1187,6 +1212,16 @@ errlHndl_t doMulticastWorkaround( DeviceFW::OperationType i_opType,
constexpr uint64_t MULTICAST_OP = 0x38000000;
constexpr uint64_t MULTICAST_OP_BITWISE = 0x10000000;
+#ifndef __HOSTBOOT_RUNTIME
+ // Some P9-specific chiplet values to make things more efficient
+ constexpr uint64_t P9_FIRST_MC = 0x07;
+ constexpr uint64_t P9_LAST_MC = 0x08;
+ constexpr uint64_t P9_FIRST_EQ = 0x10;
+ constexpr uint64_t P9_LAST_EQ = 0x1F;
+ constexpr uint64_t P9_FIRST_EC = 0x20;
+ constexpr uint64_t P9_LAST_EC = 0x2F;
+#endif
+
// Skip calls to the SENTINEL since we don't have the
// ability to find its children
if( TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL
@@ -1224,13 +1259,53 @@ errlHndl_t doMulticastWorkaround( DeviceFW::OperationType i_opType,
uint64_t l_data = 0;
uint64_t l_addr = (i_addr & ~CHIPLET_BYTE);
uint64_t l_unit = l_chiplet->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+
+#ifndef __HOSTBOOT_RUNTIME
+ // filter out some chiplets that aren't running yet
+ if( !g_useSlaveCores
+ && (((l_unit >= P9_FIRST_EQ) && (l_unit <= P9_LAST_EQ))
+ || ((l_unit >= P9_FIRST_EC) && (l_unit <= P9_LAST_EC))
+ )
+ )
+ {
+ // Only access the master ec/eq
+ static const TARGETING::Target* l_masterCore =
+ TARGETING::getMasterCore();
+ uint64_t l_ecNum =
+ l_masterCore->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ bool l_fused = TARGETING::is_fused_mode();
+ if( !((l_unit == l_ecNum) //master
+ || (l_fused && (l_unit == l_ecNum+1))) ) //fused-pair
+ {
+ continue;
+ }
+ auto l_eqNum = 0x10 + l_ecNum/4;
+ if( l_unit == l_eqNum )
+ {
+ continue;
+ }
+ }
+ if( !g_useMemChiplets
+ && ((l_unit >= P9_FIRST_MC) && (l_unit <= P9_LAST_MC)) )
+ {
+ // Only access the mem chiplets if we're not in async mode
+ // because we don't start clocks until later on in that case
+ auto l_syncMode =
+ i_target->getAttr<TARGETING::ATTR_MC_SYNC_MODE>();
+ if( l_syncMode )
+ {
+ continue;
+ }
+ }
+#endif
+
l_addr |= (l_unit << 24);
io_buflen = sizeof(uint64_t);
l_err = deviceOp(i_opType,
i_target,
&l_data,
io_buflen,
- DEVICE_XSCOM_ADDRESS(l_addr));
+ DEVICE_XSCOM_ADDRESS_NO_ERROR(l_addr));
// just ignore any errors, we expect they will happen
if( l_err )
{
OpenPOWER on IntegriCloud