summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/usr/intr/intrrp.C47
-rw-r--r--src/usr/intr/intrrp.H14
2 files changed, 38 insertions, 23 deletions
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index a7ebde8d5..c00f942e8 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -133,20 +133,10 @@ errlHndl_t IntrRp::resetIntpForMpipl()
TRACFCOMP(g_trac_intr,
"IntrRp::resetIntpForMpipl() Synchronize multi-node interrupt enablement");
- // MPIPL Step 1 -- Set the Interrupt LSI state machine to disabled
- for (uint64_t i = 0; i < LSI_LAST_SOURCE; i++)
- {
- err = sendPsiHbEOI(iv_masterHdlr, i);
- if (err)
- {
- TRACFCOMP(g_trac_intr,
- "IntrRp::resetIntpForMpipl() Error sending PsiHbEOI for int source: %d", i);
- break;
- }
- }
-
- if (err)
- { break; }
+ // MPIPL Step 1 -- Set the ESB State to Off (0x1) for the LSI SB
+ // EOI Page This is the 4th page in the IC_BAR. View the P9
+ // Interrupt Workbook section 5.1 to find info on this page
+ disableLsiInterrupts();
// Step 2 -- Set bit 0 of Interrupt Control Register
// to 1 to enable LSI mode
@@ -410,7 +400,6 @@ errlHndl_t IntrRp::_init()
}
}
-
//Disable Incoming PSI Interrupts
TRACDCOMP(g_trac_intr, "IntrRp::_init() Disabling PSI Interrupts");
uint64_t l_disablePsiIntr = PSI_BRIDGE_INTP_STATUS_CTL_DISABLE_PSI;
@@ -517,7 +506,7 @@ void IntrRp::enableLsiInterrupts()
task_affinity_migrate_to_master();
uint64_t * l_lsiEoi = iv_masterHdlr->xiveIcBarAddr;
l_lsiEoi += XIVE_IC_LSI_EOI_OFFSET;
- l_lsiEoi += (0xC00 / sizeof(uint64_t));
+ l_lsiEoi += (ESB_RESET_OFFSET / sizeof(uint64_t));
volatile uint64_t l_eoiRead = *l_lsiEoi;
TRACFCOMP(g_trac_intr, "IntrRp:: enableLsiInterrupts() read 0x%lx from pointer %p", l_eoiRead, l_lsiEoi);
@@ -526,6 +515,24 @@ void IntrRp::enableLsiInterrupts()
TRACDCOMP(g_trac_intr, "IntrRp:: enableLsiInterrupts() exit");
}
+void IntrRp::disableLsiInterrupts()
+{
+ TRACDCOMP(g_trac_intr, "IntrRp:: disableLsiInterrupts() enter");
+ //The XIVE HW is expecting these MMIO accesses to come from the
+ // core/thread they were setup (master core, thread 0)
+ // These functions will ensure this code executes there
+ task_affinity_pin();
+ task_affinity_migrate_to_master();
+ uint64_t * l_lsiEoi = iv_masterHdlr->xiveIcBarAddr;
+ l_lsiEoi += XIVE_IC_LSI_EOI_OFFSET;
+ l_lsiEoi += (ESB_OFF_OFFSET / sizeof(uint64_t));
+ volatile uint64_t l_eoiRead = *l_lsiEoi;
+ TRACFCOMP(g_trac_intr, "IntrRp:: disableLsiInterrupts() read 0x%lx from pointer %p", l_eoiRead, l_lsiEoi);
+ //MMIO Complete, rest of code can run on any thread
+ task_affinity_unpin();
+ TRACDCOMP(g_trac_intr, "IntrRp:: disableLsiInterrupts() exit");
+}
+
/**
* Clear INT_PC registers that didn't get cleared by the HW reset
* during the SBE steps of the MPIPL
@@ -1629,7 +1636,7 @@ errlHndl_t IntrRp::maskInterruptSource(uint8_t i_intr_source,
errlHndl_t l_err = NULL;
uint64_t * l_psiHbEsbptr = i_chip->psiHbEsbBaseAddr;
l_psiHbEsbptr +=
- (((i_intr_source*PAGE_SIZE)+PSI_BRIDGE_ESB_OFF_OFFSET)
+ (((i_intr_source*PAGE_SIZE)+ESB_OFF_OFFSET)
/sizeof(uint64_t));
//MMIO Read to this address transitions the ESB to the off state
@@ -1638,7 +1645,7 @@ errlHndl_t IntrRp::maskInterruptSource(uint8_t i_intr_source,
//Perform 2nd read to verify in OFF state using query offset
l_psiHbEsbptr = i_chip->psiHbEsbBaseAddr +
- (((i_intr_source*PAGE_SIZE)+PSI_BRIDGE_ESB_QUERY_OFFSET)
+ (((i_intr_source*PAGE_SIZE)+ESB_QUERY_OFFSET)
/sizeof(uint64_t));
l_maskRead = *l_psiHbEsbptr;
@@ -1724,7 +1731,7 @@ errlHndl_t IntrRp::unmaskInterruptSource(uint8_t l_intr_source,
{
uint64_t * l_psiHbEsbptr = (*targ_itr)->psiHbEsbBaseAddr;
l_psiHbEsbptr +=
- (((l_intr_source*PAGE_SIZE)+PSI_BRIDGE_ESB_RESET_OFFSET)
+ (((l_intr_source*PAGE_SIZE)+ESB_RESET_OFFSET)
/sizeof(uint64_t));
//MMIO Read to this address transitions the ESB to the RESET state
@@ -1733,7 +1740,7 @@ errlHndl_t IntrRp::unmaskInterruptSource(uint8_t l_intr_source,
//Perform 2nd read to verify in RESET state using query offset
l_psiHbEsbptr = (*targ_itr)->psiHbEsbBaseAddr +
- (((l_intr_source*PAGE_SIZE)+PSI_BRIDGE_ESB_QUERY_OFFSET)
+ (((l_intr_source*PAGE_SIZE)+ESB_QUERY_OFFSET)
/sizeof(uint64_t));
l_unmaskRead = *l_psiHbEsbptr;
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index 2173113ae..46f6f2616 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -182,9 +182,6 @@ namespace INTR
//PSI Host Bridge ESB Constants
PSI_BRIDGE_ESB_BAR_VALID = 0x0000000000000001ULL,
PSI_BRIDGE_ESB_NOTIFY_VALID = 0x0000000000000001ULL,
- PSI_BRIDGE_ESB_QUERY_OFFSET = 0x800,
- PSI_BRIDGE_ESB_OFF_OFFSET = 0xD00,
- PSI_BRIDGE_ESB_RESET_OFFSET = 0XC00,
PSI_BRIDGE_PSU_DOORBELL_REG = 0x000D0063,
PSI_BRIDGE_PSU_DOORBELL_ANDREG = 0x000D0064,
PSI_BRIDGE_PSU_HOST_DOORBELL = 0x8000000000000000,
@@ -229,6 +226,11 @@ namespace INTR
POWERBUS_STATE_QUIESCE = 0xC000000000000000,
MAX_PSU_LONG_TIMEOUT_NS = 5000*NS_PER_MSEC, //5 seconds
+ // ESB Page offsets -- This page format is used both in the
+ // PSIHB + LSI SBE EOI pages
+ ESB_QUERY_OFFSET = 0x800,
+ ESB_OFF_OFFSET = 0xD00,
+ ESB_RESET_OFFSET = 0XC00,
ESB_STATE_RESET = 0,
ESB_STATE_OFF = 1,
ESB_STATE_PENDING = 2,
@@ -406,6 +408,12 @@ namespace INTR
void enableLsiInterrupts();
/**
+ * Do a read from LSI ESB EOI page to disable presentation of LSI
+ * interrupt to Hostboot
+ */
+ void disableLsiInterrupts();
+
+ /**
* Clear INT_PC registers that didn't get cleared by the HW reset
* during the SBE steps of the MPIPL
*/
OpenPOWER on IntegriCloud