return head;
}
+static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
+ uint64_t *buid, hwaddr *pio, hwaddr *mmio,
+ unsigned n_dma, uint32_t *liobns, Error **errp)
+{
+ const uint64_t base_buid = 0x800000020000000ULL;
+ const hwaddr phb0_base = 0x10000000000ULL; /* 1 TiB */
+ const hwaddr phb_spacing = 0x1000000000ULL; /* 64 GiB */
+ const hwaddr mmio_offset = 0xa0000000; /* 2 GiB + 512 MiB */
+ const hwaddr pio_offset = 0x80000000; /* 2 GiB */
+ const uint32_t max_index = 255;
+
+ hwaddr phb_base;
+ int i;
+
+ if (index > max_index) {
+ error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
+ max_index);
+ return;
+ }
+
+ *buid = base_buid + index;
+ for (i = 0; i < n_dma; ++i) {
+ liobns[i] = SPAPR_PCI_LIOBN(index, i);
+ }
+
+ phb_base = phb0_base + index * phb_spacing;
+ *pio = phb_base + pio_offset;
+ *mmio = phb_base + mmio_offset;
+}
+
static void spapr_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus;
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
+ smc->phb_placement = spapr_phb_placement;
}
static const TypeInfo spapr_machine_info = {
sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
if (sphb->index != (uint32_t)-1) {
- hwaddr windows_base;
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ Error *local_err = NULL;
if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn[0] != (uint32_t)-1)
|| (sphb->dma_liobn[1] != (uint32_t)-1 && windows_supported == 2)
return;
}
- if (sphb->index > SPAPR_PCI_MAX_INDEX) {
- error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
- SPAPR_PCI_MAX_INDEX);
+ smc->phb_placement(spapr, sphb->index, &sphb->buid,
+ &sphb->io_win_addr, &sphb->mem_win_addr,
+ windows_supported, sphb->dma_liobn, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
return;
}
-
- sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
- for (i = 0; i < windows_supported; ++i) {
- sphb->dma_liobn[i] = SPAPR_PCI_LIOBN(sphb->index, i);
- }
-
- windows_base = SPAPR_PCI_WINDOW_BASE
- + sphb->index * SPAPR_PCI_WINDOW_SPACING;
- sphb->mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF;
- sphb->io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF;
}
if (sphb->buid == (uint64_t)-1) {
uint32_t numa_node;
};
-#define SPAPR_PCI_MAX_INDEX 255
-
-#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL
-
#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
-#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL
-#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL
-#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000
-#define SPAPR_PCI_MMIO_WIN_SIZE (SPAPR_PCI_WINDOW_SPACING - \
- SPAPR_PCI_MEM_WIN_BUS_OFFSET)
-#define SPAPR_PCI_IO_WIN_OFF 0x80000000
+#define SPAPR_PCI_MMIO_WIN_SIZE 0xf80000000
#define SPAPR_PCI_IO_WIN_SIZE 0x10000
#define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL
bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */
bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */
const char *tcg_default_cpu; /* which (TCG) CPU to simulate by default */
+ void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
+ uint64_t *buid, hwaddr *pio, hwaddr *mmio,
+ unsigned n_dma, uint32_t *liobns, Error **errp);
};
/**