summaryrefslogtreecommitdiffstats
path: root/hw/ppc/spapr_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr_pci.c')
-rw-r--r--hw/ppc/spapr_pci.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 497b896c7d..5cd676e443 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -267,6 +267,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong args, uint32_t nret,
target_ulong rets)
{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
uint32_t config_addr = rtas_ld(args, 0);
uint64_t buid = rtas_ldq(args, 1);
unsigned int func = rtas_ld(args, 3);
@@ -334,6 +335,9 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
+ if (!smc->legacy_irq_allocation) {
+ spapr_irq_msi_free(spapr, msi->first_irq, msi->num);
+ }
spapr_irq_free(spapr, msi->first_irq, msi->num);
if (msi_present(pdev)) {
spapr_msi_setmsg(pdev, 0, false, 0, 0);
@@ -372,7 +376,13 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
/* Allocate MSIs */
- irq = spapr_irq_find(spapr, req_num, ret_intr_type == RTAS_TYPE_MSI, &err);
+ if (smc->legacy_irq_allocation) {
+ irq = spapr_irq_find(spapr, req_num, ret_intr_type == RTAS_TYPE_MSI,
+ &err);
+ } else {
+ irq = spapr_irq_msi_alloc(spapr, req_num,
+ ret_intr_type == RTAS_TYPE_MSI, &err);
+ }
if (err) {
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
config_addr);
@@ -392,6 +402,9 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
/* Release previous MSIs */
if (msi) {
+ if (!smc->legacy_irq_allocation) {
+ spapr_irq_msi_free(spapr, msi->first_irq, msi->num);
+ }
spapr_irq_free(spapr, msi->first_irq, msi->num);
g_hash_table_remove(phb->msi, &config_addr);
}
@@ -1546,6 +1559,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
sPAPRMachineState *spapr =
(sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(),
TYPE_SPAPR_MACHINE);
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
SysBusDevice *s = SYS_BUS_DEVICE(dev);
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
@@ -1563,7 +1577,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
}
if (sphb->index != (uint32_t)-1) {
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
Error *local_err = NULL;
smc->phb_placement(spapr, sphb->index,
@@ -1705,14 +1718,16 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
/* Initialize the LSI table */
for (i = 0; i < PCI_NUM_PINS; i++) {
- uint32_t irq;
+ uint32_t irq = SPAPR_IRQ_PCI_LSI + sphb->index * PCI_NUM_PINS + i;
Error *local_err = NULL;
- irq = spapr_irq_findone(spapr, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- error_prepend(errp, "can't allocate LSIs: ");
- return;
+ if (smc->legacy_irq_allocation) {
+ irq = spapr_irq_findone(spapr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ error_prepend(errp, "can't allocate LSIs: ");
+ return;
+ }
}
spapr_irq_claim(spapr, irq, true, &local_err);
@@ -2123,6 +2138,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
_FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges));
_FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
_FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
+ /* TODO: fine tune the total count of allocatable MSIs per PHB */
_FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS_SPAPR));
/* Dynamic DMA window */