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,9 +2320,94 @@ static const TypeInfo spapr_machine_info = { }, }; +#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) + +/* + * pseries-2.6 + */ +static void spapr_machine_2_6_instance_options(MachineState *machine) +{ +} + +static void spapr_machine_2_6_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(2_6, "2.6", true); + +/* + * pseries-2.5 + */ +#define SPAPR_COMPAT_2_5 \ + HW_COMPAT_2_5 + +static void spapr_machine_2_5_instance_options(MachineState *machine) +{ +} + +static void spapr_machine_2_5_class_options(MachineClass *mc) +{ + 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); +} + +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_machine_2_5_instance_options(machine); +} + +static void spapr_machine_2_4_class_options(MachineClass *mc) +{ + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + + spapr_machine_2_5_class_options(mc); + smc->dr_lmb_enabled = false; + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4); +} + +DEFINE_SPAPR_MACHINE(2_4, "2.4", false); + +/* + * pseries-2.3 + */ #define SPAPR_COMPAT_2_3 \ SPAPR_COMPAT_2_4 \ HW_COMPAT_2_3 \ @@ -2310,6 +2417,24 @@ static const TypeInfo spapr_machine_info = { .value = "off",\ }, +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 void spapr_machine_2_3_class_options(MachineClass *mc) +{ + spapr_machine_2_4_class_options(mc); + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3); +} +DEFINE_SPAPR_MACHINE(2_3, "2.3", false); + +/* + * pseries-2.2 + */ + #define SPAPR_COMPAT_2_2 \ SPAPR_COMPAT_2_3 \ HW_COMPAT_2_2 \ @@ -2319,145 +2444,40 @@ static const TypeInfo spapr_machine_info = { .value = "0x20000000",\ }, +static void spapr_machine_2_2_instance_options(MachineState *machine) +{ + spapr_machine_2_3_instance_options(machine); +} + +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); + +/* + * pseries-2.1 + */ #define SPAPR_COMPAT_2_1 \ SPAPR_COMPAT_2_2 \ HW_COMPAT_2_1 -static void spapr_compat_2_3(Object *obj) +static void spapr_machine_2_1_instance_options(MachineState *machine) { - savevm_skip_section_footers(); - global_state_set_optional(); + spapr_machine_2_2_instance_options(machine); } -static void spapr_compat_2_2(Object *obj) +static void spapr_machine_2_1_class_options(MachineClass *mc) { - spapr_compat_2_3(obj); + spapr_machine_2_2_class_options(mc); + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); } - -static void spapr_compat_2_1(Object *obj) -{ - spapr_compat_2_2(obj); -} - -static void spapr_machine_2_3_instance_init(Object *obj) -{ - spapr_compat_2_3(obj); - spapr_machine_initfn(obj); -} - -static void spapr_machine_2_2_instance_init(Object *obj) -{ - spapr_compat_2_2(obj); - spapr_machine_initfn(obj); -} - -static void spapr_machine_2_1_instance_init(Object *obj) -{ - spapr_compat_2_1(obj); - spapr_machine_initfn(obj); -} - -static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_1 - { /* end of list */ } - }; - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.1"; - mc->compat_props = compat_props; -} - -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, -}; - -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); - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2"; - mc->compat_props = compat_props; -} - -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 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; -} - -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, -}; - -static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) -{ - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_4 - { /* end of list */ } - }; - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.4"; - mc->compat_props = compat_props; -} - -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, -}; - -static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) -{ - 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; -} - -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, -}; +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");