aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr.c')
-rw-r--r--hw/ppc/spapr.c470
1 files changed, 186 insertions, 284 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b0a0f8c..99b843b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -77,7 +77,6 @@
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/vhost-scsi-common.h"
-#include "exec/ram_addr.h"
#include "system/confidential-guest-support.h"
#include "hw/usb.h"
#include "qemu/config-file.h"
@@ -577,7 +576,7 @@ static int spapr_dt_dynamic_memory(SpaprMachineState *spapr, void *fdt,
/*
* Adds ibm,dynamic-reconfiguration-memory node.
- * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation
+ * Refer to docs/specs/ppc-spapr-hotplug.rst for the documentation
* of this device tree node.
*/
static int spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr,
@@ -901,12 +900,80 @@ static int spapr_dt_rng(void *fdt)
return ret ? -1 : 0;
}
+static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
+{
+ MachineState *ms = MACHINE(spapr);
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ FadumpMemStruct *fdm = &spapr->registered_fdm;
+ uint16_t dump_status_flag;
+
+ uint32_t max_possible_cpus = mc->possible_cpu_arch_ids(ms)->len;
+ uint64_t fadump_cpu_state_size = 0;
+ uint16_t fadump_versions[2] = {
+ FADUMP_VERSION /* min supported version */,
+ FADUMP_VERSION /* max supported version */
+ };
+ uint32_t fadump_rgn_sizes[2][3] = {
+ {
+ cpu_to_be32(FADUMP_CPU_STATE_DATA),
+ 0, 0 /* Calculated later */
+ },
+ {
+ cpu_to_be32(FADUMP_HPTE_REGION),
+ 0, 0 /* HPTE region not implemented */
+ }
+ };
+
+ /*
+ * CPU State Data contains multiple fields such as header, num_cpus and
+ * register entries
+ *
+ * Calculate the maximum CPU State Data size, according to maximum
+ * possible CPUs the QEMU VM can have
+ *
+ * This calculation must match the 'cpu_state_len' calculation done in
+ * 'populate_cpu_state_data' in spapr_fadump.c
+ */
+ fadump_cpu_state_size += sizeof(struct FadumpRegSaveAreaHeader);
+ fadump_cpu_state_size += 0xc; /* padding as in PAPR */
+ fadump_cpu_state_size += sizeof(uint32_t); /* num_cpus */
+ fadump_cpu_state_size += max_possible_cpus * /* reg entries */
+ FADUMP_PER_CPU_REG_ENTRIES *
+ sizeof(struct FadumpRegEntry);
+
+ /* Set maximum size for CPU state data region */
+ assert(fadump_rgn_sizes[0][0] == cpu_to_be32(FADUMP_CPU_STATE_DATA));
+
+ /* Upper 32 bits of size, usually 0 */
+ fadump_rgn_sizes[0][1] = cpu_to_be32(fadump_cpu_state_size >> 32);
+
+ /* Lower 32 bits of size */
+ fadump_rgn_sizes[0][2] = cpu_to_be32(fadump_cpu_state_size & 0xffffffff);
+
+ /* Add device tree properties required from platform for fadump */
+ _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-version",
+ fadump_versions, sizeof(fadump_versions))));
+ _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-sizes",
+ fadump_rgn_sizes, sizeof(fadump_rgn_sizes))));
+
+ dump_status_flag = be16_to_cpu(fdm->header.dump_status_flag);
+ if (dump_status_flag & FADUMP_STATUS_DUMP_TRIGGERED) {
+ uint64_t fdm_size =
+ sizeof(struct FadumpSectionHeader) +
+ (be16_to_cpu(fdm->header.dump_num_sections) *
+ sizeof(struct FadumpSection));
+
+ _FDT((fdt_setprop(fdt, rtas, "ibm,kernel-dump", fdm, fdm_size)));
+ }
+}
+
static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
{
MachineState *ms = MACHINE(spapr);
int rtas;
GString *hypertas = g_string_sized_new(256);
GString *qemu_hypertas = g_string_sized_new(256);
+ uint64_t max_device_addr = 0;
uint32_t lrdr_capacity[] = {
0,
0,
@@ -917,13 +984,15 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
/* Do we have device memory? */
if (MACHINE(spapr)->device_memory) {
- uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
+ max_device_addr = MACHINE(spapr)->device_memory->base +
memory_region_size(&MACHINE(spapr)->device_memory->mr);
-
- lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
- lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
+ } else if (ms->ram_size == ms->maxram_size) {
+ max_device_addr = ms->ram_size;
}
+ lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
+ lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
+
_FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
/* hypertas */
@@ -1013,6 +1082,8 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
_FDT(fdt_setprop(fdt, rtas, "ibm,lrdr-capacity",
lrdr_capacity, sizeof(lrdr_capacity)));
+ spapr_dt_rtas_fadump(spapr, fdt, rtas);
+
spapr_dt_rtas_tokens(fdt, rtas);
}
@@ -1070,7 +1141,6 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset)
{
MachineState *machine = MACHINE(spapr);
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
int chosen;
_FDT(chosen = fdt_add_subnode(fdt, 0, "chosen"));
@@ -1141,9 +1211,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset)
* We can deal with BAR reallocation just fine, advertise it
* to the guest
*/
- if (smc->linux_pci_probe) {
- _FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0));
- }
+ _FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0));
spapr_dt_ov5_platform_support(spapr, fdt, chosen);
}
@@ -1180,7 +1248,6 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
uint32_t root_drc_type_mask = 0;
int ret;
void *fdt;
@@ -1211,16 +1278,10 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
/* Host Model & Serial Number */
if (spapr->host_model) {
_FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
- } else if (smc->broken_host_serial_model && kvmppc_get_host_model(&buf)) {
- _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
- g_free(buf);
}
if (spapr->host_serial) {
_FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
- } else if (smc->broken_host_serial_model && kvmppc_get_host_serial(&buf)) {
- _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
- g_free(buf);
}
_FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2));
@@ -1258,9 +1319,8 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
/* ibm,drc-indexes and friends */
root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_LMB;
- if (smc->dr_phb_enabled) {
- root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PHB;
- }
+ root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PHB;
+
if (mc->nvdimm_supported) {
root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PMEM;
}
@@ -2059,13 +2119,6 @@ static const VMStateDescription vmstate_spapr_irq_map = {
},
};
-static bool spapr_dtb_needed(void *opaque)
-{
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);
-
- return smc->update_dt_enabled;
-}
-
static int spapr_dtb_pre_load(void *opaque)
{
SpaprMachineState *spapr = (SpaprMachineState *)opaque;
@@ -2081,7 +2134,6 @@ static const VMStateDescription vmstate_spapr_dtb = {
.name = "spapr_dtb",
.version_id = 1,
.minimum_version_id = 1,
- .needed = spapr_dtb_needed,
.pre_load = spapr_dtb_pre_load,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(fdt_initial_size, SpaprMachineState),
@@ -2518,7 +2570,7 @@ static void htab_save_cleanup(void *opaque)
static SaveVMHandlers savevm_htab_handlers = {
.save_setup = htab_save_setup,
.save_live_iterate = htab_save_iterate,
- .save_live_complete_precopy = htab_save_complete,
+ .save_complete = htab_save_complete,
.save_cleanup = htab_save_cleanup,
.load_state = htab_load,
};
@@ -2603,7 +2655,6 @@ static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)
static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp)
{
MachineState *ms = MACHINE(spapr);
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
Error *local_err = NULL;
bool vsmt_user = !!spapr->vsmt;
int kvm_smt = kvmppc_smt_threads();
@@ -2639,15 +2690,6 @@ static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp)
return;
}
/* In this case, spapr->vsmt has been set by the command line */
- } else if (!smc->smp_threads_vsmt) {
- /*
- * Default VSMT value is tricky, because we need it to be as
- * consistent as possible (for migration), but this requires
- * changing it for at least some existing cases. We pick 8 as
- * the value that we'd get with KVM on POWER8, the
- * overwhelmingly common case in production systems.
- */
- spapr->vsmt = MAX(8, smp_threads);
} else {
spapr->vsmt = smp_threads;
}
@@ -2756,7 +2798,6 @@ static PCIHostState *spapr_create_default_phb(void)
static hwaddr spapr_rma_size(SpaprMachineState *spapr, Error **errp)
{
MachineState *machine = MACHINE(spapr);
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
hwaddr rma_size = machine->ram_size;
hwaddr node0_size = spapr_node0_size(machine);
@@ -2769,15 +2810,6 @@ static hwaddr spapr_rma_size(SpaprMachineState *spapr, Error **errp)
*/
rma_size = MIN(rma_size, 1 * TiB);
- /*
- * Clamp the RMA size based on machine type. This is for
- * migration compatibility with older qemu versions, which limited
- * the RMA size for complicated and mostly bad reasons.
- */
- if (smc->rma_limit) {
- rma_size = MIN(rma_size, smc->rma_limit);
- }
-
if (rma_size < MIN_RMA_SLOF) {
error_setg(errp,
"pSeries SLOF firmware requires >= %" HWADDR_PRIx
@@ -2815,18 +2847,14 @@ static void spapr_machine_init(MachineState *machine)
int i;
MemoryRegion *sysmem = get_system_memory();
long load_limit, fw_size;
- Error *resize_hpt_err = NULL;
+ Error *errp = NULL;
NICInfo *nd;
if (!filename) {
error_report("Could not find LPAR firmware '%s'", bios_name);
exit(1);
}
- fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
- if (fw_size <= 0) {
- error_report("Could not load LPAR firmware '%s'", filename);
- exit(1);
- }
+ fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE, &error_fatal);
/*
* if Secure VM (PEF) support is configured, then initialize it
@@ -2843,7 +2871,7 @@ static void spapr_machine_init(MachineState *machine)
/* Determine capabilities to run with */
spapr_caps_init(spapr);
- kvmppc_check_papr_resize_hpt(&resize_hpt_err);
+ kvmppc_check_papr_resize_hpt(&errp);
if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) {
/*
* If the user explicitly requested a mode we should either
@@ -2851,10 +2879,10 @@ static void spapr_machine_init(MachineState *machine)
* it's not set explicitly, we reset our mode to something
* that works
*/
- if (resize_hpt_err) {
+ if (errp) {
spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED;
- error_free(resize_hpt_err);
- resize_hpt_err = NULL;
+ error_free(errp);
+ errp = NULL;
} else {
spapr->resize_hpt = smc->resize_hpt_default;
}
@@ -2862,14 +2890,14 @@ static void spapr_machine_init(MachineState *machine)
assert(spapr->resize_hpt != SPAPR_RESIZE_HPT_DEFAULT);
- if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && resize_hpt_err) {
+ if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && errp) {
/*
* User requested HPT resize, but this host can't supply it. Bail out
*/
- error_report_err(resize_hpt_err);
+ error_report_err(errp);
exit(1);
}
- error_free(resize_hpt_err);
+ error_free(errp);
spapr->rma_size = spapr_rma_size(spapr, &error_fatal);
@@ -3007,10 +3035,8 @@ static void spapr_machine_init(MachineState *machine)
* connectors for a PHBs PCI slots) are added as needed during their
* parent's realization.
*/
- if (smc->dr_phb_enabled) {
- for (i = 0; i < SPAPR_MAX_PHBS; i++) {
- spapr_dr_connector_new(OBJECT(machine), TYPE_SPAPR_DRC_PHB, i);
- }
+ for (i = 0; i < SPAPR_MAX_PHBS; i++) {
+ spapr_dr_connector_new(OBJECT(machine), TYPE_SPAPR_DRC_PHB, i);
}
/* Set up PCI */
@@ -3085,14 +3111,9 @@ static void spapr_machine_init(MachineState *machine)
spapr->initrd_base = (spapr->kernel_addr + spapr->kernel_size
+ 0x1ffff) & ~0xffff;
spapr->initrd_size = load_image_targphys(initrd_filename,
- spapr->initrd_base,
- load_limit
- - spapr->initrd_base);
- if (spapr->initrd_size < 0) {
- error_report("could not load initial ram disk '%s'",
- initrd_filename);
- exit(1);
- }
+ spapr->initrd_base,
+ load_limit - spapr->initrd_base,
+ &error_fatal);
}
}
@@ -3345,9 +3366,7 @@ static char *spapr_get_ic_mode(Object *obj, Error **errp)
{
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
- if (spapr->irq == &spapr_irq_xics_legacy) {
- return g_strdup("legacy");
- } else if (spapr->irq == &spapr_irq_xics) {
+ if (spapr->irq == &spapr_irq_xics) {
return g_strdup("xics");
} else if (spapr->irq == &spapr_irq_xive) {
return g_strdup("xive");
@@ -3361,11 +3380,6 @@ static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
{
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
- if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
- error_setg(errp, "This machine only uses the legacy XICS backend, don't pass ic-mode");
- return;
- }
-
/* The legacy IRQ backend can not be set */
if (strcmp(value, "xics") == 0) {
spapr->irq = &spapr_irq_xics;
@@ -4091,20 +4105,65 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
return 0;
}
+static bool spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
+ uint64_t *buid, hwaddr *pio,
+ hwaddr *mmio32, hwaddr *mmio64,
+ unsigned n_dma, uint32_t *liobns, Error **errp)
+{
+ /*
+ * New-style PHB window placement.
+ *
+ * Goals: Gives large (1TiB), naturally aligned 64-bit MMIO window
+ * for each PHB, in addition to 2GiB 32-bit MMIO and 64kiB PIO
+ * windows.
+ *
+ * Some guest kernels can't work with MMIO windows above 1<<46
+ * (64TiB), so we place up to 31 PHBs in the area 32TiB..64TiB
+ *
+ * 32TiB..(33TiB+1984kiB) contains the 64kiB PIO windows for each
+ * PHB stacked together. (32TiB+2GiB)..(32TiB+64GiB) contains the
+ * 2GiB 32-bit MMIO windows for each PHB. Then 33..64TiB has the
+ * 1TiB 64-bit MMIO windows for each PHB.
+ */
+ const uint64_t base_buid = 0x800000020000000ULL;
+ int i;
+
+ /* Sanity check natural alignments */
+ QEMU_BUILD_BUG_ON((SPAPR_PCI_BASE % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
+ QEMU_BUILD_BUG_ON((SPAPR_PCI_LIMIT % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
+ QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM64_WIN_SIZE % SPAPR_PCI_MEM32_WIN_SIZE) != 0);
+ QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM32_WIN_SIZE % SPAPR_PCI_IO_WIN_SIZE) != 0);
+ /* Sanity check bounds */
+ QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_IO_WIN_SIZE) >
+ SPAPR_PCI_MEM32_WIN_SIZE);
+ QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_MEM32_WIN_SIZE) >
+ SPAPR_PCI_MEM64_WIN_SIZE);
+
+ if (index >= SPAPR_MAX_PHBS) {
+ error_setg(errp, "\"index\" for PAPR PHB is too large (max %llu)",
+ SPAPR_MAX_PHBS - 1);
+ return false;
+ }
+
+ *buid = base_buid + index;
+ for (i = 0; i < n_dma; ++i) {
+ liobns[i] = SPAPR_PCI_LIOBN(index, i);
+ }
+
+ *pio = SPAPR_PCI_BASE + index * SPAPR_PCI_IO_WIN_SIZE;
+ *mmio32 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM32_WIN_SIZE;
+ *mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
+ return true;
+}
+
static bool spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
SpaprDrc *drc;
- if (dev->hotplugged && !smc->dr_phb_enabled) {
- error_setg(errp, "PHB hotplug not supported for this machine");
- return false;
- }
-
if (sphb->index == (uint32_t)-1) {
error_setg(errp, "\"index\" for PAPR PHB is mandatory");
return false;
@@ -4120,26 +4179,18 @@ static bool spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
* This will check that sphb->index doesn't exceed the maximum number of
* PHBs for the current machine type.
*/
- return
- smc->phb_placement(spapr, sphb->index,
- &sphb->buid, &sphb->io_win_addr,
- &sphb->mem_win_addr, &sphb->mem64_win_addr,
- windows_supported, sphb->dma_liobn,
- errp);
+ return spapr_phb_placement(spapr, sphb->index,
+ &sphb->buid, &sphb->io_win_addr,
+ &sphb->mem_win_addr, &sphb->mem64_win_addr,
+ windows_supported, sphb->dma_liobn, errp);
}
static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
- SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
SpaprDrc *drc;
bool hotplugged = spapr_drc_hotplugged(dev);
- if (!smc->dr_phb_enabled) {
- return;
- }
-
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
/* hotplug hooks should check it's enabled before getting this far */
assert(drc);
@@ -4265,7 +4316,6 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
{
SpaprMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
MachineClass *mc = MACHINE_GET_CLASS(sms);
- SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
if (spapr_memory_hot_unplug_supported(sms)) {
@@ -4280,10 +4330,6 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
}
spapr_core_unplug_request(hotplug_dev, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
- if (!smc->dr_phb_enabled) {
- error_setg(errp, "PHB hot unplug not supported on this machine");
- return;
- }
spapr_phb_unplug_request(hotplug_dev, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
spapr_tpm_proxy_unplug(hotplug_dev, dev);
@@ -4384,57 +4430,6 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
return machine->possible_cpus;
}
-static bool spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
- uint64_t *buid, hwaddr *pio,
- hwaddr *mmio32, hwaddr *mmio64,
- unsigned n_dma, uint32_t *liobns, Error **errp)
-{
- /*
- * New-style PHB window placement.
- *
- * Goals: Gives large (1TiB), naturally aligned 64-bit MMIO window
- * for each PHB, in addition to 2GiB 32-bit MMIO and 64kiB PIO
- * windows.
- *
- * Some guest kernels can't work with MMIO windows above 1<<46
- * (64TiB), so we place up to 31 PHBs in the area 32TiB..64TiB
- *
- * 32TiB..(33TiB+1984kiB) contains the 64kiB PIO windows for each
- * PHB stacked together. (32TiB+2GiB)..(32TiB+64GiB) contains the
- * 2GiB 32-bit MMIO windows for each PHB. Then 33..64TiB has the
- * 1TiB 64-bit MMIO windows for each PHB.
- */
- const uint64_t base_buid = 0x800000020000000ULL;
- int i;
-
- /* Sanity check natural alignments */
- QEMU_BUILD_BUG_ON((SPAPR_PCI_BASE % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
- QEMU_BUILD_BUG_ON((SPAPR_PCI_LIMIT % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
- QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM64_WIN_SIZE % SPAPR_PCI_MEM32_WIN_SIZE) != 0);
- QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM32_WIN_SIZE % SPAPR_PCI_IO_WIN_SIZE) != 0);
- /* Sanity check bounds */
- QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_IO_WIN_SIZE) >
- SPAPR_PCI_MEM32_WIN_SIZE);
- QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_MEM32_WIN_SIZE) >
- SPAPR_PCI_MEM64_WIN_SIZE);
-
- if (index >= SPAPR_MAX_PHBS) {
- error_setg(errp, "\"index\" for PAPR PHB is too large (max %llu)",
- SPAPR_MAX_PHBS - 1);
- return false;
- }
-
- *buid = base_buid + index;
- for (i = 0; i < n_dma; ++i) {
- liobns[i] = SPAPR_PCI_LIOBN(index, i);
- }
-
- *pio = SPAPR_PCI_BASE + index * SPAPR_PCI_IO_WIN_SIZE;
- *mmio32 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM32_WIN_SIZE;
- *mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
- return true;
-}
-
static ICSState *spapr_ics_get(XICSFabric *dev, int irq)
{
SpaprMachineState *spapr = SPAPR_MACHINE(dev);
@@ -4468,21 +4463,14 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj, GString *buf)
/*
* This is a XIVE only operation
*/
-static int spapr_match_nvt(XiveFabric *xfb, uint8_t format,
- uint8_t nvt_blk, uint32_t nvt_idx,
- bool crowd, bool cam_ignore, uint8_t priority,
- uint32_t logic_serv, XiveTCTXMatch *match)
+static bool spapr_match_nvt(XiveFabric *xfb, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool crowd, bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match)
{
SpaprMachineState *spapr = SPAPR_MACHINE(xfb);
XivePresenter *xptr = XIVE_PRESENTER(spapr->active_intc);
XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
- int count;
-
- count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd, cam_ignore,
- priority, logic_serv, match);
- if (count < 0) {
- return count;
- }
/*
* When we implement the save and restore of the thread interrupt
@@ -4493,12 +4481,14 @@ static int spapr_match_nvt(XiveFabric *xfb, uint8_t format,
* Until this is done, the sPAPR machine should find at least one
* matching context always.
*/
- if (count == 0) {
+ if (!xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd, cam_ignore,
+ priority, logic_serv, match)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is not dispatched\n",
nvt_blk, nvt_idx);
+ return false;
}
- return count;
+ return true;
}
int spapr_get_vcpu_id(PowerPCCPU *cpu)
@@ -4595,7 +4585,7 @@ static void spapr_cpu_exec_exit(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
}
}
-static void spapr_machine_class_init(ObjectClass *oc, void *data)
+static void spapr_machine_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
@@ -4644,14 +4634,12 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
hc->unplug_request = spapr_machine_device_unplug_request;
hc->unplug = spapr_machine_device_unplug;
- smc->update_dt_enabled = true;
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
mc->has_hotpluggable_cpus = true;
mc->nvdimm_supported = true;
smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
- smc->phb_placement = spapr_phb_placement;
vhc->cpu_in_nested = spapr_cpu_in_nested;
vhc->deliver_hv_excp = spapr_exit_nested;
vhc->hypercall = emulate_spapr_hypercall;
@@ -4698,10 +4686,6 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->default_caps.caps[SPAPR_CAP_AIL_MODE_3] = SPAPR_CAP_ON;
spapr_caps_add_properties(smc);
smc->irq = &spapr_irq_dual;
- smc->dr_phb_enabled = true;
- smc->linux_pci_probe = true;
- smc->smp_threads_vsmt = true;
- smc->nr_xirqs = SPAPR_NR_XIRQS;
xfc->match_nvt = spapr_match_nvt;
vmc->client_architecture_support = spapr_vof_client_architecture_support;
vmc->quiesce = spapr_vof_quiesce;
@@ -4717,7 +4701,7 @@ static const TypeInfo spapr_machine_info = {
.instance_finalize = spapr_machine_finalizefn,
.class_size = sizeof(SpaprMachineClass),
.class_init = spapr_machine_class_init,
- .interfaces = (InterfaceInfo[]) {
+ .interfaces = (const InterfaceInfo[]) {
{ TYPE_FW_PATH_PROVIDER },
{ TYPE_NMI },
{ TYPE_HOTPLUG_HANDLER },
@@ -4739,7 +4723,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
#define DEFINE_SPAPR_MACHINE_IMPL(latest, ...) \
static void MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__)( \
ObjectClass *oc, \
- void *data) \
+ const void *data) \
{ \
MachineClass *mc = MACHINE_CLASS(oc); \
MACHINE_VER_SYM(class_options, spapr, __VA_ARGS__)(mc); \
@@ -4767,14 +4751,36 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
DEFINE_SPAPR_MACHINE_IMPL(false, major, minor)
/*
+ * pseries-10.2
+ */
+static void spapr_machine_10_2_class_options(MachineClass *mc)
+{
+ /* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE_AS_LATEST(10, 2);
+
+/*
+ * pseries-10.1
+ */
+static void spapr_machine_10_1_class_options(MachineClass *mc)
+{
+ spapr_machine_10_2_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len);
+}
+
+DEFINE_SPAPR_MACHINE(10, 1);
+
+/*
* pseries-10.0
*/
static void spapr_machine_10_0_class_options(MachineClass *mc)
{
- /* Defaults for the latest behaviour inherited from the base class */
+ spapr_machine_10_1_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_10_0, hw_compat_10_0_len);
}
-DEFINE_SPAPR_MACHINE_AS_LATEST(10, 0);
+DEFINE_SPAPR_MACHINE(10, 0);
/*
* pseries-9.2
@@ -4957,110 +4963,6 @@ static void spapr_machine_5_0_class_options(MachineClass *mc)
DEFINE_SPAPR_MACHINE(5, 0);
-/*
- * pseries-4.2
- */
-static void spapr_machine_4_2_class_options(MachineClass *mc)
-{
- SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
- spapr_machine_5_0_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
- smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
- smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_OFF;
- smc->rma_limit = 16 * GiB;
- mc->nvdimm_supported = false;
-}
-
-DEFINE_SPAPR_MACHINE(4, 2);
-
-/*
- * pseries-4.1
- */
-static void spapr_machine_4_1_class_options(MachineClass *mc)
-{
- SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
- static GlobalProperty compat[] = {
- /* Only allow 4kiB and 64kiB IOMMU pagesizes */
- { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" },
- };
-
- spapr_machine_4_2_class_options(mc);
- smc->linux_pci_probe = false;
- smc->smp_threads_vsmt = false;
- compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
- compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-}
-
-DEFINE_SPAPR_MACHINE(4, 1);
-
-/*
- * pseries-4.0
- */
-static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
- uint64_t *buid, hwaddr *pio,
- hwaddr *mmio32, hwaddr *mmio64,
- unsigned n_dma, uint32_t *liobns, Error **errp)
-{
- if (!spapr_phb_placement(spapr, index, buid, pio, mmio32, mmio64, n_dma,
- liobns, errp)) {
- return false;
- }
- return true;
-}
-static void spapr_machine_4_0_class_options(MachineClass *mc)
-{
- SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
- spapr_machine_4_1_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
- smc->phb_placement = phb_placement_4_0;
- smc->irq = &spapr_irq_xics;
- smc->pre_4_1_migration = true;
-}
-
-DEFINE_SPAPR_MACHINE(4, 0);
-
-/*
- * pseries-3.1
- */
-static void spapr_machine_3_1_class_options(MachineClass *mc)
-{
- SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
- spapr_machine_4_0_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
-
- mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
- smc->update_dt_enabled = false;
- smc->dr_phb_enabled = false;
- smc->broken_host_serial_model = true;
- smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
- smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
- smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
- smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
-}
-
-DEFINE_SPAPR_MACHINE(3, 1);
-
-/*
- * pseries-3.0
- */
-
-static void spapr_machine_3_0_class_options(MachineClass *mc)
-{
- SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
- spapr_machine_3_1_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
-
- smc->legacy_irq_allocation = true;
- smc->nr_xirqs = 0x400;
- smc->irq = &spapr_irq_xics_legacy;
-}
-
-DEFINE_SPAPR_MACHINE(3, 0);
-
static void spapr_machine_register_types(void)
{
type_register_static(&spapr_machine_info);