mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 10:34:58 -06:00
ppc/pnv: Implement POWER9 LPC PSI serirq outputs and auto-clear function
The POWER8 LPC ISA device irqs all get combined and reported to the line connected the PSI LPCHC irq. POWER9 changed this so only internal LPC host controller irqs use that line, and the device irqs get routed to 4 new lines connected to PSI SERIRQ0-3. POWER9 also introduced a new feature that automatically clears the irq status in the LPC host controller when EOI'ed, so software does not have to. The powernv OPAL (skiboot) firmware managed to work because the LPCHC irq handler scanned all LPC irqs and handled those including clearing status even on POWER9 systems. So LPC irqs worked despite OPAL thinking it was running in POWER9 mode. After this change, UART interrupts show up on serirq1 which is where OPAL routes them to: cat /proc/interrupts ... 20: 0 XIVE-IRQ 1048563 Level opal-psi#0:lpchc ... 25: 34 XIVE-IRQ 1048568 Level opal-psi#0:lpc_serirq_mux1 Whereas they previously turn up on lpchc. Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
This commit is contained in:
parent
c6e07f03f7
commit
24c3caff99
3 changed files with 150 additions and 32 deletions
36
hw/ppc/pnv.c
36
hw/ppc/pnv.c
|
@ -727,7 +727,8 @@ static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)
|
|||
Pnv8Chip *chip8 = PNV8_CHIP(chip);
|
||||
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_EXTERNAL);
|
||||
|
||||
qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip8->lpc), "LPCHC", 0, irq);
|
||||
|
||||
return pnv_lpc_isa_create(&chip8->lpc, true, errp);
|
||||
}
|
||||
|
||||
|
@ -736,25 +737,48 @@ static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
|
|||
Pnv8Chip *chip8 = PNV8_CHIP(chip);
|
||||
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_LPC_I2C);
|
||||
|
||||
qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip8->lpc), "LPCHC", 0, irq);
|
||||
|
||||
return pnv_lpc_isa_create(&chip8->lpc, false, errp);
|
||||
}
|
||||
|
||||
static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
|
||||
{
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(chip);
|
||||
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPCHC);
|
||||
qemu_irq irq;
|
||||
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPCHC);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip9->lpc), "LPCHC", 0, irq);
|
||||
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPC_SIRQ0);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip9->lpc), "SERIRQ", 0, irq);
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPC_SIRQ1);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip9->lpc), "SERIRQ", 1, irq);
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPC_SIRQ2);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip9->lpc), "SERIRQ", 2, irq);
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPC_SIRQ3);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip9->lpc), "SERIRQ", 3, irq);
|
||||
|
||||
qdev_connect_gpio_out(DEVICE(&chip9->lpc), 0, irq);
|
||||
return pnv_lpc_isa_create(&chip9->lpc, false, errp);
|
||||
}
|
||||
|
||||
static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
|
||||
{
|
||||
Pnv10Chip *chip10 = PNV10_CHIP(chip);
|
||||
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPCHC);
|
||||
qemu_irq irq;
|
||||
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPCHC);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip10->lpc), "LPCHC", 0, irq);
|
||||
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPC_SIRQ0);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip10->lpc), "SERIRQ", 0, irq);
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPC_SIRQ1);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip10->lpc), "SERIRQ", 1, irq);
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPC_SIRQ2);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip10->lpc), "SERIRQ", 2, irq);
|
||||
irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPC_SIRQ3);
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip10->lpc), "SERIRQ", 3, irq);
|
||||
|
||||
qdev_connect_gpio_out(DEVICE(&chip10->lpc), 0, irq);
|
||||
return pnv_lpc_isa_create(&chip10->lpc, false, errp);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue