From 8fac481d825883154ca20612ca0a69bc52f02618 Mon Sep 17 00:00:00 2001 From: Doug Gilbert Date: Tue, 23 Apr 2013 14:10:52 -0500 Subject: 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 --- src/include/kernel/hbdescriptor.H | 5 +- src/include/kernel/ipc.H | 41 ++++ src/include/sys/msg.h | 3 +- src/include/usr/intr/interrupt.H | 7 +- src/include/usr/mbox/mbox_reasoncodes.H | 6 +- src/include/usr/mbox/mboxif.H | 67 ++++--- src/kernel/intmsghandler.C | 11 +- src/kernel/ipc.C | 97 +++++++++ src/kernel/makefile | 2 +- src/kernel/syscall.C | 73 ++++--- src/kernel/terminate.C | 7 +- src/makefile | 2 +- src/usr/intr/intrrp.C | 12 ++ src/usr/intr/test/intrtest.H | 50 ----- src/usr/mbox/mailboxsp.C | 220 ++++++++++++++++++++- src/usr/mbox/mailboxsp.H | 6 + src/usr/mbox/test/mboxsptest.H | 58 ++++++ .../targeting/common/xmltohb/attribute_types.xml | 17 ++ .../common/xmltohb/simics_MURANO.system.xml | 4 + .../common/xmltohb/simics_VENICE.system.xml | 4 + src/usr/targeting/common/xmltohb/target_types.xml | 1 + .../targeting/common/xmltohb/vbu_MURANO.system.xml | 4 + .../targeting/common/xmltohb/vbu_VENICE.system.xml | 4 + 23 files changed, 573 insertions(+), 128 deletions(-) create mode 100644 src/include/kernel/ipc.H create mode 100644 src/kernel/ipc.C 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 + +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 +#include +#include +#include +#include + +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(&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(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 #include +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(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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include #include @@ -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(); + + 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(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 #include #include +#include +#include #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(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(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(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(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, }; @@ -174,6 +175,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 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 @@ -1867,6 +1867,22 @@ + + HB_HRMOR_NODAL_BASE + Hostboot HRMOR = (HB_HRMOR_NODAL_BASE * node) + offset. + + + + 0x400000000000 + + + volatile + + + + EI_BUS_RX_MSB_LSB_SWAP PRBS scramble pattern per lane on DMI bus for p8 and centaur. @@ -1899,6 +1915,7 @@ + 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 @@ -148,6 +148,10 @@ PAYLOAD_KIND NONE + + HB_HRMOR_NODAL_BASE + 0x4000000 + MSS_MCA_HASH_MODE 0 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 @@ -124,6 +124,10 @@ PAYLOAD_KIND NONE + + HB_HRMOR_NODAL_BASE + 0x4000000 + MSS_MCA_HASH_MODE 0 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 @@ PAYLOAD_KIND PAYLOAD_BASE PAYLOAD_ENTRY + HB_HRMOR_NODAL_BASE MSS_MCA_HASH_MODE MSS_MBA_ADDR_INTERLEAVE_BIT MSS_MBA_CACHELINE_INTERLEAVE_MODE 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 @@ -140,6 +140,10 @@ PAYLOAD_KIND AVP + + HB_HRMOR_NODAL_BASE + 0x4000000 + MSS_MCA_HASH_MODE 0 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 @@ -137,6 +137,10 @@ PAYLOAD_KIND AVP + + HB_HRMOR_NODAL_BASE + 0x4000000 + MSS_MCA_HASH_MODE 0 -- cgit v1.2.1