[Skiboot] [PATCH] occ: Send self-interrupt to chip with active PSI

Joel Stanley joel at jms.id.au
Tue May 5 11:28:59 AEST 2015


We were previously asking the OCC of the current chip to generate
the self interrupt. If Hostboot does not configure all the PSI Host
Bridges, so if the current chip happens to have an unconfigured PSI HB,
the chip will never see the interrupt.

This adds a pointer to the chip's PSI in struct proc_chip so we can
use the current chip's PSI if it is active without having to look
through all of them. If that doesn't exist, then we grab a chip id from
the list of configured PSIs, and ask the OCC on that chip to generate
the self-interrupt.

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 hw/occ.c       | 18 +++++++++++++++---
 hw/psi.c       |  7 +++++++
 include/chip.h |  3 +++
 include/psi.h  |  1 +
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/hw/occ.c b/hw/occ.c
index 34d6de5..73a9b8b 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -625,12 +625,24 @@ static struct fsp_client fsp_occ_client = {
 
 void occ_send_dummy_interrupt(void)
 {
+	struct psi *psi;
+	struct proc_chip *chip = get_chip(this_cpu()->chip_id);
+
 	/* Emulators and P7 doesn't do this */
 	if (proc_gen != proc_gen_p8 || chip_quirk(QUIRK_NO_OCC_IRQ))
 		return;
-	xscom_writeme(OCB_OCI_OCCMISC_OR,
-		      OCB_OCI_OCIMISC_IRQ |
-		      OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
+
+	/* Find a functional PSI. This ensures an interrupt even if
+	 * the psihb on the current chip is not configured */
+	if (chip->psi)
+		psi = chip->psi;
+	else {
+		psi = psi_find_functional_chip();
+		assert(psi != NULL);
+	}
+
+	xscom_write(psi->chip_id, OCB_OCI_OCCMISC_OR,
+		    OCB_OCI_OCIMISC_IRQ | OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
 }
 
 void occ_interrupt(uint32_t chip_id)
diff --git a/hw/psi.c b/hw/psi.c
index c0692a1..0a013b5 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -885,6 +885,8 @@ static bool psi_init_psihb(struct dt_node *psihb)
 	psi->chip_id = chip->id;
 	psi->interrupt = get_psi_interrupt(chip->id);
 
+	chip->psi = psi;
+
 	psi_create_mm_dtnode(psi);
 	psi_register_interrupts(psi);
 	psi_activate_phb(psi);
@@ -905,6 +907,11 @@ void psi_fsp_link_in_use(struct psi *psi __unused)
 	}
 }
 
+struct psi *psi_find_functional_chip(void)
+{
+	return list_top(&psis, struct psi, list);
+}
+
 void psi_init(void)
 {
 	struct dt_node *np;
diff --git a/include/chip.h b/include/chip.h
index 0547902..1b4f4c4 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -157,6 +157,9 @@ struct proc_chip {
 
 	/* Used by hw/p8-i2c.c */
 	struct list_head	i2cms;
+
+	/* Used by hw/psi.c */
+	struct psi		*psi;
 };
 
 extern uint32_t pir_to_chip_id(uint32_t pir);
diff --git a/include/psi.h b/include/psi.h
index 7e7a24c..ef76591 100644
--- a/include/psi.h
+++ b/include/psi.h
@@ -217,6 +217,7 @@ extern void psi_disable_link(struct psi *psi);
 extern void psi_reset_fsp(struct psi *psi);
 extern bool psi_check_link_active(struct psi *psi);
 extern bool psi_poll_fsp_interrupt(struct psi *psi);
+extern struct psi *psi_find_functional_chip(void);
 
 /* Interrupts */
 extern void psi_irq_reset(void);
-- 
2.1.4



More information about the Skiboot mailing list