aboutsummaryrefslogtreecommitdiff
path: root/hw/psi.c
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2021-08-04 12:51:18 +0530
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-08-06 12:28:15 +0530
commitd1e8ed0cbfcbd69786ca33a62afeafac223fcf58 (patch)
treeb1d40705d1e3eccb8e12be8c7adb5f4ecab6ae83 /hw/psi.c
parent8784c881690a17a4d18679fb0f4821448597d6f1 (diff)
downloadskiboot-d1e8ed0cbfcbd69786ca33a62afeafac223fcf58.zip
skiboot-d1e8ed0cbfcbd69786ca33a62afeafac223fcf58.tar.gz
skiboot-d1e8ed0cbfcbd69786ca33a62afeafac223fcf58.tar.bz2
hw/psi-p10: Configure interrupt offset before notify addr
When configuring the XIVE notification address any currently pending interrupts will be delivered once the the valid bit in the BAR is set. Currently we enable the notify BAR before we've configured the global interrupt number offset for the PSI interrupts. If any PSI interrupt is we'll send an interrupt trigger notification to the XIVE with the wrong interrupt vector (0..15). This can potentially cause a checkstop since there may not be an EAS / IVT configure for that vector. Fix this by registering and masking all the PSI interrupts after we've configured the ESB BAR, but before configuring the notification address and offset. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw/psi.c')
-rw-r--r--hw/psi.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/hw/psi.c b/hw/psi.c
index 954b7bf..de074ce 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -796,16 +796,6 @@ static void psi_init_p10_interrupts(struct psi *psi)
flags |= XIVE_SRC_STORE_EOI;
}
- /* Grab and configure the notification port */
- val = xive2_get_notify_port(psi->chip_id, XIVE_HW_SRC_PSI);
- val |= PSIHB_ESB_NOTIF_VALID;
- out_be64(psi->regs + PSIHB_ESB_NOTIF_ADDR, val);
-
- /* Setup interrupt offset */
- val = xive2_get_notify_base(psi->interrupt);
- val <<= 32;
- out_be64(psi->regs + PSIHB_IVT_OFFSET, val);
-
/* Register sources */
prlog(PR_DEBUG,
"PSI[0x%03x]: Interrupts sources registered for P10 DD%i.%i\n",
@@ -820,6 +810,16 @@ static void psi_init_p10_interrupts(struct psi *psi)
for (isn = is->start; isn < is->end; isn++)
xive2_source_mask(is, isn);
+ /* Setup interrupt offset */
+ val = xive2_get_notify_base(psi->interrupt);
+ val <<= 32;
+ out_be64(psi->regs + PSIHB_IVT_OFFSET, val);
+
+ /* Grab and configure the notification port */
+ val = xive2_get_notify_port(psi->chip_id, XIVE_HW_SRC_PSI);
+ val |= PSIHB_ESB_NOTIF_VALID;
+ out_be64(psi->regs + PSIHB_ESB_NOTIF_ADDR, val);
+
/* Reset irq handling and switch to ESB mode */
out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, PSIHB_IRQ_RESET);
out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, 0);