summaryrefslogtreecommitdiffstats
path: root/src/usr/mbox
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/mbox')
-rw-r--r--src/usr/mbox/ipcSp.C136
-rw-r--r--src/usr/mbox/ipcSp.H23
-rw-r--r--src/usr/mbox/mailboxsp.C3
-rw-r--r--src/usr/mbox/makefile4
4 files changed, 164 insertions, 2 deletions
diff --git a/src/usr/mbox/ipcSp.C b/src/usr/mbox/ipcSp.C
index d0110db98..61d9f846d 100644
--- a/src/usr/mbox/ipcSp.C
+++ b/src/usr/mbox/ipcSp.C
@@ -35,6 +35,12 @@
#include <sbeio/sbeioif.H>
#include <util/utiltce.H>
#include <targeting/targplatutil.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/attributes.H>
+#include <p9_quad_scom_addresses.H>
+#include <sys/internode.h>
+#include <sys/mmio.h>
+#include <xscom/xscomif.H>
namespace ISTEP_21
{
@@ -54,7 +60,8 @@ using namespace TARGETING;
IpcSp::IpcSp()
:
- iv_msgQ()
+ iv_msgQ(),
+ iv_IsRemoteNodeAddrsValid( false )
{
}
@@ -68,6 +75,48 @@ void IpcSp::init(errlHndl_t & o_errl)
o_errl = Singleton<IpcSp>::instance()._init();
}
+void IpcSp::distributeLocalNodeAddr( void )
+{
+ // Store IPC address for local node in core scratch registers
+ // to identify IPC msg address to remote node(s)
+ uint64_t l_localNode;
+ uint64_t l_remoteAddr;
+ qryLocalIpcInfo( l_localNode, l_remoteAddr );
+
+ TARGETING::Target * l_pSys = NULL;
+ TARGETING::targetService().getTopLevelTarget( l_pSys );
+ TARGETING::TargetHandleList l_coreTargetList;
+ TARGETING::getChildChiplets( l_coreTargetList,
+ l_pSys,
+ TARGETING::TYPE_CORE,
+ true );
+
+ // Store IPC address into scom reg for each core
+ // Every core on this node needs to have the value stored
+ // in it's scratch register in case any cores get deconfigured
+ for(const auto & l_core_target : l_coreTargetList)
+ {
+ uint64_t l_remoteAddrSize = sizeof(l_remoteAddr);
+ errlHndl_t l_err = deviceWrite( l_core_target,
+ &l_remoteAddr,
+ l_remoteAddrSize,
+ DEVICE_SCOM_ADDRESS(C_SCR2) );
+
+ if (l_err)
+ {
+ errlCommit(l_err, IPC_COMP_ID);
+ }
+ }
+
+ return;
+}
+
+void IpcSp::acquireRemoteNodeAddrs( void )
+{
+ Singleton<IpcSp>::instance()._acquireRemoteNodeAddrs();
+ return;
+}
+
void* IpcSp::msg_handler(void *unused)
{
Singleton<IpcSp>::instance().msgHandler();
@@ -586,3 +635,88 @@ void IpcSp::msgHandler()
}
+void IpcSp::_acquireRemoteNodeAddrs( void )
+{
+ if // remote addresses have not been gathered
+ (iv_IsRemoteNodeAddrsValid == false)
+ {
+ TARGETING::Target * l_sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+
+ if (l_sys)
+ {
+ // If MPIPL then remote regs are no longer valid
+ uint8_t l_IsMpipl =
+ l_sys->getAttr<TARGETING::ATTR_IS_MPIPL_HB>();
+
+ if (l_IsMpipl == false )
+ {
+ // extract current ipc addr attributes
+ uint64_t l_ipcDataAddrs[MAX_NODES_PER_SYS];
+ l_sys->tryGetAttr
+ <TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>
+ (l_ipcDataAddrs);
+
+ // extract valid node map
+ uint8_t validNodeBitMap =
+ l_sys->getAttr<TARGETING::ATTR_HB_EXISTING_IMAGE>();
+
+ // determine which node is local
+ uint64_t l_ThisNode;
+ uint64_t l_RemoteAddr;
+ qryLocalIpcInfo( l_ThisNode, l_RemoteAddr );
+
+ // loop thru all Nodes
+ for ( uint64_t i = 0;
+ i < MAX_NODES_PER_SYS;
+ i++ )
+ {
+ if // remote node
+ ( i != l_ThisNode )
+ {
+ if // valid node
+ ( (validNodeBitMap & (0x80 >> i)) != 0 )
+ {
+ // read scoms for remote node
+ l_RemoteAddr =
+ XSCOM::readRemoteCoreScomMultiCast(i,
+ C_SCR2);
+ } // end valid node
+ else
+ {
+ // set an invalid value for remote address
+ l_RemoteAddr = IPC_INVALID_REMOTE_ADDR | i;
+ }
+
+ // push results to IPC and Attributes shadow
+ updateRemoteIpcAddr( i, l_RemoteAddr );
+ l_ipcDataAddrs[i] = l_RemoteAddr;
+ } // end remote node
+ else
+ {
+ // local node, do not need to get remote addrs
+ }
+ }
+
+ // update attributes
+ l_sys->setAttr<TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>
+ (l_ipcDataAddrs);
+ } // end not mpipl
+ else
+ {
+ // (remote addrs have already been shadowed from attributes)
+ }
+
+ // read the scoms only once
+ iv_IsRemoteNodeAddrsValid = true;
+ } // end acquire scoms
+ } // end remote addrs not gathered
+ else
+ {
+ // (no action needed)
+ }
+
+ return;
+}
+
+
diff --git a/src/usr/mbox/ipcSp.H b/src/usr/mbox/ipcSp.H
index 1a3ce0045..009ad2be2 100644
--- a/src/usr/mbox/ipcSp.H
+++ b/src/usr/mbox/ipcSp.H
@@ -44,6 +44,18 @@ namespace IPC
*/
static void init(errlHndl_t & o_errl);
+ /**
+ * Query the local node's IPC address and store it all of the
+ * local node's core scratch2 regs. This will allow remote nodes
+ * to read the address so they know where to write IPC messages.
+ */
+ static void distributeLocalNodeAddr( void );
+
+ /**
+ * Acquire all Remote Node IPC addresses
+ */
+ static void acquireRemoteNodeAddrs( void );
+
protected:
/**
@@ -77,10 +89,21 @@ namespace IPC
void msgHandler();
/**
+ * Acquire all Remote Node IPC addresses
+ */
+ void _acquireRemoteNodeAddrs( void );
+
+ /**
* The IPC message queue
*/
msg_q_t iv_msgQ;
+ /**
+ * Indicates whether or not the Remote Node IPC
+ * addresses have already been acquired
+ */
+ bool iv_IsRemoteNodeAddrsValid;
+
};
}; // namespace IPC
#endif
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index c0b63c3f1..777699e34 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -2138,6 +2138,9 @@ errlHndl_t MBOX::send(queue_id_t i_q_id, msg_t * i_msg,int i_node)
}
else
{
+ // stitch together routing if not already done
+ IPC::IpcSp::acquireRemoteNodeAddrs();
+
int rc = msg_send(reinterpret_cast<msg_q_t>(q_handle),
i_msg);
TRACFCOMP(g_trac_mboxmsg,INFO_MRK
diff --git a/src/usr/mbox/makefile b/src/usr/mbox/makefile
index 96d750804..1019e28e2 100644
--- a/src/usr/mbox/makefile
+++ b/src/usr/mbox/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2014
+# Contributors Listed Below - COPYRIGHT 2012,2018
# [+] International Business Machines Corp.
#
#
@@ -25,6 +25,8 @@
ROOTPATH = ../../..
MODULE = mbox
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
+
OBJS += mboxdd.o
OBJS += mailboxsp.o
OBJS += mbox_dma_buffer.o
OpenPOWER on IntegriCloud