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
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-x86.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_pc(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 (pcmc->kvmclock_enabled) {
162 kvmclock_create(pcmc->kvmclock_create_always);
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 pcms->hpet_enabled = false;
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 **)&x86ms->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_2_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_2, "pc-i440fx-5.2", NULL,
439 pc_i440fx_5_2_machine_options);
440
441static void pc_i440fx_5_1_machine_options(MachineClass *m)
442{
443 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
444
445 pc_i440fx_5_2_machine_options(m);
446 m->alias = NULL;
447 m->is_default = false;
448 compat_props_add(m->compat_props, hw_compat_5_1, hw_compat_5_1_len);
449 compat_props_add(m->compat_props, pc_compat_5_1, pc_compat_5_1_len);
450 pcmc->kvmclock_create_always = false;
451}
452
453DEFINE_I440FX_MACHINE(v5_1, "pc-i440fx-5.1", NULL,
454 pc_i440fx_5_1_machine_options);
455
456static void pc_i440fx_5_0_machine_options(MachineClass *m)
457{
458 pc_i440fx_5_1_machine_options(m);
459 m->alias = NULL;
460 m->is_default = false;
461 m->numa_mem_supported = true;
462 compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
463 compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
464 m->auto_enable_numa_with_memdev = false;
465}
466
467DEFINE_I440FX_MACHINE(v5_0, "pc-i440fx-5.0", NULL,
468 pc_i440fx_5_0_machine_options);
469
470static void pc_i440fx_4_2_machine_options(MachineClass *m)
471{
472 pc_i440fx_5_0_machine_options(m);
473 m->alias = NULL;
474 m->is_default = false;
475 compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
476 compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len);
477}
478
479DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL,
480 pc_i440fx_4_2_machine_options);
481
482static void pc_i440fx_4_1_machine_options(MachineClass *m)
483{
484 pc_i440fx_4_2_machine_options(m);
485 m->alias = NULL;
486 m->is_default = false;
487 compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len);
488 compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len);
489}
490
491DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL,
492 pc_i440fx_4_1_machine_options);
493
494static void pc_i440fx_4_0_machine_options(MachineClass *m)
495{
496 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
497 pc_i440fx_4_1_machine_options(m);
498 m->alias = NULL;
499 m->is_default = false;
500 pcmc->default_cpu_version = CPU_VERSION_LEGACY;
501 compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
502 compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
503}
504
505DEFINE_I440FX_MACHINE(v4_0, "pc-i440fx-4.0", NULL,
506 pc_i440fx_4_0_machine_options);
507
508static void pc_i440fx_3_1_machine_options(MachineClass *m)
509{
510 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
511
512 pc_i440fx_4_0_machine_options(m);
513 m->is_default = false;
514 pcmc->do_not_add_smb_acpi = true;
515 m->smbus_no_migration_support = true;
516 m->alias = NULL;
517 pcmc->pvh_enabled = false;
518 compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
519 compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
520}
521
522DEFINE_I440FX_MACHINE(v3_1, "pc-i440fx-3.1", NULL,
523 pc_i440fx_3_1_machine_options);
524
525static void pc_i440fx_3_0_machine_options(MachineClass *m)
526{
527 pc_i440fx_3_1_machine_options(m);
528 compat_props_add(m->compat_props, hw_compat_3_0, hw_compat_3_0_len);
529 compat_props_add(m->compat_props, pc_compat_3_0, pc_compat_3_0_len);
530}
531
532DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
533 pc_i440fx_3_0_machine_options);
534
535static void pc_i440fx_2_12_machine_options(MachineClass *m)
536{
537 pc_i440fx_3_0_machine_options(m);
538 compat_props_add(m->compat_props, hw_compat_2_12, hw_compat_2_12_len);
539 compat_props_add(m->compat_props, pc_compat_2_12, pc_compat_2_12_len);
540}
541
542DEFINE_I440FX_MACHINE(v2_12, "pc-i440fx-2.12", NULL,
543 pc_i440fx_2_12_machine_options);
544
545static void pc_i440fx_2_11_machine_options(MachineClass *m)
546{
547 pc_i440fx_2_12_machine_options(m);
548 compat_props_add(m->compat_props, hw_compat_2_11, hw_compat_2_11_len);
549 compat_props_add(m->compat_props, pc_compat_2_11, pc_compat_2_11_len);
550}
551
552DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
553 pc_i440fx_2_11_machine_options);
554
555static void pc_i440fx_2_10_machine_options(MachineClass *m)
556{
557 pc_i440fx_2_11_machine_options(m);
558 compat_props_add(m->compat_props, hw_compat_2_10, hw_compat_2_10_len);
559 compat_props_add(m->compat_props, pc_compat_2_10, pc_compat_2_10_len);
560 m->auto_enable_numa_with_memhp = false;
561}
562
563DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
564 pc_i440fx_2_10_machine_options);
565
566static void pc_i440fx_2_9_machine_options(MachineClass *m)
567{
568 pc_i440fx_2_10_machine_options(m);
569 compat_props_add(m->compat_props, hw_compat_2_9, hw_compat_2_9_len);
570 compat_props_add(m->compat_props, pc_compat_2_9, pc_compat_2_9_len);
571}
572
573DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
574 pc_i440fx_2_9_machine_options);
575
576static void pc_i440fx_2_8_machine_options(MachineClass *m)
577{
578 pc_i440fx_2_9_machine_options(m);
579 compat_props_add(m->compat_props, hw_compat_2_8, hw_compat_2_8_len);
580 compat_props_add(m->compat_props, pc_compat_2_8, pc_compat_2_8_len);
581}
582
583DEFINE_I440FX_MACHINE(v2_8, "pc-i440fx-2.8", NULL,
584 pc_i440fx_2_8_machine_options);
585
586static void pc_i440fx_2_7_machine_options(MachineClass *m)
587{
588 pc_i440fx_2_8_machine_options(m);
589 compat_props_add(m->compat_props, hw_compat_2_7, hw_compat_2_7_len);
590 compat_props_add(m->compat_props, pc_compat_2_7, pc_compat_2_7_len);
591}
592
593DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
594 pc_i440fx_2_7_machine_options);
595
596static void pc_i440fx_2_6_machine_options(MachineClass *m)
597{
598 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
599
600 pc_i440fx_2_7_machine_options(m);
601 pcmc->legacy_cpu_hotplug = true;
602 pcmc->linuxboot_dma_enabled = false;
603 compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
604 compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
605}
606
607DEFINE_I440FX_MACHINE(v2_6, "pc-i440fx-2.6", NULL,
608 pc_i440fx_2_6_machine_options);
609
610static void pc_i440fx_2_5_machine_options(MachineClass *m)
611{
612 X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
613
614 pc_i440fx_2_6_machine_options(m);
615 x86mc->save_tsc_khz = false;
616 m->legacy_fw_cfg_order = 1;
617 compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len);
618 compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len);
619}
620
621DEFINE_I440FX_MACHINE(v2_5, "pc-i440fx-2.5", NULL,
622 pc_i440fx_2_5_machine_options);
623
624static void pc_i440fx_2_4_machine_options(MachineClass *m)
625{
626 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
627
628 pc_i440fx_2_5_machine_options(m);
629 m->hw_version = "2.4.0";
630 pcmc->broken_reserved_end = true;
631 compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len);
632 compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len);
633}
634
635DEFINE_I440FX_MACHINE(v2_4, "pc-i440fx-2.4", NULL,
636 pc_i440fx_2_4_machine_options)
637
638static void pc_i440fx_2_3_machine_options(MachineClass *m)
639{
640 pc_i440fx_2_4_machine_options(m);
641 m->hw_version = "2.3.0";
642 compat_props_add(m->compat_props, hw_compat_2_3, hw_compat_2_3_len);
643 compat_props_add(m->compat_props, pc_compat_2_3, pc_compat_2_3_len);
644}
645
646DEFINE_I440FX_MACHINE(v2_3, "pc-i440fx-2.3", pc_compat_2_3_fn,
647 pc_i440fx_2_3_machine_options);
648
649static void pc_i440fx_2_2_machine_options(MachineClass *m)
650{
651 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
652
653 pc_i440fx_2_3_machine_options(m);
654 m->hw_version = "2.2.0";
655 m->default_machine_opts = "firmware=bios-256k.bin,suppress-vmdesc=on";
656 compat_props_add(m->compat_props, hw_compat_2_2, hw_compat_2_2_len);
657 compat_props_add(m->compat_props, pc_compat_2_2, pc_compat_2_2_len);
658 pcmc->rsdp_in_ram = false;
659}
660
661DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2_fn,
662 pc_i440fx_2_2_machine_options);
663
664static void pc_i440fx_2_1_machine_options(MachineClass *m)
665{
666 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
667
668 pc_i440fx_2_2_machine_options(m);
669 m->hw_version = "2.1.0";
670 m->default_display = NULL;
671 compat_props_add(m->compat_props, hw_compat_2_1, hw_compat_2_1_len);
672 compat_props_add(m->compat_props, pc_compat_2_1, pc_compat_2_1_len);
673 pcmc->smbios_uuid_encoded = false;
674 pcmc->enforce_aligned_dimm = false;
675}
676
677DEFINE_I440FX_MACHINE(v2_1, "pc-i440fx-2.1", pc_compat_2_1_fn,
678 pc_i440fx_2_1_machine_options);
679
680static void pc_i440fx_2_0_machine_options(MachineClass *m)
681{
682 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
683
684 pc_i440fx_2_1_machine_options(m);
685 m->hw_version = "2.0.0";
686 compat_props_add(m->compat_props, pc_compat_2_0, pc_compat_2_0_len);
687 pcmc->smbios_legacy_mode = true;
688 pcmc->has_reserved_memory = false;
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705 pcmc->legacy_acpi_table_size = 6652;
706 pcmc->acpi_data_size = 0x10000;
707}
708
709DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0_fn,
710 pc_i440fx_2_0_machine_options);
711
712static void pc_i440fx_1_7_machine_options(MachineClass *m)
713{
714 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
715
716 pc_i440fx_2_0_machine_options(m);
717 m->hw_version = "1.7.0";
718 m->default_machine_opts = NULL;
719 m->option_rom_has_mr = true;
720 compat_props_add(m->compat_props, pc_compat_1_7, pc_compat_1_7_len);
721 pcmc->smbios_defaults = false;
722 pcmc->gigabyte_align = false;
723 pcmc->legacy_acpi_table_size = 6414;
724}
725
726DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7_fn,
727 pc_i440fx_1_7_machine_options);
728
729static void pc_i440fx_1_6_machine_options(MachineClass *m)
730{
731 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
732
733 pc_i440fx_1_7_machine_options(m);
734 m->hw_version = "1.6.0";
735 m->rom_file_has_mr = false;
736 compat_props_add(m->compat_props, pc_compat_1_6, pc_compat_1_6_len);
737 pcmc->has_acpi_build = false;
738}
739
740DEFINE_I440FX_MACHINE(v1_6, "pc-i440fx-1.6", pc_compat_1_6_fn,
741 pc_i440fx_1_6_machine_options);
742
743static void pc_i440fx_1_5_machine_options(MachineClass *m)
744{
745 pc_i440fx_1_6_machine_options(m);
746 m->hw_version = "1.5.0";
747 compat_props_add(m->compat_props, pc_compat_1_5, pc_compat_1_5_len);
748}
749
750DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5_fn,
751 pc_i440fx_1_5_machine_options);
752
753static void pc_i440fx_1_4_machine_options(MachineClass *m)
754{
755 pc_i440fx_1_5_machine_options(m);
756 m->hw_version = "1.4.0";
757 compat_props_add(m->compat_props, pc_compat_1_4, pc_compat_1_4_len);
758}
759
760DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4_fn,
761 pc_i440fx_1_4_machine_options);
762
763static void pc_i440fx_1_3_machine_options(MachineClass *m)
764{
765 X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
766 static GlobalProperty compat[] = {
767 PC_CPU_MODEL_IDS("1.3.0")
768 { "usb-tablet", "usb_version", "1" },
769 { "virtio-net-pci", "ctrl_mac_addr", "off" },
770 { "virtio-net-pci", "mq", "off" },
771 { "e1000", "autonegotiation", "off" },
772 };
773
774 pc_i440fx_1_4_machine_options(m);
775 m->hw_version = "1.3.0";
776 m->deprecation_reason = "use a newer machine type instead";
777 x86mc->compat_apic_id_mode = true;
778 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
779}
780
781DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3,
782 pc_i440fx_1_3_machine_options);
783
784
785static void pc_i440fx_1_2_machine_options(MachineClass *m)
786{
787 static GlobalProperty compat[] = {
788 PC_CPU_MODEL_IDS("1.2.0")
789 { "nec-usb-xhci", "msi", "off" },
790 { "nec-usb-xhci", "msix", "off" },
791 { "qxl", "revision", "3" },
792 { "qxl-vga", "revision", "3" },
793 { "VGA", "mmio", "off" },
794 };
795
796 pc_i440fx_1_3_machine_options(m);
797 m->hw_version = "1.2.0";
798 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
799}
800
801DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2,
802 pc_i440fx_1_2_machine_options);
803
804
805static void pc_i440fx_1_1_machine_options(MachineClass *m)
806{
807 static GlobalProperty compat[] = {
808 PC_CPU_MODEL_IDS("1.1.0")
809 { "virtio-scsi-pci", "hotplug", "off" },
810 { "virtio-scsi-pci", "param_change", "off" },
811 { "VGA", "vgamem_mb", "8" },
812 { "vmware-svga", "vgamem_mb", "8" },
813 { "qxl-vga", "vgamem_mb", "8" },
814 { "qxl", "vgamem_mb", "8" },
815 { "virtio-blk-pci", "config-wce", "off" },
816 };
817
818 pc_i440fx_1_2_machine_options(m);
819 m->hw_version = "1.1.0";
820 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
821}
822
823DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2,
824 pc_i440fx_1_1_machine_options);
825
826static void pc_i440fx_1_0_machine_options(MachineClass *m)
827{
828 static GlobalProperty compat[] = {
829 PC_CPU_MODEL_IDS("1.0")
830 { TYPE_ISA_FDC, "check_media_rate", "off" },
831 { "virtio-balloon-pci", "class", stringify(PCI_CLASS_MEMORY_RAM) },
832 { "apic-common", "vapic", "off" },
833 { TYPE_USB_DEVICE, "full-path", "no" },
834 };
835
836 pc_i440fx_1_1_machine_options(m);
837 m->hw_version = "1.0";
838 compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
839}
840
841DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
842 pc_i440fx_1_0_machine_options);
843
844
845typedef struct {
846 uint16_t gpu_device_id;
847 uint16_t pch_device_id;
848 uint8_t pch_revision_id;
849} IGDDeviceIDInfo;
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866static const IGDDeviceIDInfo igd_combo_id_infos[] = {
867
868 {0x0402, 0x8c4e, 0x04},
869 {0x0406, 0x8c4e, 0x04},
870 {0x0412, 0x8c4e, 0x04},
871 {0x0416, 0x8c4e, 0x04},
872 {0x041E, 0x8c4e, 0x04},
873
874 {0x0A06, 0x8c4e, 0x04},
875 {0x0A16, 0x8c4e, 0x04},
876 {0x0A26, 0x8c4e, 0x06},
877 {0x0A2E, 0x8c4e, 0x04},
878 {0x0A1E, 0x8c4e, 0x04},
879 {0x0A0E, 0x8c4e, 0x04},
880
881 {0x0D26, 0x8c4e, 0x04},
882 {0x0D22, 0x8c4e, 0x04},
883
884 {0x041A, 0x8c4e, 0x04},
885
886 {0x040A, 0x8c4e, 0x04},
887
888 {0x1606, 0x9cc3, 0x03},
889 {0x1616, 0x9cc3, 0x03},
890 {0x1626, 0x9cc3, 0x03},
891 {0x160E, 0x9cc3, 0x03},
892 {0x161E, 0x9cc3, 0x03},
893 {0x1602, 0x9cc3, 0x03},
894 {0x1612, 0x9cc3, 0x03},
895 {0x1622, 0x9cc3, 0x03},
896 {0x162B, 0x9cc3, 0x03},
897 {0x162A, 0x9cc3, 0x03},
898 {0x162D, 0x9cc3, 0x03},
899};
900
901static void isa_bridge_class_init(ObjectClass *klass, void *data)
902{
903 DeviceClass *dc = DEVICE_CLASS(klass);
904 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
905
906 dc->desc = "ISA bridge faked to support IGD PT";
907 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
908 k->vendor_id = PCI_VENDOR_ID_INTEL;
909 k->class_id = PCI_CLASS_BRIDGE_ISA;
910};
911
912static TypeInfo isa_bridge_info = {
913 .name = "igd-passthrough-isa-bridge",
914 .parent = TYPE_PCI_DEVICE,
915 .instance_size = sizeof(PCIDevice),
916 .class_init = isa_bridge_class_init,
917 .interfaces = (InterfaceInfo[]) {
918 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
919 { },
920 },
921};
922
923static void pt_graphics_register_types(void)
924{
925 type_register_static(&isa_bridge_info);
926}
927type_init(pt_graphics_register_types)
928
929void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
930{
931 struct PCIDevice *bridge_dev;
932 int i, num;
933 uint16_t pch_dev_id = 0xffff;
934 uint8_t pch_rev_id = 0;
935
936 num = ARRAY_SIZE(igd_combo_id_infos);
937 for (i = 0; i < num; i++) {
938 if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
939 pch_dev_id = igd_combo_id_infos[i].pch_device_id;
940 pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
941 }
942 }
943
944 if (pch_dev_id == 0xffff) {
945 return;
946 }
947
948
949 bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
950 "igd-passthrough-isa-bridge");
951
952
953
954
955 if (!bridge_dev) {
956 fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
957 return;
958 }
959 pci_config_set_device_id(bridge_dev->config, pch_dev_id);
960 pci_config_set_revision(bridge_dev->config, pch_rev_id);
961}
962
963static void isapc_machine_options(MachineClass *m)
964{
965 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
966 m->desc = "ISA-only PC";
967 m->max_cpus = 1;
968 m->option_rom_has_mr = true;
969 m->rom_file_has_mr = false;
970 pcmc->pci_enabled = false;
971 pcmc->has_acpi_build = false;
972 pcmc->smbios_defaults = false;
973 pcmc->gigabyte_align = false;
974 pcmc->smbios_legacy_mode = true;
975 pcmc->has_reserved_memory = false;
976 pcmc->default_nic_model = "ne2k_isa";
977 m->default_cpu_type = X86_CPU_TYPE_NAME("486");
978}
979
980DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
981 isapc_machine_options);
982
983
984#ifdef CONFIG_XEN
985static void xenfv_4_2_machine_options(MachineClass *m)
986{
987 pc_i440fx_4_2_machine_options(m);
988 m->desc = "Xen Fully-virtualized PC";
989 m->max_cpus = HVM_MAX_VCPUS;
990 m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
991}
992
993DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
994 xenfv_4_2_machine_options);
995
996static void xenfv_3_1_machine_options(MachineClass *m)
997{
998 pc_i440fx_3_1_machine_options(m);
999 m->desc = "Xen Fully-virtualized PC";
1000 m->alias = "xenfv";
1001 m->max_cpus = HVM_MAX_VCPUS;
1002 m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
1003}
1004
1005DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
1006 xenfv_3_1_machine_options);
1007#endif
1008