1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "config-devices.h"
27
28#include "qemu/units.h"
29#include "hw/loader.h"
30#include "hw/i386/x86.h"
31#include "hw/i386/pc.h"
32#include "hw/i386/apic.h"
33#include "hw/pci-host/i440fx.h"
34#include "hw/southbridge/piix.h"
35#include "hw/display/ramfb.h"
36#include "hw/firmware/smbios.h"
37#include "hw/pci/pci.h"
38#include "hw/pci/pci_ids.h"
39#include "hw/usb.h"
40#include "net/net.h"
41#include "hw/ide/pci.h"
42#include "hw/irq.h"
43#include "sysemu/kvm.h"
44#include "hw/kvm/clock.h"
45#include "sysemu/sysemu.h"
46#include "hw/sysbus.h"
47#include "sysemu/arch_init.h"
48#include "hw/i2c/smbus_eeprom.h"
49#include "hw/xen/xen.h"
50#include "exec/memory.h"
51#include "exec/address-spaces.h"
52#include "hw/acpi/acpi.h"
53#include "cpu.h"
54#include "qapi/error.h"
55#include "qemu/error-report.h"
56#include "sysemu/xen.h"
57#ifdef CONFIG_XEN
58#include <xen/hvm/hvm_info_table.h>
59#include "hw/xen/xen_pt.h"
60#endif
61#include "migration/global_state.h"
62#include "migration/misc.h"
63#include "sysemu/numa.h"
64#include "hw/hyperv/vmbus-bridge.h"
65#include "hw/mem/nvdimm.h"
66#include "hw/i386/acpi-build.h"
67
68#define MAX_IDE_BUS 2
69
70#ifdef CONFIG_IDE_ISA
71static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
72static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
73static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
74#endif
75
76
77static void pc_init1(MachineState *machine,
78 const char *host_type, const char *pci_type)
79{
80 PCMachineState *pcms = PC_MACHINE(machine);
81 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
82 X86MachineState *x86ms = X86_MACHINE(machine);
83 MemoryRegion *system_memory = get_system_memory();
84 MemoryRegion *system_io = get_system_io();
85 PCIBus *pci_bus;
86 ISABus *isa_bus;
87 PCII440FXState *i440fx_state;
88 int piix3_devfn = -1;
89 qemu_irq smi_irq;
90 GSIState *gsi_state;
91 BusState *idebus[MAX_IDE_BUS];
92 ISADevice *rtc_state;
93 MemoryRegion *ram_memory;
94 MemoryRegion *pci_memory;
95 MemoryRegion *rom_memory;
96 ram_addr_t lowmem;
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 if (xen_enabled()) {
130 xen_hvm_init(pcms, &ram_memory);
131 } else {
132 if (!pcms->max_ram_below_4g) {
133 pcms->max_ram_below_4g = 0xe0000000;
134 }
135 lowmem = pcms->max_ram_below_4g;
136 if (machine->ram_size >= pcms->max_ram_below_4g) {
137 if (pcmc->gigabyte_align) {
138 if (lowmem > 0xc0000000) {
139 lowmem = 0xc0000000;
140 }
141 if (lowmem & (1 * GiB - 1)) {
142 warn_report("Large machine and max_ram_below_4g "
143 "(%" PRIu64 ") not a multiple of 1G; "
144 "possible bad performance.",
145 pcms->max_ram_below_4g);
146 }
147 }
148 }
149
150 if (machine->ram_size >= lowmem) {
151 x86ms->above_4g_mem_size = machine->ram_size - lowmem;
152 x86ms->below_4g_mem_size = lowmem;
153 } else {
154 x86ms->above_4g_mem_size = 0;
155 x86ms->below_4g_mem_size = machine->ram_size;
156 }
157 }
158
159 x86_cpus_init(x86ms, pcmc->default_cpu_version);
160
161 if (kvm_enabled() && pcmc->kvmclock_enabled) {
162 kvmclock_create();
163 }
164
165 if (pcmc->pci_enabled) {
166 pci_memory = g_new(MemoryRegion, 1);
167 memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
168 rom_memory = pci_memory;
169 } else {
170 pci_memory = NULL;
171 rom_memory = system_memory;
172 }
173
174 pc_guest_info_init(pcms);
175
176 if (pcmc->smbios_defaults) {
177 MachineClass *mc = MACHINE_GET_CLASS(machine);
178
179 smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)",
180 mc->name, pcmc->smbios_legacy_mode,
181 pcmc->smbios_uuid_encoded,
182 SMBIOS_ENTRY_POINT_21);
183 }
184
185
186 if (!xen_enabled()) {
187 pc_memory_init(pcms, system_memory,
188 rom_memory, &ram_memory);
189 } else {
190 pc_system_flash_cleanup_unused(pcms);
191 if (machine->kernel_filename != NULL) {
192
193 xen_load_linux(pcms);
194 }
195 }
196
197 gsi_state = pc_gsi_create(&x86ms->gsi, pcmc->pci_enabled);
198
199 if (pcmc->pci_enabled) {
200 PIIX3State *piix3;
201
202 pci_bus = i440fx_init(host_type,
203 pci_type,
204 &i440fx_state,
205 system_memory, system_io, machine->ram_size,
206 x86ms->below_4g_mem_size,
207 x86ms->above_4g_mem_size,
208 pci_memory, ram_memory);
209 pcms->bus = pci_bus;
210
211 piix3 = piix3_create(pci_bus, &isa_bus);
212 piix3->pic = x86ms->gsi;
213 piix3_devfn = piix3->dev.devfn;
214 } else {
215 pci_bus = NULL;
216 i440fx_state = NULL;
217 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
218 &error_abort);
219 no_hpet = 1;
220 }
221 isa_bus_irqs(isa_bus, x86ms->gsi);
222
223 pc_i8259_create(isa_bus, gsi_state->i8259_irq);
224
225 if (pcmc->pci_enabled) {
226 ioapic_init_gsi(gsi_state, "i440fx");
227 }
228
229 if (tcg_enabled()) {
230 x86_register_ferr_irq(x86ms->gsi[13]);
231 }
232
233 pc_vga_init(isa_bus, pcmc->pci_enabled ? pci_bus : NULL);
234
235 assert(pcms->vmport != ON_OFF_AUTO__MAX);
236 if (pcms->vmport == ON_OFF_AUTO_AUTO) {
237 pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
238 }
239
240
241 pc_basic_device_init(pcms, isa_bus, x86ms->gsi, &rtc_state, true,
242 0x4);
243
244 pc_nic_init(pcmc, isa_bus, pci_bus);
245
246 if (pcmc->pci_enabled) {
247 PCIDevice *dev;
248
249 dev = pci_create_simple(pci_bus, piix3_devfn + 1,
250 xen_enabled() ? "piix3-ide-xen" : "piix3-ide");
251 pci_ide_create_devs(dev);
252 idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
253 idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
254 pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
255 }
256#ifdef CONFIG_IDE_ISA
257 else {
258 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
259 int i;
260
261 ide_drive_get(hd, ARRAY_SIZE(hd));
262 for (i = 0; i < MAX_IDE_BUS; i++) {
263 ISADevice *dev;
264 char busname[] = "ide.0";
265 dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
266 ide_irq[i],
267 hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
268
269
270
271
272 busname[4] = '0' + i;
273 idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
274 }
275 pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
276 }
277#endif
278
279 if (pcmc->pci_enabled && machine_usb(machine)) {
280 pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
281 }
282
283 if (pcmc->pci_enabled && x86_machine_is_acpi_enabled(X86_MACHINE(pcms))) {
284 DeviceState *piix4_pm;
285
286 smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
287
288 pcms->smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
289 x86ms->gsi[9], smi_irq,
290 x86_machine_is_smm_enabled(x86ms),
291 &piix4_pm);
292 smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
293
294 object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
295 TYPE_HOTPLUG_HANDLER,
296 (Object **)&pcms->acpi_dev,
297 object_property_allow_set_link,
298 OBJ_PROP_LINK_STRONG);
299 object_property_set_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
300 OBJECT(piix4_pm), &error_abort);
301 }
302
303 if (machine->nvdimms_state->is_enabled) {
304 nvdimm_init_acpi_state(machine->nvdimms_state, system_io,
305 x86_nvdimm_acpi_dsmio,
306 x86ms->fw_cfg, OBJECT(pcms));
307 }
308}
309
310
311
312
313
314
315
316
317static void pc_compat_2_3_fn(MachineState *machine)
318{
319 X86MachineState *x86ms = X86_MACHINE(machine);
320 if (kvm_enabled()) {
321 x86ms->smm = ON_OFF_AUTO_OFF;
322 }
323}
324
325static void pc_compat_2_2_fn(MachineState *machine)
326{
327 pc_compat_2_3_fn(machine);
328}
329
330static void pc_compat_2_1_fn(MachineState *machine)
331{
332 pc_compat_2_2_fn(machine);
333 x86_cpu_change_kvm_default("svm", NULL);
334}
335
336static void pc_compat_2_0_fn(MachineState *machine)
337{
338 pc_compat_2_1_fn(machine);
339}
340
341static void pc_compat_1_7_fn(MachineState *machine)
342{
343 pc_compat_2_0_fn(machine);
344 x86_cpu_change_kvm_default("x2apic", NULL);
345}
346
347static void pc_compat_1_6_fn(MachineState *machine)
348{
349 pc_compat_1_7_fn(machine);
350}
351
352static void pc_compat_1_5_fn(MachineState *machine)
353{
354 pc_compat_1_6_fn(machine);
355}
356
357static void pc_compat_1_4_fn(MachineState *machine)
358{
359 pc_compat_1_5_fn(machine);
360}
361
362static void pc_compat_1_3(MachineState *machine)
363{
364 pc_compat_1_4_fn(machine);
365}
366
367
368static void pc_compat_1_2(MachineState *machine)
369{
370 pc_compat_1_3(machine);
371 x86_cpu_change_kvm_default("kvm-pv-eoi", NULL);
372}
373
374static void pc_init_isa(MachineState *machine)
375{
376 pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
377}
378
379#ifdef CONFIG_XEN
380static void pc_xen_hvm_init_pci(MachineState *machine)
381{
382 const char *pci_type = xen_igd_gfx_pt_enabled() ?
383 TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
384
385 pc_init1(machine,
386 TYPE_I440FX_PCI_HOST_BRIDGE,
387 pci_type);
388}
389
390static void pc_xen_hvm_init(MachineState *machine)
391{
392 PCMachineState *pcms = PC_MACHINE(machine);
393
394 if (!xen_enabled()) {
395 error_report("xenfv machine requires the xen accelerator");
396 exit(1);
397 }
398
399 pc_xen_hvm_init_pci(machine);
400 pci_create_simple(pcms->bus, -1, "xen-platform");
401}
402#endif
403
404#define DEFINE_I440FX_MACHINE(suffix, name, compatfn, optionfn) \
405 static void pc_init_##suffix(MachineState *machine) \
406 { \
407 void (*compat)(MachineState *m) = (compatfn); \
408 if (compat) { \
409 compat(machine); \
410 } \
411 pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
412 TYPE_I440FX_PCI_DEVICE); \
413 } \
414 DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
415
416static void pc_i440fx_machine_options(MachineClass *m)
417{
418 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
419 pcmc->default_nic_model = "e1000";
420
421 m->family = "pc_piix";
422 m->desc = "Standard PC (i440FX + PIIX, 1996)";
423 m->default_machine_opts = "firmware=bios-256k.bin";
424 m->default_display = "std";
425 machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
426 machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
427}
428
429static void pc_i440fx_5_1_machine_options(MachineClass *m)
430{
431 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
432 pc_i440fx_machine_options(m);
433 m->alias = "pc";
434 m->is_default = true;
435 pcmc->default_cpu_version = 1;
436}
437
438DEFINE_I440FX_MACHINE(v5_1, "pc-i440fx-5.1", NULL,
439 pc_i440fx_5_1_machine_options);
440
441static void pc_i440fx_5_0_machine_options(MachineClass *m)
442{
443 pc_i440fx_5_1_machine_options(m);
444 m->alias = NULL;
445 m->is_default = false;
446 m->numa_mem_supported = true;
447 compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
448 compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
449 m->auto_enable_numa_with_memdev = false;
450}
451
452DEFINE_I440FX_MACHINE(v5_0, "pc-i440fx-5.0", NULL,
453 pc_i440fx_5_0_machine_options);
454
455static void pc_i440fx_4_2_machine_options(MachineClass *m)
456{
457 pc_i440fx_5_0_machine_options(m);
458 m->alias = NULL;
459 m->is_default = false;
460 compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
461 compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len);
462}
463
464DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL,
465 pc_i440fx_4_2_machine_options);
466
467static void pc_i440fx_4_1_machine_options(MachineClass *m)
468{
469 pc_i440fx_4_2_machine_options(m);
470 m->alias = NULL;
471 m->is_default = false;
472 compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len);
473 compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len);
474}
475
476DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL,
477 pc_i440fx_4_1_machine_options);
478
479static void pc_i440fx_4_0_machine_options(MachineClass *m)
480{
481 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
482 pc_i440fx_4_1_machine_options(m);
483 m->alias = NULL;
484 m->is_default = false;
485 pcmc->default_cpu_version = CPU_VERSION_LEGACY;
486 compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
487 compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
488}
489
490DEFINE_I440FX_MACHINE(v4_0, "pc-i440fx-4.0", NULL,
491 pc_i440fx_4_0_machine_options);
492
493static void pc_i440fx_3_1_machine_options(MachineClass *m)
494{
495 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
496
497 pc_i440fx_4_0_machine_options(m);
498 m->is_default = false;
499 pcmc->do_not_add_smb_acpi = true;
500 m->smbus_no_migration_support = true;
501 m->alias = NULL;
502 pcmc->pvh_enabled = false;
503 compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
504 compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
505}
506
507DEFINE_I440FX_MACHINE(v3_1, "pc-i440fx-3.1", NULL,
508 pc_i440fx_3_1_machine_options);
509
510static void pc_i440fx_3_0_machine_options(MachineClass *m)
511{
512 pc_i440fx_3_1_machine_options(m);
513 compat_props_add(m->compat_props, hw_compat_3_0, hw_compat_3_0_len);
514 compat_props_add(m->compat_props, pc_compat_3_0, pc_compat_3_0_len);
515}
516
517DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
518 pc_i440fx_3_0_machine_options);
519
520static void pc_i440fx_2_12_machine_options(MachineClass *m)
521{
522 pc_i440fx_3_0_machine_options(m);
523 compat_props_add(m->compat_props, hw_compat_2_12, hw_compat_2_12_len);
524 compat_props_add(m->compat_props, pc_compat_2_12, pc_compat_2_12_len);
525}
526
527DEFINE_I440FX_MACHINE(v2_12, "pc-i440fx-2.12", NULL,
528 pc_i440fx_2_12_machine_options);
529
530static void pc_i440fx_2_11_machine_options(MachineClass *m)
531{
532 pc_i440fx_2_12_machine_options(m);
533 compat_props_add(m->compat_props, hw_compat_2_11, hw_compat_2_11_len);
534 compat_props_add(m->compat_props, pc_compat_2_11, pc_compat_2_11_len);
535}
536
537DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
538 pc_i440fx_2_11_machine_options);
539
540static void pc_i440fx_2_10_machine_options(MachineClass *m)
541{
542 pc_i440fx_2_11_machine_options(m);
543 compat_props_add(m->compat_props, hw_compat_2_10, hw_compat_2_10_len);
544 compat_props_add(m->compat_props, pc_compat_2_10, pc_compat_2_10_len);
545 m->auto_enable_numa_with_memhp = false;
546}
547
548DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
549 pc_i440fx_2_10_machine_options);
550
551static void pc_i440fx_2_9_machine_options(MachineClass *m)
552{
553 pc_i440fx_2_10_machine_options(m);
554 compat_props_add(m->compat_props, hw_compat_2_9, hw_compat_2_9_len);
555 compat_props_add(m->compat_props, pc_compat_2_9, pc_compat_2_9_len);
556 m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
557}
558
559DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
560 pc_i440fx_2_9_machine_options);
561
562static void pc_i440fx_2_8_machine_options(MachineClass *m)
563{
564 pc_i440fx_2_9_machine_options(m);
565 compat_props_add(m->compat_props, hw_compat_2_8, hw_compat_2_8_len);
566 compat_props_add(m->compat_props, pc_compat_2_8, pc_compat_2_8_len);
567}
568
569DEFINE_I440FX_MACHINE(v2_8, "pc-i440fx-2.8", NULL,
570 pc_i440fx_2_8_machine_options);
571
572static void pc_i440fx_2_7_machine_options(MachineClass *m)
573{
574 pc_i440fx_2_8_machine_options(m);
575 compat_props_add(m->compat_props, hw_compat_2_7, hw_compat_2_7_len);
576 compat_props_add(m->compat_props, pc_compat_2_7, pc_compat_2_7_len);
577}
578
579DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
580 pc_i440fx_2_7_machine_options);
581
582static void pc_i440fx_2_6_machine_options(MachineClass *m)
583{
584 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
585
586 pc_i440fx_2_7_machine_options(m);
587 pcmc->legacy_cpu_hotplug = true;
588 pcmc->linuxboot_dma_enabled = false;
589 compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
590 compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
591}
592
593DEFINE_I440FX_MACHINE(v2_6, "pc-i440fx-2.6", NULL,
594 pc_i440fx_2_6_machine_options);
595
596static void pc_i440fx_2_5_machine_options(MachineClass *m)
597{
598 X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
599
600 pc_i440fx_2_6_machine_options(m);
601 x86mc->save_tsc_khz = false;
602 m->legacy_fw_cfg_order = 1;
603 compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len);
604 compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len);
605}
606
607DEFINE_I440FX_MACHINE(v2_5, "pc-i440fx-2.5", NULL,
608 pc_i440fx_2_5_machine_options);
609
610static void pc_i440fx_2_4_machine_options(MachineClass *m)
611{
612 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
613
614 pc_i440fx_2_5_machine_options(m);
615 m->hw_version = "2.4.0";
616 pcmc->broken_reserved_end = true;
617 compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len);
618 compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len);
619}
620
621DEFINE_I440FX_MACHINE(v2_4, "pc-i440fx-2.4", NULL,
622 pc_i440fx_2_4_machine_options)
623
624static void pc_i440fx_2_3_machine_options(MachineClass *m)
625{
626 pc_i440fx_2_4_machine_options(m);
627 m->hw_version = "2.3.0";
628 compat_props_add(m->compat_props, hw_compat_2_3, hw_compat_2_3_len);
629 compat_props_add(m->compat_props, pc_compat_2_3, pc_compat_2_3_len);
630}
631
632DEFINE_I440FX_MACHINE(v2_3, "pc-i440fx-2.3", pc_compat_2_3_fn,
633 pc_i440fx_2_3_machine_options);
634
635static void pc_i440fx_2_2_machine_options(MachineClass *m)
636{
637 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
638
639 pc_i440fx_2_3_machine_options(m);
640 m->hw_version = "2.2.0";
641 m->default_machine_opts = "firmware=bios-256k.bin,suppress-vmdesc=on";
642 compat_props_add(m->compat_props, hw_compat_2_2, hw_compat_2_2_len);
643 compat_props_add(m->compat_props, pc_compat_2_2, pc_compat_2_2_len);
644 pcmc->rsdp_in_ram = false;
645}
646
647DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2_fn,
648 pc_i440fx_2_2_machine_options);
649
650static void pc_i440fx_2_1_machine_options(MachineClass *m)
651{
652 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
653
654 pc_i440fx_2_2_machine_options(m);
655 m->hw_version = "2.1.0";
656 m->default_display = NULL;
657 compat_props_add(m->compat_props, hw_compat_2_1, hw_compat_2_1_len);
658 compat_props_add(m->compat_props, pc_compat_2_1, pc_compat_2_1_len);
659 pcmc->smbios_uuid_encoded = false;
660 pcmc->enforce_aligned_dimm = false;
661}
662
663DEFINE_I440FX_MACHINE(v2_1, "pc-i440fx-2.1", pc_compat_2_1_fn,
664 pc_i440fx_2_1_machine_options);
665
666static void pc_i440fx_2_0_machine_options(MachineClass *m)
667{
668 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
669
670 pc_i440fx_2_1_machine_options(m);
671 m->hw_version = "2.0.0";
672 compat_props_add(m->compat_props, pc_compat_2_0, pc_compat_2_0_len);
673 pcmc->smbios_legacy_mode = true;
674 pcmc->has_reserved_memory = false;
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691 pcmc->legacy_acpi_table_size = 6652;
692 pcmc->acpi_data_size = 0x10000;
693}
694
695DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0_fn,
696 pc_i440fx_2_0_machine_options);
697
698static void pc_i440fx_1_7_machine_options(MachineClass *m)
699{
700 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
701
702 pc_i440fx_2_0_machine_options(m);
703 m->hw_version = "1.7.0";
704 m->default_machine_opts = NULL;
705 m->option_rom_has_mr = true;
706 compat_props_add(m->compat_props, pc_compat_1_7, pc_compat_1_7_len);
707 pcmc->smbios_defaults = false;
708 pcmc->gigabyte_align = false;
709 pcmc->legacy_acpi_table_size = 6414;
710}
711
712DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7_fn,
713 pc_i440fx_1_7_machine_options);
714
715static void pc_i440fx_1_6_machine_options(MachineClass *m)
716{
717 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
718
719 pc_i440fx_1_7_machine_options(m);
720 m->hw_version = "1.6.0";
721 m->rom_file_has_mr = false;
722 compat_props_add(m->compat_props, pc_compat_1_6, pc_compat_1_6_len);
723 pcmc->has_acpi_build = false;
724}
725
726DEFINE_I440FX_MACHINE(v1_6, "pc-i440fx-1.6", pc_compat_1_6_fn,
727 pc_i440fx_1_6_machine_options);
728
729static void pc_i440fx_1_5_machine_options(MachineClass *m)
730{
731 pc_i440fx_1_6_machine_options(m);
732 m->hw_version = "1.5.0";
733 compat_props_add(m->compat_props, pc_compat_1_5, pc_compat_1_5_len);
734}
735
736DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5_fn,
737 pc_i440fx_1_5_machine_options);
738
739static void pc_i440fx_1_4_machine_options(MachineClass *m)
740{
741 pc_i440fx_1_5_machine_options(m);
742 m->hw_version = "1.4.0";
743 m->hot_add_cpu = NULL;
744 compat_props_add(m->compat_props, pc_compat_1_4, pc_compat_1_4_len);
745}
746
747DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4_fn,
748 pc_i440fx_1_4_machine_options);
749
750static void pc_i440fx_1_3_machine_options(MachineClass *m)
751{
752 X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
753 static GlobalProperty compat[] = {
754 PC_CPU_MODEL_IDS("1.3.0")
755 { "usb-tablet", "usb_version", "1" },
756 { "virtio-net-pci", "ctrl_mac_addr", "off" },
757 { "virtio-net-pci", "mq", "off" },
758 { "e1000", "autonegotiation", "off" },
759 };
760
761 pc_i440fx_1_4_machine_options(m);
762 m->hw_version = "1.3.0";
763 m->deprecation_reason = "use a newer machine type instead";
764 x86mc->compat_apic_id_mode = true;
765 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
766}
767
768DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3,
769 pc_i440fx_1_3_machine_options);
770
771
772static void pc_i440fx_1_2_machine_options(MachineClass *m)
773{
774 static GlobalProperty compat[] = {
775 PC_CPU_MODEL_IDS("1.2.0")
776 { "nec-usb-xhci", "msi", "off" },
777 { "nec-usb-xhci", "msix", "off" },
778 { "qxl", "revision", "3" },
779 { "qxl-vga", "revision", "3" },
780 { "VGA", "mmio", "off" },
781 };
782
783 pc_i440fx_1_3_machine_options(m);
784 m->hw_version = "1.2.0";
785 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
786}
787
788DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2,
789 pc_i440fx_1_2_machine_options);
790
791
792static void pc_i440fx_1_1_machine_options(MachineClass *m)
793{
794 static GlobalProperty compat[] = {
795 PC_CPU_MODEL_IDS("1.1.0")
796 { "virtio-scsi-pci", "hotplug", "off" },
797 { "virtio-scsi-pci", "param_change", "off" },
798 { "VGA", "vgamem_mb", "8" },
799 { "vmware-svga", "vgamem_mb", "8" },
800 { "qxl-vga", "vgamem_mb", "8" },
801 { "qxl", "vgamem_mb", "8" },
802 { "virtio-blk-pci", "config-wce", "off" },
803 };
804
805 pc_i440fx_1_2_machine_options(m);
806 m->hw_version = "1.1.0";
807 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
808}
809
810DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2,
811 pc_i440fx_1_1_machine_options);
812
813static void pc_i440fx_1_0_machine_options(MachineClass *m)
814{
815 static GlobalProperty compat[] = {
816 PC_CPU_MODEL_IDS("1.0")
817 { TYPE_ISA_FDC, "check_media_rate", "off" },
818 { "virtio-balloon-pci", "class", stringify(PCI_CLASS_MEMORY_RAM) },
819 { "apic-common", "vapic", "off" },
820 { TYPE_USB_DEVICE, "full-path", "no" },
821 };
822
823 pc_i440fx_1_1_machine_options(m);
824 m->hw_version = "1.0";
825 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
826}
827
828DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
829 pc_i440fx_1_0_machine_options);
830
831
832typedef struct {
833 uint16_t gpu_device_id;
834 uint16_t pch_device_id;
835 uint8_t pch_revision_id;
836} IGDDeviceIDInfo;
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853static const IGDDeviceIDInfo igd_combo_id_infos[] = {
854
855 {0x0402, 0x8c4e, 0x04},
856 {0x0406, 0x8c4e, 0x04},
857 {0x0412, 0x8c4e, 0x04},
858 {0x0416, 0x8c4e, 0x04},
859 {0x041E, 0x8c4e, 0x04},
860
861 {0x0A06, 0x8c4e, 0x04},
862 {0x0A16, 0x8c4e, 0x04},
863 {0x0A26, 0x8c4e, 0x06},
864 {0x0A2E, 0x8c4e, 0x04},
865 {0x0A1E, 0x8c4e, 0x04},
866 {0x0A0E, 0x8c4e, 0x04},
867
868 {0x0D26, 0x8c4e, 0x04},
869 {0x0D22, 0x8c4e, 0x04},
870
871 {0x041A, 0x8c4e, 0x04},
872
873 {0x040A, 0x8c4e, 0x04},
874
875 {0x1606, 0x9cc3, 0x03},
876 {0x1616, 0x9cc3, 0x03},
877 {0x1626, 0x9cc3, 0x03},
878 {0x160E, 0x9cc3, 0x03},
879 {0x161E, 0x9cc3, 0x03},
880 {0x1602, 0x9cc3, 0x03},
881 {0x1612, 0x9cc3, 0x03},
882 {0x1622, 0x9cc3, 0x03},
883 {0x162B, 0x9cc3, 0x03},
884 {0x162A, 0x9cc3, 0x03},
885 {0x162D, 0x9cc3, 0x03},
886};
887
888static void isa_bridge_class_init(ObjectClass *klass, void *data)
889{
890 DeviceClass *dc = DEVICE_CLASS(klass);
891 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
892
893 dc->desc = "ISA bridge faked to support IGD PT";
894 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
895 k->vendor_id = PCI_VENDOR_ID_INTEL;
896 k->class_id = PCI_CLASS_BRIDGE_ISA;
897};
898
899static TypeInfo isa_bridge_info = {
900 .name = "igd-passthrough-isa-bridge",
901 .parent = TYPE_PCI_DEVICE,
902 .instance_size = sizeof(PCIDevice),
903 .class_init = isa_bridge_class_init,
904 .interfaces = (InterfaceInfo[]) {
905 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
906 { },
907 },
908};
909
910static void pt_graphics_register_types(void)
911{
912 type_register_static(&isa_bridge_info);
913}
914type_init(pt_graphics_register_types)
915
916void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
917{
918 struct PCIDevice *bridge_dev;
919 int i, num;
920 uint16_t pch_dev_id = 0xffff;
921 uint8_t pch_rev_id;
922
923 num = ARRAY_SIZE(igd_combo_id_infos);
924 for (i = 0; i < num; i++) {
925 if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
926 pch_dev_id = igd_combo_id_infos[i].pch_device_id;
927 pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
928 }
929 }
930
931 if (pch_dev_id == 0xffff) {
932 return;
933 }
934
935
936 bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
937 "igd-passthrough-isa-bridge");
938
939
940
941
942 if (!bridge_dev) {
943 fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
944 return;
945 }
946 pci_config_set_device_id(bridge_dev->config, pch_dev_id);
947 pci_config_set_revision(bridge_dev->config, pch_rev_id);
948}
949
950static void isapc_machine_options(MachineClass *m)
951{
952 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
953 m->desc = "ISA-only PC";
954 m->max_cpus = 1;
955 m->option_rom_has_mr = true;
956 m->rom_file_has_mr = false;
957 pcmc->pci_enabled = false;
958 pcmc->has_acpi_build = false;
959 pcmc->smbios_defaults = false;
960 pcmc->gigabyte_align = false;
961 pcmc->smbios_legacy_mode = true;
962 pcmc->has_reserved_memory = false;
963 pcmc->default_nic_model = "ne2k_isa";
964 m->default_cpu_type = X86_CPU_TYPE_NAME("486");
965}
966
967DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
968 isapc_machine_options);
969
970
971#ifdef CONFIG_XEN
972static void xenfv_4_2_machine_options(MachineClass *m)
973{
974 pc_i440fx_4_2_machine_options(m);
975 m->desc = "Xen Fully-virtualized PC";
976 m->max_cpus = HVM_MAX_VCPUS;
977 m->default_machine_opts = "accel=xen";
978}
979
980DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
981 xenfv_4_2_machine_options);
982
983static void xenfv_3_1_machine_options(MachineClass *m)
984{
985 pc_i440fx_3_1_machine_options(m);
986 m->desc = "Xen Fully-virtualized PC";
987 m->alias = "xenfv";
988 m->max_cpus = HVM_MAX_VCPUS;
989 m->default_machine_opts = "accel=xen";
990}
991
992DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
993 xenfv_3_1_machine_options);
994#endif
995