summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authordgilbert <dgilbert@us.ibm.com>2012-11-27 11:41:04 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-12-19 16:02:43 -0600
commitf5ae894024733fe3fb5ae26aaaa67cc8df0d0a3c (patch)
tree7bcc9aa241f64758736e88d4f1bc9c4bf72db252 /src/usr
parent9458535739acca481800bbda1b59d4f1b213d2c2 (diff)
downloadtalos-hostboot-f5ae894024733fe3fb5ae26aaaa67cc8df0d0a3c.tar.gz
talos-hostboot-f5ae894024733fe3fb5ae26aaaa67cc8df0d0a3c.zip
Initialize the PIB hardware layer for interrupts
RTC: 47105 Change-Id: Iba893e65ee468b56e9e929a26d2888a67a4788af Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2433 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/diag/attn/attnbits.H82
-rw-r--r--src/usr/diag/attn/attnfwd.H2
-rw-r--r--src/usr/diag/attn/attnsvc.C247
-rw-r--r--src/usr/diag/attn/attnsvc.H30
-rw-r--r--src/usr/diag/attn/test/attnfakepresenter.C4
-rw-r--r--src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C57
-rw-r--r--src/usr/intr/intrrp.C428
-rw-r--r--src/usr/intr/intrrp.H203
-rw-r--r--src/usr/intr/test/intrtest.H76
-rw-r--r--src/usr/mbox/mailboxsp.C4
-rw-r--r--src/usr/mbox/mboxdd.C60
-rw-r--r--src/usr/mbox/mboxdd.H61
12 files changed, 740 insertions, 514 deletions
diff --git a/src/usr/diag/attn/attnbits.H b/src/usr/diag/attn/attnbits.H
index 534e72bc7..c678d7964 100644
--- a/src/usr/diag/attn/attnbits.H
+++ b/src/usr/diag/attn/attnbits.H
@@ -170,92 +170,12 @@ bool getCheckbits(
uint64_t & o_bits);
}
-/**
- * @brief PsiHbXivr Layout for XIVR registers.
- */
-struct PsiHbXivr
-{
- union
- {
- uint64_t u64;
-
- struct
- {
- uint64_t res1:8; // zeros
- uint64_t pir:14; // interrupt destination (server)
- uint64_t linkptr:2; // which link reg in intr presenter
- uint64_t priority:8; // intr priority level
- uint64_t source:3; // source number
- uint64_t res2:4; // zeros
- uint64_t intr_pend:25; // interrupt is pending
- } PACKED;
- };
-
- PsiHbXivr() : u64(0) {}
-};
-
-/**
- * @brief IcpXisr The XISR fields of the XIRR register.
- */
-struct IcpXisr
-{
- union
- {
- uint64_t u64;
-
- struct
- {
- uint64_t res1:44; // zeros
- uint64_t node:4; // isn - node
- uint64_t chip:3; // isn - chip
- uint64_t unit:2; // isn - unit
- uint64_t source:11; // isn - source
- } PACKED;
- };
-
- IcpXisr() : u64(0) {}
-};
-
-/**
- * @brief PsiHbIrqSrcCmp Layout for the IRQ source compare register.
- *
- * FIXME: This can go away when RTC 47105 in place.
- */
-struct PsiHbIrqSrcCmp
-{
- union
- {
- uint64_t u64;
-
- struct
- {
- uint64_t irsn:19;
- uint64_t res1:10;
- uint64_t reset:1;
- uint64_t die:1;
- uint64_t uie:1;
- uint64_t mask:19;
- uint64_t res2:13;
- } PACKED;
- };
-
- PsiHbIrqSrcCmp() : u64(0) {}
-};
/**
- * @brief PSI host bridge interrupt
- * config related constants
+ * @brief Interrupt config related constants
*/
enum
{
- PSI_HB_IC_ENABLE = 1,
- LCL_ERR_ISN = 4,
- LCL_ERR_XIVR_ADDR = 0x02010919,
- LCL_ERR_PRIO_DISABLED = 0xff,
- LCL_ERR_PRIO = 0x20,
- PSI_HB_IRQ_SRC_CMP_ADDR = 0x0201091b,
- PSI_HB_IRSN = 0x18,
- PSI_HB_IRSN_MASK = 0x7FFF8,
INTR_TYPE_LCL_ERR_STATUS_REG = 0x1020000,
INTR_TYPE_MASK_REG = 0x102000c,
INTR_TYPE_CONFIG_REG = 0x102000f,
diff --git a/src/usr/diag/attn/attnfwd.H b/src/usr/diag/attn/attnfwd.H
index af857ddfb..c28551e47 100644
--- a/src/usr/diag/attn/attnfwd.H
+++ b/src/usr/diag/attn/attnfwd.H
@@ -79,7 +79,7 @@ enum MessageType
/**
* @brief ATTENTION Attention message.
*/
- ATTENTION = INTR::ATTENTION,
+ ATTENTION = 0x1,
/**
* @brief SHUTDOWN Shutdown message.
diff --git a/src/usr/diag/attn/attnsvc.C b/src/usr/diag/attn/attnsvc.C
index 5f8fb5eca..e61ada0a1 100644
--- a/src/usr/diag/attn/attnsvc.C
+++ b/src/usr/diag/attn/attnsvc.C
@@ -45,56 +45,6 @@ using namespace ERRORLOG;
namespace ATTN
{
-errlHndl_t Service::configureInterrupt(
- ConfigureMode i_mode,
- TargetHandle_t i_proc,
- msg_q_t i_q,
- uint64_t i_xisr,
- uint64_t i_xivrData,
- uint64_t i_xivrAddr)
-{
- errlHndl_t err = NULL;
-
- do {
-
- if(i_mode == UP)
- {
- err = INTR::registerMsgQ(
- i_q,
- ATTENTION,
- static_cast<INTR::ext_intr_t>(i_xisr));
- }
- else
- {
- if(NULL == INTR::unRegisterMsgQ(
- static_cast<INTR::ext_intr_t>(i_xisr)))
- {
- ATTN_ERR("INTR did not find xisr: 0x%07x, tgt: %p",
- i_xisr, i_proc);
- }
- }
-
- if(err)
- {
- break;
- }
-
-
- // TODO: validate this order of operations doesn't
- // cause any checkstops (RTC: 52894)
-
- err = putScom(i_proc, i_xivrAddr, i_xivrData);
-
- if(err)
- {
- break;
- }
-
- } while(0);
-
- return err;
-}
-
void getMask(uint64_t i_type, void * i_data)
{
uint64_t & mask = *static_cast<uint64_t *>(i_data);
@@ -109,152 +59,113 @@ errlHndl_t Service::configureInterrupts(
msg_q_t i_q,
ConfigureMode i_mode)
{
- uint64_t prio = i_mode == UP
- ? LCL_ERR_PRIO
- : LCL_ERR_PRIO_DISABLED;
-
errlHndl_t err = NULL;
- TargetHandleList procs;
-
- getTargetService().getAllChips(procs, TYPE_PROC);
-
- TargetHandleList::iterator it = procs.begin();
-
- while(it != procs.end())
+ // First register for Q
+ // This will set up the lcl_err interrupt on all chips
+ if(i_mode == UP)
{
- PsiHbIrqSrcCmp psiHbIrqSrcCmpData;
-
- psiHbIrqSrcCmpData.irsn = PSI_HB_IRSN;
- psiHbIrqSrcCmpData.mask = PSI_HB_IRSN_MASK;
- psiHbIrqSrcCmpData.die = PSI_HB_IC_ENABLE;
- psiHbIrqSrcCmpData.uie = PSI_HB_IC_ENABLE;
-
- if(i_mode == UP)
- {
- // setup psihb interrupts
-
- // FIXME: This scom can go away when RTC 47105 in place.
-
- err = putScom(
- *it,
- PSI_HB_IRQ_SRC_CMP_ADDR,
- psiHbIrqSrcCmpData.u64);
- }
-
- if(err)
+ err = INTR::registerMsgQ(i_q,
+ ATTENTION,
+ INTR::ISN_LCL_ERR);
+ }
+ else
+ {
+ if(NULL == INTR::unRegisterMsgQ(INTR::ISN_LCL_ERR))
{
- break;
+ ATTN_ERR("INTR did not find isn: 0x%07x",
+ INTR::ISN_LCL_ERR);
}
+ }
- // setup local error interrupts
-
- IcpXisr xisr;
-
- uint64_t node = 0, chip = 0;
-
- getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node);
- getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip);
-
- xisr.node = node;
- xisr.chip = chip;
- xisr.source = PSI_HB_IRSN | LCL_ERR_ISN;
-
- PsiHbXivr psiHbXivrData;
-
- psiHbXivrData.source = LCL_ERR_ISN;
- psiHbXivrData.priority = prio;
- psiHbXivrData.pir = INTR::intrDestCpuId(xisr.u64);
- err = configureInterrupt(
- i_mode,
- *it,
- i_q,
- xisr.u64,
- psiHbXivrData.u64,
- LCL_ERR_XIVR_ADDR);
+ //Issue scoms to allow attentions to flow via INTR
+ if(!err)
+ {
+ TargetHandleList procs;
+ getTargetService().getAllChips(procs, TYPE_PROC);
+ TargetHandleList::iterator it = procs.begin();
- if(err)
+ while(it != procs.end())
{
- break;
- }
+ uint64_t mask = 0;
- uint64_t mask = 0;
+ // clear status
- // clear status
+ if(i_mode == UP)
+ {
+ err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_REG,
+ 0);
+ }
- if(i_mode == UP)
- {
- err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_REG, 0);
- }
+ if(err)
+ {
+ break;
+ }
- if(err)
- {
- break;
- }
+ // unmask lcl err intr
- // unmask lcl err intr
+ mask = 0x8000000000000000ull;
- mask = 0x8000000000000000ull;
+ err = modifyScom(
+ *it,
+ INTR_TYPE_MASK_REG,
+ i_mode == UP ? ~mask : mask,
+ i_mode == UP ? SCOM_AND : SCOM_OR);
- err = modifyScom(
- *it,
- INTR_TYPE_MASK_REG,
- i_mode == UP ? ~mask : mask,
- i_mode == UP ? SCOM_AND : SCOM_OR);
+ if(err)
+ {
+ break;
+ }
- if(err)
- {
- break;
- }
+ // set lcl err intr conf - or
- // set lcl err intr conf - or
+ if(i_mode == UP)
+ {
+ err = modifyScom(*it, INTR_TYPE_CONFIG_REG,
+ ~mask, SCOM_AND);
+ }
- if(i_mode == UP)
- {
- err = modifyScom(*it, INTR_TYPE_CONFIG_REG, ~mask, SCOM_AND);
- }
+ if(err)
+ {
+ break;
+ }
- if(err)
- {
- break;
- }
+ // enable powerbus gpin
- // enable powerbus gpin
+ mask = 0x0018000000000000ull;
- mask = 0x0018000000000000ull;
+ err = modifyScom(
+ *it,
+ GP2_REG,
+ i_mode == UP ? mask : ~mask,
+ i_mode == UP ? SCOM_OR : SCOM_AND);
- err = modifyScom(
- *it,
- GP2_REG,
- i_mode == UP ? mask : ~mask,
- i_mode == UP ? SCOM_OR : SCOM_AND);
+ if(err)
+ {
+ break;
+ }
- if(err)
- {
- break;
- }
+ // enable interrupts in ipoll mask
- // enable interrupts in ipoll mask
+ mask = 0;
- mask = 0;
+ IPOLL::forEach(~0, &mask, &getMask);
- IPOLL::forEach(~0, &mask, &getMask);
+ err = modifyScom(
+ *it,
+ IPOLL::address,
+ i_mode == UP ? mask : ~mask,
+ i_mode == UP ? SCOM_OR : SCOM_AND);
- err = modifyScom(
- *it,
- IPOLL::address,
- i_mode == UP ? mask : ~mask,
- i_mode == UP ? SCOM_OR : SCOM_AND);
+ if(err)
+ {
+ break;
+ }
- if(err)
- {
- break;
+ ++it;
}
-
- ++it;
}
-
return err;
}
@@ -326,9 +237,9 @@ errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
TargetHandle_t proc = NULL;
- IcpXisr xisr;
+ INTR::XISR_t xisr;
- xisr.u64 = i_msg.data[0];
+ xisr.u32 = i_msg.data[0];
TargetHandleList procs;
getTargetService().getAllChips(procs, TYPE_PROC);
@@ -352,7 +263,7 @@ errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
++it;
}
- ATTN_DBG("preack: xisr: 0x%07x, tgt: %p", xisr.u64, proc);
+ ATTN_DBG("preack: xisr: 0x%07x, tgt: %p", xisr.u32, proc);
do {
diff --git a/src/usr/diag/attn/attnsvc.H b/src/usr/diag/attn/attnsvc.H
index 94b231847..2ee84f81e 100644
--- a/src/usr/diag/attn/attnsvc.H
+++ b/src/usr/diag/attn/attnsvc.H
@@ -125,36 +125,6 @@ class Service
ConfigureMode i_mode);
/**
- * @brief configureInterrupt enable or disable
- * a specific interrupt type on a single processor.
- *
- * @post Service (un)hooked to/from interrupt service
- * for local error and host interrupts.
- * @post local error and host priority set(cleared).
- * @post local error and host interrupts (un)masked at GFIR macro.
- *
- * @param[in] i_mode Up or down
- * @param[in] i_proc The proc to be configured.
- * @param[in] i_q The msg q to be registered with the
- * interrupt service.
- * @param[in] i_xisr The XISR value for the type being configured.
- * @param[in] i_xivrData The XIVR register content for
- * the type being configured.
- * @param[in] i_xivrAddr The XIVR register address for the type
- * being configured.
- *
- * @retval[0] No error
- * @retval[!0] Unexpected error
- */
- errlHndl_t configureInterrupt(
- ConfigureMode i_mode,
- TARGETING::TargetHandle_t i_proc,
- msg_q_t i_q,
- uint64_t i_xisr,
- uint64_t i_xivrData,
- uint64_t i_xivrAddr);
-
- /**
* @brief intrTask infinite wait-for-interrupt loop
*
* repeatedly call intrTaskWait and processIntrQMsg
diff --git a/src/usr/diag/attn/test/attnfakepresenter.C b/src/usr/diag/attn/test/attnfakepresenter.C
index bc137a26b..3c6866ade 100644
--- a/src/usr/diag/attn/test/attnfakepresenter.C
+++ b/src/usr/diag/attn/test/attnfakepresenter.C
@@ -129,7 +129,7 @@ void FakePresenter::interrupt(
if(iv_tid)
{
- IcpXisr xisr;
+ INTR::XISR_t xisr;
uint64_t node = 0, chip = 0;
@@ -145,7 +145,7 @@ void FakePresenter::interrupt(
p->type = i_type;
p->data = i_data;
p->callback = i_callback;
- p->xisr = xisr.u64;
+ p->xisr = xisr.u32;
msg_t * m = msg_allocate();
diff --git a/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C b/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C
index a2bb5e300..dddaa60c0 100644
--- a/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C
+++ b/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C
@@ -76,6 +76,7 @@
#include "proc_fab_iovalid/proc_fab_iovalid.H"
#include <diag/prdf/common/prdfMain.H>
#include "fabric_io_dccal/fabric_io_dccal.H"
+#include <intr/interrupt.H>
// eRepair Restore
#include <erepairAccessorHwpFuncs.H>
@@ -822,30 +823,8 @@ void* call_proc_fab_iovalid( void *io_pArgs )
(l_errl ? "ERROR" : "SUCCESS"));
}
- if (l_errl)
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR : call_proc_fab_iovalid encountered an error");
- /*@
- * @errortype
- * @reasoncode ISTEP_EDI_EI_INITIALIZATION_FAILED
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid ISTEP_PROC_FAB_IOVALID
- * @userdata1 bytes 0-1: plid identifying first error
- * bytes 2-3: reason code of first error
- * @userdata2 bytes 0-1: total number of elogs included
- * bytes 2-3: N/A
- * @devdesc call to proc_fab_iovalid has failed
- */
- l_StepError.addErrorDetails(ISTEP_EDI_EI_INITIALIZATION_FAILED,
- ISTEP_PROC_FAB_IOVALID,
- l_errl );
-
- errlCommit( l_errl, HWPF_COMP_ID );
-
- }
// no errors during the proc_fabric_iovalid so switch to XSCOM
- else
+ if(!l_errl)
{
// At the point where we can now change the proc chips to use
// XSCOM rather than FSISCOM which is the default.
@@ -878,9 +857,41 @@ void* call_proc_fab_iovalid( void *io_pArgs )
}
}
+ // Enable PSI interrupts even if can't Xscom as
+ // Pbus is up and interrupts can flow
+ l_errl = INTR::enablePsiIntr(l_proc_target);
+ if(l_errl)
+ {
+ break;
+ }
+
++curproc;
}
}
+
+ if (l_errl)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR : call_proc_fab_iovalid encountered an error");
+ /*@
+ * @errortype
+ * @reasoncode ISTEP_EDI_EI_INITIALIZATION_FAILED
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid ISTEP_PROC_FAB_IOVALID
+ * @userdata1 bytes 0-1: plid identifying first error
+ * bytes 2-3: reason code of first error
+ * @userdata2 bytes 0-1: total number of elogs included
+ * bytes 2-3: N/A
+ * @devdesc call to proc_fab_iovalid has failed
+ */
+ l_StepError.addErrorDetails(ISTEP_EDI_EI_INITIALIZATION_FAILED,
+ ISTEP_PROC_FAB_IOVALID,
+ l_errl );
+
+ errlCommit( l_errl, HWPF_COMP_ID );
+
+ }
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_proc_fab_iovalid exit" );
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index 989f47979..f667220f3 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -36,16 +36,19 @@
#include <sys/misc.h>
#include <kernel/console.H>
#include <sys/task.h>
-#include <targeting/common/targetservice.H>
#include <vmmconst.h>
+#include <targeting/common/targetservice.H>
#include <targeting/common/attributes.H>
+#include <targeting/common/utilFilter.H>
#include <devicefw/userif.H>
#include <sys/time.h>
#include <sys/vfs.h>
+#include <hwas/common/hwasCallout.H>
#define INTR_TRACE_NAME INTR_COMP_NAME
using namespace INTR;
+using namespace TARGETING;
trace_desc_t * g_trac_intr = NULL;
TRAC_INIT(&g_trac_intr, INTR_TRACE_NAME, KILOBYTE, TRACE::BUFFER_SLOW);
@@ -161,6 +164,12 @@ errlHndl_t IntrRp::_init()
INITSERVICE::INTR_PRIORITY);
}
+ if(!err)
+ {
+ // Enable PSI to present interrupts
+ err = initIRSCReg(procTarget);
+ }
+
return err;
}
@@ -263,7 +272,7 @@ void IntrRp::msgHandler()
}
msg_free(rmsg);
}
- else if (type == INTERPROC)
+ else if (type == INTERPROC_XISR)
{
// Ignore "spurious" IPIs (handled below).
@@ -278,13 +287,13 @@ void IntrRp::msgHandler()
TRACFCOMP(g_trac_intr,ERR_MRK
"External Interrupt recieved type = %d, but "
"nothing registered to handle it. "
- "Ignoreing it.",
+ "Ignoring it.",
(uint32_t)type);
}
// Handle IPIs special since they're used for waking up
// cores and have special clearing requirements.
- if (type == INTERPROC)
+ if (type == INTERPROC_XISR)
{
// Clear IPI request.
volatile uint8_t * mfrr =
@@ -331,8 +340,15 @@ void IntrRp::msgHandler()
{
msg_q_t l_msgQ = reinterpret_cast<msg_q_t>(msg->data[0]);
uint64_t l_type = msg->data[1];
- ext_intr_t l_intr_type = static_cast<ext_intr_t>(l_type & 0xFFFF);
- errlHndl_t err = registerInterrupt(l_msgQ,l_type >> 32,l_intr_type);
+ ISNvalue_t l_intr_type = static_cast<ISNvalue_t>
+ (l_type & 0xFFFF);
+
+ errlHndl_t err = registerInterruptISN(l_msgQ,l_type >> 32,
+ l_intr_type);
+ if(!err)
+ {
+ err = initXIVR(l_intr_type, true);
+ }
msg->data[1] = reinterpret_cast<uint64_t>(err);
msg_respond(iv_msgQ,msg);
@@ -344,14 +360,18 @@ void IntrRp::msgHandler()
TRACFCOMP(g_trac_intr,
"INTR remove registration of interrupt type = 0x%lx",
msg->data[0]);
+ ISNvalue_t l_type = static_cast<ISNvalue_t>(msg->data[0]);
+ msg_q_t msgQ = unregisterInterruptISN(l_type);
- msg_q_t msgQ = NULL;
- ext_intr_t type = static_cast<ext_intr_t>(msg->data[0]);
- Registry_t::iterator r = iv_registry.find(type);
- if(r != iv_registry.end())
+ if(msgQ)
{
- msgQ = r->second.msgQ;
- iv_registry.erase(r);
+ //shouldn't get an error since we found a queue
+ //Just commit it
+ errlHndl_t err = initXIVR(l_type, false);
+ if(err)
+ {
+ errlCommit(err,INTR_COMP_ID);
+ }
}
msg->data[1] = reinterpret_cast<uint64_t>(msgQ);
@@ -405,6 +425,16 @@ void IntrRp::msgHandler()
}
break;
+ case MSG_INTR_ENABLE_PSI_INTR:
+ {
+ TARGETING::Target * target =
+ reinterpret_cast<TARGETING::Target *>(msg->data[0]);
+ errlHndl_t err = initIRSCReg(target);
+ msg->data[1] = reinterpret_cast<uint64_t>(err);
+ msg_respond(iv_msgQ,msg);
+ }
+ break;
+
case MSG_INTR_SHUTDOWN:
{
TRACFCOMP(g_trac_intr,"Shutdown event received");
@@ -454,47 +484,293 @@ errlHndl_t IntrRp::setBAR(TARGETING::Target * i_target,
}
+errlHndl_t IntrRp::initIRSCReg(TARGETING::Target * i_target)
+{
+ errlHndl_t err = NULL;
+
+ // Only do once for each proc chip
+ if(std::find(iv_chipList.begin(),iv_chipList.end(),i_target) ==
+ iv_chipList.end())
+ {
+ uint8_t chip = 0;
+ uint8_t node = 0;
+
+ i_target->tryGetAttr<ATTR_FABRIC_NODE_ID>(node);
+ i_target->tryGetAttr<ATTR_FABRIC_CHIP_ID>(chip);
+
+ size_t scom_len = sizeof(uint64_t);
+
+ // Setup PHBISR
+ // EN.TPC.PSIHB.PSIHB_ISRN_REG set to 0x00030003FFFF0000
+ PSIHB_ISRN_REG_t reg;
+
+ PIR_t pir(0);
+ pir.nodeId = node;
+ pir.chipId = chip;
+ // IRSN must be unique for each processor chip
+ reg.irsn = makeXISR(pir,0);
+ reg.die = PSIHB_ISRN_REG_t::ENABLE;
+ reg.uie = PSIHB_ISRN_REG_t::ENABLE;
+ reg.mask = PSIHB_ISRN_REG_t::IRSN_MASK;
+
+ TRACFCOMP(g_trac_intr,"PSIHB_ISRN_REG: 0x%016lx",reg.d64);
+
+ err = deviceWrite
+ ( i_target,
+ &reg,
+ scom_len,
+ DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_ISRN_REG));
+
+ if(err)
+ {
+ // add callout
+ err->addHwCallout(i_target,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ else
+ {
+ iv_chipList.push_back(i_target);
+ }
+ }
+
+ return err;
+}
-errlHndl_t IntrRp::registerInterrupt(msg_q_t i_msgQ,
+errlHndl_t IntrRp::initXIVR(enum ISNvalue_t i_isn, bool i_enable)
+{
+ errlHndl_t err = NULL;
+ size_t scom_len = sizeof(uint64_t);
+ uint64_t scom_addr = 0;
+
+ //Don't do any of this for ISN_INTERPROC
+ if(ISN_INTERPROC != i_isn)
+ {
+ //Setup the XIVR register
+ PsiHbXivr xivr;
+ PIR_t pir = intrDestCpuId();
+ xivr.pir = pir.word;
+ xivr.source = i_isn;
+
+ switch(i_isn)
+ {
+ case ISN_OCC:
+ xivr.priority = PsiHbXivr::OCC_PRIO;
+ scom_addr = PsiHbXivr::OCC_XIVR_ADRR;
+ break;
+
+ case ISN_FSI: //FSP_MAILBOX
+ xivr.priority = PsiHbXivr::FSI_PRIO;
+ scom_addr = PsiHbXivr::FSI_XIVR_ADRR;
+ break;
+
+ case ISN_LPC:
+ xivr.priority = PsiHbXivr::LPC_PRIO;
+ scom_addr = PsiHbXivr::LPC_XIVR_ADRR;
+ break;
+
+ case ISN_LCL_ERR:
+ xivr.priority = PsiHbXivr::LCL_ERR_PRIO;
+ scom_addr = PsiHbXivr::LCL_ERR_XIVR_ADDR;
+ break;
+
+ case ISN_HOST:
+ xivr.priority = PsiHbXivr::HOST_PRIO;
+ scom_addr = PsiHbXivr::HOST_XIVR_ADRR;
+ break;
+
+ default: //Unsupported ISN
+ TRACFCOMP(g_trac_intr,"Unsupported ISN: 0x%02x",i_isn);
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid INTR::MOD_INTR_INIT_XIVR
+ * @reasoncode INTR::RC_BAD_ISN
+ * @userdata1 Interrupt type to register
+ * @userdata2 0
+ *
+ * @defdesc Unsupported ISN Requested
+ *
+ */
+ err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
+ INTR::MOD_INTR_INIT_XIVR, // moduleid
+ INTR::RC_BAD_ISN, // reason code
+ static_cast<uint64_t>(i_isn),
+ 0
+ );
+ }
+
+ // Init the XIVR on all chips we have setup
+ // Note that this doesn't handle chips getting added midstream,
+ // But the current use case only has FSIMbox (1 chip) and
+ // ATTN (all chips) at stable points in the IPL
+ if(!err)
+ {
+ if(i_enable)
+ {
+ iv_isnList.push_back(i_isn);
+ }
+ else
+ {
+ xivr.priority = PsiHbXivr::PRIO_DISABLED;
+
+ //Remove from isn list
+ ISNList_t::iterator itr = std::find(iv_isnList.begin(),
+ iv_isnList.end(),
+ i_isn);
+ if(itr != iv_isnList.end())
+ {
+ iv_isnList.erase(itr);
+ }
+ }
+
+ for(ChipList_t::iterator target_itr = iv_chipList.begin();
+ target_itr != iv_chipList.end(); ++target_itr)
+ {
+ err = deviceWrite
+ (*target_itr,
+ &xivr,
+ scom_len,
+ DEVICE_SCOM_ADDRESS(scom_addr));
+
+ if(err)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return err;
+}
+
+
+
+errlHndl_t IntrRp::registerInterruptISN(msg_q_t i_msgQ,
uint32_t i_msg_type,
ext_intr_t i_intr_type)
{
errlHndl_t err = NULL;
- Registry_t::iterator r = iv_registry.find(i_intr_type);
+ //INTERPROC is special -- same for all procs
+ if(i_intr_type == ISN_INTERPROC)
+ {
+ err = registerInterruptXISR(i_msgQ, i_msg_type,
+ INTERPROC_XISR);
+ }
+ else
+ {
+ //Register interrupt type on all present procs
+ for(ChipList_t::iterator target_itr = iv_chipList.begin();
+ target_itr != iv_chipList.end(); ++target_itr)
+ {
+ uint8_t chip = 0;
+ uint8_t node = 0;
+ (*target_itr)->tryGetAttr<ATTR_FABRIC_NODE_ID>(node);
+ (*target_itr)->tryGetAttr<ATTR_FABRIC_CHIP_ID>(chip);
+
+ PIR_t pir(0);
+ pir.nodeId = node;
+ pir.chipId = chip;
+ uint32_t l_irsn = makeXISR(pir, i_intr_type);
+
+ err = registerInterruptXISR(i_msgQ, i_msg_type, l_irsn);
+ if(err)
+ {
+ break;
+ }
+ }
+ }
+ return err;
+}
+
+errlHndl_t IntrRp::registerInterruptXISR(msg_q_t i_msgQ,
+ uint32_t i_msg_type,
+ ext_intr_t i_xisr)
+{
+ errlHndl_t err = NULL;
+
+ Registry_t::iterator r = iv_registry.find(i_xisr);
if(r == iv_registry.end())
{
- TRACFCOMP(g_trac_intr,"INTR::register intr type 0x%x", i_intr_type);
- iv_registry[i_intr_type] = intr_response_t(i_msgQ,i_msg_type);
+ TRACFCOMP(g_trac_intr,"INTR::register intr type 0x%x", i_xisr);
+ iv_registry[i_xisr] = intr_response_t(i_msgQ,i_msg_type);
}
else
{
if(r->second.msgQ != i_msgQ)
{
- /*@ errorlog tag
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid INTR::MOD_INTRRP_REGISTERINTERRUPT
- * @reasoncode INTR::RC_ALREADY_REGISTERED
- * @userdata1 Interrupt type
- * @userdata2 0
- *
- * @defdesc Interrupt type already registered
- *
- */
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid INTR::MOD_INTRRP_REGISTERINTERRUPT
+ * @reasoncode INTR::RC_ALREADY_REGISTERED
+ * @userdata1 XISR
+ * @userdata2 0
+ *
+ * @defdesc Interrupt type already registered
+ *
+ */
err = new ERRORLOG::ErrlEntry
- (
- ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
- INTR::MOD_INTRRP_REGISTERINTERRUPT, // moduleid
- INTR::RC_ALREADY_REGISTERED, // reason code
- i_intr_type,
- 0
- );
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
+ INTR::MOD_INTRRP_REGISTERINTERRUPT, // moduleid
+ INTR::RC_ALREADY_REGISTERED, // reason code
+ i_xisr,
+ 0
+ );
}
-
}
return err;
}
+msg_q_t IntrRp::unregisterInterruptISN(ISNvalue_t i_intr_type)
+{
+ msg_q_t msgQ = NULL;
+
+ //INTERPROC is special -- same for all procs
+ if(i_intr_type == ISN_INTERPROC)
+ {
+ msgQ = unregisterInterruptXISR(INTERPROC_XISR);
+ }
+ else
+ {
+ //Unregister interrupt type on all present procs
+ for(ChipList_t::iterator target_itr = iv_chipList.begin();
+ target_itr != iv_chipList.end(); ++target_itr)
+ {
+ uint8_t chip = 0;
+ uint8_t node = 0;
+ (*target_itr)->tryGetAttr<ATTR_FABRIC_NODE_ID>(node);
+ (*target_itr)->tryGetAttr<ATTR_FABRIC_CHIP_ID>(chip);
+
+ PIR_t pir(0);
+ pir.nodeId = node;
+ pir.chipId = chip;
+ uint32_t l_irsn = makeXISR(pir, i_intr_type);
+
+ msgQ = unregisterInterruptXISR(l_irsn);
+ }
+ }
+
+ return msgQ;
+}
+
+msg_q_t IntrRp::unregisterInterruptXISR(ext_intr_t i_xisr)
+{
+ msg_q_t msgQ = NULL;
+
+ Registry_t::iterator r = iv_registry.find(i_xisr);
+ if(r != iv_registry.end())
+ {
+ msgQ = r->second.msgQ;
+ iv_registry.erase(r);
+ }
+
+ return msgQ;
+}
+
void IntrRp::initInterruptPresenter(const PIR_t i_pir) const
{
uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(i_pir);
@@ -621,6 +897,7 @@ errlHndl_t IntrRp::checkAddress(uint64_t i_addr)
void IntrRp::shutDown()
{
+ errlHndl_t err = NULL;
msg_t * rmsg = msg_allocate();
// Call everyone and say shutting down!
@@ -647,7 +924,49 @@ void IntrRp::shutDown()
msg_free(rmsg);
- // Reset the hardware regiseters
+ // Reset the PSI regs
+ // NOTE: there is nothing in the IRSN Proposal.odt document that
+ // specifies a procedure or order for disabling interrupts.
+ // @see RTC story 47105 discussion for Firmware & Hardware requirements
+ //
+
+ //Going to clear the XIVRs first
+ ISNList_t l_isnList = iv_isnList;
+ for(ISNList_t::iterator isnItr = l_isnList.begin();
+ isnItr != l_isnList.end();++isnItr)
+ {
+ //shouldn't get an error since we found a queue
+ //so just commit it
+ err = initXIVR((*isnItr), false);
+ if(err)
+ {
+ errlCommit(err,INTR_COMP_ID);
+ err = NULL;
+ }
+ }
+
+ // TODO secure boot - how do we know a processor chip has been added?
+ PSIHB_ISRN_REG_t reg; //zeros self
+ size_t scom_len = sizeof(reg);
+
+ for(ChipList_t::iterator target_itr = iv_chipList.begin();
+ target_itr != iv_chipList.end(); ++target_itr)
+ {
+ err = deviceWrite
+ (*target_itr,
+ &reg,
+ scom_len,
+ DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_ISRN_REG));
+
+ if(err)
+ {
+ errlCommit(err,INTR_COMP_ID);
+ err = NULL;
+ }
+ }
+
+
+ // Reset the IP hardware regiseters
iv_cpuList.push_back(iv_masterCpu);
@@ -839,8 +1158,43 @@ errlHndl_t INTR::disableExternalInterrupts()
return err;
}
-uint32_t INTR::intrDestCpuId(uint32_t i_xisr)
+errlHndl_t INTR::enablePsiIntr(TARGETING::Target * i_target)
{
- return Singleton<IntrRp>::instance().intrDestCpuId(i_xisr);
+ errlHndl_t err = NULL;
+ msg_q_t intr_msgQ = msg_q_resolve(VFS_ROOT_MSG_INTR);
+ if(intr_msgQ)
+ {
+ msg_t * msg = msg_allocate();
+ msg->type = MSG_INTR_ENABLE_PSI_INTR;
+ msg->data[0] = reinterpret_cast<uint64_t>(i_target);
+
+ msg_sendrecv(intr_msgQ, msg);
+
+ err = reinterpret_cast<errlHndl_t>(msg->data[1]);
+ msg_free(msg);
+ }
+ else
+ {
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid INTR::MOD_INTR_ENABLE_PSI_INTR
+ * @reasoncode INTR::RC_RP_NOT_INITIALIZED
+ * @userdata1 MSG_INTR_ENABLE_PSI_INTR
+ * @userdata2 0
+ *
+ * @defdesc Interrupt resource provider not initialized yet.
+ *
+ */
+ err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
+ INTR::MOD_INTR_ENABLE_PSI_INTR, // moduleid
+ INTR::RC_RP_NOT_INITIALIZED, // reason code
+ static_cast<uint64_t>(MSG_INTR_ENABLE_PSI_INTR),
+ 0
+ );
+ }
+ return err;
}
+
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index d8c01208b..ad13c1679 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -31,6 +31,7 @@
#include <sys/misc.h>
#include <intr/interrupt.H>
#include <map>
+#include <algorithm>
struct msg_t;
@@ -41,6 +42,57 @@ namespace TARGETING
namespace INTR
{
+ /**
+ * cpu PIR register
+ */
+ struct PIR_t
+ {
+ union
+ {
+ uint32_t word;
+ struct
+ {
+ //P8:
+ uint32_t reserved:19; //!< zeros
+ uint32_t nodeId:3; //!< node (0-3)
+ uint32_t chipId:3; //!< chip pos on node (0-5)
+ uint32_t coreId:4; //!< Core number (1-6,9-14)?
+ uint32_t threadId:3; //!< Thread number (0-7)
+ } PACKED;
+ };
+ PIR_t(uint32_t i_word) : word(i_word) {}
+
+ PIR_t operator= (uint32_t i_word)
+ {
+ word = i_word;
+ return word;
+ }
+
+ bool operator< (const PIR_t& r) const
+ {
+ return word < r.word;
+ }
+ };
+
+ /**
+ * Make an XISR value
+ * @param[in] i_node The PIR node id (0-7)
+ * @param[in] i_chip The PIR chip id (0-7)
+ * @param[in] i_isn The Interrupt Source Number (0-7)
+ * @return the XISR value
+ */
+ inline
+ uint32_t makeXISR(PIR_t i_pir, uint32_t i_isn)
+ {
+ XISR_t r;
+ r.u32 = 0;
+ r.isn = i_isn;
+ r.chip = i_pir.chipId;
+ r.node = i_pir.nodeId;
+ r.intrproc = 1; // not interproc intr
+ return r.u32;
+ }
+
class IntrRp
{
public:
@@ -53,9 +105,10 @@ namespace INTR
/**
* Get the CPU id of the master cpu.
+ * @return cpu id of the master cpu
*/
ALWAYS_INLINE
- uint32_t intrDestCpuId(uint32_t i_xisr) const { return iv_masterCpu.word; }
+ PIR_t intrDestCpuId() const { return iv_masterCpu; }
protected:
@@ -81,21 +134,21 @@ namespace INTR
enum
{
- XIRR_RO_OFFSET = 0, //!< offset to XIRR (poll)
- CPPR_OFFSET = 4, //!< offset to CPPR (1 byte)
- XIRR_OFFSET = 4, //!< offset to XIRR (4 bytes)
- MFRR_OFFSET = 12, //!< offset to MFRR (12 bytes)
- LINKA_OFFSET = 16, //!< offset to LINKA register
- LINKB_OFFSET = 20, //!< offset to LINKB register
- LINKC_OFFSET = 24, //!< offset to LINKC register
- XISR_MASK = 0x00FFFFFF, //!< XISR MASK in XIRR register
+ XIRR_RO_OFFSET = 0, //!< offset to XIRR (poll)
+ CPPR_OFFSET = 4, //!< offset to CPPR (1 byte)
+ XIRR_OFFSET = 4, //!< offset to XIRR (4 bytes)
+ MFRR_OFFSET = 12, //!< offset to MFRR (12 bytes)
+ LINKA_OFFSET = 16, //!< offset to LINKA register
+ LINKB_OFFSET = 20, //!< offset to LINKB register
+ LINKC_OFFSET = 24, //!< offset to LINKC register
+ XISR_MASK = 0x00FFFFFF, //!< XISR MASK in XIRR register
ICPBAR_EN = 30, //!< BAR enable bit pos
ICPBAR_SCOM_ADDR = 0x020109ca, //!< ICP BAR scom address
// MASK base ICP address
ICPBAR_BASE_ADDRESS_MASK = 0xFFFFFFFFFC000000ULL,
- };
+ };
// If the interrupt can't be handled by the current chip there are
// three link registers used provide targets to forward the
@@ -136,37 +189,85 @@ namespace INTR
};
/**
- * cpu PIR register
+ * This is the Interrupt Requestoer Source Compare Register.
+ * See Book IV, PSI chapter.
*/
- struct PIR_t
+ struct PSIHB_ISRN_REG_t
{
+ enum
+ {
+ //PSIHB_ISRN_REG_t values. See book IV & P8 scom reg defn.
+ DISABLE = 0,
+ ENABLE = 1,
+ IRSN_MASK = 0x7FFF8, //!< IRSN bits
+ PSIHB_ISRN_REG = 0x0201091b, //!< ISRN SCOM Address
+ };
+
union
{
- uint32_t word;
+ uint64_t d64;
+
struct
{
- //P8:
- uint32_t reserved:19; //!< zeros
- uint32_t nodeId:3; //!< node (0-3)
- uint32_t chipId:3; //!< chip pos on node (0-5)
- uint32_t coreId:4; //!< Core number (1-6,9-14)?
- uint32_t threadId:3; //!< Thread number (0-7)
+ uint64_t irsn:19; //!< IRSN compare reg
+ uint64_t res1:10; //!< zeros
+ uint64_t reset:1; //!< ICS Reset
+ uint64_t die:1; //!< Downstream Interrupt Enable
+ uint64_t uie:1; //!< Upstream Interrupt Enable
+ uint64_t mask:19; //!< IRSN Compare Mask
+ uint64_t res2:13; //!< zeros
} PACKED;
};
- PIR_t(uint32_t i_word) : word(i_word) {}
- PIR_t operator= (uint32_t i_word)
+ /**
+ * Default Contructor
+ */
+ PSIHB_ISRN_REG_t() : d64(0) {}
+ };
+
+ /**
+ * @brief PsiHbXivr Layout for XIVR registers.
+ */
+ struct PsiHbXivr
+ {
+ enum
{
- word = i_word;
- return word;
- }
+ PRIO_DISABLED = 0xff,
+
+ OCC_PRIO = 0x30,
+ FSI_PRIO = 0x20,
+ LPC_PRIO = 0x40,
+ LCL_ERR_PRIO = 0x10,
+ HOST_PRIO = 0x50,
+
+ OCC_XIVR_ADRR = 0x02010916,
+ FSI_XIVR_ADRR = 0x02010917,
+ LPC_XIVR_ADRR = 0x02010918,
+ LCL_ERR_XIVR_ADDR = 0x02010919,
+ HOST_XIVR_ADRR = 0x0201091A,
+ };
- bool operator< (const PIR_t& r) const
+
+ union
{
- return word < r.word;
- }
+ uint64_t u64;
+
+ struct
+ {
+ uint64_t res1:8; // zeros
+ uint64_t pir:14; // interrupt destination (server)
+ uint64_t linkptr:2; // which link reg in intr presenter
+ uint64_t priority:8; // intr priority level
+ uint64_t source:3; // source number
+ uint64_t res2:4; // zeros
+ uint64_t intr_pend:25; // interrupt is pending
+ } PACKED;
+ };
+
+ PsiHbXivr() : u64(0) {}
};
+
struct intr_response_t
{
msg_q_t msgQ;
@@ -187,9 +288,10 @@ namespace INTR
};
-
typedef std::map<ext_intr_t,intr_response_t> Registry_t;
typedef std::vector<PIR_t> CpuList_t;
+ typedef std::vector<TARGETING::Target *> ChipList_t;
+ typedef std::vector<ISNvalue_t> ISNList_t;
msg_q_t iv_msgQ; //!< Kernel Interrupt message queue
@@ -197,6 +299,8 @@ namespace INTR
uint64_t iv_baseAddr; //!< Base address of hw INTR regs
PIR_t iv_masterCpu; //!< Master cpu PIR
CpuList_t iv_cpuList; //!< Other CPU chips
+ ChipList_t iv_chipList; //!< Proc chips with PSI intr enabled
+ ISNList_t iv_isnList; //!< List of ISN's to clear on shutdown
typedef std::pair<uint8_t, msg_t*> IPI_Info_t;
typedef std::map<PIR_t, IPI_Info_t> IPI_Pending_t;
@@ -220,8 +324,8 @@ namespace INTR
* i_intr_type occurrs.
* @param[in] i_intr_type, The interrupt type to register.
*
- * @note the interrupt type is currently the XISR value in the XIRR
- * register and consists of the chipid, buid, and level
+ * @note the interrupt type is currently the ISN value in the XIVR
+ * register. and consists of the chipid, buid, and level
* @see src/include/usr/intr/interrupt.H i_intr_type for
* enumerations.
*
@@ -230,9 +334,28 @@ namespace INTR
* i_msgQ with i_intr_type in message data word 0 and then waits
* for a response.
*/
- errlHndl_t registerInterrupt(msg_q_t i_msgQ,
+ errlHndl_t registerInterruptISN(msg_q_t i_msgQ,
uint32_t i_msg_type,
ext_intr_t i_intr_type);
+ /* Same as above, but operates directly on XISR*/
+ errlHndl_t registerInterruptXISR(msg_q_t i_msgQ,
+ uint32_t i_msg_type,
+ ext_intr_t i_xisr);
+
+ /**
+ * Unregister for a given interrupt type
+ * @param[in] i_isn_type The type of interrupt to unregister
+ *
+ * @note the interrupt type is currently the ISN value in the PSIHB
+ * XIVR register
+ * @see i_intr_type for enumerations.
+ *
+ * @return The message queue that was unregistered with i_type
+ * | NULL if no queue was not found for i_type
+ */
+ msg_q_t unregisterInterruptISN(ISNvalue_t i_intr_type);
+ /*Same as above, but operates on XISR*/
+ msg_q_t unregisterInterruptXISR(ext_intr_t i_xisr);
/**
* Enable hardware to reporting external interrupts
@@ -271,6 +394,22 @@ namespace INTR
const PIR_t i_pir);
/**
+ * Initialize the IRSCReg to enable PSI to present interrupts
+ * @param[in] i_target The target processor
+ * @return error log handle on error
+ */
+ errlHndl_t initIRSCReg(TARGETING::Target * i_target);
+
+ /**
+ * Initialize the PSIHB XIVR Reg to generate interrupts
+ * on all processors for given ISN
+ * @param[in] i_isn XIVR to enable/disable
+ * @param[in] i_enable enable (true), disable(false)
+ * @return error log handle on error
+ */
+ errlHndl_t initXIVR(enum ISNvalue_t i_isn, bool i_enable);
+
+ /**
* Shutdown procedure
*/
void shutDown();
@@ -280,7 +419,7 @@ namespace INTR
* @param[in] i_pir PIR value for the presenter
* @return the offset
*/
- ALWAYS_INLINE
+ ALWAYS_INLINE
uint64_t cpuOffsetAddr(const PIR_t i_pir) const
{
// TODO when P7 support is removed then change this
diff --git a/src/usr/intr/test/intrtest.H b/src/usr/intr/test/intrtest.H
index 93c2d235a..c12835d77 100644
--- a/src/usr/intr/test/intrtest.H
+++ b/src/usr/intr/test/intrtest.H
@@ -1,25 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/intr/test/intrtest.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// 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
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/intr/test/intrtest.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2011,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 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 __INTRTEST_H
#define __INTRTEST_H
@@ -139,7 +139,7 @@ class IntrTest: public CxxTest::TestSuite
// Need to register a msgq
msg_q_t msgQ = msg_q_create();
- err = INTR::registerMsgQ(msgQ,0,INTR::INTERPROC);
+ err = INTR::registerMsgQ(msgQ,0,INTR::ISN_INTERPROC);
if(err)
{
TS_FAIL("Errl from INTR::registerMsgQ()");
@@ -151,16 +151,17 @@ class IntrTest: public CxxTest::TestSuite
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)
+ 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::INTERPROC);
+ msgQ = INTR::unRegisterMsgQ(INTR::ISN_INTERPROC);
if(msgQ)
{
msg_q_destroy(msgQ);
@@ -171,6 +172,29 @@ class IntrTest: public CxxTest::TestSuite
}
}
+ // 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
+ // to test with.
+ void test_enablePsi( void )
+ {
+ errlHndl_t err = NULL;
+ if( TARGETING::is_vpo() )
+ {
+ return;
+ }
+
+ TARGETING::Target* target = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle( target );
+
+ err = INTR::enablePsiIntr(target);
+ if(err)
+ {
+ TS_FAIL("Errl from INTER::enablePsiIntr");
+ errlCommit(err,INTR_COMP_ID);
+ }
+ }
+
IntrTest() : CxxTest::TestSuite()
{
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index 90e479dea..8688c43a5 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -146,7 +146,9 @@ errlHndl_t MailboxSp::_init()
}
// Register to get interrupts for mailbox
- err = INTR::registerMsgQ(iv_msgQ, MSG_INTR, INTR::FSP_MAILBOX);
+ err = INTR::registerMsgQ(iv_msgQ,
+ MSG_INTR,
+ INTR::FSP_MAILBOX);
if(err)
{
return err;
diff --git a/src/usr/mbox/mboxdd.C b/src/usr/mbox/mboxdd.C
index e78b03c90..0be70fec9 100644
--- a/src/usr/mbox/mboxdd.C
+++ b/src/usr/mbox/mboxdd.C
@@ -599,63 +599,19 @@ errlHndl_t mboxInit(TARGETING::Target* i_target)
errlHndl_t err = NULL;
size_t scom_len = sizeof(uint64_t);
- // Setup PHBISR
- // EN.TPC.PSIHB.PSIHB_INTERRUPT2_REG set to 0x0000A00140000000
- // EN.TPC.PSIHB.PSIHB_ISRN_REG set to 0x00030003FFFF0000
- PSIHB_ISRN_REG_t reg;
-
- reg.irsn = IRSN_INIT;
- reg.die = ENABLE;
- reg.uie = ENABLE;
- reg.mask = IRSN_MASK; // 6 left bits are hardcoded in hardware to '1'
-
- TRACFCOMP(g_trac_mbox,"PSIHB_ISRN_REG: 0x%016lx",reg.d64);
-
- err = deviceOp(DeviceFW::WRITE,
- i_target,
- reinterpret_cast<void*>(&reg),
- scom_len,
- DEVICE_XSCOM_ADDRESS(PSIHB_ISRN_REG));
-
- if(!err)
- {
- PSIHB_INTERRUPT2_REG_t reg;
-
- // Whichever cpu core inits the mboxdd should be the desired cpu
- reg.pir = INTR::intrDestCpuId(IRSN_INIT | IRSN_SOURCE);
- reg.priority = 2; // could be 1 - 0xfe, 0xff means off
-
- // The source gets OR'd with the irsn to form the interrupt presenter
- // type (XISR) (e.g. 0x1A)
- reg.source = IRSN_SOURCE;
-
- TRACFCOMP(g_trac_mbox,"PSIHB_INTERRUPT2_REG: 0x%016lx",reg.d64);
-
- err = deviceOp(DeviceFW::WRITE,
- i_target,
- reinterpret_cast<void*>(&reg),
- scom_len,
- DEVICE_XSCOM_ADDRESS(PSIHB_INTERRUPT2_REG));
- }
-
// Setup mailbox intr mask reg
// Set bits 2,1,0
// assume we always use mailbox 1
- if(!err)
- {
- 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;
-
- err = deviceOp(DeviceFW::WRITE,
- i_target,
- reinterpret_cast<void*>(&scom_data),
- scom_len,
- DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RS));
- }
+ 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;
+ err = deviceOp(DeviceFW::WRITE,
+ i_target,
+ reinterpret_cast<void*>(&scom_data),
+ scom_len,
+ 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 f8e157fee..a3eb37b28 100644
--- a/src/usr/mbox/mboxdd.H
+++ b/src/usr/mbox/mboxdd.H
@@ -170,67 +170,6 @@ namespace MBOX
MBOX_DATA_LBUS_SLAVE_B =0x000000FF, // Data Count LBUS Slave B
}; // Doorbell 1
- // PHBISR - PSI Host Bridget Interrupt Service Registers
- enum EN_TCP_PSIHB
- {
- DISABLE = 0,
- ENABLE = 1,
- IRSN_SOURCE = 2, //!<< IRSN_SOURCE gets OR'd with
- IRSN_INIT = 0x18, //!<< IRSN_INIT to form XISR(0x1A)
- IRSN_MASK = 0x7FFF8,
- PSIHB_INTERRUPT2_REG = 0x02010917,
- PSIHB_ISRN_REG = 0x0201091b,
- };
-
- struct PSIHB_INTERRUPT2_REG_t
- {
- union
- {
- uint64_t d64;
-
- struct
- {
- uint64_t res1:8; //!< zeros
- uint64_t pir:14; //!< Interrupt destination (server)
- uint64_t linkptr:2; //!< Which link reg in intr presenter
- uint64_t priority:8; //!< INTR priority level
- uint64_t source:3; //!< Source number (Default b010)
- uint64_t res2:4; //!< zeros
- uint64_t intr_pend:25; //!< Interrupt is pending
- } PACKED;
- };
-
- /**
- * Default contructor
- */
- PSIHB_INTERRUPT2_REG_t() : d64(0) {}
- };
-
- struct PSIHB_ISRN_REG_t
- {
- union
- {
- uint64_t d64;
-
- struct
- {
- uint64_t irsn:19; //!< IRSN compare reg
- uint64_t res1:10; //!< zeros
- uint64_t reset:1; //!< ICS Reset
- uint64_t die:1; //!< Downstream Interrupt Enable
- uint64_t uie:1; //!< Upstream Interrupt Enable
- uint64_t mask:19; //!< IRSN Compare Mask
- uint64_t res2:13; //!< zeros
- } PACKED;
- };
-
- /**
- * Default Contructor
- */
- PSIHB_ISRN_REG_t() : d64(0) {}
- };
-
-
}; // namespace MBOX
#endif
OpenPOWER on IntegriCloud