summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr.c262
-rw-r--r--hw/ppc/spapr_rtc.c1
-rw-r--r--hw/ppc/spapr_vio.c12
-rw-r--r--include/hw/boards.h9
-rw-r--r--include/hw/i386/pc.h8
-rw-r--r--include/hw/ppc/spapr.h3
-rw-r--r--include/hw/ppc/spapr_vio.h2
-rw-r--r--target-ppc/kvm.c36
8 files changed, 180 insertions, 153 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6bfb908da7..414e0f9b7a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -375,6 +375,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
qemu_uuid[14], qemu_uuid[15]);
_FDT((fdt_property_string(fdt, "vm,uuid", buf)));
+ if (qemu_uuid_set) {
+ _FDT((fdt_property_string(fdt, "system-id", buf)));
+ }
g_free(buf);
if (qemu_get_vm_name()) {
@@ -1914,7 +1917,11 @@ static void ppc_spapr_init(MachineState *machine)
}
if (machine->usb) {
- pci_create_simple(phb->bus, -1, "pci-ohci");
+ if (smc->use_ohci_by_default) {
+ pci_create_simple(phb->bus, -1, "pci-ohci");
+ } else {
+ pci_create_simple(phb->bus, -1, "nec-usb-xhci");
+ }
if (spapr->has_graphics) {
USBBus *usb_bus = usb_bus_find(-1);
@@ -2101,6 +2108,13 @@ static void spapr_machine_initfn(Object *obj)
NULL);
}
+static void spapr_machine_finalizefn(Object *obj)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+
+ g_free(spapr->kvm_type);
+}
+
static void ppc_cpu_do_nmi_on_cpu(void *arg)
{
CPUState *cs = arg;
@@ -2262,6 +2276,13 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
NMIClass *nc = NMI_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ mc->desc = "pSeries Logical Partition (PAPR compliant)";
+
+ /*
+ * We set up the default / latest behaviour here. The class_init
+ * functions for the specific versioned machine types can override
+ * these details for backwards compatibility
+ */
mc->init = ppc_spapr_init;
mc->reset = ppc_spapr_reset;
mc->block_default_type = IF_SCSI;
@@ -2277,7 +2298,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
hc->unplug = spapr_machine_device_unplug;
mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id;
- smc->dr_lmb_enabled = false;
+ smc->dr_lmb_enabled = true;
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
}
@@ -2288,6 +2309,7 @@ static const TypeInfo spapr_machine_info = {
.abstract = true,
.instance_size = sizeof(sPAPRMachineState),
.instance_init = spapr_machine_initfn,
+ .instance_finalize = spapr_machine_finalizefn,
.class_size = sizeof(sPAPRMachineClass),
.class_init = spapr_machine_class_init,
.interfaces = (InterfaceInfo[]) {
@@ -2298,166 +2320,164 @@ static const TypeInfo spapr_machine_info = {
},
};
-#define SPAPR_COMPAT_2_4 \
- HW_COMPAT_2_4
-
-#define SPAPR_COMPAT_2_3 \
- SPAPR_COMPAT_2_4 \
- HW_COMPAT_2_3 \
- {\
- .driver = "spapr-pci-host-bridge",\
- .property = "dynamic-reconfiguration",\
- .value = "off",\
- },
-
-#define SPAPR_COMPAT_2_2 \
- SPAPR_COMPAT_2_3 \
- HW_COMPAT_2_2 \
- {\
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\
- .property = "mem_win_size",\
- .value = "0x20000000",\
- },
-
-#define SPAPR_COMPAT_2_1 \
- SPAPR_COMPAT_2_2 \
- HW_COMPAT_2_1
+#define DEFINE_SPAPR_MACHINE(suffix, verstr, latest) \
+ static void spapr_machine_##suffix##_class_init(ObjectClass *oc, \
+ void *data) \
+ { \
+ MachineClass *mc = MACHINE_CLASS(oc); \
+ spapr_machine_##suffix##_class_options(mc); \
+ if (latest) { \
+ mc->alias = "pseries"; \
+ mc->is_default = 1; \
+ } \
+ } \
+ static void spapr_machine_##suffix##_instance_init(Object *obj) \
+ { \
+ MachineState *machine = MACHINE(obj); \
+ spapr_machine_##suffix##_instance_options(machine); \
+ } \
+ static const TypeInfo spapr_machine_##suffix##_info = { \
+ .name = MACHINE_TYPE_NAME("pseries-" verstr), \
+ .parent = TYPE_SPAPR_MACHINE, \
+ .class_init = spapr_machine_##suffix##_class_init, \
+ .instance_init = spapr_machine_##suffix##_instance_init, \
+ }; \
+ static void spapr_machine_register_##suffix(void) \
+ { \
+ type_register(&spapr_machine_##suffix##_info); \
+ } \
+ machine_init(spapr_machine_register_##suffix)
-static void spapr_compat_2_3(Object *obj)
+/*
+ * pseries-2.6
+ */
+static void spapr_machine_2_6_instance_options(MachineState *machine)
{
- savevm_skip_section_footers();
- global_state_set_optional();
}
-static void spapr_compat_2_2(Object *obj)
+static void spapr_machine_2_6_class_options(MachineClass *mc)
{
- spapr_compat_2_3(obj);
+ /* Defaults for the latest behaviour inherited from the base class */
}
-static void spapr_compat_2_1(Object *obj)
-{
- spapr_compat_2_2(obj);
-}
+DEFINE_SPAPR_MACHINE(2_6, "2.6", true);
-static void spapr_machine_2_3_instance_init(Object *obj)
+/*
+ * pseries-2.5
+ */
+#define SPAPR_COMPAT_2_5 \
+ HW_COMPAT_2_5
+
+static void spapr_machine_2_5_instance_options(MachineState *machine)
{
- spapr_compat_2_3(obj);
- spapr_machine_initfn(obj);
}
-static void spapr_machine_2_2_instance_init(Object *obj)
+static void spapr_machine_2_5_class_options(MachineClass *mc)
{
- spapr_compat_2_2(obj);
- spapr_machine_initfn(obj);
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_2_6_class_options(mc);
+ smc->use_ohci_by_default = true;
+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_5);
}
-static void spapr_machine_2_1_instance_init(Object *obj)
+DEFINE_SPAPR_MACHINE(2_5, "2.5", false);
+
+/*
+ * pseries-2.4
+ */
+#define SPAPR_COMPAT_2_4 \
+ HW_COMPAT_2_4
+
+static void spapr_machine_2_4_instance_options(MachineState *machine)
{
- spapr_compat_2_1(obj);
- spapr_machine_initfn(obj);
+ spapr_machine_2_5_instance_options(machine);
}
-static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data)
+static void spapr_machine_2_4_class_options(MachineClass *mc)
{
- MachineClass *mc = MACHINE_CLASS(oc);
- static GlobalProperty compat_props[] = {
- SPAPR_COMPAT_2_1
- { /* end of list */ }
- };
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
- mc->desc = "pSeries Logical Partition (PAPR compliant) v2.1";
- mc->compat_props = compat_props;
+ spapr_machine_2_5_class_options(mc);
+ smc->dr_lmb_enabled = false;
+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4);
}
-static const TypeInfo spapr_machine_2_1_info = {
- .name = MACHINE_TYPE_NAME("pseries-2.1"),
- .parent = TYPE_SPAPR_MACHINE,
- .class_init = spapr_machine_2_1_class_init,
- .instance_init = spapr_machine_2_1_instance_init,
-};
+DEFINE_SPAPR_MACHINE(2_4, "2.4", false);
-static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data)
-{
- static GlobalProperty compat_props[] = {
- SPAPR_COMPAT_2_2
- { /* end of list */ }
- };
- MachineClass *mc = MACHINE_CLASS(oc);
+/*
+ * pseries-2.3
+ */
+#define SPAPR_COMPAT_2_3 \
+ SPAPR_COMPAT_2_4 \
+ HW_COMPAT_2_3 \
+ {\
+ .driver = "spapr-pci-host-bridge",\
+ .property = "dynamic-reconfiguration",\
+ .value = "off",\
+ },
- mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2";
- mc->compat_props = compat_props;
+static void spapr_machine_2_3_instance_options(MachineState *machine)
+{
+ spapr_machine_2_4_instance_options(machine);
+ savevm_skip_section_footers();
+ global_state_set_optional();
}
-static const TypeInfo spapr_machine_2_2_info = {
- .name = MACHINE_TYPE_NAME("pseries-2.2"),
- .parent = TYPE_SPAPR_MACHINE,
- .class_init = spapr_machine_2_2_class_init,
- .instance_init = spapr_machine_2_2_instance_init,
-};
-
-static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data)
+static void spapr_machine_2_3_class_options(MachineClass *mc)
{
- static GlobalProperty compat_props[] = {
- SPAPR_COMPAT_2_3
- { /* end of list */ }
- };
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "pSeries Logical Partition (PAPR compliant) v2.3";
- mc->compat_props = compat_props;
+ spapr_machine_2_4_class_options(mc);
+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3);
}
+DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
-static const TypeInfo spapr_machine_2_3_info = {
- .name = MACHINE_TYPE_NAME("pseries-2.3"),
- .parent = TYPE_SPAPR_MACHINE,
- .class_init = spapr_machine_2_3_class_init,
- .instance_init = spapr_machine_2_3_instance_init,
-};
+/*
+ * pseries-2.2
+ */
+
+#define SPAPR_COMPAT_2_2 \
+ SPAPR_COMPAT_2_3 \
+ HW_COMPAT_2_2 \
+ {\
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\
+ .property = "mem_win_size",\
+ .value = "0x20000000",\
+ },
-static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data)
+static void spapr_machine_2_2_instance_options(MachineState *machine)
{
- static GlobalProperty compat_props[] = {
- SPAPR_COMPAT_2_4
- { /* end of list */ }
- };
- MachineClass *mc = MACHINE_CLASS(oc);
+ spapr_machine_2_3_instance_options(machine);
+}
- mc->desc = "pSeries Logical Partition (PAPR compliant) v2.4";
- mc->compat_props = compat_props;
+static void spapr_machine_2_2_class_options(MachineClass *mc)
+{
+ spapr_machine_2_3_class_options(mc);
+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_2);
}
+DEFINE_SPAPR_MACHINE(2_2, "2.2", false);
-static const TypeInfo spapr_machine_2_4_info = {
- .name = MACHINE_TYPE_NAME("pseries-2.4"),
- .parent = TYPE_SPAPR_MACHINE,
- .class_init = spapr_machine_2_4_class_init,
-};
+/*
+ * pseries-2.1
+ */
+#define SPAPR_COMPAT_2_1 \
+ SPAPR_COMPAT_2_2 \
+ HW_COMPAT_2_1
-static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data)
+static void spapr_machine_2_1_instance_options(MachineState *machine)
{
- MachineClass *mc = MACHINE_CLASS(oc);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
-
- mc->name = "pseries-2.5";
- mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5";
- mc->alias = "pseries";
- mc->is_default = 1;
- smc->dr_lmb_enabled = true;
+ spapr_machine_2_2_instance_options(machine);
}
-static const TypeInfo spapr_machine_2_5_info = {
- .name = MACHINE_TYPE_NAME("pseries-2.5"),
- .parent = TYPE_SPAPR_MACHINE,
- .class_init = spapr_machine_2_5_class_init,
-};
+static void spapr_machine_2_1_class_options(MachineClass *mc)
+{
+ spapr_machine_2_2_class_options(mc);
+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1);
+}
+DEFINE_SPAPR_MACHINE(2_1, "2.1", false);
static void spapr_machine_register_types(void)
{
type_register_static(&spapr_machine_info);
- type_register_static(&spapr_machine_2_1_info);
- type_register_static(&spapr_machine_2_2_info);
- type_register_static(&spapr_machine_2_3_info);
- type_register_static(&spapr_machine_2_4_info);
- type_register_static(&spapr_machine_2_5_info);
}
type_init(spapr_machine_register_types)
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index 34b27db709..b591a8ee23 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -200,7 +200,6 @@ static const TypeInfo spapr_rtc_info = {
.name = TYPE_SPAPR_RTC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(sPAPRRTCState),
- .class_size = sizeof(XICSStateClass),
.class_init = spapr_rtc_class_init,
};
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index c51eb8e244..46f3b8d3ef 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -388,7 +388,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
{
- VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus);
+ VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
BusChild *kid;
VIOsPAPRDevice *other;
@@ -449,7 +449,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
}
} else {
/* Need to assign an address */
- VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus);
+ VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
do {
dev->reg = bus->next_reg++;
@@ -523,13 +523,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
DeviceState *dev;
/* Create bridge device */
- dev = qdev_create(NULL, "spapr-vio-bridge");
+ dev = qdev_create(NULL, TYPE_SPAPR_VIO_BRIDGE);
qdev_init_nofail(dev);
/* Create bus on bridge device */
-
qbus = qbus_create(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio");
- bus = DO_UPCAST(VIOsPAPRBus, bus, qbus);
+ bus = SPAPR_VIO_BUS(qbus);
bus->next_reg = 0x71000000;
/* hcall-vio */
@@ -567,9 +566,8 @@ static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo spapr_vio_bridge_info = {
- .name = "spapr-vio-bridge",
+ .name = TYPE_SPAPR_VIO_BRIDGE,
.parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(SysBusDevice),
.class_init = spapr_vio_bridge_class_init,
};
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 051db5ed25..0f30959e2e 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -157,4 +157,13 @@ struct MachineState {
} \
machine_init(machine_initfn##_register_types)
+#define SET_MACHINE_COMPAT(m, COMPAT) \
+ do { \
+ static GlobalProperty props[] = { \
+ COMPAT \
+ { /* end of list */ } \
+ }; \
+ (m)->compat_props = props; \
+ } while (0)
+
#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8122229477..588a33cfa3 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -857,13 +857,5 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
} \
machine_init(pc_machine_init_##suffix)
-#define SET_MACHINE_COMPAT(m, COMPAT) do { \
- static GlobalProperty props[] = { \
- COMPAT \
- { /* end of list */ } \
- }; \
- (m)->compat_props = props; \
-} while (0)
-
extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
#endif
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 5baa90683b..53af76a93c 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -35,7 +35,8 @@ struct sPAPRMachineClass {
MachineClass parent_class;
/*< public >*/
- bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */
+ bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */
+ bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */
};
/**
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 2299a5405a..c9733e7552 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -34,7 +34,7 @@
#define TYPE_SPAPR_VIO_BUS "spapr-vio-bus"
#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS)
-struct VIOsPAPRDevice;
+#define TYPE_SPAPR_VIO_BRIDGE "spapr-vio-bridge"
typedef struct VIOsPAPR_CRQ {
uint64_t qladdr;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index ac70f0897b..9940a90462 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1838,13 +1838,8 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len)
return 0;
}
-/* Read a CPU node property from the host device tree that's a single
- * integer (32-bit or 64-bit). Returns 0 if anything goes wrong
- * (can't find or open the property, or doesn't understand the
- * format) */
-static uint64_t kvmppc_read_int_cpu_dt(const char *propname)
+static uint64_t kvmppc_read_int_dt(const char *filename)
{
- char buf[PATH_MAX], *tmp;
union {
uint32_t v32;
uint64_t v64;
@@ -1852,14 +1847,7 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname)
FILE *f;
int len;
- if (kvmppc_find_cpu_dt(buf, sizeof(buf))) {
- return -1;
- }
-
- tmp = g_strdup_printf("%s/%s", buf, propname);
-
- f = fopen(tmp, "rb");
- g_free(tmp);
+ f = fopen(filename, "rb");
if (!f) {
return -1;
}
@@ -1877,6 +1865,26 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname)
return 0;
}
+/* Read a CPU node property from the host device tree that's a single
+ * integer (32-bit or 64-bit). Returns 0 if anything goes wrong
+ * (can't find or open the property, or doesn't understand the
+ * format) */
+static uint64_t kvmppc_read_int_cpu_dt(const char *propname)
+{
+ char buf[PATH_MAX], *tmp;
+ uint64_t val;
+
+ if (kvmppc_find_cpu_dt(buf, sizeof(buf))) {
+ return -1;
+ }
+
+ tmp = g_strdup_printf("%s/%s", buf, propname);
+ val = kvmppc_read_int_dt(tmp);
+ g_free(tmp);
+
+ return val;
+}
+
uint64_t kvmppc_get_clockfreq(void)
{
return kvmppc_read_int_cpu_dt("clock-frequency");