From 034db70a607c406106e9e1351d956d0f4f0864d2 Mon Sep 17 00:00:00 2001 From: Bill Hoffa Date: Thu, 7 Jun 2018 09:31:59 -0500 Subject: Multinode MPIPL INTRP Initialization Changes - Replace PSIHB ESB Off for every LSI interrupt source with Setting ESB off to the XIVE IC (Page 4), The LSI SB EOI page Change-Id: I01b11c6c8466f559fce4c754bd91d07a97ff713a CQ: SW431120 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60102 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: William G. Hoffa --- src/usr/intr/intrrp.C | 47 +++++++++++++++++++++++++++-------------------- src/usr/intr/intrrp.H | 14 +++++++++++--- 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, @@ -405,6 +407,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 -- cgit v1.2.1