diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/usr/mbox/mboxif.H | 12 | ||||
| -rw-r--r-- | src/usr/hwpf/hwp/core_activate/core_activate.C | 25 | ||||
| -rw-r--r-- | src/usr/mbox/mailboxsp.C | 48 | ||||
| -rw-r--r-- | src/usr/mbox/mailboxsp.H | 2 | ||||
| -rw-r--r-- | src/usr/mbox/mboxdd.C | 36 | ||||
| -rw-r--r-- | src/usr/mbox/mboxdd.H | 10 |
6 files changed, 114 insertions, 19 deletions
diff --git a/src/include/usr/mbox/mboxif.H b/src/include/usr/mbox/mboxif.H index 1f56d6c95..497a22893 100644 --- a/src/include/usr/mbox/mboxif.H +++ b/src/include/usr/mbox/mboxif.H @@ -116,13 +116,21 @@ namespace MBOX /** * Suspend the mailbox. * + * @param[in] i_disable_hw_int, disable interrupts from hw along + * with SW suspend. Defaults to SW suspend only + * @param[in] i_allow_resp, Allow suspend to happen even if + * there are pending HB responses to FSP. Use + * with extreme caution + * * @return error handle on error * * @note: * Any message sent to the FSP will be queued and send after the mailbox - * is resumed. Interrupts from the FSP MBox will be masked. + * is resumed. Interrupts from the FSP MBox will be masked if + * i_disable_hw_int is set */ - errlHndl_t suspend(); + errlHndl_t suspend(bool i_disable_hw_int = false, + bool i_allow_resp = false); /** * Resume the mailbox diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C index 7e37a4609..934345ef3 100644 --- a/src/usr/hwpf/hwp/core_activate/core_activate.C +++ b/src/usr/hwpf/hwp/core_activate/core_activate.C @@ -160,6 +160,22 @@ void* call_host_activate_master( void *io_pArgs ) "proc_prep_master_winkle SUCCESS" ); } + //Because of a bug in how the SBE injects the IPI used to wake + //up the master core, need to ensure no mailbox traffic + //or even an interrupt in the interrupt presenter + // 1) suspend the mailbox with interrupt disable + // 2) ensure that interrupt presenter is drained + l_errl = MBOX::suspend(true, true); + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_host_activate_master ERROR : MBOX::suspend"); + break; + } + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "drainging interrupt Q"); + INTR::drainQueue(); + // Call p8_block_wakeup_intr to prevent stray interrupts from // popping core out of winkle before SBE sees it. @@ -254,6 +270,15 @@ void* call_host_activate_master( void *io_pArgs ) TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Returned from Winkle." ); + //Re-enable the mailbox + l_errl = MBOX::resume(); + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_host_activate_master ERROR : MBOX::resume"); + break; + } + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Call proc_stop_deadman_timer. Target %.8X", TARGETING::get_huid(l_cpu_target) ); diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C index abcc93b76..bb7b01513 100644 --- a/src/usr/mbox/mailboxsp.C +++ b/src/usr/mbox/mailboxsp.C @@ -81,6 +81,8 @@ MailboxSp::MailboxSp() iv_dma_pend(false), iv_disabled(true), iv_suspended(false), + iv_suspend_intr(false), + iv_allow_blk_resp(false), iv_sum_alloc(0), iv_pend_alloc(), iv_allocAddrs() @@ -364,6 +366,8 @@ void MailboxSp::msgHandler() iv_suspend_msg = msg; // Respond to this when done iv_suspended = true; // Queue any new messages + iv_suspend_intr = static_cast<bool>(msg->data[0]); + iv_allow_blk_resp = static_cast<bool>(msg->data[1]); if(quiesced()) { @@ -1488,12 +1492,19 @@ bool MailboxSp::quiesced() { bool result = iv_rts && !iv_dma_pend && iv_sendq.empty(); + TRACFCOMP(g_trac_mbox,INFO_MRK"Checking quiesced.. rts[%d] dma_pend[%d] sendq[%d]", + iv_rts, iv_dma_pend, iv_sendq.empty()); + + if( result == true ) { + TRACFCOMP(g_trac_mbox,INFO_MRK"quiesed == true, iv_shutdown_msg[%p]", + iv_shutdown_msg); if(iv_shutdown_msg == NULL || (iv_shutdown_msg->data[1] == SHUTDOWN_STATUS_GOOD)) { - result = result && iv_respondq.empty(); + //Check that respond q is empty OR don't care + result = result && (iv_respondq.empty() || iv_allow_blk_resp); } else // mbox is shutting down and system status is bad { @@ -1524,6 +1535,8 @@ bool MailboxSp::quiesced() } } + TRACFCOMP(g_trac_mbox,INFO_MRK"Quiesced [%d]", result); + return result; } @@ -1736,6 +1749,19 @@ void MailboxSp::handleShutdown() void MailboxSp::suspend() { + TRACFCOMP(g_trac_mbox,INFO_MRK"Entering suspended"); + if(iv_suspend_intr) + { + errlHndl_t err = mboxddMaskInterrupts(iv_trgt); + if(err) // SCOM failed. + { + // If this failed, the whole system is probably buggered up. + errlCommit(err,MBOX_COMP_ID); + TRACFCOMP(g_trac_mbox, + ERR_MRK"MBOXSP suspend HALTED on critical error!"); + crit_assert(0); + } + } msg_respond(iv_msgQ,iv_suspend_msg); TRACFCOMP(g_trac_mbox,INFO_MRK"Mailbox is suspended"); } @@ -1743,9 +1769,25 @@ void MailboxSp::suspend() void MailboxSp::resume() { iv_suspended = false; + iv_allow_blk_resp = false; if(!iv_disabled) { + //If interrupts were disabled, re-enable + if(iv_suspend_intr) + { + errlHndl_t err = mboxddEnableInterrupts(iv_trgt); + if(err) // SCOM failed. + { + // If this failed, the whole system is probably buggered up. + errlCommit(err,MBOX_COMP_ID); + TRACFCOMP(g_trac_mbox, + ERR_MRK"MBOXSP resume HALTED on critical error!"); + crit_assert(0); + } + iv_suspend_intr = false; + } + send_msg(); // send next message on queue } } @@ -2042,7 +2084,7 @@ bool MBOX::mailbox_enabled() return enabled; } -errlHndl_t MBOX::suspend() +errlHndl_t MBOX::suspend(bool i_disable_hw_int, bool i_allow_resp) { errlHndl_t err = NULL; msg_q_t mboxQ = msg_q_resolve(VFS_ROOT_MSG_MBOX); @@ -2050,6 +2092,8 @@ errlHndl_t MBOX::suspend() { msg_t * msg = msg_allocate(); msg->type = MSG_MBOX_SUSPEND; + msg->data[0] = static_cast<uint64_t>(i_disable_hw_int); + msg->data[1] = static_cast<uint64_t>(i_allow_resp); int rc = msg_sendrecv(mboxQ, msg); diff --git a/src/usr/mbox/mailboxsp.H b/src/usr/mbox/mailboxsp.H index c643fbe6b..caec9cc3f 100644 --- a/src/usr/mbox/mailboxsp.H +++ b/src/usr/mbox/mailboxsp.H @@ -328,6 +328,8 @@ namespace MBOX bool iv_dma_pend; //!< Request pending for more DMA bufs bool iv_disabled; //!< Mailboxsp shut off (rejects new) bool iv_suspended; //!< Mailbox is suspended (queues new) + bool iv_suspend_intr;//!< Disable HW interrupts on suspend + bool iv_allow_blk_resp;//!< Disable HW interrupts on suspend uint64_t iv_sum_alloc; //!< Total extra_data storage allocated msg_list_t iv_pend_alloc; //!< Pending memory allocations addr_list_t iv_allocAddrs; //!< memory addresses allocated by mbox diff --git a/src/usr/mbox/mboxdd.C b/src/usr/mbox/mboxdd.C index 5ad5ad45c..63bca0ffd 100644 --- a/src/usr/mbox/mboxdd.C +++ b/src/usr/mbox/mboxdd.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -605,43 +607,49 @@ errlHndl_t mboxGetErrStat(TARGETING::Target* i_target,uint64_t &o_status) errlHndl_t mboxInit(TARGETING::Target* i_target) { + //For now init only enables the interrupts + return mboxddEnableInterrupts(i_target); +} + + +errlHndl_t mboxddMaskInterrupts(TARGETING::Target * i_target) +{ errlHndl_t err = NULL; - size_t scom_len = sizeof(uint64_t); - // Setup mailbox intr mask reg - // Set bits 2,1,0 - // assume we always use mailbox 1 + // Mask off all interrupts + // Reset intr enable bits by setting the bits in MBOX_DB_INT_MASK_PIB_RC uint64_t scom_data = (static_cast<uint64_t>(MBOX_DOORBELL_ERROR) | static_cast<uint64_t>(MBOX_HW_ACK) | static_cast<uint64_t>(MBOX_DATA_PENDING)) << 32; + size_t scom_len = sizeof(uint64_t); + err = deviceOp(DeviceFW::WRITE, i_target, reinterpret_cast<void*>(&scom_data), scom_len, - DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RS)); + DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RC)); + return err; } - -errlHndl_t mboxddMaskInterrupts(TARGETING::Target * i_target) +errlHndl_t mboxddEnableInterrupts(TARGETING::Target * i_target) { errlHndl_t err = NULL; + size_t scom_len = sizeof(uint64_t); - // Mask off all interrupts - // Reset intr enable bits by setting the bits in MBOX_DB_INT_MASK_PIB_RC + // Setup mailbox intr mask reg + // Set bits 2,1,0 + // assume we always use mailbox 1 uint64_t scom_data = (static_cast<uint64_t>(MBOX_DOORBELL_ERROR) | static_cast<uint64_t>(MBOX_HW_ACK) | static_cast<uint64_t>(MBOX_DATA_PENDING)) << 32; - size_t scom_len = sizeof(uint64_t); - err = deviceOp(DeviceFW::WRITE, i_target, reinterpret_cast<void*>(&scom_data), scom_len, - DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RC)); - + DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RS)); return err; } diff --git a/src/usr/mbox/mboxdd.H b/src/usr/mbox/mboxdd.H index e5c1cb9cb..86fb1ee80 100644 --- a/src/usr/mbox/mboxdd.H +++ b/src/usr/mbox/mboxdd.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -69,6 +71,12 @@ namespace MBOX errlHndl_t mboxddMaskInterrupts(TARGETING::Target * i_target); /** + * @brief Enable the reporting of interrupts + * @param[in] i_target, Chip target of the MBOX operations + */ + errlHndl_t mboxddEnableInterrupts(TARGETING::Target * i_target); + + /** * @brief Shutdown device driver * * @param[in] i_target, Chip target of the MBOX operation |

