summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBill Hoffa <wghoffa@us.ibm.com>2015-10-15 13:59:58 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-03-30 16:24:17 -0400
commit6b5097872a33a20d4c03f995ca8f1585b9e43e53 (patch)
treeb97d48402b8e54b14d1ce554191bbeb78890d09c /src
parent550f30129f455317e65610cd90e9d06b2018e4c1 (diff)
downloadtalos-hostboot-6b5097872a33a20d4c03f995ca8f1585b9e43e53.tar.gz
talos-hostboot-6b5097872a33a20d4c03f995ca8f1585b9e43e53.zip
P9 PSIHB Base Interrupt Support
This change includes the following: - Kernel Updates to handle hypervisor interrupt vector - Interrupt Resource Provider changes to setup and handle LSI Based interrupts - Kernel updates to handle modified interrupt flow for LSI Based interrupts - Attribute updates for Scom BAR Registers Change-Id: If63f246a0090ab8c81c3fa8ac3ab6871a0af2e31 RTC:137561 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/20692 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com> Reviewed-by: Prachi Gupta <pragupta@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/build/citest/etc/bbuild2
-rw-r--r--src/include/kernel/cpumgr.H5
-rw-r--r--src/include/kernel/intmsghandler.H26
-rw-r--r--src/include/usr/intr/interrupt.H35
-rw-r--r--src/include/usr/intr/intr_reasoncodes.H14
-rw-r--r--src/kernel/exception.C2
-rw-r--r--src/kernel/intmsghandler.C35
-rw-r--r--src/kernel/msghandler.C4
-rw-r--r--src/kernel/start.S15
-rw-r--r--src/kernel/syscall.C2
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H4
-rw-r--r--src/usr/intr/intrrp.C1556
-rw-r--r--src/usr/intr/intrrp.H285
-rw-r--r--src/usr/intr/test/intrtest.H33
-rw-r--r--src/usr/isteps/istep14/call_proc_exit_cache_contained.C13
-rw-r--r--src/usr/mbox/mailboxsp.C76
-rwxr-xr-xsrc/usr/targeting/common/genHwsvMrwXml.pl8
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml15
-rw-r--r--src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml9
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/target_types.xml3
20 files changed, 1166 insertions, 976 deletions
diff --git a/src/build/citest/etc/bbuild b/src/build/citest/etc/bbuild
index 996ad34be..a99905b3e 100644
--- a/src/build/citest/etc/bbuild
+++ b/src/build/citest/etc/bbuild
@@ -1 +1 @@
-/esw/fips910/Builds/b0323b_1614.910 \ No newline at end of file
+/esw/fips910/Builds/b0323b_1614.910
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H
index 30009da73..25bb794bf 100644
--- a/src/include/kernel/cpumgr.H
+++ b/src/include/kernel/cpumgr.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2015 */
+/* Contributors Listed Below - COPYRIGHT 2010,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -170,8 +170,9 @@ class CpuManager
* bit 51 - Wake-up from machine check.
* bit 60 - LPES(0) = 1 (see ISA).
* bit 61 - LPES(1) = 0 (P8 RFC02204 forces to 0)
+ * bit 62 - HVICE - Hypervisor Virt Interrupt Conditionally Enable
*/
- static const uint64_t WAKEUP_LPCR_VALUE = 0x0000000000007008;
+ static const uint64_t WAKEUP_LPCR_VALUE = 0x000000000000700A;
/** Desired value for RPR after wakeup.
*
diff --git a/src/include/kernel/intmsghandler.H b/src/include/kernel/intmsghandler.H
index 98d8d5288..8fd4e34b6 100644
--- a/src/include/kernel/intmsghandler.H
+++ b/src/include/kernel/intmsghandler.H
@@ -46,6 +46,7 @@ class InterruptMsgHdlr : public MessageHandler
public:
/**
+ * TODO RTC 150260
* Field values for P8
* @note This is used to calculate the mmio address offset
* from the PIR for the interrupt presenter memory mapped registers.
@@ -56,19 +57,20 @@ class InterruptMsgHdlr : public MessageHandler
*/
enum
{
- P8_PIR_THREADID_MSK = PIR_t::THREAD_MASK,
- P8_PIR_COREID_MSK = PIR_t::CORE_MASK,
- P8_PIR_CHIPID_MSK = PIR_t::CHIP_MASK,
- P8_PIR_NODEID_MSK = PIR_t::GROUP_MASK,
+ P9_PIR_THREADID_MSK = PIR_t::THREAD_MASK,
+ P9_PIR_COREID_MSK = PIR_t::CORE_MASK,
+ P9_PIR_CHIPID_MSK = PIR_t::CHIP_MASK,
+ P9_PIR_NODEID_MSK = PIR_t::GROUP_MASK,
// Logical Shift Left fields for mmio Base address from PIR.
// (IP addr bit pos - PIR bit pos)
- P8_IP_THREADID_LSL = (12-PIR_t::BITS_AFTER_CORE),
- P8_IP_COREID_LSL = (15-PIR_t::BITS_AFTER_CORE),
- P8_IP_CHIPID_LSL = (20-PIR_t::BITS_AFTER_CHIP),
- P8_IP_NODEID_LSL = (22-PIR_t::BITS_AFTER_GROUP),
+ P9_IP_THREADID_LSL = (12-PIR_t::BITS_AFTER_CORE),
+ P9_IP_COREID_LSL = (15-PIR_t::BITS_AFTER_CORE),
+ P9_IP_CHIPID_LSL = (20-PIR_t::BITS_AFTER_CHIP),
+ P9_IP_NODEID_LSL = (22-PIR_t::BITS_AFTER_GROUP),
XIRR_ADDR_OFFSET = 4,
MFRR_ADDR_OFFSET = 12,
+ ACK_HYPERVISOR_INT_REG_OFFSET = 0x830,
INTP_BAR_VALUE = 0xFFFFE000, // upper 32 bits of IPCBAR
@@ -109,16 +111,16 @@ class InterruptMsgHdlr : public MessageHandler
// The PIR chip id field has 1 extra bit (8 chips), so we need
// to shift the node and chip separately
offset |=
- (i_pir & P8_PIR_NODEID_MSK) << P8_IP_NODEID_LSL;
+ (i_pir & P9_PIR_NODEID_MSK) << P9_IP_NODEID_LSL;
offset |=
- (i_pir & P8_PIR_CHIPID_MSK) << P8_IP_CHIPID_LSL;
+ (i_pir & P9_PIR_CHIPID_MSK) << P9_IP_CHIPID_LSL;
// The core and thread id field are adjacent in both the PIR and
// the mmio offset, so they can be done in one shift operation.
offset |=
- (i_pir & (P8_PIR_COREID_MSK | P8_PIR_THREADID_MSK))
- << P8_IP_THREADID_LSL;
+ (i_pir & (P9_PIR_COREID_MSK | P9_PIR_THREADID_MSK))
+ << P9_IP_THREADID_LSL;
return offset;
}
diff --git a/src/include/usr/intr/interrupt.H b/src/include/usr/intr/interrupt.H
index 1b24c2eed..1666abd15 100644
--- a/src/include/usr/intr/interrupt.H
+++ b/src/include/usr/intr/interrupt.H
@@ -51,7 +51,8 @@ namespace INTR
enum XISRvalue_t
{
NO_INTERRUPT = 0, //!< no interrupt present
- INTERPROC_XISR = 2, //!< XISR value for IPIs
+ //TODO RTC 137564
+ INTERPROC_XISR = 0xFF, //!< XISR value for IPIs
MAX_XISR = 0x00FFFFFF, //!< Max value of the XISR
SHUT_DOWN = 0x01000000, //!< INTR presenter sends this when shutting down
};
@@ -71,6 +72,33 @@ namespace INTR
//Converts to INTERPROC_XISR when registered
};
+ //These values are HW defined values from the LSI Interrupts status register
+ // on the PSIHB. These should only be changed if the spec changes.
+ enum LSIvalue_t
+ {
+ LSI_PSI = 0,
+ LSI_OCC = 1,
+ LSI_FSIMBOX = 2,
+ LSI_LPC = 3,
+ LSI_LCL_FIR = 4,
+ LSI_GLOBAL = 5,
+ LSI_TPM = 6,
+ LSI_LPC_SERIAL0 = 7,
+ LSI_LPC_SERIAL1 = 8,
+ LSI_LPC_SERIAL2 = 9,
+ LSI_LPC_SERIAL3 = 10,
+ LSI_SBE_OR_I2C = 11,
+ LSI_DIO = 12,
+ LSI_PSU = 13,
+ LSI_LAST_SOURCE,
+
+//TODO RTC 137564
+// ISN_INTERPROC = 0xF0, //"special" as it isn't part of PSIHB
+// //Converts to INTERPROC_XISR when registered
+// //
+ };
+
+
/**
* The XISR value is the logical OR of the Interrup Requestor Source
* Number (IRSN) and the Interrrupt Source Number (ISN).
@@ -107,12 +135,12 @@ namespace INTR
MSG_INTR_ENABLE, //!< Enable external Interrupts
MSG_INTR_DISABLE, //!< Disable external interrupts
MSG_INTR_SHUTDOWN, //!< Call to shutdown interrupt presenter
- MSG_INTR_ENABLE_PSI_INTR, //!< Enable PSI interrupts
MSG_INTR_MPIPL_CLEANUP, //!< Clean up interrupts on MPIPL
MSG_INTR_ADD_CPU_TIMEOUT, //!< Check for a timeout waiting for a core.
MSG_INTR_ADD_HBNODE, //!< Add node info for MPIPL
MSG_INTR_EOI, //!< Issue EOI when received
MSG_INTR_DRAIN_QUEUE, //!< Allow intrp to drain Q of EOI
+ MSG_INTR_COALESCE, //!< Pending interrupt to be handled
};
/**
@@ -181,12 +209,13 @@ namespace INTR
*/
errlHndl_t disableExternalInterrupts();
+ //TODO RTC 150260
/**
* Initialize the IRSCReg to enable PSI to present interrupts
* @param[in] i_target The target processor
* @return error log handle on error
*/
- errlHndl_t enablePsiIntr(TARGETING::Target * i_target);
+ //errlHndl_t enablePsiIntr(TARGETING::Target * i_target);
/**
* Return the interrupt presenter for requested target/thread
diff --git a/src/include/usr/intr/intr_reasoncodes.H b/src/include/usr/intr/intr_reasoncodes.H
index 31869ac69..8ab758519 100644
--- a/src/include/usr/intr/intr_reasoncodes.H
+++ b/src/include/usr/intr/intr_reasoncodes.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* [+] 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. */
@@ -42,6 +44,11 @@ namespace INTR
MOD_INTR_SYNC_ADDNODE = 0x0A, /**< intrrp.C : IntrRp::addHbNodeToMpiplSyncArea */
MOD_INTR_ADDHBNODE = 0x0B, /**< intrrp.C : INTR::addHbNode */
MOD_INTR_EXTRACTNODEINFO = 0x0C, /**< intrrp.C : INTR::extractHbNodeInfo */
+ MOD_INTRRP_SENDEOI = 0x0D, /**< intrrp.C : INTR::sendEOI */
+ MOD_INTRRP_MASKINTERRUPT = 0x0E, /**< intrrp.C : INTR::maskInterruptSource */
+ MOD_INTRRP_UNMASKINTERRUPT = 0x0F, /**< intrrp.C : INTR::unmaskInterruptSource */
+ MOD_INTRRP_HNDLPSUINTERRUPT = 0x10, /**< intrrp.C : INTR::handlePsuInterrupt */
+ MOD_INTRRP_RESETINTUNIT = 0x11, /**< intrrp.C : IntrRp::resetIntUnit */
};
enum IntrReasonCode
@@ -54,6 +61,11 @@ namespace INTR
//termination_rc
RC_PERSISTENT_INTERRUPTS = INTR_COMP_ID | 0x06,
RC_CANNOT_MAP_MEMORY = INTR_COMP_ID | 0x07,
+ RC_PSIHB_ESB_EOI_FAIL = INTR_COMP_ID | 0x08,
+ RC_XIVE_ESB_WRONG_STATE = INTR_COMP_ID | 0x09,
+ RC_PSU_DOORBELL_TIMEOUT = INTR_COMP_ID | 0x0A,
+ RC_XIVE_PBUS_QUIESCE_TIMEOUT = INTR_COMP_ID | 0x0B,
+ RC_MESSAGE_SEND_ERROR = INTR_COMP_ID | 0x0C,
};
};
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index 5c16d46cd..686d3012c 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2015 */
+/* Contributors Listed Below - COPYRIGHT 2010,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/kernel/intmsghandler.C b/src/kernel/intmsghandler.C
index f203439be..10c1dcfd8 100644
--- a/src/kernel/intmsghandler.C
+++ b/src/kernel/intmsghandler.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* [+] 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. */
@@ -76,26 +78,22 @@ void InterruptMsgHdlr::handleInterrupt()
if( cv_ipc_base_address != 0 )
{
- uint64_t xirrAddress = cv_ipc_base_address;
-
- xirrAddress += mmio_offset(pir); // Add offset for this cpu
- xirrAddress += XIRR_ADDR_OFFSET; // Add offset for XIRR register
+ uint64_t ackHypeInt2RegAddress = cv_ipc_base_address;
+ ackHypeInt2RegAddress += ACK_HYPERVISOR_INT_REG_OFFSET;
// Ignore HRMOR setting
- xirrAddress |= 0x8000000000000000ul;
-
- uint32_t xirr = 0;
- printkd ("XirrAddr %lx\n",xirrAddress);
+ ackHypeInt2RegAddress |= 0x8000000000000000ul;
+ uint16_t ackHypeInt2Reg = 0;
// Reading this register acknowledges the interrupt and deactivates the
// external interrupt signal to the processor. The XIRR is now locked
// and can't be pre-empted by a "more favored" interrupt.
// This is a cache-inhibited load from hypervisor state.
- // lwzcix BOP1,Ref_G0,BOP2
- asm volatile("lwzcix %0, 0, %1"
- : "=r" (xirr) // output, %0
- : "r" (xirrAddress) // input, %1
- : ); // no impacts
+ // lhzcix BOP1,Ref_G0,BOP2
+ asm volatile("lhzcix %0, 0, %1"
+ : "=r" (ackHypeInt2Reg) // output, %0
+ : "r" (ackHypeInt2RegAddress) // input, %1
+ : ); // no impacts
if(cv_instance)
{
@@ -103,8 +101,9 @@ void InterruptMsgHdlr::handleInterrupt()
//sendMessage needs a unique key, otherwise it
//drops messages. PIR is not unique enough, make
- //it (xirr<<32) | PIR
- uint64_t l_data0 = pir | (static_cast<uint64_t>(xirr) <<32);
+ //it (ackHypInt2Reg<<32) | PIR
+ uint64_t l_data0 =
+ pir | (static_cast<uint64_t>(ackHypeInt2Reg) <<32);
cv_instance->sendMessage(MSG_INTR_EXTERN,
reinterpret_cast<void*>(l_data0),
NULL,
@@ -115,7 +114,6 @@ void InterruptMsgHdlr::handleInterrupt()
else
{
printk("InterrurptMsgHdlr got called before IPC was setup\n");
-
// The INTR mmio base address is not yet available via the attributes.
// If we get here during an MPIPL then the BAR value could be read
// from the ICP BAR SCOM register, however, since this value will
@@ -142,9 +140,8 @@ void InterruptMsgHdlr::handleInterrupt()
// There should not be any more interrupts until an eoi is sent
// by writing the xirr back with the value read.
- printk("XIRR @ %lx = %x\n",xirrAddress,xirr);
-
//If this is an IPI -- clean it up
+ //TODO RTC 137564
if((xirr & 0x00FFFFFF) == INTERPROC_XISR)
{
uint64_t mfrrAddress =
diff --git a/src/kernel/msghandler.C b/src/kernel/msghandler.C
index 5a3beefac..cb051eb88 100644
--- a/src/kernel/msghandler.C
+++ b/src/kernel/msghandler.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* [+] 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. */
diff --git a/src/kernel/start.S b/src/kernel/start.S
index 86c2d1c18..740f961e8 100644
--- a/src/kernel/start.S
+++ b/src/kernel/start.S
@@ -208,6 +208,7 @@ UNIMPL_INTERRUPT_STUB(hype_data_storage, 0xE00)
UNIMPL_INTERRUPT_STUB(hype_inst_storage, 0xE20)
STD_INTERRUPT_STUB(hype_emu_assist, 0xE40)
UNIMPL_INTERRUPT_STUB(hype_maint, 0xE60)
+STD_INTERRUPT_STUB(hypervisor_external, 0xEA0)
UNIMPL_INTERRUPT_STUB(perf_monitor, 0xF00)
UNIMPL_INTERRUPT_STUB(vector_unavail, 0xF20)
UNIMPL_INTERRUPT_STUB(vsx_unavail, 0xF40)
@@ -698,6 +699,20 @@ intvect_system_reset_external:
b intvect_external
+ ;// @fn intvect_hypervisor_external
+ ;// Handle hypervisor external interrupt
+ ;// This function moves the hypervisor external interrupt regs
+ ;// into the external interrupt regs and then branches to the
+ ;// external interrupt handler
+intvect_hypervisor_external:
+ mtsprg1 r1 ;// Save off R1 temporarily.
+ mfspr r1, HSRR0 ;// Move HSRR0 -> SRR0.
+ mtsrr0 r1
+ mfspr r1, HSRR1 ;// Move HSRR1 -> SRR1.
+ mtsrr1 r1
+ mfsprg1 r1 ;// Restore R1 and use external interrupt handler
+ b intvect_external
+
;// @fn system_call_fast_path
;// Handle fast path system calls.
;// 0x800 = HMER read (HMER -> r3).
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 92907c3df..fe59ea0c3 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2015 */
+/* Contributors Listed Below - COPYRIGHT 2010,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index f0eece8bd..46bd65473 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -96,8 +96,6 @@ const TaskInfo g_exttaskinfolist[] = {
}
},
- // @todo RTC:126643 P9 interrupt support
-#if (0)
/**
* @brief External interrupt resource provider
*/
@@ -109,8 +107,6 @@ const TaskInfo g_exttaskinfolist[] = {
EXT_IMAGE, // Extended Module
}
},
-#endif
-
/**
* @brief Mailbox service provider
*/
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index 7a19429aa..f1bacb540 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -58,26 +58,6 @@
using namespace INTR;
using namespace TARGETING;
-const uint32_t IntrRp::cv_PE_IRSN_COMP_SCOM_LIST[] =
-{
- PE0_IRSN_COMP_SCOM_ADDR,
- PE1_IRSN_COMP_SCOM_ADDR,
- PE2_IRSN_COMP_SCOM_ADDR
-};
-
-const uint32_t IntrRp::cv_PE_IRSN_MASK_SCOM_LIST[] =
-{
- PE0_IRSN_MASK_SCOM_ADDR,
- PE1_IRSN_MASK_SCOM_ADDR,
- PE2_IRSN_MASK_SCOM_ADDR
-};
-
-const uint32_t IntrRp::cv_PE_BAR_SCOM_LIST[] =
-{
- PE0_BAREN_SCOM_ADDR,
- PE1_BAREN_SCOM_ADDR,
- PE2_BAREN_SCOM_ADDR
-};
trace_desc_t * g_trac_intr = NULL;
TRAC_INIT(&g_trac_intr, INTR_TRACE_NAME, 16*KILOBYTE, TRACE::BUFFER_SLOW);
@@ -88,69 +68,6 @@ TRAC_INIT(&g_trac_intr, INTR_TRACE_NAME, 16*KILOBYTE, TRACE::BUFFER_SLOW);
TASK_ENTRY_MACRO( IntrRp::init );
-/**
- * @brief Utility function to get the list of enabled threads
- * @return Bitstring of enabled threads
- */
-uint64_t get_enabled_threads( void )
-{
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
- assert( sys != NULL );
- uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>();
- if( en_threads == 0 )
- {
-
-// Set max thread for VPO, nanosleep() here takes too long in VPO environment
-#ifdef CONFIG_VPO_COMPILE
- en_threads = 0xFF00000000000000;
- sys->setAttr<TARGETING::ATTR_ENABLED_THREADS>(en_threads);
- TRACFCOMP( g_trac_intr, "Enabled Threads for VPO = %.16X", en_threads );
- return en_threads;
-#endif
-
- // Read the scratch reg that the SBE setup
- // Enabled threads are listed as a bitstring in bits 16:23
- // A value of zero means the SBE hasn't set them up yet
-
- // Loop for 1 sec (1000 x 1 msec) for this value to be set
- uint64_t loop_count = 0;
- const uint64_t LOOP_MAX = 1000;
-
- while( (en_threads == 0) && (loop_count < LOOP_MAX) )
- {
- en_threads = mmio_scratch_read(MMIO_SCRATCH_AVP_THREADS);
-
- if( en_threads == 0 )
- {
- // Sleep if value has not been set
- nanosleep(0,NS_PER_MSEC); // 1 msec
- }
-
- // Update the counter
- loop_count++;
- }
-
- // If LOOP_MAX reached, CRIT_ASSERT
- if ( unlikely(loop_count == LOOP_MAX) )
- {
- TRACFCOMP( g_trac_intr,"SBE Didn't Set Active Threads");
- crit_assert(0);
- }
- else
- {
- en_threads = en_threads << 16; //left-justify the threads
- TRACFCOMP( g_trac_intr,
- "Enabled Threads = %.16X",
- en_threads );
- sys->setAttr<TARGETING::ATTR_ENABLED_THREADS>(en_threads);
- }
-
- }
- TRACDCOMP( g_trac_intr, "en_threads=%.16X", en_threads );
- return en_threads;
-}
-
void IntrRp::init( errlHndl_t &io_errlHndl_t )
{
errlHndl_t err = NULL;
@@ -161,23 +78,9 @@ void IntrRp::init( errlHndl_t &io_errlHndl_t )
io_errlHndl_t = err ;
}
-// ICPBAR = INTP.ICP_BAR[0:25] in P8 = 0x3FFFF800 + (8*node) + procPos
-// P8 Scom address = 0x020109c9
-//
-// BaseAddress P8:
-// BA[14:43] = ICPBAR (30 bits)
-// BA[45:48] = coreID (1-6,9-14) (12 cores)
-// BA[49:51] = thread (0-7)
-//
-// BA+0 = XIRR (poll - Read/Write has no side effects))
-// BA+4 = XIRR (Read locks HW, Write -> EOI to HW))
-// BA+12 = MFRR (1 byte)
-// BA+16 = LINKA (4 bytes)
-// BA+20 = LINKB (4 bytes)
-// BA+24 = LINKC (4 bytes)
errlHndl_t IntrRp::_init()
{
- errlHndl_t err = NULL;
+ errlHndl_t l_err = NULL;
// get the PIR
// Which ever cpu core this is running on is the MASTER cpu
@@ -186,32 +89,16 @@ errlHndl_t IntrRp::_init()
iv_masterCpu = cpuid;
iv_masterCpu.threadId = 0;
- TRACFCOMP(g_trac_intr,"Master cpu group[%d], chip[%d], core[%d], thread[%d]",
+ TRACFCOMP(g_trac_intr,"IntrRp::_init() Master cpu group[%d], "
+ "chip[%d], core[%d], thread[%d]",
iv_masterCpu.groupId, iv_masterCpu.chipId, iv_masterCpu.coreId,
iv_masterCpu.threadId);
- // The base realAddr is the base address for the whole system.
- // Therefore the realAddr must be based on the processor
- // that would have the lowest BAR value in the system,
- // whether it exists or not. In this case n0p0
-
+ // Do the initialization steps on the master proc chip
+ // The other proc chips will be setup at a later point
TARGETING::Target* procTarget = NULL;
TARGETING::targetService().masterProcChipTargetHandle( procTarget );
- uint64_t barValue = 0;
- barValue = procTarget->getAttr<TARGETING::ATTR_INTP_BASE_ADDR>();
-
- // Mask off group & chip id to get base address
- uint64_t realAddr = barValue & ICPBAR_BASE_ADDRESS_MASK;
-
- TRACFCOMP(g_trac_intr,"INTR: realAddr = %lx",realAddr);
-
- // VADDR_SIZE is 1MB per chip - max 32 -> 32MB
- iv_baseAddr = reinterpret_cast<uint64_t>
- (mmio_dev_map(reinterpret_cast<void*>(realAddr),THIRTYTWO_MB));
-
- TRACFCOMP(g_trac_intr,"INTR: vAddr = %lx",iv_baseAddr);
-
// Set up the IPC message Data area
TARGETING::Target * sys = NULL;
TARGETING::targetService().getTopLevelTarget( sys );
@@ -223,16 +110,22 @@ errlHndl_t IntrRp::_init()
KernelIpc::ipc_data_area.hrmor_base = hrmor_base;
KernelIpc::ipc_data_area.msg_queue_id = IPC_DATA_AREA_CLEAR;
- // Set the BAR scom reg
- err = setBAR(procTarget,iv_masterCpu);
-
- if(!err)
+ do
{
- err = checkAddress(iv_baseAddr);
- }
+ //TODO RTC 150562 - updates for multi-chip. My understanding is
+ // the setting of the BARs + Enables can be done at the point in the IPL
+ // where Xscoms are enabled.
+ // Set the Interrupt BAR Scom Registers
+ l_err = setInterruptBARs(procTarget);
- if(!err)
- {
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "IntrRp::_init() Error setting Interrupt BARs.");
+ break;
+ }
+
+ //TODO RTC 134431
+ #ifdef CONFIG_MPIPL_ENABLED
uint8_t is_mpipl = 0;
TARGETING::Target * sys = NULL;
TARGETING::targetService().getTopLevelTarget(sys);
@@ -241,76 +134,218 @@ errlHndl_t IntrRp::_init()
is_mpipl)
{
TRACFCOMP(g_trac_intr,"Disable interupts for MPIPL");
- err = hw_disableIntrMpIpl();
+ l_err = hw_disableIntrMpIpl();
- if(err)
+ if(l_err)
{
- errlCommit(err,INTR_COMP_ID);
- err = NULL;
+ errlCommit(l_err,INTR_COMP_ID);
+ l_err = NULL;
}
}
+ #endif
+ TRACFCOMP(g_trac_intr, "IntrRp::_init() Masking Interrupts");
+ //Mask off all interrupt sources - these will be enabled as SW entities
+ // register for specific interrupts via the appropriate message queue
+ l_err = maskAllInterruptSources();
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "IntrRp::_init() Error masking all interrupt sources.");
+ break;
+ }
- // Set up the interrupt provider registers
- // NOTE: It's only possible to set up the master core at this point.
- //
- // Set up link registers to forward all intrpts to master cpu.
- //
- // There is one register set per cpu thread.
- uint64_t max_threads = cpu_thread_count();
- uint64_t en_threads = get_enabled_threads();
-
- PIR_t pir = iv_masterCpu;
- for(size_t thread = 0; thread < max_threads; ++thread)
+ TRACFCOMP(g_trac_intr, "IntrRp::_init() Enabling PSIHB Interrupts");
+ //Enable PSIHB Interrupts
+ l_err = enableInterrupts();
+ if (l_err)
{
- // Skip threads that we shouldn't be starting
- if( !(en_threads & (0x8000000000000000>>thread)) )
- {
- TRACDCOMP(g_trac_intr,
- "IntrRp::_init: Skipping thread %d : en_threads=%X",
- thread,en_threads);
- continue;
- }
- pir.threadId = thread;
- initInterruptPresenter(pir);
+ TRACFCOMP(g_trac_intr, "IntrRp::_init() Error enabling Interrupts");
+ break;
}
- // Get the kernel msg queue for ext intr
- // Create a task to handle the messages
+ // Create the kernel msg queue for external interrupts
iv_msgQ = msg_q_create();
- msg_intr_q_register(iv_msgQ, realAddr);
+ msg_intr_q_register(iv_msgQ,
+ procTarget->getAttr<TARGETING::ATTR_XIVE_THREAD_MGMT1_BAR_ADDR>());
+ // Create a task to handle the messages
task_create(IntrRp::msg_handler, NULL);
// Register event to be called on shutdown
INITSERVICE::registerShutdownEvent(iv_msgQ,
MSG_INTR_SHUTDOWN,
INITSERVICE::INTR_PRIORITY);
- }
- if(!err)
+ //The INTRP itself will monitor/handle PSU Interrupts
+ // so unmask those interrupts
+ l_err = unmaskInterruptSource(LSI_PSU);
+
+ } while(0);
+
+ return l_err;
+}
+
+void IntrRp::acknowledgeInterrupt()
+{
+ //A uint16 store from the Acknowledge Hypervisor Interrupt
+ // offset in the Thread Management BAR space signals
+ // the interrupt is acknowledged
+ uint16_t * l_ack_int_ptr = (uint16_t *)iv_xiveTmBar1Address;
+ l_ack_int_ptr += ACK_HYPERVISOR_INT_REG_OFFSET;
+
+ uint16_t l_ackRead = *l_ack_int_ptr;
+ TRACDCOMP(g_trac_intr, "IntrRp::acknowledgeInterrupt(), read result: %16x", l_ackRead);
+}
+
+errlHndl_t IntrRp::resetIntUnit()
+{
+ errlHndl_t l_err = NULL;
+ uint64_t l_barValue = XIVE_RESET_POWERBUS_QUIESCE_ENABLE;
+ uint64_t size = sizeof(l_barValue);
+ uint32_t l_addr = XIVE_RESET_INT_CQ_RST_CTL_SCOM_ADDR;
+
+ TARGETING::Target* procTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle( procTarget );
+
+ do {
+ //First quiesce the power bus
+ TRACDCOMP(g_trac_intr, "IntrRp::resetIntUnit() - "
+ "Quiesce the PowerBus Interface");
+ l_err = deviceWrite(procTarget,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(l_addr));
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "IntrRp::resetIntUnit() - "
+ "Error Quiescing the PowerBus");
+ break;
+ }
+
+ //A short amount of time is needed to let the powerbus quiesce before
+ // the next step in the reset can occur, so do a short polling loop
+ // for the indicator the power bus has been quiesced
+ uint64_t l_quiesceTimeout = XIVE_RESET_POWERBUS_QUIESCE_TIMEOUT;
+ uint64_t l_timeWaited = 0;
+ uint64_t reg = 0x0;
+
+ do
+ {
+ if (l_timeWaited >= l_quiesceTimeout)
+ {
+ TRACFCOMP(g_trac_intr, "IntrRp::resetIntUnit() - Timeout "
+ "waiting for PowerBus to quiesce");
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid INTR::MOD_INTRRP_RESETINTUNIT
+ ` * @reasoncode INTR::RC_XIVE_PBUS_QUIESCE_TIMEOUT
+ * @userdata1 XIVE Powerbus Scom Register Address
+ * @userdata2 XIVE Powerbus Scom Register Data
+ *
+ * @devdesc Timeout waiting for Powerbus to Quiesce
+ */
+ l_err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE, // severity
+ INTR::MOD_INTRRP_RESETINTUNIT, // moduleid
+ INTR::RC_XIVE_PBUS_QUIESCE_TIMEOUT, // reason code
+ l_addr,
+ reg
+ );
+
+ break;
+ }
+
+ uint64_t scom_len = sizeof(reg);
+
+ //Read the powerbus state
+ l_err = deviceRead( procTarget,
+ &reg,
+ scom_len,
+ DEVICE_SCOM_ADDRESS(l_addr));
+
+
+ if (l_err)
+ {
+ //Logging below this loop
+ break;
+ }
+
+
+ if (reg & POWERBUS_STATE_QUIESCE)
+ {
+ //Powerbus Quiesced
+ break;
+ }
+ else
+ {
+ nanosleep(0,XIVE_RESET_POWERBUS_QUIESCE_TIMEOUT / 10);
+ l_timeWaited += XIVE_RESET_POWERBUS_QUIESCE_TIMEOUT / 10;
+ }
+ } while(1);
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "Error getting Powerbus state");
+ break;
+ }
+
+ TRACDCOMP(g_trac_intr, "Reset XIVE INT unit");
+ l_barValue = XIVE_RESET_UNIT_ENABLE;
+ l_err = deviceWrite(procTarget,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(l_addr));
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "Error resetting XIVE INT unit");
+ break;
+ }
+
+ } while (0);
+
+ if (l_err)
{
- // Enable PSI to present interrupts
- err = initIRSCReg(procTarget);
+ TRACFCOMP(g_trac_intr, "Error: Interrupt Engine not reset successfully");
}
- return err;
+ return l_err;
}
errlHndl_t IntrRp::enableInterrupts()
{
errlHndl_t err = NULL;
+ PSIHB_SW_INTERFACES_t * l_psihb_ptr = iv_psiHbBaseAddr;
- // Enable the interrupt on master processor core, thread 0
- uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(iv_masterCpu);
-
- err = checkAddress(baseAddr);
- if(!err)
+ do
{
- uint8_t * cppr = reinterpret_cast<uint8_t*>(baseAddr+CPPR_OFFSET);
- *cppr = 0xff;
- }
+ //Set bit to route interrupts to CEC instead of FSP
+ l_psihb_ptr->psihbcr =
+ (l_psihb_ptr->psihbcr | PSI_BRIDGE_ENABLE_CEC_INTERRUPT);
+ //Set bit to enable PSIHB Interrupts
+ l_psihb_ptr->icr =
+ (l_psihb_ptr->icr | PSI_BRIDGE_INTP_STATUS_CTL_ENABLE);
+
+ //Set Physical Thread Enable register in the PC space
+ uint64_t * l_ic_ptr = iv_xiveIcBarAddress;
+ l_ic_ptr += XIVE_IC_BAR_INT_PC_MMIO_REG_OFFSET;
+
+ XIVE_IC_THREAD_CONTEXT_t * l_xive_ic_ptr =
+ reinterpret_cast<XIVE_IC_THREAD_CONTEXT_t *>(l_ic_ptr);
+ l_xive_ic_ptr->phys_thread_enable0_set = XIVE_IC_THREAD0_ENABLE;
+
+ //Set bit to configure LSI mode for HB cec interrupts
+ XIVE_IVPE_THREAD_CONTEXT_t * this_ivpe_ptr =
+ reinterpret_cast<XIVE_IVPE_THREAD_CONTEXT_t *> (iv_xiveTmBar1Address);
+ this_ivpe_ptr->cams = XIVE_IVPE_QW3_LSI_ENABLE;
+
+ } while (0);
+
+ //TODO RTC 150260 - Determine if any error checking can be done above, if so
+ // create/return errorlogs. If not, change the funciton return type.
return err;
}
@@ -343,15 +378,39 @@ void* IntrRp::msg_handler(void * unused)
void IntrRp::msgHandler()
{
+ TRACDCOMP(g_trac_intr, ENTER_MRK"IntrRp::msgHandler()");
+
while(1)
{
msg_t* msg = msg_wait(iv_msgQ); // wait for interrupt msg
switch(msg->type)
{
+ //Both cases require the same functinality, EXTERN comes from
+ // the kernel. COALESCE comes from userspace as the final step of
+ // the EOI path involves a read, if that returns 1 it signifies a
+ // new interrupt is already pending. So the EOI path will send a
+ // new COALESCE message to trigger the handling.
+ case MSG_INTR_COALESCE:
case MSG_INTR_EXTERN:
{
ext_intr_t type = NO_INTERRUPT;
+ uint32_t ackResponse =
+ static_cast<uint32_t>(msg->data[0]>>32);
+ //Check if LSI-Based Interrupt
+ if ((ackResponse & LSI_INTERRUPT) == LSI_INTERRUPT)
+ {
+ TRACDCOMP(g_trac_intr, "IntrRp::msgHandler() "
+ "- LSI Interrupt Detected");
+ //Read LSI Interrupt Status register
+ PSIHB_SW_INTERFACES_t * l_psihb_ptr = iv_psiHbBaseAddr;
+ uint64_t lsiIntStatus = l_psihb_ptr->lsiintstatus;
+ TRACDCOMP(g_trac_intr, "IntrRp::msgHandler() "
+ "lsiIntStatus 0x%016lx", lsiIntStatus);
+ LSIvalue_t l_intrType = static_cast<LSIvalue_t>
+ (__builtin_clzl(lsiIntStatus));
+ type = static_cast<ext_intr_t>(l_intrType);
+ }
// xirr was read by interrupt message handler.
// Passed in as upper word of data[0]
@@ -365,22 +424,29 @@ void IntrRp::msgHandler()
uint32_t * xirrAddress =
reinterpret_cast<uint32_t*>(baseAddr + XIRR_OFFSET);
- // type = XISR = XIRR[8:31]
- // priority = XIRR[0:7]
- // Use the XISR as the type (for now)
- type = static_cast<ext_intr_t>(xirr & XISR_MASK);
-
TRACFCOMP(g_trac_intr,
"External Interrupt received. XIRR=%x, PIR=%x",
xirr,pir.word);
+ //An external interrupt comes from two paths
+ // 1) kernel space - synchronous - response needed
+ // 2) User space (coalesce interrupt) - asynchronous
+ // - no response needed, just free message
+ if (msg_is_async(msg))
+ {
+ msg_free(msg);
+ }
+ else
+ {
+ // Acknowlege msg
+ msg->data[1] = 0;
+ msg_respond(iv_msgQ, msg);
+ }
- // Acknowlege msg
- msg->data[1] = 0;
- msg_respond(iv_msgQ, msg);
-
+ //Search if anyone is subscribed to the given
+ // interrupt source
Registry_t::iterator r = iv_registry.find(type);
- if(r != iv_registry.end() &&
- type != INTERPROC_XISR) //handle IPI after EOI, not here
+
+ if(r != iv_registry.end() && type != INTERPROC_XISR)
{
msg_q_t msgQ = r->second.msgQ;
@@ -399,11 +465,6 @@ void IntrRp::msgHandler()
" handler. Ignoring it. rc = %d",
(uint32_t) type, rc);
}
-
- //Since non IPI EOIs are blocking fashion need to open
- //up the interrupt priority to max (CPRR)
- uint8_t *cppr = reinterpret_cast<uint8_t*>(xirrAddress);
- *cppr = CPPR_ENABLE_ALL; //allow any INTR
}
else if (type == INTERPROC_XISR)
{
@@ -414,6 +475,11 @@ void IntrRp::msgHandler()
// as well. This is to catch the case where no one
// has registered for an IPI.
}
+ else if (type == LSI_PSU)
+ {
+ TRACDCOMP(g_trac_intr, "PSU Interrupt Detected");
+ handlePsuInterrupt(type);
+ }
else // no queue registered for this interrupt type
{
// Throw it away for now.
@@ -508,82 +574,54 @@ void IntrRp::msgHandler()
case MSG_INTR_EOI:
{
- // Write the XIRR with the same value read earlier
- // to signal EOI. XIRR value was stored in data[1]
- // Only do this for non IPI types (type is in data[0])
+ // Use standrard EOI (End of Interrupt) sequence
if(msg->data[0] != INTERPROC_XISR)
{
- // Passed in as upper word of data[1]
- uint32_t xirr = static_cast<uint32_t>(msg->data[1]>>32);
- // data[1] (lower word) has the PIR
- uint64_t l_data0 = (msg->data[1] & 0xFFFFFFFF);
- PIR_t pir = static_cast<PIR_t>(l_data0);
-
- uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(pir);
- uint32_t * xirrAddress =
- reinterpret_cast<uint32_t*>(baseAddr + XIRR_OFFSET);
-
- xirr |= CPPR_MASK; //set all CPPR bits - allow any INTR
- *xirrAddress = xirr;
-
- TRACDCOMP(g_trac_intr,
- "EOI issued. XIRR=%x, PIR=%x",
- xirr,pir);
+ uint64_t intSource = msg->data[0];
+ sendEOI(intSource);
}
msg_free(msg);
}
break;
-
-
case MSG_INTR_REGISTER_MSGQ:
{
+
msg_q_t l_msgQ = reinterpret_cast<msg_q_t>(msg->data[0]);
uint64_t l_type = msg->data[1];
- ISNvalue_t l_intr_type = static_cast<ISNvalue_t>
+ LSIvalue_t l_intr_type = static_cast<LSIvalue_t>
(l_type & 0xFFFF);
- errlHndl_t err = registerInterruptISN(l_msgQ,l_type >> 32,
- l_intr_type);
- if(!err)
+ errlHndl_t err = registerInterruptXISR(l_msgQ, l_type >> 32,
+ l_intr_type);
+ if (err)
{
- err = initXIVR(l_intr_type, true);
+ TRACFCOMP(g_trac_intr,
+ "IntrRp::msgHandler MSG_INTR_REGISTER_MSGQ error "
+ "registering handler for interrupt type: %lx",
+ l_intr_type);
}
-
- msg->data[1] = reinterpret_cast<uint64_t>(err);
- msg_respond(iv_msgQ,msg);
- }
- break;
-
- case MSG_INTR_UNREGISTER_MSGQ:
- {
- 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);
-
- if(msgQ)
+ else
{
- //shouldn't get an error since we found a queue
- //Just commit it
- errlHndl_t err = initXIVR(l_type, false);
- if(err)
+ //Enable (aka unmask) Interrupts for the source being
+ // registered for
+ err = unmaskInterruptSource(l_intr_type);
+ if (err)
{
- errlCommit(err,INTR_COMP_ID);
+ TRACFCOMP(g_trac_intr,
+ "IntrRp::msgHandler MSG_INTR_REGISTER_MSGQ error"
+ " unmasking interrupt type: %lx",
+ l_intr_type);
}
}
- msg->data[1] = reinterpret_cast<uint64_t>(msgQ);
-
- TRACDCOMP(g_trac_intr,
- "UNREG: msgQ = 0x%lx",
- msg->data[1]);
-
+ msg->data[1] = reinterpret_cast<uint64_t>(err);
msg_respond(iv_msgQ,msg);
}
break;
-
+ case MSG_INTR_UNREGISTER_MSGQ:
+ //TODO RTC 150260 add functionality
+ break;
case MSG_INTR_ENABLE:
{
errlHndl_t err = enableInterrupts();
@@ -594,12 +632,13 @@ void IntrRp::msgHandler()
case MSG_INTR_DISABLE:
{
- errlHndl_t err =disableInterrupts();
+ errlHndl_t err = disableInterrupts();
msg->data[1] = reinterpret_cast<uint64_t>(err);
msg_respond(iv_msgQ,msg);
}
break;
+#ifdef CONFIG_ENABLE_P9_IPI
// Called when a new cpu becomes active other than the master
// Expect a call for each new core
case MSG_INTR_ADD_CPU:
@@ -627,7 +666,7 @@ void IntrRp::msgHandler()
continue;
}
pir.threadId = thread;
- initInterruptPresenter(pir);
+ //wh_p9 initInterruptPresenter(pir);
sendIPI(pir);
}
@@ -636,7 +675,7 @@ void IntrRp::msgHandler()
reinterpret_cast<void*>(pir.word));
}
break;
-
+#endif
case MSG_INTR_ADD_CPU_TIMEOUT:
{
PIR_t pir = msg->data[0];
@@ -684,46 +723,6 @@ void IntrRp::msgHandler()
msg_respond(iv_msgQ, msg);
}
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_ISSUE_SBE_MBOX_WA:
- {
- //The SBE IPI injection on master winkle wakeup
- //can clobber a pending mailbox interrupt in the ICP
- //To workaround need to issue EOI on mailbox. If
- //mbx intr is not hot this does nothing, if it is
- //then the EOI will cause intr to be represented
-
- //This is safe on FSPless since the PSI intr are
- //always setup on master chip
- uint64_t baseAddr = iv_baseAddr +
- cpuOffsetAddr(iv_masterCpu);
- uint32_t * xirrAddress =
- reinterpret_cast<uint32_t*>(baseAddr + XIRR_OFFSET);
-
- //Generate the mailbox IRSN for this group
- uint32_t l_irsn = makeXISR(iv_masterCpu, ISN_FSI);
- l_irsn |= CPPR_MASK; //set all CPPR bits - allow any INTR
-
- TRACFCOMP(g_trac_intr,
- "MBX SBE WA Issue EOI to %x",l_irsn);
- *xirrAddress = l_irsn; //Issue EOI
-
- // Acknowlege msg
- msg->data[1] = 0;
- msg_respond(iv_msgQ, msg);
- }
- break;
-
case MSG_INTR_SHUTDOWN:
{
TRACFCOMP(g_trac_intr,"Shutdown event received");
@@ -733,7 +732,7 @@ void IntrRp::msgHandler()
}
break;
-
+#ifdef CONFIG_MPIPL_ENABLED //TODO RTC 134431
case MSG_INTR_ADD_HBNODE: // node info for mpipl
{
errlHndl_t err = addHbNodeToMpiplSyncArea(msg->data[0]);
@@ -744,7 +743,7 @@ void IntrRp::msgHandler()
msg_free(msg); // async message
}
break;
-
+#endif
case MSG_INTR_DRAIN_QUEUE:
{
//The purpose of this message is allow the
@@ -761,379 +760,370 @@ void IntrRp::msgHandler()
}
}
+errlHndl_t IntrRp::sendEOI(uint64_t& i_intSource)
+{
+ //Send an EOI to the Power bus using the PSIHB ESB Space
+ //This is done with a read to the page specific to the interrupt source.
+ //Each interrupt source gets one page
+ uint64_t * l_psiHbPowerBusEoiAddr =
+ iv_psiHbEsbBaseAddr + ((i_intSource)*PAGE_SIZE)/sizeof(uint64_t);
+ errlHndl_t l_err = NULL;
+ do {
-errlHndl_t IntrRp::setBAR(TARGETING::Target * i_target,
- const PIR_t i_pir)
-{
- errlHndl_t err = NULL;
+ uint64_t eoiRead = *l_psiHbPowerBusEoiAddr;
+ if (eoiRead != 0)
+ {
+ TRACFCOMP(g_trac_intr, ERR_MRK"IntrRp::sendEOI error sending EOI"
+ " to PSIHB ESB. EOI load returned: %x", eoiRead);
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid INTR::MOD_INTRRP_SENDEOI
+ * @reasoncode INTR::RC_PSIHB_ESB_EOI_FAIL
+ * @userdata1 Value read from EOI load
+ * @userdata2 Interrupt Source to issue EOI to
+ * @devdesc Unexpected RC from issuing PSIHB EOI store
+ */
+ l_err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE, // severity
+ INTR::MOD_INTRRP_SENDEOI, // moduleid
+ INTR::RC_PSIHB_ESB_EOI_FAIL, // reason code
+ eoiRead, // read value
+ i_intSource // interrupt source number
+ );
+ break;
+ }
- uint64_t barValue = 0;
- barValue = i_target->getAttr<TARGETING::ATTR_INTP_BASE_ADDR>();
+ TRACDCOMP(g_trac_intr, "IntrRp::sendEOI read response: %lx", eoiRead);
- barValue <<= 14;
- barValue |= 1ULL << (63 - ICPBAR_EN);
+ //EOI Part 2 - LSI ESB Internal to the IVPE
+ uint64_t * l_lsiEoi = iv_xiveIcBarAddress;
+ l_lsiEoi += XIVE_IC_LSI_EOI_OFFSET;
+ uint64_t l_intPending = *l_lsiEoi;
- TRACFCOMP(g_trac_intr,"INTR: Target %p. ICPBAR value: 0x%016lx",
- i_target,barValue);
+ //If an interrupt is pending, HB userspace will send a message to
+ // trigger the handling of a 'new' interrupt. In this situation the
+ // interrupt will not be triggered via the kernel.
+ if (l_intPending == 1)
+ {
+ //First acknowledge the interrupt so it won't be re-presented
+ acknowledgeInterrupt();
- uint64_t size = sizeof(barValue);
+ uint64_t l_data0 = LSI_INTERRUPT << 32;
+ if (iv_msgQ)
+ {
+ msg_t * int_msg = msg_allocate();
+ int_msg->type = MSG_INTR_COALESCE;
+ int_msg->data[0] = reinterpret_cast<uint64_t>(l_data0);
+ int send_rc = msg_send(iv_msgQ, int_msg);
+ if (send_rc != 0)
+ {
+ TRACFCOMP(g_trac_intr, ERR_MRK"IntrRp::sendEOI error "
+ "sending coalesce message");
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid INTR::MOD_INTRRP_SENDEOI
+ * @reasoncode INTR::RC_MESSAGE_SEND_ERROR
+ * @userdata1 RC from msg_send command
+ * @devdesc Error encountered sending coalesce
+ * message to INTRP
+ */
+ l_err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE, // severity
+ INTR::MOD_INTRRP_SENDEOI, // moduleid
+ INTR::RC_MESSAGE_SEND_ERROR, // reason code
+ send_rc,
+ 0
+ );
+ break;
+ }
+ }
+ }
+ } while(0);
- err = deviceWrite(i_target,
- &barValue,
- size,
- DEVICE_SCOM_ADDRESS(ICPBAR_SCOM_ADDR));
+ return l_err;
+}
- if(err)
+errlHndl_t IntrRp::maskAllInterruptSources(void)
+{
+ errlHndl_t l_err = NULL;
+ for (uint8_t i = 0; i < LSI_LAST_SOURCE; i++)
{
- TRACFCOMP(g_trac_intr,ERR_MRK"Unable to set IPCBAR");
+ TRACDCOMP(g_trac_intr, "MaskInterruptSource: %d", i);
+ l_err = maskInterruptSource(i);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "Error Masking Interrupt source: %x", i);
+ break;
+ }
}
- return err;
+ TRACDCOMP(g_trac_intr, EXIT_MRK"MaskAllInterruptSources");
+ return l_err;
}
-errlHndl_t IntrRp::getPsiIRSN(TARGETING::Target * i_target,
- uint32_t& o_irsn, uint32_t& o_num)
+errlHndl_t IntrRp::maskInterruptSource(uint8_t l_intr_source)
{
- errlHndl_t err = NULL;
+ errlHndl_t l_err = NULL;
+ uint64_t * l_psiHbEsbptr = iv_psiHbEsbBaseAddr;
+ l_psiHbEsbptr +=
+ (((l_intr_source*PAGE_SIZE)+PSI_BRIDGE_ESB_OFF_OFFSET)/sizeof(uint64_t));
- // Setup PHBISR
- // 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
+ uint64_t l_maskRead = *l_psiHbEsbptr;
+ TRACDCOMP(g_trac_intr, "Mask read result: %lx", l_maskRead);
- do{
- err = deviceRead
- ( i_target,
- &reg,
- scom_len,
- DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_ISRN_REG));
+/*
+ TODO RTC 150260
- if(err)
- {
- break;
- }
+ //Perform 2nd read to verify in OFF state
+ l_maskRead = *l_psiHbEsbptr;
+ TRACDCOMP(g_trac_intr, "Mask read result: %lx", l_maskRead);
- //only calc IRSN if downstream interrupts are enabled
- o_irsn = 0;
- if(reg.die == 1) //downstream interrupt enable = 1
- {
- o_irsn = reg.irsn & reg.mask;
- }
- }while(0);
+ if (l_maskRead != ESB_STATE_OFF)
+ {
+ TRACFCOMP(g_trac_intr, "Error masking interrupt source: %x."
+ " ESB state is: %lx.",
+ l_intr_source, l_maskRead);
+ l_err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
+ INTR::MOD_INTRRP_MASKINTERRUPT, // moduleid
+ INTR::RC_XIVE_ESB_WRONG_STATE, // reason code
+ l_intr_source,
+ l_maskRead
+ );
- TRACFCOMP(g_trac_intr,"PSIHB_ISRN: 0x%x",o_irsn);
+ }
+**/
- return err;
+ return l_err;
}
-errlHndl_t IntrRp::getNxIRSN(TARGETING::Target * i_target,
- uint32_t& o_irsn, uint32_t& o_num)
+errlHndl_t IntrRp::unmaskInterruptSource(uint8_t l_intr_source)
{
- errlHndl_t err = NULL;
+ errlHndl_t l_err = NULL;
+ uint64_t * l_psiHbEsbptr = iv_psiHbEsbBaseAddr;
+ l_psiHbEsbptr +=
+ (((l_intr_source*PAGE_SIZE)+PSI_BRIDGE_ESB_RESET_OFFSET)/sizeof(uint64_t));
- size_t scom_len = sizeof(uint64_t);
- uint64_t reg = 0x0;
+ uint64_t l_unmaskRead = *l_psiHbEsbptr;
+ TRACDCOMP(g_trac_intr, "Unmask read result: %lx", l_unmaskRead);
- do{
- err = deviceRead
- ( i_target,
- &reg,
- scom_len,
- DEVICE_SCOM_ADDRESS(NX_BUID_SCOM_ADDR));
-
- if(err)
- {
- break;
- }
+/* TODO RTC 150260
- //only calc IRSN if downstream interrupts are enabled
- o_irsn = 0;
- if(reg &(1ull << (63-NX_BUID_ENABLE))) //reg has NX_BUID_ENABLE set
- {
- 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)
- & 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);
+ //Read 2nd time to verify proper ESB state
+ l_unmaskRead = *l_psiHbEsbptr;
+ if (l_unmaskRead != ESB_STATE_RESET)
+ {
+ TRACFCOMP(g_trac_intr, "Error unmasking interrupt source: %x."
+ " ESB state is: %lx.",
+ l_intr_source, l_unmaskRead);
- TRACFCOMP(g_trac_intr,"NX_ISRN: 0x%x, num: 0x%x",o_irsn, o_num);
+ l_err = new ERRORLOG::ErrlEntry
+ (
+ ERRORLOG::ERRL_SEV_INFORMATIONAL, // severity
+ INTR::MOD_INTRRP_UNMASKINTERRUPT, // moduleid
+ INTR::RC_XIVE_ESB_WRONG_STATE, // reason code
+ l_intr_source,
+ l_unmaskRead
+ );
- return err;
+ }
+**/
+ return l_err;
}
-errlHndl_t IntrRp::initIRSCReg(TARGETING::Target * i_target)
+errlHndl_t IntrRp::setInterruptBARs(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 group = 0;
+ errlHndl_t l_err = NULL;
- group = i_target->getAttr<ATTR_FABRIC_NODE_ID>();
- chip = i_target->getAttr<ATTR_FABRIC_CHIP_ID>();
+ do {
- size_t scom_len = sizeof(uint64_t);
-
- // Mask off interrupts from isn's on this target
- // This also sets the source isn and PIR destination
- // such that if an interrupt is pending when when the ISRN
- // is written, simics get the right destination for the
- // interrupt. err is from deviceWrite(...)
- err = maskXIVR(i_target);
-
- if(!err)
+ l_err = setPsiHbBAR(i_target);
+ if (l_err)
{
- // Setup PHBISR
- // EN.TPC.PSIHB.PSIHB_ISRN_REG set to 0x00030003FFFF0000
- PSIHB_ISRN_REG_t reg;
-
- PIR_t pir(0);
- pir.groupId = group;
- 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, "Error setting PSIHB BAR");
+ break;
+ }
- TRACFCOMP(g_trac_intr,"PSIHB_ISRN_REG: 0x%016lx",reg.d64);
+ l_err = setPsiHbEsbBAR(i_target, true);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "Error setting PSIHB ESB BAR");
+ break;
+ }
- err = deviceWrite
- ( i_target,
- &reg,
- scom_len,
- DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_ISRN_REG));
+ l_err = setXiveIcBAR(i_target);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "Error setting XIVE IC BAR");
+ break;
}
- if(!err)
+ l_err = setXiveIvpeTmBAR1(i_target);
+ if (l_err)
{
- iv_chipList.push_back(i_target);
+ TRACFCOMP(g_trac_intr, "Error setting XIVE TM BAR1");
+ break;
}
- }
- return err;
+ } while (0);
+
+ return l_err;
}
-errlHndl_t IntrRp::initXIVR(enum ISNvalue_t i_isn, bool i_enable)
+errlHndl_t IntrRp::handlePsuInterrupt(ext_intr_t i_type)
{
- errlHndl_t err = NULL;
+ //TODO FIXME RTC 149698
+ // Long term will leverage mask register to avoid
+ // polling loop below
+ errlHndl_t l_err = NULL;
+ uint32_t l_addr = PSI_BRIDGE_PSU_DOORBELL_REG;
size_t scom_len = sizeof(uint64_t);
- uint64_t scom_addr = 0;
+ uint64_t reg = 0x0;
+ uint64_t l_elapsed_time_ns = 0;
+ TARGETING::Target* procTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle( procTarget );
- //Don't do any of this for ISN_INTERPROC
- if(ISN_INTERPROC != i_isn)
+ do
{
- //Setup the XIVR register
- PsiHbXivr xivr;
- PIR_t pir = intrDestCpuId();
- xivr.pir = pir.word;
- xivr.source = i_isn;
+ l_err = deviceRead(procTarget,
+ &reg,
+ scom_len,
+ DEVICE_SCOM_ADDRESS(l_addr));
- switch(i_isn)
+ if (l_err)
{
- case ISN_PSI:
- xivr.priority = PsiHbXivr::PSI_PRIO;
- scom_addr = PsiHbXivr::PSI_XIVR_ADRR;
- break;
-
- 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;
+ TRACFCOMP(g_trac_intr, "Error Reading PSU SCOM address: %lx",
+ l_addr);
break;
+ }
- case ISN_HOST:
- xivr.priority = PsiHbXivr::HOST_PRIO;
- scom_addr = PsiHbXivr::HOST_XIVR_ADRR;
+ //If the PSU Host Doorbell bit is on, wait for the
+ // PSU DD to handle
+ if (reg & PSI_BRIDGE_PSU_HOST_DOORBELL)
+ {
+ TRACDCOMP(g_trac_intr, "Host/SBE Mailbox "
+ "response. Wait for Polling to handle"
+ " response");
+ nanosleep(0,10000);
+ l_elapsed_time_ns += 10000;
+ }
+ else
+ {
+ //Polling Complete
break;
-
- default: //Unsupported ISN
- TRACFCOMP(g_trac_intr,"Unsupported ISN: 0x%02x",i_isn);
+ }
+ if (l_elapsed_time_ns > MAX_PSU_LONG_TIMEOUT_NS)
+ {
+ TRACFCOMP(g_trac_intr, "PSU Timeout hit");
/*@ errorlog tag
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid INTR::MOD_INTR_INIT_XIVR
- * @reasoncode INTR::RC_BAD_ISN
- * @userdata1 Interrupt type to register
- * @userdata2 0
- *
- * @devdesc Unsupported ISN Requested
- *
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid INTR::MOD_INTRRP_HNDLPSUINTERRUPT
+ * @reasoncode INTR::RC_PSU_DOORBELL_TIMEOUT
+ * @userdata1 Scom Address with interrupt condition
+ * @userdata2 Register Value
+ * @devdesc PSU Doorbell Timeout hit waiting for doorbell
+ * interrupt condition to be cleared
*/
- err = new ERRORLOG::ErrlEntry
+ l_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
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE, // severity
+ INTR::MOD_INTRRP_HNDLPSUINTERRUPT, // moduleid
+ INTR::RC_PSU_DOORBELL_TIMEOUT, // reason code
+ l_addr,
+ reg
);
+ break;
}
- // 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);
- }
- }
+ } while(1);
- 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));
+ do {
- if(err)
- {
- break;
- }
- }
+ if (l_err)
+ {
+ break;
}
- }
- return err;
-}
+ //Clear the PSU Scom Reg Interrupt Status register
+ uint64_t l_barValue = 0;
+ uint64_t size = sizeof(l_barValue);
+ l_err = deviceWrite(procTarget,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(l_addr));
-//----------------------------------------------------------------------------
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_intr, "Error clearing scom - %x", l_addr);
+ break;
+ }
-// Set priority highest (disabled) ,but with valid PIR
-errlHndl_t IntrRp::maskXIVR(TARGETING::Target *i_target)
-{
- struct XIVR_INFO
- {
- ISNvalue_t isn:8;
- uint32_t addr;
- };
+ //Issue standard EOI for the PSU Interupt
+ uint64_t intSource = i_type;
+ TRACDCOMP(g_trac_intr, "Sending PSU EOI");
+ sendEOI(intSource);
- static const XIVR_INFO xivr_info[] =
- {
- {ISN_PSI, PsiHbXivr::PSI_XIVR_ADRR},
- {ISN_OCC, PsiHbXivr::OCC_XIVR_ADRR},
- {ISN_FSI, PsiHbXivr::FSI_XIVR_ADRR},
- {ISN_LPC, PsiHbXivr::LPC_XIVR_ADRR},
- {ISN_LCL_ERR, PsiHbXivr::LCL_ERR_XIVR_ADDR},
- {ISN_HOST, PsiHbXivr::HOST_XIVR_ADRR}
- };
+ } while(0);
- errlHndl_t err = NULL;
- size_t scom_len = sizeof(uint64_t);
- PIR_t pir = intrDestCpuId();
- PsiHbXivr xivr;
+ return l_err;
+}
- xivr.pir = pir.word;
- xivr.priority = PsiHbXivr::PRIO_DISABLED;
+errlHndl_t IntrRp::getNxIRSN(TARGETING::Target * i_target,
+ uint32_t& o_irsn, uint32_t& o_num)
+{
+ errlHndl_t err = NULL;
- for(size_t i = 0; i < sizeof(xivr_info)/sizeof(xivr_info[0]); ++i)
- {
- xivr.source = xivr_info[i].isn;
+ size_t scom_len = sizeof(uint64_t);
+ uint64_t reg = 0x0;
- err = deviceWrite
- (i_target,
- &xivr,
- scom_len,
- DEVICE_SCOM_ADDRESS(xivr_info[i].addr));
+ do{
+ err = deviceRead
+ ( i_target,
+ &reg,
+ scom_len,
+ DEVICE_SCOM_ADDRESS(NX_BUID_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;
- //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)
+ //only calc IRSN if downstream interrupts are enabled
+ o_irsn = 0;
+ if(reg &(1ull << (63-NX_BUID_ENABLE))) //reg has NX_BUID_ENABLE set
{
- uint8_t chip = 0;
- uint8_t node = 0;
- node = (*target_itr)->getAttr<ATTR_FABRIC_NODE_ID>();
- chip = (*target_itr)->getAttr<ATTR_FABRIC_CHIP_ID>();
+ uint32_t l_mask = ((static_cast<uint32_t>(reg >> NX_IRSN_MASK_SHIFT)
+ & NX_IRSN_MASK_MASK) | NX_IRSN_UPPER_MASK);
- PIR_t pir(0);
- pir.groupId = node;
- pir.chipId = chip;
- uint32_t l_irsn = makeXISR(pir, i_intr_type);
+ o_irsn = ((static_cast<uint32_t>(reg >> NX_IRSN_COMP_SHIFT)
+ & IRSN_COMP_MASK) & l_mask);
- err = registerInterruptXISR(i_msgQ, i_msg_type, l_irsn);
- if(err)
- {
- break;
- }
+ //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, num: 0x%x",o_irsn, o_num);
+
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_xisr);
@@ -1166,38 +1156,6 @@ errlHndl_t IntrRp::registerInterruptXISR(msg_q_t i_msgQ,
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;
- node = (*target_itr)->getAttr<ATTR_FABRIC_NODE_ID>();
- chip = (*target_itr)->getAttr<ATTR_FABRIC_CHIP_ID>();
-
- PIR_t pir(0);
- pir.groupId = 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;
@@ -1212,91 +1170,6 @@ msg_q_t IntrRp::unregisterInterruptXISR(ext_intr_t i_xisr)
return msgQ;
}
-void IntrRp::initInterruptPresenter(const PIR_t i_pir) const
-{
- uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(i_pir);
- uint8_t * cppr =
- reinterpret_cast<uint8_t*>(baseAddr + CPPR_OFFSET);
- uint32_t * plinkReg =
- reinterpret_cast<uint32_t *>(baseAddr + LINKA_OFFSET);
-
- TRACDCOMP(g_trac_intr,"PIR 0x%x offset: 0x%lx",
- i_pir.word,
- cpuOffsetAddr(i_pir));
-
- if(i_pir.word == iv_masterCpu.word)
- {
- *cppr = 0xff; // Allow all interrupts
- }
- else
- {
- // Allow Wake-up IPIs only
- // link regs route non-IPIs to iv_masterCPU) anyway
- // IPC IPIs are only directed at iv_masterCpu
- *cppr = IPI_USR_PRIO + 1;
- }
-
- // Links are intended to be set up in rings. If an interrupt ends up
- // where it started, it gets rejected by hardware.
- //
- // According to BOOK IV, The links regs are setup by firmware.
- //
- // Should be possible to link all interrupt forwarding directly to
- // the master core and either make them direct (lspec = 0) or by setting
- // the LOOPTRIP bit to stop the forwarding at the masterProc.
- //
- LinkReg_t linkReg;
- linkReg.word = 0;
- linkReg.loopTrip = 1; // needed?
- linkReg.node = iv_masterCpu.groupId;
- linkReg.pchip= iv_masterCpu.chipId;
- linkReg.pcore= iv_masterCpu.coreId;
- linkReg.tspec= iv_masterCpu.threadId;
-
- *(plinkReg) = linkReg.word;
- *(plinkReg + 1) = linkReg.word;
- linkReg.last = 1;
- *(plinkReg + 2) = linkReg.word;
-}
-
-
-
-void IntrRp::disableInterruptPresenter(const PIR_t i_pir) const
-{
- uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(i_pir);
- uint8_t * cppr =
- reinterpret_cast<uint8_t*>(baseAddr + CPPR_OFFSET);
- uint32_t * plinkReg =
- reinterpret_cast<uint32_t *>(baseAddr + LINKA_OFFSET);
-
- // non- side effect xirr register
- uint32_t * xirrAddr =
- reinterpret_cast<uint32_t *>(baseAddr + XIRR_RO_OFFSET);
-
- uint32_t xirr = *xirrAddr & 0x00FFFFFF;
-
- TRACDCOMP(g_trac_intr,"PIR 0x%x offset: 0x%lx",
- i_pir.word,
- cpuOffsetAddr(i_pir));
-
- // Not sure if this will ever happen, but squawk alittle if it does
- if(xirr)
- {
- TRACFCOMP(g_trac_intr,
- ERR_MRK
- "Pending interrupt found on shutdown. CpuId:0x%x XIRR:0x%x",
- i_pir.word,
- xirr);
- }
-
- *cppr = 0; // Set priority to most favored (off)
-
- *plinkReg = 0; // Reset link registers - clear all forwarding
- *(plinkReg + 1) = 0;
- *(plinkReg + 2) = 0;
-}
-
-
void IntrRp::sendIPI(const PIR_t i_pir) const
{
uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(i_pir);
@@ -1340,7 +1213,6 @@ errlHndl_t IntrRp::checkAddress(uint64_t i_addr)
void IntrRp::shutDown(uint64_t i_status)
{
- errlHndl_t err = NULL;
msg_t * rmsg = msg_allocate();
// Call everyone and say shutting down!
@@ -1367,51 +1239,25 @@ void IntrRp::shutDown(uint64_t i_status)
msg_free(rmsg);
- // 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;
- }
- }
-
- 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;
- }
- }
+ //TODO FIXME RTC 149694 - Workaround to set proper PSIHB ESB BAR for PHYP
+ TARGETING::Target* procTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle( procTarget );
+ TRACDCOMP(g_trac_intr, "Disable PSIHB ESB BAR");
+ setPsiHbEsbBAR(procTarget, false);
+ //Reset PSIHB Interrupt Space
+ TRACDCOMP(g_trac_intr, "Reset PSIHB Interrupt Space");
+ PSIHB_SW_INTERFACES_t * this_psihb_ptr = iv_psiHbBaseAddr;
+ this_psihb_ptr->icr = PSI_BRIDGE_INTP_STATUS_CTL_RESET;
+ TRACDCOMP(g_trac_intr, "Reset PSIHB INTR Complete");
- // Reset the IP hardware regiseters
+ //Reset XIVE Interrupt unit
+ resetIntUnit();
+ // Reset the IP hardware registers
iv_cpuList.push_back(iv_masterCpu);
+#ifdef CONFIG_ENABLE_P9_IPI
size_t threads = cpu_thread_count();
uint64_t en_threads = get_enabled_threads();
@@ -1429,14 +1275,17 @@ void IntrRp::shutDown(uint64_t i_status)
continue;
}
pir.threadId = thread;
- disableInterruptPresenter(pir);
+ //wh_p9 disableInterruptPresenter(pir);
}
}
+#endif
TRACFCOMP(g_trac_intr,INFO_MRK"INTR is shutdown");
}
//----------------------------------------------------------------------------
+#ifdef CONFIG_MPIPL_ENABLED
+
errlHndl_t IntrRp::hw_disableRouting(TARGETING::Target * i_proc,
INTR_ROUTING_t i_rx_tx)
{
@@ -1453,7 +1302,8 @@ errlHndl_t IntrRp::hw_disableRouting(TARGETING::Target * i_proc,
i_proc,
&reg,
scom_len,
- DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_ISRN_REG)
+ DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_STATUS_CTL_REG)
+
);
if(err)
@@ -1478,7 +1328,7 @@ errlHndl_t IntrRp::hw_disableRouting(TARGETING::Target * i_proc,
i_proc,
&reg,
scom_len,
- DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_ISRN_REG)
+ DEVICE_SCOM_ADDRESS(PSIHB_ISRN_REG_t::PSIHB_STATUS_CTL_REG)
);
if(err)
@@ -1578,9 +1428,11 @@ errlHndl_t IntrRp::hw_disableRouting(TARGETING::Target * i_proc,
} while(0);
return err;
}
+#endif
//----------------------------------------------------------------------------
+#ifdef CONFIG_MPIPL_ENABLED
errlHndl_t IntrRp::hw_resetIRSNregs(TARGETING::Target * i_proc)
{
errlHndl_t err = NULL;
@@ -1661,9 +1513,10 @@ errlHndl_t IntrRp::hw_resetIRSNregs(TARGETING::Target * i_proc)
} while(0);
return err;
}
+#endif
//----------------------------------------------------------------------------
-
+#ifdef CONFIG_MPIPL_ENABLED
errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
{
errlHndl_t err = NULL;
@@ -1767,7 +1620,7 @@ errlHndl_t IntrRp::blindIssueEOIs(TARGETING::Target * i_proc)
} while(0);
return err;
}
-
+#endif
//----------------------------------------------------------------------------
@@ -1933,7 +1786,7 @@ void IntrRp::disableAllInterrupts(TARGETING::Target* i_core)
for(size_t thread = 0; thread < threads; ++thread)
{
pir.threadId = thread;
- disableInterruptPresenter(pir);
+ //wh_p9 disableInterruptPresenter(pir);
}
}
@@ -2014,7 +1867,7 @@ void IntrRp::drainMpIplInterrupts(TARGETING::TargetHandleList & i_cores)
}
-
+#ifdef CONFIG_MPIPL_ENABLED
errlHndl_t IntrRp::hw_disableIntrMpIpl()
{
errlHndl_t err = NULL;
@@ -2162,7 +2015,7 @@ errlHndl_t IntrRp::hw_disableIntrMpIpl()
} while(0);
return err;
}
-
+#endif
errlHndl_t syncNodesError(void * i_p, uint64_t i_len)
{
@@ -2311,7 +2164,7 @@ errlHndl_t IntrRp::syncNodes(intr_mpipl_sync_t i_sync_type)
return err;
}
-
+#ifdef CONFIG_MPIPL_ENABLED
errlHndl_t IntrRp::initializeMpiplSyncArea()
{
errlHndl_t err = NULL;
@@ -2371,7 +2224,9 @@ errlHndl_t IntrRp::initializeMpiplSyncArea()
}
return err;
}
+#endif
+#ifdef CONFIG_MPIPL_ENABLED
errlHndl_t IntrRp::addHbNodeToMpiplSyncArea(uint64_t i_hbNode)
{
errlHndl_t err = NULL;
@@ -2420,7 +2275,9 @@ errlHndl_t IntrRp::addHbNodeToMpiplSyncArea(uint64_t i_hbNode)
}
return err;
}
+#endif
+#ifdef CONFIG_MPIPL_ENABLED
errlHndl_t IntrRp::extractHbNodeInfo(void)
{
errlHndl_t err = NULL;
@@ -2488,7 +2345,7 @@ errlHndl_t IntrRp::extractHbNodeInfo(void)
return err;
}
-
+#endif
//----------------------------------------------------------------------------
// External interfaces
@@ -2503,6 +2360,7 @@ errlHndl_t INTR::registerMsgQ(msg_q_t i_msgQ,
// Can't add while handling an interrupt, so
// send msg instead of direct call
msg_q_t intr_msgQ = msg_q_resolve(VFS_ROOT_MSG_INTR);
+
if(intr_msgQ)
{
msg_t * msg = msg_allocate();
@@ -2524,7 +2382,6 @@ errlHndl_t INTR::registerMsgQ(msg_q_t i_msgQ,
}
msg_free(msg);
-
}
else
{
@@ -2547,6 +2404,7 @@ errlHndl_t INTR::registerMsgQ(msg_q_t i_msgQ,
0
);
}
+
return err;
}
@@ -2671,59 +2529,208 @@ errlHndl_t INTR::disableExternalInterrupts()
return err;
}
-errlHndl_t INTR::enablePsiIntr(TARGETING::Target * i_target)
+errlHndl_t IntrRp::setPsiHbBAR(TARGETING::Target * i_target)
{
- 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);
+ errlHndl_t l_err = NULL;
+ uint64_t l_baseBarValue =
+ i_target->getAttr<TARGETING::ATTR_PSI_BRIDGE_BASE_ADDR>();
- msg_sendrecv(intr_msgQ, msg);
+ do {
+ //Get base BAR Value from attribute
+ uint64_t l_barValue = l_baseBarValue;
- err = reinterpret_cast<errlHndl_t>(msg->data[1]);
- msg_free(msg);
- }
- else
+ TRACFCOMP(g_trac_intr,"INTR: Setting PSI BRIDGE Bar Address value for -"
+ " Target %p. PSI BRIDGE BAR value: 0x%016lx",
+ i_target,l_barValue);
+
+ //Set base BAR Value
+ uint64_t size = sizeof(l_barValue);
+ l_err = deviceWrite(i_target,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(PSI_BRIDGE_BAR_SCOM_ADDR));
+
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_intr,ERR_MRK"Unable to set PSI BRIDGE BAR Address");
+ break;
+ }
+
+ //Now set the enable bit
+ l_barValue += PSI_BRIDGE_BAR_ENABLE;
+ size = sizeof(l_barValue);
+
+ TRACDCOMP(g_trac_intr,"INTR: Setting PSI BRIDGE Bar enable value for Target - %p. PSI BRIDGE BAR value: 0x%016lx",
+ i_target,l_barValue);
+
+ l_err = deviceWrite(i_target,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(PSI_BRIDGE_BAR_SCOM_ADDR));
+
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_intr,ERR_MRK"Error enabling PSIHB BAR");
+ break;
+ }
+
+ //Map Memory Internally for HB and store in member variable
+ void *l_psiHbAddress =
+ reinterpret_cast<void *>(l_baseBarValue);
+ iv_psiHbBaseAddr =
+ reinterpret_cast<PSIHB_SW_INTERFACES_t *>
+ (mmio_dev_map(l_psiHbAddress, PAGE_SIZE));
+ } while(0);
+
+ return l_err;
+}
+
+errlHndl_t IntrRp::setPsiHbEsbBAR(TARGETING::Target * i_target,
+ bool i_enable)
+{
+ errlHndl_t l_err = NULL;
+ uint64_t l_baseBarValue
+ = i_target->getAttr<TARGETING::ATTR_PSI_HB_ESB_ADDR>();
+
+ do {
+
+ uint64_t l_barValue = l_baseBarValue;
+ TRACDCOMP(g_trac_intr,"INTR: Target %p. "
+ "PSI BRIDGE ESB BAR value: 0x%016lx",
+ i_target,l_barValue);
+
+ uint64_t size = sizeof(l_barValue);
+ l_err = deviceWrite(i_target,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(PSI_BRIDGE_ESB_BAR_SCOM_ADDR));
+
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_intr,ERR_MRK"Unable to set PSIHB ESB BAR ");
+ break;
+ }
+
+ //If we are trying to enable this BAR register
+ if (i_enable)
+ {
+ l_barValue += PSI_BRIDGE_ESB_BAR_VALID;
+ TRACDCOMP(g_trac_intr,"INTR: Target %p. PSI BRIDGE ESB BAR value: 0x%016lx",
+ i_target,l_barValue);
+
+ size = sizeof(l_barValue);
+ l_err = deviceWrite(i_target,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(PSI_BRIDGE_ESB_BAR_SCOM_ADDR));
+
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_intr,ERR_MRK"Error setting PSIHB ESB BAR");
+ break;
+ }
+
+ //Map Memory Internally for HB and store in member variable
+ void *l_psiHbEoiAddress =
+ reinterpret_cast<void *>(l_baseBarValue);
+ iv_psiHbEsbBaseAddr =
+ reinterpret_cast<uint64_t *>
+ (mmio_dev_map(l_psiHbEoiAddress, (LSI_LAST_SOURCE)*PAGE_SIZE));
+ }
+
+ } while (0);
+
+ return l_err;
+}
+
+errlHndl_t IntrRp::setXiveIvpeTmBAR1(TARGETING::Target * i_target)
+{
+ errlHndl_t l_err = NULL;
+ uint64_t l_baseBarValue =
+ i_target->getAttr<TARGETING::ATTR_XIVE_THREAD_MGMT1_BAR_ADDR>();
+
+ do
{
- /*@ 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
- *
- * @devdesc 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;
+ uint64_t l_barValue = l_baseBarValue + XIVE_IVPE_TM_BAR1_VALIDATE;
+
+ TRACDCOMP(g_trac_intr,"INTR: Target %p. XIVE IVPE TM BAR1 value: 0x%016lx",
+ i_target,l_barValue);
+
+ uint64_t size = sizeof(l_barValue);
+ l_err = deviceWrite(i_target,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(XIVE_IVPE_TM_BAR1_SCOM_ADDR));
+
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_intr,ERR_MRK"Unable to set XIVE IVPE TM BAR1");
+ break;
+ }
+
+ //Map Memory Internally for HB and store in member variable
+ void *l_xiveTmBar1Address =
+ reinterpret_cast<void *>(l_baseBarValue);
+ iv_xiveTmBar1Address =
+ reinterpret_cast<uint64_t *>
+ (mmio_dev_map(l_xiveTmBar1Address, PAGE_SIZE));
+
+ } while(0);
+
+ return l_err;
+}
+
+
+errlHndl_t IntrRp::setXiveIcBAR(TARGETING::Target * i_target)
+{
+ errlHndl_t l_err = NULL;
+ uint64_t l_baseBarValue
+ = i_target->getAttr<TARGETING::ATTR_XIVE_CONTROLLER_BAR_ADDR>();
+
+ do {
+ uint64_t l_barValue = l_baseBarValue + XIVE_IC_BAR_VALID;
+
+ TRACDCOMP(g_trac_intr,"INTR: Target %p. XIVE IC BAR value: 0x%016lx",
+ i_target,l_barValue);
+
+ uint64_t size = sizeof(l_barValue);
+ l_err = deviceWrite(i_target,
+ &l_barValue,
+ size,
+ DEVICE_SCOM_ADDRESS(XIVE_IC_BAR_SCOM_ADDR));
+
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_intr,ERR_MRK"Unable to set XIVE IC BAR");
+ break;
+ }
+
+ //Map Memory Internally for HB and store in member variable
+ void *l_xiveIcBarAddress =
+ reinterpret_cast<void *>(l_baseBarValue);
+ iv_xiveIcBarAddress =
+ reinterpret_cast<uint64_t *>
+ (mmio_dev_map(l_xiveIcBarAddress, 40*PAGE_SIZE));
+
+ } while(0);
+
+ return l_err;
}
-uint64_t INTR::getIntpAddr(const TARGETING::Target * i_ex, uint8_t i_thread)
+uint64_t INTR::getIntpAddr(const TARGETING::Target * i_ec, uint8_t i_thread)
{
- const TARGETING::Target * l_proc = getParentChip(i_ex);
+ const TARGETING::Target * l_proc = getParentChip(i_ec);
uint64_t l_intB =l_proc->getAttr<TARGETING::ATTR_INTP_BASE_ADDR>();
PIR_t pir(0);
- pir.groupId = l_proc->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();
+ pir.groupId = l_proc->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();
pir.chipId = l_proc->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
- pir.coreId = i_ex->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ pir.coreId = i_ec->getAttr<TARGETING::ATTR_CHIP_UNIT>();
pir.threadId = i_thread;
return (l_intB+ InterruptMsgHdlr::mmio_offset(
- pir.word & (InterruptMsgHdlr::P8_PIR_THREADID_MSK |
- InterruptMsgHdlr::P8_PIR_COREID_MSK)));
+ pir.word & (InterruptMsgHdlr::P9_PIR_THREADID_MSK |
+ InterruptMsgHdlr::P9_PIR_COREID_MSK)));
}
void* INTR::IntrRp::handleCpuTimeout(void* _pir)
@@ -2797,9 +2804,6 @@ errlHndl_t INTR::addHbNode(uint64_t i_hbNode)
return err;
}
-/*
- * Drain interrupt message queue (if present)
- */
void INTR::drainQueue()
{
// send a sync message if queue is found
@@ -2808,9 +2812,7 @@ void INTR::drainQueue()
{
msg_t * msg = msg_allocate();
msg->type = MSG_INTR_DRAIN_QUEUE;
-
msg_sendrecv(intr_msgQ, msg);
-
msg_free(msg);
}
//else no queue, no need to do anything
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index ca0fa83aa..23fd8c74c 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -92,7 +92,9 @@ namespace INTR
IntrRp() :
iv_msgQ(NULL),
iv_baseAddr(0),
- iv_masterCpu(0) {}
+ iv_masterCpu(0),
+ iv_psiHbBaseAddr(NULL),
+ iv_psiHbEsbBaseAddr(NULL) {}
/**
* Destructor
@@ -142,6 +144,7 @@ namespace INTR
PE0_IRSN_MASK_SCOM_ADDR = 0x0201201B, //INTR IRSN mask
PE0_BAREN_SCOM_ADDR = 0x02012045, //INTR enable/disable
+
PE1_IRSN_COMP_SCOM_ADDR = 0x0201241A, //INTR IRSN compare
PE1_IRSN_MASK_SCOM_ADDR = 0x0201241B, //INTR IRSN mask
PE1_BAREN_SCOM_ADDR = 0x02012445, //INTR enable/disable
@@ -161,6 +164,56 @@ namespace INTR
PSI_HBCR_AND_SCOM_ADDR = 0x02010913,
IPI_USR_PRIO = 0x2, //<! IPI priority from USR space
+
+ LSI_INTERRUPT = 0xC000,
+
+ //PSI Host Bridge Constants
+ PSI_BRIDGE_BAR_SCOM_ADDR = 0x0501290A,
+ PSI_BRIDGE_BAR_ENABLE = 0x0000000000000001ULL,
+ PSI_BRIDGE_ENABLE_CEC_INTERRUPT = 0x1000000000000000ULL,
+ PSI_BRIDGE_ESB_BAR_SCOM_ADDR = 0x05012916,
+
+ //PSI Host Bridge ESB Constants
+ PSI_BRIDGE_ESB_BAR_VALID = 0x0000000000000001ULL,
+ PSI_BRIDGE_ESB_OFF_OFFSET = 0xD00,
+ PSI_BRIDGE_ESB_RESET_OFFSET = 0XC00,
+ PSI_BRIDGE_PSU_DOORBELL_REG = 0x000D0063,
+ PSI_BRIDGE_PSU_HOST_DOORBELL = 0x8000000000000000,
+
+ //XIVE Interrupt Controller Constants
+ XIVE_IC_BAR_SCOM_ADDR = 0x05013010,
+ XIVE_IC_BAR_VALID = 0x8000000000000000ULL,
+ XIVE_IC_PHYSICAL_THREAD_ENABLE_OFFSET = 0x400,
+ XIVE_IC_BAR_INT_PC_MMIO_REG_OFFSET =
+ XIVE_IC_PHYSICAL_THREAD_ENABLE_OFFSET/sizeof(uint64_t),
+ XIVE_IC_THREAD0_ENABLE = 0x8000000000000000ULL,
+ XIVE_IC_ESB_EOI_OFFSET = 0x3000,
+ XIVE_IC_LSI_EOI_OFFSET =
+ XIVE_IC_ESB_EOI_OFFSET/sizeof(uint64_t),
+
+ //XIVE IVPE (Presentation Engine) Constants
+ XIVE_IVPE_TM_BAR1_SCOM_ADDR = 0x05013012,
+ XIVE_IVPE_TM_BAR1_MMIO_OFFSET = 0x0006020000000000ULL,
+ XIVE_IVPE_TM_BAR1_VALIDATE = 0x8000000000000000ULL,
+ XIVE_IVPE_QW3_OFFSET = 0x38,
+ XIVE_IVPE_QW3_LSI_ENABLE = 0x81000000,
+
+ PSI_BRIDGE_INTP_STATUS_CTL_SCOM_ADDR = 0x0501290E,
+ PSI_BRIDGE_INTP_STATUS_CTL_ENABLE = 0x8000000000000000ULL,
+ PSI_BRIDGE_INTP_STATUS_CTL_RESET = 0x4000000000000000ULL,
+
+ XIVE_RESET_INT_CQ_RST_CTL_SCOM_ADDR = 0x05013023,
+ XIVE_RESET_POWERBUS_QUIESCE_ENABLE = 0x4000000000000000,
+ XIVE_RESET_POWERBUS_QUIESCE_TIMEOUT = 1000000, //1 millisecond
+ XIVE_RESET_UNIT_ENABLE = 0x8000000000000000,
+ ACK_HYPERVISOR_INT_REG_OFFSET = 0x830/sizeof(uint16_t),
+ POWERBUS_STATE_QUIESCE = 0xC000000000000000,
+ MAX_PSU_LONG_TIMEOUT_NS = 100000*NS_PER_MSEC,
+
+ ESB_STATE_RESET = 0,
+ ESB_STATE_OFF = 1,
+ ESB_STATE_PENDING = 2,
+ ESB_STATE_QUEUED = 3,
};
enum INTR_ROUTING_t
@@ -199,88 +252,76 @@ namespace INTR
};
};
- /**
- * This is the Interrupt Requestoer Source Compare Register.
- * See Book IV, PSI chapter.
- */
- struct PSIHB_ISRN_REG_t
+ //Derived from 15.8 PSIHB Software Interfaces of the
+ // P9 Pervasive Workbook
+ struct PSIHB_SW_INTERFACES_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
- {
- 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) {}
+ uint64_t psihbbar; //Host Bridge Base Address Register - 0x0
+ uint64_t fspbar; //FSP Base Address Register - 0x8
+ uint64_t fspmmr; //FSP Memory Mask Register - 0x10
+ uint64_t reserved1; //Unused / Reserved
+ uint64_t psihbcr; //PSI Host Bridge Ctrl/Status Register - 0x20
+ uint64_t psisemr; //PSIHB Status / Error Mask Register - 0x28
+ uint64_t reserved2; //Unused / Reserved
+ uint64_t phbdsr; //PSIHB Debug Setting register - 0x38
+ uint64_t phbscr; //PSI Host Bridge Ctrl/Status Register - 0x40
+ uint64_t phbccr; //PSI Host Bridge clear ctl/status reg - 0x48
+ uint64_t dmaupaddr; //DMA Upper Address Register - 0x50
+ uint64_t icr; //Interrupt Control Register - 0x58
+ uint64_t esbciaddr; //ESB CI Base Address - 0x60
+ uint64_t esbnotifaddr; //ESB Notification Address - 0x68
+ uint64_t ivtofforig; //IVT Offset Origin Register - 0x70
+ uint64_t lsiintlevel; //LSI Int Level Register (lab use) - 0x78
+ uint64_t lsiintstatus; //LSI Interrupt Status register - 0x80
};
- /**
- * @brief PsiHbXivr Layout for XIVR registers.
- */
- struct PsiHbXivr
+ //Found in the PC Register Specification Document
+ struct XIVE_IC_THREAD_CONTEXT_t
{
- enum
- {
- PRIO_DISABLED = 0xff,
-
- OCC_PRIO = 0x30,
- FSI_PRIO = 0x20,
- LPC_PRIO = 0x40,
- LCL_ERR_PRIO = 0x10,
- HOST_PRIO = 0x50,
- PSI_PRIO = 0x60,
-
- PSI_XIVR_ADRR = 0x02010910,
- OCC_XIVR_ADRR = 0x02010916,
- FSI_XIVR_ADRR = 0x02010917,
- LPC_XIVR_ADRR = 0x02010918,
- LCL_ERR_XIVR_ADDR = 0x02010919,
- HOST_XIVR_ADRR = 0x0201091A,
- };
-
-
- 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) {}
+ uint64_t tctxt_cfg; // 0x00
+ uint64_t tctxt_track; // 0x08
+ uint64_t unused0; // 0x10
+ uint64_t unused1; // 0x18
+ uint64_t ind_thread_context_access0; //0x20
+ uint64_t ind_thread_context_access1; //0x28
+ uint64_t ind_thread_context_access2; //0x30
+ uint64_t ind_thread_context_access3; //0x38
+ uint64_t phys_thread_enable0; //0x40
+ uint64_t phys_thread_enable0_set; //0x48
+ uint64_t phys_thread_enable0_reset; //0x50
+ uint64_t unused3; //0x58
+ uint64_t phys_thread_enable1; //0x60
+ uint64_t phys_thread_enable1_set; //0x68
+ uint64_t phys_thread_enable1_reset; //0x70
};
+ //Found in External Interrupt Virtualization Engine (XIVE) Document
+ // in Chapter 4.4 - Per Thread Interrupt Management Area
+ struct XIVE_IVPE_THREAD_CONTEXT_t
+ {
+ uint64_t qw0_0;
+ uint64_t qw0_1;
+ uint64_t qw1_0;
+ uint64_t qw1_1;
+ uint64_t qw2_0;
+ uint64_t qw2_1;
+ uint8_t nsr; //Notification Source Register - 0x0
+ uint8_t cppr; //Current processor priority register - 0x1
+ uint8_t ipb; //Interrupt pending buffer - 0x2
+ uint8_t lsmfb; //logical server most favored backlog - 0x3
+ uint8_t ack; //O/S Interrupt Acknowledge Counter - 0x4
+ uint8_t inc; //Age increment - 0x5
+ uint8_t age; //Thread age since last selected - 0x6
+ uint8_t pipr; //Pending Interrupt Priority Register - 0x7
+ uint32_t cams; //qw0/1/2/3 - 0x8
+ };
+ #define PSIHB_SW_INTERFACES_SIZE (sizeof(PSIHB_SW_INTERFACES_t))
+ #define XIVE_IVPE_THREAD_CONTEXT_SIZE (sizeof(XIVE_IVPE_THREAD_CONTEXT_t))
+ /**
+ * This is the Interrupt Requester Source Compare Register.
+ * See Book IV, PSI chapter.
+ */
struct intr_response_t
{
msg_q_t msgQ;
@@ -318,6 +359,11 @@ namespace INTR
Registry_t iv_registry; //!< registered interrupt type
uint64_t iv_baseAddr; //!< Base address of hw INTR regs
PIR_t iv_masterCpu; //!< Master cpu PIR
+
+ PSIHB_SW_INTERFACES_t *iv_psiHbBaseAddr; //INTR PSIHB regs base addr
+ uint64_t *iv_psiHbEsbBaseAddr; //INTR PSIHB ESB regs base addr
+ uint64_t *iv_xiveIcBarAddress; //XIVE Controller regs base addr
+ uint64_t *iv_xiveTmBar1Address; //Xive Thread mgmt bar reg 1 addr
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
@@ -410,12 +456,91 @@ namespace INTR
void sendIPI(const PIR_t i_pir) const;
/**
- * Set the IPCBAR scom register
+ * Mask all PSIHB Interrupt Sources which will block any
+ * interrupts from the PSIHB to be sent to the HB kernel.
+ * @return Errorlog from masking the sources
+ */
+ errlHndl_t maskAllInterruptSources(void);
+
+ /**
+ * Mask specific PSIHB Interrupt source
+ * @param[in] i_intr_source, The interrupt source to be masked
+ * @return Errorlog from masking the source
+ */
+ errlHndl_t maskInterruptSource(uint8_t i_intr_source);
+
+ /**
+ * Unmask (enable) specific PSIHB Interrupt source
+ * @param[in] i_intr_source, The interrupt source to be unmasked
+ * @return Errorlog from unmasking the source
+ */
+ errlHndl_t unmaskInterruptSource(uint8_t i_intr_source);
+
+ /**
+ * Set all of the Interrupt BAR scom registers
* @param[in] i_target, the Target.
- * @param[in] i_pir, The pir for this processor
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t setInterruptBARs(TARGETING::Target * i_target);
+
+ /**
+ * Perform HW Functions to acknowledge Interrupt which will
+ * stop the interrupt from being re-presented by HW
+ */
+ void acknowledgeInterrupt(void);
+
+ /**
+ * Send EOI (End of Interrupt) sequence
+ * @param[in] i_intSource, interrupt source to perform EOI for
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t sendEOI(uint64_t& i_intSource);
+
+ /**
+ * Handle Interrupt from PSU Source
+ * - Acknowledge Interrupt
+ * - Clear Interrupt Condition
+ * - Issue EOI
+ * @param[in] i_type, interrupt type encountered
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t handlePsuInterrupt(ext_intr_t i_type);
+
+ /**
+ * Set the PSI Host Bridge BAR scom register
+ * @param[in] i_target, the Target.
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t setPsiHbBAR(TARGETING::Target * i_target);
+
+ /**
+ * Set the PSI Host Bridge ESB BAR scom register
+ * @param[in] i_target, the Target.
+ * @param[in] i_enable, indicator to enable/disable the BAR
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t setPsiHbEsbBAR(TARGETING::Target * i_target,
+ bool i_enable);
+
+ /**
+ * Set the XIVE Thread Management (TM) BAR1 scom register
+ * @param[in] i_target, the Target.
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t setXiveIvpeTmBAR1(TARGETING::Target * i_target);
+
+ /**
+ * Set the XIVE Interrupt Controller (IC) BAR scom register
+ * @param[in] i_target, the Target.
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t setXiveIcBAR(TARGETING::Target * i_target);
+
+ /**
+ * Reset Interrupt Unit (both the XIVE and PSIHB Interrupt Units)
+ * @return Errorlog from DeviceWrite
*/
- errlHndl_t setBAR(TARGETING::Target * i_target,
- const PIR_t i_pir);
+ errlHndl_t resetIntUnit();
/**
* Initialize the IRSCReg to enable PSI to present interrupts
diff --git a/src/usr/intr/test/intrtest.H b/src/usr/intr/test/intrtest.H
index 320f38a12..a1d6ee3bd 100644
--- a/src/usr/intr/test/intrtest.H
+++ b/src/usr/intr/test/intrtest.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* [+] 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. */
@@ -49,7 +51,7 @@ class IntrTest: public CxxTest::TestSuite
*/
void test_verifyState( void )
{
-
+/* TODO RTC 150260
uint32_t * addr = reinterpret_cast<uint32_t *>(iv_masterAddr);
if(*addr != 0xFF000000) // XIRR ro reg
@@ -95,6 +97,7 @@ class IntrTest: public CxxTest::TestSuite
}
// Potentially could check all link registers on other chips
+**/
}
/**
@@ -103,6 +106,7 @@ class IntrTest: public CxxTest::TestSuite
void test_enableDisable( void )
{
+/* TODO RTC 150260
uint32_t * addr = reinterpret_cast<uint32_t *>(iv_masterAddr);
errlHndl_t err = INTR::disableExternalInterrupts();
@@ -133,6 +137,7 @@ class IntrTest: public CxxTest::TestSuite
{
TS_FAIL("INTR not enabled. Addr %p", addr);
}
+**/
}
// This checks the enablePsiIntr. Even though the master proc
@@ -141,6 +146,7 @@ class IntrTest: public CxxTest::TestSuite
// to test with.
void test_enablePsi( void )
{
+/* TODO RTC 150260
errlHndl_t err = NULL;
if( TARGETING::is_vpo() )
{
@@ -156,10 +162,12 @@ class IntrTest: public CxxTest::TestSuite
TS_FAIL("Errl from INTER::enablePsiIntr");
errlCommit(err,INTR_COMP_ID);
}
+**/
}
void test_mpipl_node_data( void )
{
+/* TODO RTC 150260
errlHndl_t err = NULL;
for(uint64_t hb_node = 0; hb_node < MAX_NODES_PER_SYS; ++hb_node)
{
@@ -221,16 +229,24 @@ class IntrTest: public CxxTest::TestSuite
{
TS_FAIL("INTR Could not map memory of NODE_DATA_AREA");
}
-
+**/
}
IntrTest() : CxxTest::TestSuite()
{
+/* TODO RTC 150260
+ TARGETING::Target* procTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle( procTarget );
+ // Set the Interrupt BAR Scom Registers
+ l_err = setInterruptBARs(procTarget);
+
iv_baseAddr = reinterpret_cast<uint64_t>
(mmio_dev_map(reinterpret_cast<void*>(cv_realAddr),THIRTYTWO_MB));
- TRACDCOMP(g_trac_intr,"IntrTest()> iv_baseAddr=0x%.X",iv_baseAddr);
+ TRACFCOMP(g_trac_intr,"IntrTest()> iv_baseAddr=0x%.X",iv_baseAddr);
+
+
task_affinity_pin(); // pin this task to current cpu
task_affinity_migrate_to_master(); // Move to the master cpu
@@ -238,7 +254,7 @@ class IntrTest: public CxxTest::TestSuite
// Get the master cpu id, thread 0
iv_masterPIR = task_getcpuid();
- TRACDCOMP(g_trac_intr,"IntrTest()> iv_masterPIR=0x%.X",iv_masterPIR);
+ TRACFCOMP(g_trac_intr,"IntrTest()> iv_masterPIR=0x%.X",iv_masterPIR);
iv_masterPIR &= 0xFFFFFFF8;
@@ -246,24 +262,31 @@ class IntrTest: public CxxTest::TestSuite
iv_masterAddr = InterruptMsgHdlr::mmio_offset(iv_masterPIR) + iv_baseAddr;
+**/
};
~IntrTest()
{
+/* TODO RTC 150260
mmio_dev_unmap(reinterpret_cast<void*>(iv_baseAddr));
+**/
};
private:
+/* TODO RTC 150260
uint64_t iv_baseAddr;
uint64_t iv_masterAddr;
cpuid_t iv_masterPIR;
static const uint64_t cv_realAddr;
+**/
};
+/* TODO RTC 150260
//note: this must be changed if the BAR changes
const uint64_t IntrTest::cv_realAddr = 0x3ffff80000000ul;
+**/
diff --git a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
index a3a11e59e..f62982465 100644
--- a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
+++ b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
@@ -289,14 +289,15 @@ void* call_proc_exit_cache_contained (void *io_pArgs)
// End of Add P9 - Fake trigger for memory expansion
//Set PSI and FSP BARs, activate the PSI link BAR
- uint64_t psi = l_masterProc->getAttr<ATTR_PSI_BRIDGE_BASE_ADDR>();
+ //TODO RTC 150260 Re-evaluate if this should be deleted or enabled
+// uint64_t psi = l_masterProc->getAttr<ATTR_PSI_BRIDGE_BASE_ADDR>();
uint64_t fsp = l_masterProc->getAttr<ATTR_FSP_BASE_ADDR>();
- psi |= 0x1; //turn on enable bit for PSI, FSP is in PSI Init HWP
+// psi |= 0x1; //turn on enable bit for PSI, FSP is in PSI Init HWP
- l_errl = deviceWrite( l_masterProc,
- &psi,
- scom_size,
- DEVICE_SCOM_ADDRESS(0x0501290a) );
+// l_errl = deviceWrite( l_masterProc,
+// &psi,
+// scom_size,
+// DEVICE_SCOM_ADDRESS(0x0501290a) );
if ( l_errl )
{
// Create IStep error log and cross reference to error that
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index 9f8a90d24..e3a2c2dbf 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -46,7 +46,7 @@
#include <sys/misc.h>
#include <errl/errludprintk.H>
#include <errno.h>
-#include <sys/time.h>
+#include <kernel/console.H>
#include <arch/pirformat.H>
// Local functions
@@ -112,49 +112,6 @@ void* MailboxSp::msg_handler(void * unused)
return NULL;
}
-// helper function to start mailbox message handler
-// @todo RTC:126643 Remove poller when interrupts avail
-void* MailboxSp::poller(void * unused)
-{
- TRACFCOMP(g_trac_mbox, "start MBOX::pollTask");
- Singleton<MailboxSp>::instance().pollTask();
- return NULL;
-}
-
-// @todo RTC:126643 Remove pollTask when interrupts avail
-void MailboxSp::pollTask()
-{
- int rc = 0;
-
- msg_q_t mboxQ = msg_q_resolve(VFS_ROOT_MSG_MBOX);
- if(mboxQ)
- {
- //Loop until there is a shutdown request AND quiesced
- while(!(iv_shutdown_msg && quiesced()))
- {
- msg_t * msg = msg_allocate();
- msg->type = MSG_INTR;
- msg->data[0] = 0;
- msg->data[1] = 0;
-
- rc = msg_sendrecv(mboxQ, msg);
-
- msg_free(msg);
-
- if (rc)
- {
- TRACFCOMP(g_trac_mbox, ERR_MRK
- "MBOX::pollTask msg_sendrecv() failed. errno = %d",
- rc);
- break;
- }
-
- nanosleep(0, NS_PER_MSEC*100);
- }
- }
-}
-
-
errlHndl_t MailboxSp::_init()
{
errlHndl_t err = NULL;
@@ -197,20 +154,21 @@ errlHndl_t MailboxSp::_init()
if(mbxComm)
{
- // Initialize the mailbox hardware
- err = mboxInit(iv_trgt);
+ //TODO RTC 150260 Move after init after mask issues resolved
+ // Register to get interrupts for mailbox
+ err = INTR::registerMsgQ(iv_msgQ,
+ MSG_INTR,
+ INTR::LSI_FSIMBOX);
+
if (err)
{
return err;
}
-#if (0) // @todo RTC:126643
- // Register to get interrupts for mailbox
- err = INTR::registerMsgQ(iv_msgQ,
- MSG_INTR,
- INTR::FSP_MAILBOX);
-#endif
- if(err)
+ // Initialize the mailbox hardware
+ err = mboxInit(iv_trgt);
+
+ if (err)
{
return err;
}
@@ -242,9 +200,6 @@ errlHndl_t MailboxSp::_init()
MSG_MBOX_SHUTDOWN,
INITSERVICE::MBOX_PRIORITY);
- //@todo RTC:126643 -- poll mbox until interrupts are working
- task_create(MailboxSp::poller, NULL);
-
}
// else leave iv_disabled as true;
@@ -287,20 +242,21 @@ void MailboxSp::msgHandler()
continue;
}
+ printkd("mbox received type: %d\n", (uint32_t) msg->type);
+
// Now look for other messages
switch(msg->type)
{
// Interrupt from the mailbox hardware
case MSG_INTR:
{
+ printkd("MSG_INTR type - handling interrupt\n");
err = handleInterrupt();
-#if 0 // @todo RTC:126643 Remove poller and turn on when interrupts are working
+
+ printkd("MSG_INTR type - sending EOI\n");
// Respond to the interrupt handler regardless of err
INTR::sendEOI(iv_msgQ,msg);
-#else
- msg_respond(iv_msgQ,msg);
-#endif
// err will be set if scom failed in mbox DD
// or MBOX_DATA_WRITE_ERR - serious - assert
diff --git a/src/usr/targeting/common/genHwsvMrwXml.pl b/src/usr/targeting/common/genHwsvMrwXml.pl
index 0775db90b..6d80bdc07 100755
--- a/src/usr/targeting/common/genHwsvMrwXml.pl
+++ b/src/usr/targeting/common/genHwsvMrwXml.pl
@@ -3347,8 +3347,14 @@ sub generate_proc
0x0006030203180000 + $nodeSize*$lognode + $chipSize*$logid );
printf( " </attribute>\n" );
+ #XIVE - Thread Management Bar Address register 1
+ printf( " <attribute><id>XIVE_THREAD_MGMT1_BAR_ADDR</id>\n" );
+ printf( " <default>0x%016X</default>\n",
+ 0x0006020000000000 + $nodeSize*$lognode + $chipSize*$logid );
+ printf( " </attribute>\n" );
+
#PSI HB - ESP space address
- printf( " <attribute><id>PSI_HB_ESP_ADDR</id>\n" );
+ printf( " <attribute><id>PSI_HB_ESB_ADDR</id>\n" );
printf( " <default>0x%016X</default>\n",
0x00060302031C0000 + $nodeSize*$lognode + $chipSize*$logid );
printf( " </attribute>\n" );
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index be09f240c..ad989a825 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -17360,7 +17360,20 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
</attribute>
<attribute>
- <id>PSI_HB_ESP_ADDR</id>
+ <id>XIVE_THREAD_MGMT1_BAR_ADDR</id>
+ <description>XIVE - Thread Management Bar address register 1
+ MMIO consumed by HB/PHYP
+ </description>
+ <simpleType>
+ <uint64_t></uint64_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+
+<attribute>
+ <id>PSI_HB_ESB_ADDR</id>
<description>PSIHB - ESB space address - MMIO consumed by PHYP
</description>
<simpleType>
diff --git a/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml b/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml
index c6deca575..3682337c1 100644
--- a/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml
@@ -217,6 +217,15 @@
<attribute><id>PSI_BRIDGE_BASE_ADDR</id>
<default>0x0006030203000000</default>
</attribute>
+ <attribute><id>PSI_HB_ESB_ADDR</id>
+ <default>0x00060302031C0000</default>
+ </attribute>
+ <attribute><id>XIVE_CONTROLLER_BAR_ADDR</id>
+ <default>0x0006030203100000</default>
+ </attribute>
+ <attribute><id>XIVE_THREAD_MGMT1_BAR_ADDR</id>
+ <default>0x0006020000000000</default>
+ </attribute>
<attribute><id>INTP_BASE_ADDR</id>
<default>0x0003FFFF80300000</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index efe6a3d8a..f7ca36667 100755
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -2125,7 +2125,8 @@
<attribute><id>NVIDIA_PHY1_REG_ADDR</id></attribute>
<attribute><id>XIVE_CONTROLLER_BAR_ADDR</id></attribute>
<attribute><id>XIVE_PRESENTATION_BAR_ADDR</id></attribute>
- <attribute><id>PSI_HB_ESP_ADDR</id></attribute>
+ <attribute><id>PSI_HB_ESB_ADDR</id></attribute>
+ <attribute><id>XIVE_THREAD_MGMT1_BAR_ADDR</id></attribute>
<attribute><id>NX_RNG_ADDR</id></attribute>
<!-- end Memory Map -->
OpenPOWER on IntegriCloud