summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Sanner <dsanner@us.ibm.com>2013-11-10 13:00:35 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-11-11 15:30:11 -0600
commit1fcebca1ba2e9f8bd21811d9fa6167a2e590fe59 (patch)
tree4d0c102bbd42442af1b3e4ad106aaad479d4693b
parentc2f709814c7b031e09c0aba66a201f0d63698674 (diff)
downloadtalos-hostboot-1fcebca1ba2e9f8bd21811d9fa6167a2e590fe59.tar.gz
talos-hostboot-1fcebca1ba2e9f8bd21811d9fa6167a2e590fe59.zip
Determine MPIPL EOIs emperically
Change-Id: I78c7ed630b2f23c6bd243f94b061bad9aaf47510 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/7149 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/usr/intr/intrrp.C65
-rw-r--r--src/usr/intr/intrrp.H14
2 files changed, 51 insertions, 28 deletions
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index 675d08fae..4f11b53f4 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -662,7 +662,8 @@ errlHndl_t IntrRp::setBAR(TARGETING::Target * i_target,
return err;
}
-errlHndl_t IntrRp::getPsiIRSN(TARGETING::Target * i_target, uint32_t& o_irsn)
+errlHndl_t IntrRp::getPsiIRSN(TARGETING::Target * i_target,
+ uint32_t& o_irsn, uint32_t& o_num)
{
errlHndl_t err = NULL;
@@ -670,6 +671,7 @@ errlHndl_t IntrRp::getPsiIRSN(TARGETING::Target * i_target, uint32_t& o_irsn)
// EN.TPC.PSIHB.PSIHB_ISRN_REG set to 0x00030003FFFF0000
PSIHB_ISRN_REG_t reg;
size_t scom_len = sizeof(uint64_t);
+ o_num = ISN_HOST; //Hardcoded based on HB knowledge of HW
do{
err = deviceRead
@@ -692,7 +694,8 @@ errlHndl_t IntrRp::getPsiIRSN(TARGETING::Target * i_target, uint32_t& o_irsn)
return err;
}
-errlHndl_t IntrRp::getNxIRSN(TARGETING::Target * i_target, uint32_t& o_irsn)
+errlHndl_t IntrRp::getNxIRSN(TARGETING::Target * i_target,
+ uint32_t& o_irsn, uint32_t& o_num)
{
errlHndl_t err = NULL;
@@ -711,21 +714,28 @@ errlHndl_t IntrRp::getNxIRSN(TARGETING::Target * i_target, uint32_t& o_irsn)
break;
}
+ uint32_t l_mask = ((static_cast<uint32_t>(reg >> NX_IRSN_MASK_SHIFT)
+ & NX_IRSN_MASK_MASK) | NX_IRSN_UPPER_MASK);
+
o_irsn = ((static_cast<uint32_t>(reg >> NX_IRSN_COMP_SHIFT)
- & NX_IRSN_COMP_MASK) &
- ((static_cast<uint32_t>(reg >> NX_IRSN_MASK_SHIFT)
- & NX_IRSN_MASK_MASK) | NX_IRSN_UPPER_MASK));
+ & IRSN_COMP_MASK) & l_mask);
+
+ //To get the number of interrupts, we need to "count" the 0 bits
+ //cheat by extending mask to FFF8 + mask, then invert and add 1
+ o_num = (~((~IRSN_COMP_MASK) | l_mask)) +1;
+
}while(0);
- TRACFCOMP(g_trac_intr,"NX_ISRN: 0x%x",o_irsn);
+ TRACFCOMP(g_trac_intr,"NX_ISRN: 0x%x, num: 0x%x",o_irsn, o_num);
return err;
}
errlHndl_t IntrRp::getPcieIRSNs(TARGETING::Target * i_target,
- std::vector<uint32_t> &o_irsn)
+ std::vector<uint32_t> &o_irsn,
+ std::vector<uint32_t> &o_num)
{
errlHndl_t err = NULL;
o_irsn.clear();
@@ -770,14 +780,21 @@ errlHndl_t IntrRp::getPcieIRSNs(TARGETING::Target * i_target,
}
uint64_t l_irsn64 = reg & mask;
- reg >>= PE_IRSN_SHIFT;
- mask >>=PE_IRSN_SHIFT;
l_irsn64 >>=PE_IRSN_SHIFT;
uint32_t l_irsn = l_irsn64;
- TRACFCOMP(g_trac_intr,"PE_ISRN[0x%08x] PE%d ", l_irsn, i);
+
+ //To get the number of interrupts, we need to "count" the 0 bits
+ //cheat by extending mask to FFF8 + mask, then invert and add 1
+ mask >>=PE_IRSN_SHIFT;
+ uint32_t l_intNum = mask;
+ l_intNum = (~((~IRSN_COMP_MASK) | l_intNum)) +1;
+
+ TRACFCOMP(g_trac_intr,"PE_ISRN[0x%08x] PE%d intNum: 0x%x ",
+ l_irsn, i, l_intNum);
if(l_irsn != 0x0)
{
o_irsn.push_back(l_irsn);
+ o_num.push_back(l_intNum);
}
}
if(err)
@@ -1462,8 +1479,10 @@ errlHndl_t IntrRp::hw_disableRouting(TARGETING::Target * i_proc,
//NX has no up/down stream enable bit - just one enable bit.
//The NX should be cleared as part of an MPIPL so no
- //interrupts should be pending from this unit.
- if(i_rx_tx == INTR_UPSTREAM)
+ //interrupts should be pending from this unit, however
+ //we must allow EOIs to flow, so only disable when
+ //downstream is requested
+ if(i_rx_tx == INTR_DOWNSTREAM)
{
uint64_t reg = 0;
scom_len = sizeof(uint64_t);
@@ -1638,7 +1657,8 @@ errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
//Issue eio to PSI logic
uint32_t l_psiBaseIsn;
- err = getPsiIRSN(i_proc, l_psiBaseIsn);
+ uint32_t l_maxInt = 0;
+ err = getPsiIRSN(i_proc, l_psiBaseIsn, l_maxInt);
if(err)
{
break;
@@ -1648,7 +1668,7 @@ errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
if(l_psiBaseIsn)
{
l_psiBaseIsn |= 0xFF000000;
- uint32_t l_psiMaxIsn = l_psiBaseIsn + ISN_HOST;
+ uint32_t l_psiMaxIsn = l_psiBaseIsn + l_maxInt;
TRACFCOMP(g_trac_intr,"Issuing EOI to PSIHB range %x - %x",
l_psiBaseIsn, l_psiMaxIsn);
@@ -1663,19 +1683,18 @@ errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
//Issue EIOs to PE (PCIE) ISN
std::vector<uint32_t> l_peIsn;
- err = getPcieIRSNs(i_proc, l_peIsn);
+ std::vector<uint32_t> l_peIntNum;
+ err = getPcieIRSNs(i_proc, l_peIsn, l_peIntNum);
if(err)
{
break;
}
- for(std::vector<uint32_t>::iterator peIsn = l_peIsn.begin();
- peIsn != l_peIsn.end();
- ++peIsn)
+ for(uint32_t i = 0; i < l_peIsn.size(); i++)
{
//now need to issue on all SN up to 2048
- uint32_t l_peBaseIsn = (*peIsn) | 0xFF000000;
- uint32_t l_peMaxIsn = l_peBaseIsn + MAX_PE_IRSN_SN;
+ uint32_t l_peBaseIsn = l_peIsn[i] | 0xFF000000;
+ uint32_t l_peMaxIsn = l_peBaseIsn + l_peIntNum[i];
TRACFCOMP(g_trac_intr,"Issuing EOI to PCIE range %x - %x",
l_peBaseIsn, l_peMaxIsn);
@@ -1687,7 +1706,7 @@ errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
//Issue eio to NX logic
uint32_t l_nxBaseIsn;
- err = getNxIRSN(i_proc, l_nxBaseIsn);
+ err = getNxIRSN(i_proc, l_nxBaseIsn, l_maxInt);
if(err)
{
break;
@@ -1697,8 +1716,8 @@ errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
if(l_nxBaseIsn)
{
l_nxBaseIsn |= 0xFF000000;
- uint32_t l_nxMaxIsn = l_nxBaseIsn + MAX_NX_IRSN_SN;
- TRACFCOMP(g_trac_intr,"Issuing EOI to NX range % - %x",
+ uint32_t l_nxMaxIsn = l_nxBaseIsn + l_maxInt;
+ TRACFCOMP(g_trac_intr,"Issuing EOI to NX range %x - %x",
l_nxBaseIsn, l_nxMaxIsn);
for(uint32_t l_isn = l_nxBaseIsn; l_isn < l_nxMaxIsn; ++l_isn)
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index e2495fb27..1c03e3d19 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -124,12 +124,11 @@ namespace INTR
// Used to enable/disable and control interrupt routing
NX_BUID_SCOM_ADDR = 0x0201308E, //INTR CTRL for NX
NX_BUID_ENABLE = 0, //INTR Enable bit for NX
- NX_IRSN_COMP_MASK = 0x7FFFF,
+ IRSN_COMP_MASK = 0x7FFFF,
NX_IRSN_MASK_MASK = 0x1FFF,
NX_IRSN_UPPER_MASK = 0x7E000,
NX_IRSN_COMP_SHIFT = 44,
NX_IRSN_MASK_SHIFT = 31,
- MAX_NX_IRSN_SN = 32,
@@ -482,30 +481,35 @@ namespace INTR
*
* @param i_target Processor target to read value from
* @param o_irsn IRSN of the PSI unit for the processor
+ * @param o_num Number of interrupts behind IRSN
* @return an error handle on error
*/
errlHndl_t getPsiIRSN(TARGETING::Target * i_target,
- uint32_t& o_irsn);
+ uint32_t& o_irsn, uint32_t& o_num);
/**
* Read the PCIE interrupt source numbers out of the HW
*
* @param i_target Processor target to read value from
* @param o_irsn List of IRSN for the PCIE units
+ * @param o_num Number of interrupts behind IRSN
* @return an error handle on error
*/
errlHndl_t getPcieIRSNs(TARGETING::Target * i_target,
- std::vector<uint32_t> &o_irsn);
+ std::vector<uint32_t> &o_irsn,
+ std::vector<uint32_t> &o_num);
/**
* Read the NX interrupt source number out of the HW
*
* @param i_target Processor target to read value from
* @param o_irsn IRSN of the NX unit for the processor
+ * @param o_num Number of interrupts behind IRSN
* @return an error handle on error
*/
errlHndl_t getNxIRSN(TARGETING::Target * i_target,
- uint32_t& o_irsn);
+ uint32_t& o_irsn,
+ uint32_t& o_num);
/**
OpenPOWER on IntegriCloud