summaryrefslogtreecommitdiffstats
path: root/src/usr/intr/intrrp.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/intr/intrrp.H')
-rw-r--r--src/usr/intr/intrrp.H131
1 files changed, 105 insertions, 26 deletions
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index a8a1eafba..f5ebae4f6 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -98,9 +98,7 @@ namespace INTR
IntrRp() :
iv_msgQ(NULL),
iv_baseAddr(0),
- iv_masterCpu(0),
- iv_psiHbBaseAddr(NULL),
- iv_psiHbEsbBaseAddr(NULL) {}
+ iv_masterCpu(0) {}
/**
* Destructor
@@ -179,9 +177,11 @@ namespace INTR
PSI_BRIDGE_BAR_ENABLE = 0x0000000000000001ULL,
PSI_BRIDGE_ENABLE_CEC_INTERRUPT = 0x1000000000000000ULL,
PSI_BRIDGE_ESB_BAR_SCOM_ADDR = 0x05012916,
+ PSI_BRIDGE_ENABLE_LSI_INTR_REMOTE = 0x0000000000000000ULL,
//PSI Host Bridge ESB Constants
PSI_BRIDGE_ESB_BAR_VALID = 0x0000000000000001ULL,
+ PSI_BRIDGE_ESB_NOTIFY_VALID = 0x0000000000000001ULL,
PSI_BRIDGE_ESB_OFF_OFFSET = 0xD00,
PSI_BRIDGE_ESB_RESET_OFFSET = 0XC00,
PSI_BRIDGE_PSU_DOORBELL_REG = 0x000D0063,
@@ -194,6 +194,7 @@ namespace INTR
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_LSI_TRIGGER_PAGE_OFFSET = 0x2000,
XIVE_IC_ESB_EOI_OFFSET = 0x3000,
XIVE_IC_LSI_EOI_OFFSET =
XIVE_IC_ESB_EOI_OFFSET/sizeof(uint64_t),
@@ -279,7 +280,7 @@ namespace INTR
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 esbnotifyaddr; //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
@@ -355,6 +356,20 @@ namespace INTR
};
+ struct intr_hdlr_t
+ {
+ TARGETING::Target *proc;
+ PSIHB_SW_INTERFACES_t *psiHbBaseAddr;
+ uint64_t *psiHbEsbBaseAddr;
+ uint64_t *xiveIcBarAddr;
+
+ intr_hdlr_t(): proc(NULL), psiHbBaseAddr(NULL),
+ psiHbEsbBaseAddr(NULL) {}
+ intr_hdlr_t(TARGETING::Target *i_target) :
+ proc(i_target), psiHbBaseAddr(NULL),
+ psiHbEsbBaseAddr(NULL) {}
+ };
+
enum
{
CPU_WAKEUP_SECONDS = 1,
@@ -365,21 +380,26 @@ namespace INTR
typedef std::map<ext_intr_t,intr_response_t> Registry_t;
typedef std::vector<PIR_t> CpuList_t;
- typedef std::vector<TARGETING::Target *> ChipList_t;
- typedef std::vector<ISNvalue_t> ISNList_t;
+ typedef std::vector<intr_hdlr_t *> ChipList_t;
+ typedef std::vector<ISNvalue_t> ISNList_t;
+ typedef std::vector<uint8_t> MaskList_t;
+ typedef std::vector< std::pair<PIR_t,ext_intr_t> >PendingIntrList_t;
msg_q_t iv_msgQ; //!< Kernel Interrupt message queue
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
+ intr_hdlr_t *iv_masterHdlr; //!< Master cpu interrupt handler
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
+ MaskList_t iv_maskList; //!< List of interrput sources which
+ // are masked
+ PendingIntrList_t iv_pendingIntr; //!< List of pending interrupts
+ // That haven't been EOI'ed
typedef std::pair<uint64_t, msg_t*> IPI_Info_t;
typedef std::map<PIR_t, IPI_Info_t> IPI_Pending_t;
@@ -442,8 +462,10 @@ namespace INTR
/**
* Enable hardware to reporting external interrupts
+ * @param[in] i_proc Proc handler for processor to enable
+ * interrupts for
*/
- errlHndl_t enableInterrupts();
+ errlHndl_t enableInterrupts(intr_hdlr_t *i_proc) ;
/**
* Disable hardware from reporting external interupts
@@ -473,7 +495,16 @@ namespace INTR
* interrupts from the PSIHB to be sent to the HB kernel.
* @return Errorlog from masking the sources
*/
- errlHndl_t maskAllInterruptSources(void);
+ errlHndl_t maskAllInterruptSources();
+
+ /**
+ * Mask specific PSIHB Interrupt source
+ * @param[in] i_intr_source, The interrupt source to be masked
+ * @param[in] i_proc, The proc interrupt handler
+ * @return Errorlog from masking the source
+ */
+ errlHndl_t maskInterruptSource(uint8_t i_intr_source,
+ intr_hdlr_t *i_proc);
/**
* Mask specific PSIHB Interrupt source
@@ -485,16 +516,28 @@ namespace INTR
/**
* Unmask (enable) specific PSIHB Interrupt source
* @param[in] i_intr_source, The interrupt source to be unmasked
+ * @param[in] i_proc, The proc interrupt handler to unmask the
+ * given interrupt source for
* @return Errorlog from unmasking the source
*/
- errlHndl_t unmaskInterruptSource(uint8_t i_intr_source);
+ errlHndl_t unmaskInterruptSource(uint8_t i_intr_source,
+ intr_hdlr_t *i_proc);
/**
- * Set all of the Interrupt BAR scom registers
+ * Set all of the Interrupt BAR scom registers specific
+ * to the master chip.
* @param[in] i_target, the Target.
* @return Errorlog from DeviceWrite
*/
- errlHndl_t setInterruptBARs(TARGETING::Target * i_target);
+ errlHndl_t setMasterInterruptBARs(TARGETING::Target * i_target);
+
+ /**
+ * Set all of the Interrupt BAR scom registers common
+ * to all the chips (procs)
+ * @param[in] i_proc, the interrupt handler for one chip
+ * @return Errorlog from DeviceWrite
+ */
+ errlHndl_t setCommonInterruptBARs(intr_hdlr_t * i_proc);
/**
* Perform HW Functions to acknowledge Interrupt which will
@@ -505,9 +548,22 @@ namespace INTR
/**
* Send EOI (End of Interrupt) sequence
* @param[in] i_intSource, interrupt source to perform EOI for
- * @return Errorlog from DeviceWrite
+ * @param[in] i_pir, The PIR value for the proc where the
+ * interrupt condtion occurred
+ * @return Errorlog from DeviceWriste
*/
- errlHndl_t sendEOI(uint64_t& i_intSource);
+ errlHndl_t sendEOI(uint64_t& i_intSource, PIR_t& i_pir);
+
+ /**
+ * Route Interrupt to correct listener
+ * @param[in] i_proc, the proc intrp handler
+ * @param[in] i_type, the interrupt type
+ * @param[in] i_pir, the pir value for the proc the interrupt
+ * was seen on
+ */
+ void routeInterrupt(intr_hdlr_t* i_proc,
+ ext_intr_t i_type,
+ PIR_t& i_pir);
/**
* Handle Interrupt from PSU Source
@@ -515,48 +571,54 @@ namespace INTR
* - Clear Interrupt Condition
* - Issue EOI
* @param[in] i_type, interrupt type encountered
+ * @param[in] i_proc, The proc interrupt handler for the proc
+ * the interrupt occurred on
+ * param[in] i_pir, The PIR value for the proc the interrupt
+ * was seen on
* @return Errorlog from DeviceWrite
*/
- errlHndl_t handlePsuInterrupt(ext_intr_t i_type);
+ errlHndl_t handlePsuInterrupt(ext_intr_t i_type,
+ intr_hdlr_t* i_proc,
+ PIR_t& i_pir);
/**
* Set the PSI Host Bridge BAR scom register
- * @param[in] i_target, the Target.
+ * @param[in] i_proc, the proc intrp handler
* @return Errorlog from DeviceWrite
*/
- errlHndl_t setPsiHbBAR(TARGETING::Target * i_target);
+ errlHndl_t setPsiHbBAR(intr_hdlr_t* i_proc);
/**
* Set the PSI Host Bridge ESB BAR scom register
- * @param[in] i_target, the Target.
+ * @param[in] i_proc, the proc intrp handler.
* @param[in] i_enable, indicator to enable/disable the BAR
* @return Errorlog from DeviceWrite
*/
- errlHndl_t setPsiHbEsbBAR(TARGETING::Target * i_target,
+ errlHndl_t setPsiHbEsbBAR(intr_hdlr_t* i_proc,
bool i_enable);
/**
* Set the XIVE Thread Management (TM) BAR1 scom register
- * @param[in] i_target, the Target.
+ * @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.
+ * @param[in] i_proc, the proc intrp handler
* @return Errorlog from DeviceWrite
*/
- errlHndl_t setXiveIcBAR(TARGETING::Target * i_target);
+ errlHndl_t setXiveIcBAR(intr_hdlr_t* i_proc);
/**
* When in LSI mode the IC VPC flags and error, thus we
* need to disable while we use, and enable after we clean
* up
- * @param[in] i_target, the Target.
+ * @param[in] i_proc, the proc intrp handler
* @return Errorlog from DeviceWrite
*/
- errlHndl_t disableVPCPullErr(TARGETING::Target * i_target);
+ errlHndl_t disableVPCPullErr(intr_hdlr_t* i_proc);
/**
* When in LSI mode the IC VPC flags and error, thus we
@@ -569,9 +631,26 @@ namespace INTR
/**
* Reset Interrupt Unit (both the XIVE and PSIHB Interrupt Units)
+ * @param[in] i_proc, the proc intrp handler
* @return Errorlog from DeviceWrite
*/
- errlHndl_t resetIntUnit();
+ errlHndl_t resetIntUnit(intr_hdlr_t* i_proc);
+
+ /**
+ * Setup structures, BAR Regs, Mask interrupts, and enable interrupt
+ * routing on non-master proc chip
+ * @param[in] i_target, the proc Target to enable
+ * @return Errorlog from enablement steps
+ */
+ errlHndl_t enableSlaveProcInterrupts(TARGETING::Target * i_target);
+
+ /**
+ * Set correct PSIHB Regs to route + enable LSI interrupts from
+ * non-master proc to correct address on master proc
+ * @param[in] i_proc, the proc intrp handler
+ * @return void
+ */
+ void enableSlaveProcInterruptRouting(intr_hdlr_t* i_proc);
/**
* Initialize the IRSCReg to enable PSI to present interrupts
OpenPOWER on IntegriCloud