summaryrefslogtreecommitdiffstats
path: root/src/usr/xscom
diff options
context:
space:
mode:
authorBrian Bakke <bbakke@us.ibm.com>2018-05-22 11:30:26 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-06-07 13:37:46 -0400
commite364f91be1727019dd594c57d496e5ce43e8f5f0 (patch)
tree3515d4777d5ca4705fc232b02110d6c480151eff /src/usr/xscom
parent0c6d58230e615000dee1a1940bf4bc84ad5c1798 (diff)
downloadtalos-hostboot-e364f91be1727019dd594c57d496e5ce43e8f5f0.tar.gz
talos-hostboot-e364f91be1727019dd594c57d496e5ce43e8f5f0.zip
Fixes to node IPC messaging to handle non-zero base addresses
Current code has each Node calculate each Remote Node's IPC area remote address by performing a fixed format calculation. This change has each Node calculating its IPC area Remote address and posting this value to a local SCOM register. A Node reads a Remote Node's SCOM register to acquire the Remote IPC area address. Change-Id: I25260ce180e0d07e5e81990d4c1f99e249912491 RTC:191463 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59177 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@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: Prachi Gupta <pragupta@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/xscom')
-rw-r--r--src/usr/xscom/xscom.C113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C
index 18594d7cd..7c8bd607c 100644
--- a/src/usr/xscom/xscom.C
+++ b/src/usr/xscom/xscom.C
@@ -35,12 +35,14 @@
#include <sys/task.h>
#include <sys/sync.h>
#include <sys/misc.h>
+#include <sys/time.h>
#include <string.h>
#include <devicefw/driverif.H>
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <targeting/common/targetservice.H>
+#include <targeting/common/utilFilter.H>
#include <xscom/xscomreasoncodes.H>
#include "xscom.H"
#include <assert.h>
@@ -818,4 +820,115 @@ uint64_t generate_mmio_addr( TARGETING::Target* i_proc,
return l_returnAddr;
}
+
+/**
+ * @brief Multicast Read of core XSCOM register on remote Node
+ */
+uint64_t readRemoteCoreScomMultiCast( uint64_t i_node,
+ uint64_t i_scomAddr )
+{
+ // definitions of 64 bit xscom address contents that are
+ // useful for this function
+ // hi 32 bits lo 32 bits
+ // representation : 0x0000_0000__0000_0000
+ //
+ // (hi 32 bits, xscom mmio control)
+ //
+ // chip field 0x0000_0400__0000_0000
+ // (to be multiplied by chip ID to give field value)
+ //
+ // node/group field (0-7) 0xE000_0000__0000_0000
+ //
+ // (lo 32 bits, scom addr)
+ //
+ // multicast 0x0000_0000__4000_0000
+ // multicast op type 0x0000_0000__3800_0000
+ // - read OR 00
+ // - read AND 08
+ // - read bitwise 10
+ // - rsvd 18
+ // - write compare 20
+ // - write 28
+ // - rsvd 30
+ // - rsvd 38
+ // multicast group 0x0000_0000__0700_0000
+ // relative scomAddr field 0x0000_0000__00FF_FFFF
+ constexpr uint64_t XSCOM_MULTICAST = 0x0000000040000000;
+ constexpr uint64_t XSCOM_MULTICAST_OP_READ_OR = 0x0000000000000000;
+ constexpr uint64_t XSCOM_MULTICAST_GROUP_CORE = 0x0000000001000000;
+ constexpr uint64_t XSCOM_MULTICAST_REL_ADDR_MASK = 0x0000000000FFFFFF;
+
+ // Symmetry between nodes is enforced so we know the remote
+ // node contains this chip
+ TARGETING::Target * l_MasterProcTarget = nullptr;
+ TARGETING::TargetService & l_tgtServ = TARGETING::targetService();
+ l_tgtServ.masterProcChipTargetHandle( l_MasterProcTarget );
+ uint8_t l_chipId =
+ l_MasterProcTarget->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
+
+ // compute xscom address & control, then map into processor space
+ uint64_t l_xscomBaseAddr =
+ computeMemoryMapOffset( MMIO_GROUP0_CHIP0_XSCOM_BASE_ADDR,
+ i_node,
+ l_chipId );
+
+ uint64_t l_xscomAddr = ( (i_scomAddr & XSCOM_MULTICAST_REL_ADDR_MASK) |
+ XSCOM_MULTICAST |
+ XSCOM_MULTICAST_OP_READ_OR |
+ XSCOM_MULTICAST_GROUP_CORE );
+
+ uint64_t * l_virtAddr =
+ static_cast<uint64_t*>
+ (mmio_dev_map(reinterpret_cast<void*>(l_xscomBaseAddr),
+ THIRTYTWO_GB));
+
+ // execute the SCOM op to do the multicast read
+ // init return value to dummy to verify read happened
+ uint64_t l_rv = IPC_INVALID_REMOTE_ADDR | i_node;
+ size_t l_rvSize = sizeof(l_rv);
+ HMER l_hmer;
+
+ do
+ {
+ errlHndl_t l_err = xScomDoOp( DeviceFW::READ,
+ l_virtAddr,
+ l_xscomAddr,
+ &l_rv,
+ l_rvSize,
+ l_hmer );
+
+ // If not successful
+ if (l_err)
+ {
+ delete l_err;
+ l_err = nullptr;
+
+ TRACFCOMP( g_trac_xscom,
+ ERR_MRK "readRemoteCoreScomMultiCast() Read xScom Failed: "
+ "XscomAddr = %.16llx, VAddr=%llx",
+ l_xscomAddr, l_virtAddr );
+
+ // re-seed return value in case changed before error detected
+ l_rv = IPC_INVALID_REMOTE_ADDR | i_node;
+ break;
+ }
+ else
+ {
+ }
+
+ // regs not yet populated
+ if (l_rv == 0 )
+ {
+ // delay to allow remote core to populate regs
+ nanosleep(0, (NS_PER_MSEC * 100));
+ }
+
+ // wait for remote node to populate its core scom regs
+ } while( l_rv == 0 );
+
+ mmio_dev_unmap(reinterpret_cast<void*>(l_virtAddr));
+
+ return l_rv;
+}
+
} // end namespace
OpenPOWER on IntegriCloud