summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2013-04-23 14:10:52 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-05-16 12:36:09 -0500
commit8fac481d825883154ca20612ca0a69bc52f02618 (patch)
tree4429e6f57e9b73a4750181cbe138d74c359c6cf1
parenta151ccb70dab1007ca8aed2f0b89dfdf1cfe406b (diff)
downloadtalos-hostboot-8fac481d825883154ca20612ca0a69bc52f02618.tar.gz
talos-hostboot-8fac481d825883154ca20612ca0a69bc52f02618.zip
Inter-processor communications for multinode
RTC: 63128 Change-Id: Ica27c7f714bc8b874c9bccb663a32d3cfba37c5a Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4193 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/kernel/hbdescriptor.H5
-rw-r--r--src/include/kernel/ipc.H41
-rw-r--r--src/include/sys/msg.h3
-rw-r--r--src/include/usr/intr/interrupt.H7
-rw-r--r--src/include/usr/mbox/mbox_reasoncodes.H6
-rw-r--r--src/include/usr/mbox/mboxif.H67
-rw-r--r--src/kernel/intmsghandler.C11
-rw-r--r--src/kernel/ipc.C97
-rw-r--r--src/kernel/makefile2
-rw-r--r--src/kernel/syscall.C73
-rw-r--r--src/kernel/terminate.C7
-rw-r--r--src/makefile2
-rw-r--r--src/usr/intr/intrrp.C12
-rw-r--r--src/usr/intr/test/intrtest.H50
-rw-r--r--src/usr/mbox/mailboxsp.C220
-rw-r--r--src/usr/mbox/mailboxsp.H6
-rw-r--r--src/usr/mbox/test/mboxsptest.H58
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml17
-rw-r--r--src/usr/targeting/common/xmltohb/simics_MURANO.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/simics_VENICE.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml1
-rw-r--r--src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml4
23 files changed, 573 insertions, 128 deletions
diff --git a/src/include/kernel/hbdescriptor.H b/src/include/kernel/hbdescriptor.H
index e90861a48..e5c6a9c0f 100644
--- a/src/include/kernel/hbdescriptor.H
+++ b/src/include/kernel/hbdescriptor.H
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012 */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
/* */
/* p1 */
/* */
@@ -30,9 +30,12 @@
struct HB_TI_DataArea;
+namespace KernelIpc { struct ipc_data_area_t; };
+
struct HB_Descriptor
{
HB_TI_DataArea *TI_DataAreaPtr; // ptr to the TI data area structure
+ KernelIpc::ipc_data_area_t *IPC_DataAreaPtr; // ptr to the IPC data area
};
#endif /* __KERNEL_HBDESCRIPTOR_H */
diff --git a/src/include/kernel/ipc.H b/src/include/kernel/ipc.H
new file mode 100644
index 000000000..a67ea5463
--- /dev/null
+++ b/src/include/kernel/ipc.H
@@ -0,0 +1,41 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/kernel/ipc.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#if !defined(__IPC_H)
+#define __IPC_H
+
+#include <sys/msg.h>
+
+namespace KernelIpc
+{
+struct ipc_data_area_t
+{
+ uint64_t msg_queue_id;
+ msg_t msg_payload;
+ uint64_t hrmor_base;
+ uint32_t pir;
+};
+
+extern ipc_data_area_t ipc_data_area;
+};
+
+#endif
diff --git a/src/include/sys/msg.h b/src/include/sys/msg.h
index 9fadd8b70..b9ff8f513 100644
--- a/src/include/sys/msg.h
+++ b/src/include/sys/msg.h
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2010,2012 */
+/* COPYRIGHT International Business Machines Corp. 2010,2013 */
/* */
/* p1 */
/* */
@@ -71,6 +71,7 @@ enum msg_root_queue_types_t
{
MSGQ_ROOT_VFS,
MSGQ_ROOT_INTR,
+ MSGQ_TYPE_IPC = 0x08, //!< Value is OR'd with the physical node number
};
/** @var msg_sys_types_t::MSG_MM_RP_READ
diff --git a/src/include/usr/intr/interrupt.H b/src/include/usr/intr/interrupt.H
index 2ac07cc15..cf129712a 100644
--- a/src/include/usr/intr/interrupt.H
+++ b/src/include/usr/intr/interrupt.H
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* COPYRIGHT International Business Machines Corp. 2011,2013 */
/* */
/* p1 */
/* */
@@ -67,6 +67,7 @@ namespace INTR
ISN_LCL_ERR = 4,
ISN_HOST = 5,
ISN_INTERPROC = 0xF0, //"special" as it isn't part of PSIHB
+ //Converts to INTERPROC_XISR when registered
};
/**
@@ -119,7 +120,9 @@ namespace INTR
*
* @note the interrupt type is currently the ISN value in the PSIHB
* XIVR register
- * @see i_intr_type for enumerations.
+ * @see ISNvalue_t for enumerations.
+ * The XISR value is calculated and registered for all chips
+ * presently capable of generaing interrupts.
*
* @note when an interrupt of type i_msg_type occurrs, the
* interrupt presenter sends a sync message with type i_msg_type to
diff --git a/src/include/usr/mbox/mbox_reasoncodes.H b/src/include/usr/mbox/mbox_reasoncodes.H
index 424b0ad13..4760d1de1 100644
--- a/src/include/usr/mbox/mbox_reasoncodes.H
+++ b/src/include/usr/mbox/mbox_reasoncodes.H
@@ -39,7 +39,9 @@ namespace MBOX
MOD_MBOXSRV_FSP_MSG = 0x07, // MailboxSp::handle_hbmbox_msg
MOD_MBOXSRV_SENDMSG = 0x08, // MailboxSp::send_msg
MOD_MBOXSRV_INIT = 0x09, // MailboxSp::_init
- MOD_MBOXSRC_UNCLAIMED = 0x0A, // MailboxSp::invalidMsgResponder
+ MOD_MBOXSRC_UNCLAIMED = 0x0A, // MailboxSp::handleUnclaimed
+ MOD_MBOX_SEND = 0x0B, // MBOX::send
+ MOD_MBOXSRV_IPC_MSG = 0x0C, // MailboxSp::handleIPC
};
enum MBOXReasonCode
@@ -60,6 +62,8 @@ namespace MBOX
RC_INVALID_DMA_LENGTH = MBOX_COMP_ID | 0x0E,
RC_KERNEL_REG_FAILED = MBOX_COMP_ID | 0x0F,
RC_MAILBOX_DISABLED = MBOX_COMP_ID | 0x10,
+ RC_IPC_INVALID_NODE = MBOX_COMP_ID | 0x11,
+ RC_MSG_SEND_ERROR = MBOX_COMP_ID | 0x12,
};
diff --git a/src/include/usr/mbox/mboxif.H b/src/include/usr/mbox/mboxif.H
index d427e5e28..a8609a31f 100644
--- a/src/include/usr/mbox/mboxif.H
+++ b/src/include/usr/mbox/mboxif.H
@@ -1,26 +1,25 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/include/usr/mbox/mboxif.H $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/mbox/mboxif.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
#ifndef __MBOX_MBOXIF_H
#define __MBOX_MBOXIF_H
@@ -30,6 +29,11 @@
namespace MBOX
{
+ enum
+ {
+ MBOX_NODE_FSP = -1,
+ };
+
/**
* Register a message queue to receive mailbox messages
* @param[in] i_queueu_id, The queue identifier
@@ -50,20 +54,29 @@ namespace MBOX
* Send message asynchronously
* @param[in] i_q_id id, of the FSP message queue to send the msg to.
* @param[in] i_msg. The message to send.
+ * @param[in] i_node The destination node [0-7] for IPC messages,
+ * otherwise the default is FSP
*
* @return errlHndl_t on error.
*
- * @pre i_msg->extra_data == NULL If there is no extra data is associated
- * with the message.
+ * @note extra_data payload is not supported for interprocessor
+ * communication(IPC) messages therefore the i_msg->extra_data field
+ * may be used as another user data field
+ *
+ * @pre For FSP mbox messages, i_msg->extra_data must be NULL If there is
+ * no payload associated with the message.
*
- * @pre i_msg->extra_data = malloc(size); i_msg->data[1] = size;
+ * @pre For FSP mbox messages,
+ * i_msg->extra_data = malloc(size); i_msg->data[1] = size;
* Any extra data associated with i_msg was obtained from the heap
* using malloc and i_msg->data[1] contains the length of that data.
*
* @post free(i_msg->extra_dat) was done (if no error)
* @post msg_free(i_msg) was done (if no error)
*/
- errlHndl_t send(queue_id_t i_q_id, msg_t * i_msg);
+ errlHndl_t send(queue_id_t i_q_id,
+ msg_t * i_msg,
+ int i_node = MBOX_NODE_FSP);
/**
* Send message synchronously
diff --git a/src/kernel/intmsghandler.C b/src/kernel/intmsghandler.C
index 8bf68950c..610335731 100644
--- a/src/kernel/intmsghandler.C
+++ b/src/kernel/intmsghandler.C
@@ -119,15 +119,6 @@ void InterruptMsgHdlr::handleInterrupt()
printk("InterrurptMsgHdlr got called before IPC was setup\n");
hit = true;
}
-
-
- // else we got an external interrupt before we got things set up.
- // TODO Is there anything that can be done other than
- // leave the interrupt presenter locked.
- // Does the code that sets up the IP registers need to check to see if
- // there is an interrupt sitting there and send an EOI?
- // Story 41868 - Mask off all interrupts very early - might
- // resolve this TODO.
}
}
@@ -155,6 +146,8 @@ void InterruptMsgHdlr::sendIPI(uint64_t i_pir)
mfrrAddress += mmio_offset(i_pir);
mfrrAddress += MFRR_ADDR_OFFSET;
+ mfrrAddress |= 0x8000000000000000ul;
+
register uint8_t data = 0;
eieio(); sync();
diff --git a/src/kernel/ipc.C b/src/kernel/ipc.C
new file mode 100644
index 000000000..3f522c4ee
--- /dev/null
+++ b/src/kernel/ipc.C
@@ -0,0 +1,97 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/kernel/ipc.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <arch/ppc.H>
+#include <kernel/ipc.H>
+#include <kernel/cpu.H>
+#include <kernel/intmsghandler.H>
+#include <kernel/console.H>
+
+using namespace KernelIpc;
+
+namespace KernelIpc
+{
+ void send(uint64_t i_q, msg_t * i_msg);
+};
+
+/**
+ * IPC communication area. Interrupt service provider initializes.
+ * @see intrrp.C
+ */
+KernelIpc::ipc_data_area_t KernelIpc::ipc_data_area;
+
+// Put the IPC message in the other nodes memory space
+// Two potential issues:
+// 1. The destination node is not there - memory location is nonexistant.
+// 2. The destination node never responds, potentially hanging this thread.
+void KernelIpc::send(uint64_t i_q, msg_t * i_msg)
+{
+ // @note
+ // Point to memory in the destination image.
+ // All host boot images are assured to be at the same code level.
+ // PIR node and physical node are not always the same. For instance a
+ // single node system with an alt-master could be designed such that the
+ // alt-master were on a different logical (power bus numbering) node.
+ // Since it's not in plan to use this IPC mechanism in a single node
+ // system, this case will ge ignored for now.
+ uint64_t this_node = getPIR()/KERNEL_MAX_SUPPORTED_CPUS_PER_NODE;
+ uint64_t hrmor_offset = getHRMOR()-(this_node*(ipc_data_area.hrmor_base));
+ uint64_t dest_node = (i_q >> 32) & 0x07;
+ uint64_t dest_hrmor = (ipc_data_area.hrmor_base*dest_node) + hrmor_offset;
+
+ uint64_t dest_addr = reinterpret_cast<uint64_t>(&ipc_data_area);
+ dest_addr += dest_hrmor;
+ dest_addr |= 0x8000000000000000ul;
+
+ printkd("IPC Dest addr %lx\n",dest_addr);
+
+ // pointer to the ipc_data_area in the destination node
+ ipc_data_area_t * p_dest =
+ reinterpret_cast<ipc_data_area_t*>(dest_addr);
+
+ // get lock on IPC data area in other node
+ while(false == __sync_bool_compare_and_swap(&(p_dest->msg_queue_id),
+ 0,
+ 0xFFFFFFFFFFFFFFFFul))
+ {
+ setThreadPriorityLow();
+ }
+ setThreadPriorityHigh();
+
+ p_dest->msg_payload = *i_msg; // copy in message
+ lwsync();
+
+ p_dest->msg_queue_id = i_q; // set destination queue id
+ lwsync();
+
+ // send IPI
+ InterruptMsgHdlr::sendIPI(p_dest->pir);
+
+ // The message allocation is freed here to make msg_send for IPC
+ // messages behave the same as non-IPC msg_send; that is, the message
+ // is freed by the consumer; however, i_msg was allocated in user space
+ // code and freed here in kernel space. The assumption is that this is OK.
+ msg_free(i_msg);
+
+ return;
+}
+
diff --git a/src/kernel/makefile b/src/kernel/makefile
index a3a750dcb..3627798a6 100644
--- a/src/kernel/makefile
+++ b/src/kernel/makefile
@@ -27,7 +27,7 @@ OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o timemgr.o
OBJS += futexmgr.o ptmgr.o segmentmgr.o devicesegment.o basesegment.o
OBJS += block.o cpuid.o misc.o msghandler.o blockmsghdlr.o stacksegment.o
OBJS += softpatch_p8.o barrier.o idebug.o intmsghandler.o deferred.o
-OBJS += shutdown.o forceattn_p8.o terminate.o
+OBJS += shutdown.o forceattn_p8.o terminate.o ipc.o
include ${ROOTPATH}/config.mk
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 985d9c0ab..0a8e644a0 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -42,6 +42,10 @@
#include <kernel/intmsghandler.H>
#include <sys/sync.h>
+namespace KernelIpc
+{
+ void send(uint64_t i_q, msg_t * i_msg);
+};
extern "C"
void kernel_execute_decrementer()
@@ -308,44 +312,55 @@ namespace Systemcalls
void MsgSend(task_t* t)
{
- MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
+ uint64_t q_handle = TASK_GETARG0(t);
msg_t* m = (msg_t*) TASK_GETARG1(t);
- if ((NULL == mq) || (NULL == m))
+ if(((q_handle >> 32) & MSGQ_TYPE_IPC) != 0)
{
- printkd("NULL pointer for message queue (%p) or message (%p).\n",
- mq, m);
- TASK_SETRTN(t, -EINVAL);
- return;
+ // IPC message
+ KernelIpc::send(q_handle, m);
}
+ else
+ {
- m->__reserved__async = 0; // set to async msg.
+ MessageQueue* mq = reinterpret_cast<MessageQueue*>(q_handle);
- if (m->type >= MSG_FIRST_SYS_TYPE)
- {
- printkd("Invalid type for msg_send, type=%d.\n", m->type);
- TASK_SETRTN(t, -EINVAL);
- return;
- }
+ if ((NULL == mq) || (NULL == m))
+ {
+ printkd("NULL pointer for message queue (%p) or message (%p).\n",
+ mq, m);
+ TASK_SETRTN(t, -EINVAL);
+ return;
+ }
- mq->lock.lock();
+ m->__reserved__async = 0; // set to async msg.
- // Get waiting (server) task.
- task_t* waiter = mq->waiting.remove();
- if (NULL == waiter) // None found, add to 'messages' queue.
- {
- MessagePending* mp = new MessagePending();
- mp->key = m;
- mp->task = t;
- mq->messages.insert(mp);
- }
- else // Add waiter back to its scheduler.
- {
- TASK_SETRTN(waiter, (uint64_t) m);
- waiter->cpu->scheduler->addTask(waiter);
- }
+ if (m->type >= MSG_FIRST_SYS_TYPE)
+ {
+ printkd("Invalid type for msg_send, type=%d.\n", m->type);
+ TASK_SETRTN(t, -EINVAL);
+ return;
+ }
- mq->lock.unlock();
+ mq->lock.lock();
+
+ // Get waiting (server) task.
+ task_t* waiter = mq->waiting.remove();
+ if (NULL == waiter) // None found, add to 'messages' queue.
+ {
+ MessagePending* mp = new MessagePending();
+ mp->key = m;
+ mp->task = t;
+ mq->messages.insert(mp);
+ }
+ else // Add waiter back to its scheduler.
+ {
+ TASK_SETRTN(waiter, (uint64_t) m);
+ waiter->cpu->scheduler->addTask(waiter);
+ }
+
+ mq->lock.unlock();
+ }
TASK_SETRTN(t, 0);
}
diff --git a/src/kernel/terminate.C b/src/kernel/terminate.C
index 2c103c5af..bbb8d4aa9 100644
--- a/src/kernel/terminate.C
+++ b/src/kernel/terminate.C
@@ -26,6 +26,7 @@
#include <kernel/terminate.H>
#include <stdint.h>
#include <kernel/console.H>
+#include <kernel/ipc.H>
#include <builtins.h>
#include <kernel/kernel_reasoncodes.H>
@@ -37,7 +38,11 @@ extern "C" void p8_force_attn() NO_RETURN;
HB_TI_DataArea kernel_TIDataArea;
/* Instance of the HB desriptor struct */
-HB_Descriptor kernel_hbDescriptor = {&kernel_TIDataArea};
+HB_Descriptor kernel_hbDescriptor =
+{
+ &kernel_TIDataArea,
+ &KernelIpc::ipc_data_area
+};
diff --git a/src/makefile b/src/makefile
index 74179a56e..21aeedd16 100644
--- a/src/makefile
+++ b/src/makefile
@@ -43,7 +43,7 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \
ptmgr.o segmentmgr.o basesegment.o devicesegment.o \
block.o cxxtest_data.o cpuid.o misc.o msghandler.o \
blockmsghdlr.o stacksegment.o softpatch_p8.o \
- shutdown.o forceattn_p8.o terminate.o
+ shutdown.o forceattn_p8.o terminate.o ipc.o
BASE_MODULES = trace errl devicefw scom xscom initservice \
pnor vfs
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index b374c9f7d..39ea2d470 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -35,6 +35,7 @@
#include <sys/mmio.h>
#include <sys/misc.h>
#include <kernel/console.H>
+#include <kernel/ipc.H>
#include <sys/task.h>
#include <vmmconst.h>
#include <targeting/common/targetservice.H>
@@ -181,6 +182,17 @@ errlHndl_t IntrRp::_init()
TRACFCOMP(g_trac_intr,"INTR: vAddr = %lx",iv_baseAddr);
+ // Set up the IPC message Data area
+ TARGETING::Target * sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != NULL);
+ uint64_t hrmor_base =
+ sys->getAttr<TARGETING::ATTR_HB_HRMOR_NODAL_BASE>();
+
+ KernelIpc::ipc_data_area.pir = iv_masterCpu.word;
+ KernelIpc::ipc_data_area.hrmor_base = hrmor_base;
+ KernelIpc::ipc_data_area.msg_queue_id = 0;
+
// Set the BAR scom reg
err = setBAR(procTarget,iv_masterCpu);
diff --git a/src/usr/intr/test/intrtest.H b/src/usr/intr/test/intrtest.H
index 56670329e..c653d6609 100644
--- a/src/usr/intr/test/intrtest.H
+++ b/src/usr/intr/test/intrtest.H
@@ -133,56 +133,6 @@ class IntrTest: public CxxTest::TestSuite
}
}
- /**
- * @brief Register an interrupt message queue, force an interrupt,
- * then handle the interrupt.
- */
- void test_intr( void )
- {
-
- // DISABLE in VBU
- if( TARGETING::is_vpo() )
- {
- return;
- }
-
- errlHndl_t err = NULL;
-
- // Need to register a msgq
- msg_q_t msgQ = msg_q_create();
- err = INTR::registerMsgQ(msgQ,0,INTR::ISN_INTERPROC);
- if(err)
- {
- TS_FAIL("Errl from INTR::registerMsgQ()");
- delete err;
- err = NULL;
- }
-
- // Force an interrupt by writing to the MFFR on master
- volatile uint8_t * mfrr =
- reinterpret_cast<uint8_t *>(iv_masterAddr+12);
- *(mfrr) = 0x55;
-
- TRACFCOMP(g_trac_intr,"Waiting for IPI interrupt");
- msg_t* msg = msg_wait(msgQ); // wait for interrupt msg
- TRACFCOMP(g_trac_intr,"Interrupt handled! Type=%lx",msg->data[0]);
- if(msg->data[0] != INTR::INTERPROC_XISR)
- {
- TS_FAIL("INTR::unexpected interrupt type %lx",msg->data[0]);
- }
- msg_respond(msgQ,msg);
-
- msgQ = INTR::unRegisterMsgQ(INTR::ISN_INTERPROC);
- if(msgQ)
- {
- msg_q_destroy(msgQ);
- }
- else
- {
- TS_FAIL("INTR::unRegisterMsgQ failed");
- }
- }
-
// This checks the enablePsiIntr. Even though the master proc
// is already configured it does not use this interface
// and there are no other processor currently configured in simics
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index 2419e67ee..aad84b043 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -35,6 +35,8 @@
#include <mbox/mbox_reasoncodes.H>
#include <mbox/mboxUdParser.H>
#include <targeting/common/commontargeting.H>
+#include <kernel/ipc.H>
+#include <arch/ppc.H>
#define MBOX_TRACE_NAME MBOX_COMP_NAME
@@ -154,6 +156,11 @@ errlHndl_t MailboxSp::_init()
}
}
+ // Register for IPC messages
+ err = INTR::registerMsgQ(iv_msgQ,
+ MSG_IPC,
+ INTR::ISN_INTERPROC);
+
task_create(MailboxSp::msg_handler, NULL);
@@ -281,6 +288,16 @@ void MailboxSp::msgHandler()
}
break;
+ case MSG_IPC: // Interprocessor Messages
+ // Look for IPC message
+ // If not, just ignore
+ handleIPC();
+ msg->data[0] = 0;
+ msg->data[1] = 0;
+ msg_respond(iv_msgQ,msg);
+
+ break;
+
default:
TRACFCOMP(g_trac_mbox, ERR_MRK "MailboxSp::msgHandler() "
@@ -668,17 +685,17 @@ void MailboxSp::recv_msg(mbox_msg_t & i_mbox_msg)
/*@ errorlog tag
* @errortype ERRL_SEV_CRITICAL_SYS_TERM
* @moduleid MBOX::MOD_MBOXSRV_RCV
- * @reasoncode MBOX::RC_INVALID_QUEUE
+ * @reasoncode MBOX::RC_MSG_SEND_ERROR
* @userdata1 rc from msg_send()
* @userdata2 msg queue id
- * @devdesc Ivalid msg or msg queue
+ * @devdesc Invalid msg or msg queue
*
*/
err = new ERRORLOG::ErrlEntry
(
ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
MBOX::MOD_MBOXSRV_RCV,
- MBOX::RC_INVALID_QUEUE, // reason Code
+ MBOX::RC_MSG_SEND_ERROR, // reason Code
rc, // rc from msg_send
i_mbox_msg.msg_queue_id
);
@@ -1290,6 +1307,128 @@ errlHndl_t MailboxSp::handleInterrupt()
return err;
}
+void MailboxSp::handleIPC()
+{
+ // Check for IPC message. If no msg then ignore - could be other things
+ // All IPC messages are secure
+ uint64_t msg_q_id = KernelIpc::ipc_data_area.msg_queue_id;
+
+ // msg_q_id == 0 means no IPC message available
+ // msg_q_id == (all ones) means message incomming, but not ready and
+ // not associated with this interupt
+ if(msg_q_id == 0xFFFFFFFFFFFFFFFFul)
+ {
+ msg_q_id = 0;
+ }
+
+ // destination message queue id is lower 32 bits.
+ msg_q_id &= 0x00000000FFFFFFFFull;
+ if(0 != msg_q_id)
+ {
+ msg_t * msg = msg_allocate();
+ isync();
+ *msg = KernelIpc::ipc_data_area.msg_payload;
+ lwsync();
+ KernelIpc::ipc_data_area.msg_queue_id = 0; // set ready for next msg
+
+ TRACFCOMP(g_trac_mboxmsg,
+ "MBOXSP IPC RECV MSG: msg_id:0x%08x",
+ (uint32_t)msg_q_id);
+ TRACFCOMP(g_trac_mboxmsg,
+ "MBOXSP IPC RECV MSG: 0x%08x 0x%016lx 0x%016lx %p",
+ msg->type,
+ msg->data[0],
+ msg->data[1],
+ msg->extra_data);
+
+ registry_t::iterator r =
+ iv_registry.find(static_cast<queue_id_t>(msg_q_id));
+ if(r != iv_registry.end())
+ {
+ // found queue
+ msg_q_t msgq = r->second;
+
+ // Only async message supported right now
+ // Interface already inforces this.
+ int rc = msg_send(msgq,msg);
+
+ if(rc)
+ {
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MBOX::MOD_MBOXSRV_IPC_MSG
+ * @reasoncode MBOX::RC_MSG_SEND_ERROR
+ * @userdata1 rc from msg_send()
+ * @userdata2 msg queue id
+ * @devdesc Invalid msg or msg queue
+ *
+ */
+ errlHndl_t err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ MBOX::MOD_MBOXSRV_IPC_MSG,
+ MBOX::RC_MSG_SEND_ERROR, // reason Code
+ rc, // rc from msg_send
+ msg_q_id
+ );
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ UserDetailsMboxMsg
+ ffdc(reinterpret_cast<uint64_t*>(msg),
+ sizeof(msg_t));
+
+ ffdc.addToLog(err);
+
+ err->collectTrace(MBOXMSG_TRACE_NAME);
+ errlCommit(err,MBOX_COMP_ID);
+
+ msg_free(msg);
+ }
+ }
+ else // not registered
+ {
+ // thow it away log error
+ TRACFCOMP(g_trac_mbox,
+ ERR_MRK
+ "MailboxSp::handleIPC: Unregistered msg queue id 0x%x"
+ " message dropped.",
+ msg_q_id);
+
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid MOD_MBOXSRV_IPC_MSG
+ * @reasoncode RC_INVALID_QUEUE
+ * @userdata1 msg queue
+ * @userdata2 msg type
+ * @devdesc Invalid message queue ID
+ */
+ errlHndl_t err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ MBOX::MOD_MBOXSRV_IPC_MSG,
+ MBOX::RC_INVALID_QUEUE,
+ msg_q_id,
+ msg->type
+ );
+
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ UserDetailsMboxMsg
+ ffdc(reinterpret_cast<uint64_t*>(msg), sizeof(msg_t));
+
+ ffdc.addToLog(err);
+ err->collectTrace(MBOXMSG_TRACE_NAME);
+ errlCommit(err,MBOX_COMP_ID);
+
+ msg_free(msg);
+ }
+
+ }
+}
+
// Send a message to the FSP mailbox that a message it sent
// had an invalid or undeliverable message
void MailboxSp::invalidMsgResponder(mbox_msg_t & i_mbox_msg)
@@ -1373,6 +1512,7 @@ void MailboxSp::handleShutdown()
errlHndl_t err = mboxddShutDown(iv_trgt);
INTR::unRegisterMsgQ(INTR::FSP_MAILBOX);
+ INTR::unRegisterMsgQ(INTR::ISN_INTERPROC);
if(err) // SCOM failed.
{
@@ -1393,18 +1533,84 @@ void MailboxSp::handleShutdown()
// External Interfaces @see mboxif.H
// ----------------------------------------------------------------------------
-errlHndl_t MBOX::send(queue_id_t i_q_id, msg_t * i_msg)
+errlHndl_t MBOX::send(queue_id_t i_q_id, msg_t * i_msg,int i_node)
{
+ errlHndl_t err = NULL;
+
i_msg->__reserved__async = 0;
- return MailboxSp::send(i_q_id, i_msg);
+
+ if(i_node == MBOX::MBOX_NODE_FSP)
+ {
+ err = MailboxSp::send(i_q_id, i_msg);
+ }
+ else // IPC msg
+ {
+ if(i_node < MSGQ_TYPE_IPC)
+ {
+ uint64_t q_handle = i_q_id;
+ q_handle |= (((uint64_t)MSGQ_TYPE_IPC | (uint64_t)i_node) << 32);
+ int rc = msg_send(reinterpret_cast<msg_q_t>(q_handle),
+ i_msg);
+
+ if(rc)
+ {
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MBOX::MOD_MBOX_SEND
+ * @reasoncode MBOX::RC_INVALID_QUEUE
+ * @userdata1 returncode from msg_send()
+ *
+ * @devdesc Invalid message or message queue
+ *
+ */
+ err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity
+ MBOX::MOD_MBOX_SEND, // moduleid
+ MBOX::RC_INVALID_QUEUE, // reason Code
+ rc, // msg_send errno
+ q_handle // msg queue id
+ );
+
+ // This Trace has the msg
+ err->collectTrace(MBOXMSG_TRACE_NAME);
+ }
+ }
+ else
+ {
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid MBOX::MOD_MBOX_SEND
+ * @reasoncode MBOX::RC_IPC_INVALID_NODE
+ * @userdata1 The destination queue id
+ * @userdata2 The node
+ *
+ * @devdesc An invalid node was specified
+ *
+ */
+ err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
+ MBOX::MOD_MBOX_SEND, // moduleid
+ MBOX::RC_IPC_INVALID_NODE, // reason Code
+ i_q_id, // queue id
+ i_node //
+ );
+ }
+ }
+ return err;
}
+// ---------------------------------------------------------------------------
+
errlHndl_t MBOX::sendrecv(queue_id_t i_q_id, msg_t * io_msg)
{
io_msg->__reserved__async = 1;
return MailboxSp::send(i_q_id, io_msg);
}
+// ---------------------------------------------------------------------------
+
errlHndl_t MBOX::msgq_register(queue_id_t i_queue_id, msg_q_t i_msgQ)
{
// Could use a mutex to protect the queueid to msgQ map, but since
@@ -1460,6 +1666,8 @@ errlHndl_t MBOX::msgq_register(queue_id_t i_queue_id, msg_q_t i_msgQ)
return err;
}
+// ---------------------------------------------------------------------------
+
msg_q_t MBOX::msgq_unregister(queue_id_t i_queue_id)
{
msg_q_t msgQ = NULL;
@@ -1493,6 +1701,8 @@ msg_q_t MBOX::msgq_unregister(queue_id_t i_queue_id)
return msgQ;
}
+// ---------------------------------------------------------------------------
+
bool MBOX::mailbox_enabled()
{
bool enabled = false;
diff --git a/src/usr/mbox/mailboxsp.H b/src/usr/mbox/mailboxsp.H
index dc3337923..7a87ed871 100644
--- a/src/usr/mbox/mailboxsp.H
+++ b/src/usr/mbox/mailboxsp.H
@@ -57,6 +57,7 @@ namespace MBOX
MSG_UNREGISTER_MSGQ,
MSG_INTR,
MSG_MBOX_SHUTDOWN,
+ MSG_IPC,
};
@@ -175,6 +176,11 @@ namespace MBOX
errlHndl_t handleInterrupt();
/**
+ * Handle potential IPC message
+ */
+ void handleIPC();
+
+ /**
* Trace the message to the "fast" trace buffer
* @param[in] i_text, a Description
* @param[in] i_mbox_msg, the message to trace
diff --git a/src/usr/mbox/test/mboxsptest.H b/src/usr/mbox/test/mboxsptest.H
index d1315038b..e3d546e5e 100644
--- a/src/usr/mbox/test/mboxsptest.H
+++ b/src/usr/mbox/test/mboxsptest.H
@@ -309,6 +309,64 @@ class MboxSPTest : public CxxTest::TestSuite
msg_free(msg);
#endif
}
+
+ /**
+ * @brief IPC message test
+ *
+ */
+ void testIPC(void)
+ {
+ errlHndl_t err = NULL;
+ msg_t * msg = msg_allocate();
+ msg_t * tmsg = msg_allocate();
+ msg_q_t msgQ = msg_q_create();
+
+ err = MBOX::msgq_register(MBOX::HB_TEST_MSGQ,msgQ);
+ if(err)
+ {
+ TS_FAIL("MBOX IPC: Could not register message queue");
+ errlCommit(err,MBOX_COMP_ID);
+ }
+
+ msg->type = 1;
+ msg->data[0] = 0x1111111111111111ull;
+ msg->data[1] = 0x4444444444444444ull;
+ msg->extra_data = (void *)0x3333333333333333ull;
+
+ *tmsg = *msg; // save for compare
+ uint64_t node = 0;
+
+ err = MBOX::send(MBOX::HB_TEST_MSGQ,msg,node);
+ if(err)
+ {
+ TS_FAIL("MBOX::send (IPC) returned and error log");
+ errlCommit(err,MBOX_COMP_ID);
+ msg_free(msg);
+ return;
+ }
+
+ msg_t * rmsg = msg_wait(msgQ);
+
+ if(rmsg->type != tmsg->type ||
+ rmsg->data[0] != tmsg->data[0] ||
+ rmsg->data[1] != tmsg->data[1] ||
+ rmsg->extra_data != tmsg->extra_data)
+ {
+ TS_FAIL("IPCTEST: Unexpected IPC message");
+
+ TRACFCOMP(g_trac_mbox,
+ "IPCTEST IPC MSG: %d %lx %lx %p",
+ rmsg->type,
+ rmsg->data[0],
+ rmsg->data[1],
+ rmsg->extra_data);
+ }
+
+ msgQ = MBOX::msgq_unregister(MBOX::HB_TEST_MSGQ);
+ msg_q_destroy(msgQ);
+ msg_free(rmsg);
+ msg_free(tmsg);
+ }
};
#endif
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 3d27e1c55..a156b9858 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -1868,6 +1868,22 @@
</attribute>
<attribute>
+ <id>HB_HRMOR_NODAL_BASE</id>
+ <description>Hostboot HRMOR = (HB_HRMOR_NODAL_BASE * node) + offset. </description>
+ <!-- This value is set by the FSP.
+ Hostboot uses it to find the HRMOR of Hostboot images running on other nodes.
+ The value of HB_HRMOR_NODAL_BASE does NOT include the offset -->
+ <simpleType>
+ <uint64_t>
+ <default>0x400000000000</default> <!-- 64TB -->
+ </uint64_t>
+ </simpleType>
+ <persistency>volatile</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
<id>EI_BUS_RX_MSB_LSB_SWAP</id>
<description>PRBS scramble pattern per lane on DMI bus for p8 and centaur.</description>
<simpleType>
@@ -1899,6 +1915,7 @@
</hwpfToHbAttrMap>
</attribute>
+
<!-- TARGETING attributes to support mss_setup_bars and proc_setup_bars -->
<attribute>
diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
index da0134271..c7c2d0b54 100644
--- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
@@ -149,6 +149,10 @@
<default>NONE</default>
</attribute>
<attribute>
+ <id>HB_HRMOR_NODAL_BASE</id>
+ <default>0x4000000</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
index 24afc7486..8ac32d65c 100644
--- a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
@@ -125,6 +125,10 @@
<default>NONE</default>
</attribute>
<attribute>
+ <id>HB_HRMOR_NODAL_BASE</id>
+ <default>0x4000000</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 5799da941..d5080c21e 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -100,6 +100,7 @@
<attribute><id>PAYLOAD_KIND</id></attribute>
<attribute><id>PAYLOAD_BASE</id></attribute>
<attribute><id>PAYLOAD_ENTRY</id></attribute>
+ <attribute><id>HB_HRMOR_NODAL_BASE</id></attribute>
<attribute><id>MSS_MCA_HASH_MODE</id></attribute>
<attribute><id>MSS_MBA_ADDR_INTERLEAVE_BIT</id></attribute>
<attribute><id>MSS_MBA_CACHELINE_INTERLEAVE_MODE</id></attribute>
diff --git a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml
index c7d0e4cec..cfdc16af6 100644
--- a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml
+++ b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml
@@ -141,6 +141,10 @@
<default>AVP</default>
</attribute>
<attribute>
+ <id>HB_HRMOR_NODAL_BASE</id>
+ <default>0x4000000</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml
index 858870439..7315bfdcb 100644
--- a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml
+++ b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml
@@ -138,6 +138,10 @@
<default>AVP</default>
</attribute>
<attribute>
+ <id>HB_HRMOR_NODAL_BASE</id>
+ <default>0x4000000</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
OpenPOWER on IntegriCloud