hw/i386/pc_piix: Make PIIX4 south bridge usable in PC machine

QEMU's PIIX3 implementation actually models the real PIIX4, but with different
PCI IDs. Usually, guests deal just fine with it. Still, in order to provide a
more consistent illusion to guests, allow QEMU's PIIX4 implementation to be used
in the PC machine.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Message-Id: <20231007123843.127151-30-shentey@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Bernhard Beschow 2023-10-07 14:38:37 +02:00 committed by Michael S. Tsirkin
parent 12cecd4550
commit aa0c9aec57
4 changed files with 71 additions and 1 deletions

View file

@ -71,3 +71,11 @@ machine property, i.e.
|qemu_system_x86| some.img \
-audiodev <backend>,id=<name> \
-machine pcspk-audiodev=<name>
Machine-specific options
~~~~~~~~~~~~~~~~~~~~~~~~
It supports the following machine-specific options:
- ``x-south-bridge=PIIX3|piix4-isa`` (Experimental option to select a particular
south bridge. Default: ``PIIX3``)

View file

@ -1706,6 +1706,7 @@ static void pc_machine_initfn(Object *obj)
#endif /* CONFIG_VMPORT */
pcms->max_ram_below_4g = 0; /* use default */
pcms->smbios_entry_point_type = pcmc->default_smbios_ep_type;
pcms->south_bridge = pcmc->default_south_bridge;
/* acpi build is enabled by default if machine supports it */
pcms->acpi_build_enabled = pcmc->has_acpi_build;

View file

@ -262,7 +262,7 @@ static void pc_init1(MachineState *machine,
DeviceState *dev;
size_t i;
pci_dev = pci_new_multifunction(-1, TYPE_PIIX3_DEVICE);
pci_dev = pci_new_multifunction(-1, pcms->south_bridge);
object_property_set_bool(OBJECT(pci_dev), "has-usb",
machine_usb(machine), &error_abort);
object_property_set_bool(OBJECT(pci_dev), "has-acpi",
@ -394,6 +394,56 @@ static void pc_init1(MachineState *machine,
}
}
typedef enum PCSouthBridgeOption {
PC_SOUTH_BRIDGE_OPTION_PIIX3,
PC_SOUTH_BRIDGE_OPTION_PIIX4,
PC_SOUTH_BRIDGE_OPTION_MAX,
} PCSouthBridgeOption;
static const QEnumLookup PCSouthBridgeOption_lookup = {
.array = (const char *const[]) {
[PC_SOUTH_BRIDGE_OPTION_PIIX3] = TYPE_PIIX3_DEVICE,
[PC_SOUTH_BRIDGE_OPTION_PIIX4] = TYPE_PIIX4_PCI_DEVICE,
},
.size = PC_SOUTH_BRIDGE_OPTION_MAX
};
#define NotifyVmexitOption_str(val) \
qapi_enum_lookup(&NotifyVmexitOption_lookup, (val))
static int pc_get_south_bridge(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
int i;
for (i = 0; i < PCSouthBridgeOption_lookup.size; i++) {
if (g_strcmp0(PCSouthBridgeOption_lookup.array[i],
pcms->south_bridge) == 0) {
return i;
}
}
error_setg(errp, "Invalid south bridge value set");
return 0;
}
static void pc_set_south_bridge(Object *obj, int value, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
if (value < 0) {
error_setg(errp, "Value can't be negative");
return;
}
if (value >= PCSouthBridgeOption_lookup.size) {
error_setg(errp, "Value too big");
return;
}
pcms->south_bridge = PCSouthBridgeOption_lookup.array[value];
}
/* Looking for a pc_compat_2_4() function? It doesn't exist.
* pc_compat_*() functions that run on machine-init time and
* change global QEMU state are deprecated. Please don't create
@ -473,6 +523,8 @@ static void pc_xen_hvm_init(MachineState *machine)
static void pc_i440fx_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
ObjectClass *oc = OBJECT_CLASS(m);
pcmc->default_south_bridge = TYPE_PIIX3_DEVICE;
pcmc->pci_root_uid = 0;
pcmc->default_cpu_version = 1;
@ -484,6 +536,13 @@ static void pc_i440fx_machine_options(MachineClass *m)
m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption",
&PCSouthBridgeOption_lookup,
pc_get_south_bridge,
pc_set_south_bridge);
object_class_property_set_description(oc, "x-south-bridge",
"Use a different south bridge than PIIX3");
}
static void pc_i440fx_8_2_machine_options(MachineClass *m)

View file

@ -42,6 +42,7 @@ typedef struct PCMachineState {
uint64_t max_ram_below_4g;
OnOffAuto vmport;
SmbiosEntryPointType smbios_entry_point_type;
const char *south_bridge;
bool acpi_build_enabled;
bool smbus_enabled;
@ -92,6 +93,7 @@ struct PCMachineClass {
/* Device configuration: */
bool pci_enabled;
bool kvmclock_enabled;
const char *default_south_bridge;
/* Compat options: */