aboutsummaryrefslogtreecommitdiff
path: root/hw/psi.c
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2016-10-25 12:20:12 +0200
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-12-16 15:47:52 +1100
commite44f3bebeb00cf22885b994f3da5494e16d7e8c9 (patch)
tree9102f539a18970b4fa338a0c3422c9e7d40ef826 /hw/psi.c
parent9418533911728f6d8bb7aa647033c317772ddb97 (diff)
downloadskiboot-e44f3bebeb00cf22885b994f3da5494e16d7e8c9.zip
skiboot-e44f3bebeb00cf22885b994f3da5494e16d7e8c9.tar.gz
skiboot-e44f3bebeb00cf22885b994f3da5494e16d7e8c9.tar.bz2
psi: fix the xive registers initialization on P8
When skiboot initializes PSIHB, it fills the xive registers with server=0, prio=0xff. The source (irq) value is left shifted by 29 bits and the last two xive registers (irq 4 and 5) are set with a bogus value : write 0x30 val 0x000000ff00000000 write 0x60 val 0x000000ff20000000 write 0x68 val 0x000000ff40000000 write 0x70 val 0x000000ff60000000 write 0x78 val 0xffffffff80000000 write 0x80 val 0xffffffffa0000000 which seems to be fine for real HW but causes a lof of pain under qemu. Let's use an 'unsigned' type to initialize the xive registers and also use a loop on the PSI irq numbers, like it is done in psi_cleanup_irq. Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/psi.c')
-rw-r--r--hw/psi.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/hw/psi.c b/hw/psi.c
index 9913c3a..533eabd 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -720,6 +720,9 @@ static void psi_init_p7_interrupt(struct psi *psi)
static void psi_init_p8_interrupts(struct psi *psi)
{
+ uint32_t irq;
+ uint64_t xivr_p;
+
/* On P8 we get a block of 8, set up the base/mask
* and mask all the sources for now
*/
@@ -728,18 +731,11 @@ static void psi_init_p8_interrupts(struct psi *psi)
SETFIELD(PSIHB_IRSN_MASK, 0ul, 0x7fff8ul) |
PSIHB_IRSN_DOWNSTREAM_EN |
PSIHB_IRSN_UPSTREAM_EN);
- out_be64(psi->regs + PSIHB_XIVR_FSP,
- (0xffull << 32) | (P8_IRQ_PSI_FSP << 29));
- out_be64(psi->regs + PSIHB_XIVR_OCC,
- (0xffull << 32) | (P8_IRQ_PSI_OCC << 29));
- out_be64(psi->regs + PSIHB_XIVR_FSI,
- (0xffull << 32) | (P8_IRQ_PSI_FSI << 29));
- out_be64(psi->regs + PSIHB_XIVR_LPC,
- (0xffull << 32) | (P8_IRQ_PSI_LPC << 29));
- out_be64(psi->regs + PSIHB_XIVR_LOCAL_ERR,
- (0xffull << 32) | (P8_IRQ_PSI_LOCAL_ERR << 29));
- out_be64(psi->regs + PSIHB_XIVR_HOST_ERR,
- (0xffull << 32) | (P8_IRQ_PSI_EXTERNAL << 29));
+
+ for (irq = 0; irq < P8_IRQ_PSI_IRQ_COUNT; irq++) {
+ xivr_p = psi_p8_irq_to_xivr[irq];
+ out_be64(psi->regs + xivr_p, (0xffull << 32) | (irq << 29));
+ }
/*
* Register the IRQ sources FSP, OCC, FSI, LPC