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_init_isa(MachineState *machine)
363{
364 pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
365}
366
367#ifdef CONFIG_XEN
368static void pc_xen_hvm_init_pci(MachineState *machine)
369{
370 const char *pci_type = xen_igd_gfx_pt_enabled() ?
371 TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
372
373 pc_init1(machine,
374 TYPE_I440FX_PCI_HOST_BRIDGE,
375 pci_type);
376}
377
378static void pc_xen_hvm_init(MachineState *machine)
379{
380 PCMachineState *pcms = PC_MACHINE(machine);
381
382 if (!xen_enabled()) {
383 error_report("xenfv machine requires the xen accelerator");
384 exit(1);
385 }
386
387 pc_xen_hvm_init_pci(machine);
388 pci_create_simple(pcms->bus, -1, "xen-platform");
389}
390#endif
391
392#define DEFINE_I440FX_MACHINE(suffix, name, compatfn, optionfn) \
393 static void pc_init_##suffix(MachineState *machine) \
394 { \
395 void (*compat)(MachineState *m) = (compatfn); \
396 if (compat) { \
397 compat(machine); \
398 } \
399 pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
400 TYPE_I440FX_PCI_DEVICE); \
401 } \
402 DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
403
404static void pc_i440fx_machine_options(MachineClass *m)
405{
406 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
407 pcmc->default_nic_model = "e1000";
408 pcmc->pci_root_uid = 0;
409
410 m->family = "pc_piix";
411 m->desc = "Standard PC (i440FX + PIIX, 1996)";
412 m->default_machine_opts = "firmware=bios-256k.bin";
413 m->default_display = "std";
414 machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
415 machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
416}
417
418static void pc_i440fx_6_0_machine_options(MachineClass *m)
419{
420 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
421 pc_i440fx_machine_options(m);
422 m->alias = "pc";
423 m->is_default = true;
424 pcmc->default_cpu_version = 1;
425}
426
427DEFINE_I440FX_MACHINE(v6_0, "pc-i440fx-6.0", NULL,
428 pc_i440fx_6_0_machine_options);
429
430static void pc_i440fx_5_2_machine_options(MachineClass *m)
431{
432 pc_i440fx_6_0_machine_options(m);
433 m->alias = NULL;
434 m->is_default = false;
435 compat_props_add(m->compat_props, hw_compat_5_2, hw_compat_5_2_len);
436 compat_props_add(m->compat_props, pc_compat_5_2, pc_compat_5_2_len);
437}
438
439DEFINE_I440FX_MACHINE(v5_2, "pc-i440fx-5.2", NULL,
440 pc_i440fx_5_2_machine_options);
441
442static void pc_i440fx_5_1_machine_options(MachineClass *m)
443{
444 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
445
446 pc_i440fx_5_2_machine_options(m);
447 m->alias = NULL;
448 m->is_default = false;
449 compat_props_add(m->compat_props, hw_compat_5_1, hw_compat_5_1_len);
450 compat_props_add(m->compat_props, pc_compat_5_1, pc_compat_5_1_len);
451 pcmc->kvmclock_create_always = false;
452 pcmc->pci_root_uid = 1;
453}
454
455DEFINE_I440FX_MACHINE(v5_1, "pc-i440fx-5.1", NULL,
456 pc_i440fx_5_1_machine_options);
457
458static void pc_i440fx_5_0_machine_options(MachineClass *m)
459{
460 pc_i440fx_5_1_machine_options(m);
461 m->alias = NULL;
462 m->is_default = false;
463 m->numa_mem_supported = true;
464 compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
465 compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
466 m->auto_enable_numa_with_memdev = false;
467}
468
469DEFINE_I440FX_MACHINE(v5_0, "pc-i440fx-5.0", NULL,
470 pc_i440fx_5_0_machine_options);
471
472static void pc_i440fx_4_2_machine_options(MachineClass *m)
473{
474 pc_i440fx_5_0_machine_options(m);
475 m->alias = NULL;
476 m->is_default = false;
477 compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
478 compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len);
479}
480
481DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL,
482 pc_i440fx_4_2_machine_options);
483
484static void pc_i440fx_4_1_machine_options(MachineClass *m)
485{
486 pc_i440fx_4_2_machine_options(m);
487 m->alias = NULL;
488 m->is_default = false;
489 compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len);
490 compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len);
491}
492
493DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL,
494 pc_i440fx_4_1_machine_options);
495
496static void pc_i440fx_4_0_machine_options(MachineClass *m)
497{
498 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
499 pc_i440fx_4_1_machine_options(m);
500 m->alias = NULL;
501 m->is_default = false;
502 pcmc->default_cpu_version = CPU_VERSION_LEGACY;
503 compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
504 compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
505}
506
507DEFINE_I440FX_MACHINE(v4_0, "pc-i440fx-4.0", NULL,
508 pc_i440fx_4_0_machine_options);
509
510static void pc_i440fx_3_1_machine_options(MachineClass *m)
511{
512 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
513
514 pc_i440fx_4_0_machine_options(m);
515 m->is_default = false;
516 pcmc->do_not_add_smb_acpi = true;
517 m->smbus_no_migration_support = true;
518 m->alias = NULL;
519 pcmc->pvh_enabled = false;
520 compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
521 compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
522}
523
524DEFINE_I440FX_MACHINE(v3_1, "pc-i440fx-3.1", NULL,
525 pc_i440fx_3_1_machine_options);
526
527static void pc_i440fx_3_0_machine_options(MachineClass *m)
528{
529 pc_i440fx_3_1_machine_options(m);
530 compat_props_add(m->compat_props, hw_compat_3_0, hw_compat_3_0_len);
531 compat_props_add(m->compat_props, pc_compat_3_0, pc_compat_3_0_len);
532}
533
534DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
535 pc_i440fx_3_0_machine_options);
536
537static void pc_i440fx_2_12_machine_options(MachineClass *m)
538{
539 pc_i440fx_3_0_machine_options(m);
540 compat_props_add(m->compat_props, hw_compat_2_12, hw_compat_2_12_len);
541 compat_props_add(m->compat_props, pc_compat_2_12, pc_compat_2_12_len);
542}
543
544DEFINE_I440FX_MACHINE(v2_12, "pc-i440fx-2.12", NULL,
545 pc_i440fx_2_12_machine_options);
546
547static void pc_i440fx_2_11_machine_options(MachineClass *m)
548{
549 pc_i440fx_2_12_machine_options(m);
550 compat_props_add(m->compat_props, hw_compat_2_11, hw_compat_2_11_len);
551 compat_props_add(m->compat_props, pc_compat_2_11, pc_compat_2_11_len);
552}
553
554DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
555 pc_i440fx_2_11_machine_options);
556
557static void pc_i440fx_2_10_machine_options(MachineClass *m)
558{
559 pc_i440fx_2_11_machine_options(m);
560 compat_props_add(m->compat_props, hw_compat_2_10, hw_compat_2_10_len);
561 compat_props_add(m->compat_props, pc_compat_2_10, pc_compat_2_10_len);
562 m->auto_enable_numa_with_memhp = false;
563}
564
565DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
566 pc_i440fx_2_10_machine_options);
567
568static void pc_i440fx_2_9_machine_options(MachineClass *m)
569{
570 pc_i440fx_2_10_machine_options(m);
571 compat_props_add(m->compat_props, hw_compat_2_9, hw_compat_2_9_len);
572 compat_props_add(m->compat_props, pc_compat_2_9, pc_compat_2_9_len);
573}
574
575DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
576 pc_i440fx_2_9_machine_options);
577
578static void pc_i440fx_2_8_machine_options(MachineClass *m)
579{
580 pc_i440fx_2_9_machine_options(m);
581 compat_props_add(m->compat_props, hw_compat_2_8, hw_compat_2_8_len);
582 compat_props_add(m->compat_props, pc_compat_2_8, pc_compat_2_8_len);
583}
584
585DEFINE_I440FX_MACHINE(v2_8, "pc-i440fx-2.8", NULL,
586 pc_i440fx_2_8_machine_options);
587
588static void pc_i440fx_2_7_machine_options(MachineClass *m)
589{
590 pc_i440fx_2_8_machine_options(m);
591 compat_props_add(m->compat_props, hw_compat_2_7, hw_compat_2_7_len);
592 compat_props_add(m->compat_props, pc_compat_2_7, pc_compat_2_7_len);
593}
594
595DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
596 pc_i440fx_2_7_machine_options);
597
598static void pc_i440fx_2_6_machine_options(MachineClass *m)
599{
600 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
601
602 pc_i440fx_2_7_machine_options(m);
603 pcmc->legacy_cpu_hotplug = true;
604 pcmc->linuxboot_dma_enabled = false;
605 compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
606 compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
607}
608
609DEFINE_I440FX_MACHINE(v2_6, "pc-i440fx-2.6", NULL,
610 pc_i440fx_2_6_machine_options);
611
612static void pc_i440fx_2_5_machine_options(MachineClass *m)
613{
614 X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
615
616 pc_i440fx_2_6_machine_options(m);
617 x86mc->save_tsc_khz = false;
618 m->legacy_fw_cfg_order = 1;
619 compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len);
620 compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len);
621}
622
623DEFINE_I440FX_MACHINE(v2_5, "pc-i440fx-2.5", NULL,
624 pc_i440fx_2_5_machine_options);
625
626static void pc_i440fx_2_4_machine_options(MachineClass *m)
627{
628 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
629
630 pc_i440fx_2_5_machine_options(m);
631 m->hw_version = "2.4.0";
632 pcmc->broken_reserved_end = true;
633 compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len);
634 compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len);
635}
636
637DEFINE_I440FX_MACHINE(v2_4, "pc-i440fx-2.4", NULL,
638 pc_i440fx_2_4_machine_options)
639
640static void pc_i440fx_2_3_machine_options(MachineClass *m)
641{
642 pc_i440fx_2_4_machine_options(m);
643 m->hw_version = "2.3.0";
644 compat_props_add(m->compat_props, hw_compat_2_3, hw_compat_2_3_len);
645 compat_props_add(m->compat_props, pc_compat_2_3, pc_compat_2_3_len);
646}
647
648DEFINE_I440FX_MACHINE(v2_3, "pc-i440fx-2.3", pc_compat_2_3_fn,
649 pc_i440fx_2_3_machine_options);
650
651static void pc_i440fx_2_2_machine_options(MachineClass *m)
652{
653 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
654
655 pc_i440fx_2_3_machine_options(m);
656 m->hw_version = "2.2.0";
657 m->default_machine_opts = "firmware=bios-256k.bin,suppress-vmdesc=on";
658 compat_props_add(m->compat_props, hw_compat_2_2, hw_compat_2_2_len);
659 compat_props_add(m->compat_props, pc_compat_2_2, pc_compat_2_2_len);
660 pcmc->rsdp_in_ram = false;
661}
662
663DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2_fn,
664 pc_i440fx_2_2_machine_options);
665
666static void pc_i440fx_2_1_machine_options(MachineClass *m)
667{
668 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
669
670 pc_i440fx_2_2_machine_options(m);
671 m->hw_version = "2.1.0";
672 m->default_display = NULL;
673 compat_props_add(m->compat_props, hw_compat_2_1, hw_compat_2_1_len);
674 compat_props_add(m->compat_props, pc_compat_2_1, pc_compat_2_1_len);
675 pcmc->smbios_uuid_encoded = false;
676 pcmc->enforce_aligned_dimm = false;
677}
678
679DEFINE_I440FX_MACHINE(v2_1, "pc-i440fx-2.1", pc_compat_2_1_fn,
680 pc_i440fx_2_1_machine_options);
681
682static void pc_i440fx_2_0_machine_options(MachineClass *m)
683{
684 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
685
686 pc_i440fx_2_1_machine_options(m);
687 m->hw_version = "2.0.0";
688 compat_props_add(m->compat_props, pc_compat_2_0, pc_compat_2_0_len);
689 pcmc->smbios_legacy_mode = true;
690 pcmc->has_reserved_memory = false;
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707 pcmc->legacy_acpi_table_size = 6652;
708 pcmc->acpi_data_size = 0x10000;
709}
710
711DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0_fn,
712 pc_i440fx_2_0_machine_options);
713
714static void pc_i440fx_1_7_machine_options(MachineClass *m)
715{
716 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
717
718 pc_i440fx_2_0_machine_options(m);
719 m->hw_version = "1.7.0";
720 m->default_machine_opts = NULL;
721 m->option_rom_has_mr = true;
722 compat_props_add(m->compat_props, pc_compat_1_7, pc_compat_1_7_len);
723 pcmc->smbios_defaults = false;
724 pcmc->gigabyte_align = false;
725 pcmc->legacy_acpi_table_size = 6414;
726}
727
728DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7_fn,
729 pc_i440fx_1_7_machine_options);
730
731static void pc_i440fx_1_6_machine_options(MachineClass *m)
732{
733 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
734
735 pc_i440fx_1_7_machine_options(m);
736 m->hw_version = "1.6.0";
737 m->rom_file_has_mr = false;
738 compat_props_add(m->compat_props, pc_compat_1_6, pc_compat_1_6_len);
739 pcmc->has_acpi_build = false;
740}
741
742DEFINE_I440FX_MACHINE(v1_6, "pc-i440fx-1.6", pc_compat_1_6_fn,
743 pc_i440fx_1_6_machine_options);
744
745static void pc_i440fx_1_5_machine_options(MachineClass *m)
746{
747 pc_i440fx_1_6_machine_options(m);
748 m->hw_version = "1.5.0";
749 compat_props_add(m->compat_props, pc_compat_1_5, pc_compat_1_5_len);
750}
751
752DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5_fn,
753 pc_i440fx_1_5_machine_options);
754
755static void pc_i440fx_1_4_machine_options(MachineClass *m)
756{
757 pc_i440fx_1_5_machine_options(m);
758 m->hw_version = "1.4.0";
759 compat_props_add(m->compat_props, pc_compat_1_4, pc_compat_1_4_len);
760}
761
762DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4_fn,
763 pc_i440fx_1_4_machine_options);
764
765typedef struct {
766 uint16_t gpu_device_id;
767 uint16_t pch_device_id;
768 uint8_t pch_revision_id;
769} IGDDeviceIDInfo;
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786static const IGDDeviceIDInfo igd_combo_id_infos[] = {
787
788 {0x0402, 0x8c4e, 0x04},
789 {0x0406, 0x8c4e, 0x04},
790 {0x0412, 0x8c4e, 0x04},
791 {0x0416, 0x8c4e, 0x04},
792 {0x041E, 0x8c4e, 0x04},
793
794 {0x0A06, 0x8c4e, 0x04},
795 {0x0A16, 0x8c4e, 0x04},
796 {0x0A26, 0x8c4e, 0x06},
797 {0x0A2E, 0x8c4e, 0x04},
798 {0x0A1E, 0x8c4e, 0x04},
799 {0x0A0E, 0x8c4e, 0x04},
800
801 {0x0D26, 0x8c4e, 0x04},
802 {0x0D22, 0x8c4e, 0x04},
803
804 {0x041A, 0x8c4e, 0x04},
805
806 {0x040A, 0x8c4e, 0x04},
807
808 {0x1606, 0x9cc3, 0x03},
809 {0x1616, 0x9cc3, 0x03},
810 {0x1626, 0x9cc3, 0x03},
811 {0x160E, 0x9cc3, 0x03},
812 {0x161E, 0x9cc3, 0x03},
813 {0x1602, 0x9cc3, 0x03},
814 {0x1612, 0x9cc3, 0x03},
815 {0x1622, 0x9cc3, 0x03},
816 {0x162B, 0x9cc3, 0x03},
817 {0x162A, 0x9cc3, 0x03},
818 {0x162D, 0x9cc3, 0x03},
819};
820
821static void isa_bridge_class_init(ObjectClass *klass, void *data)
822{
823 DeviceClass *dc = DEVICE_CLASS(klass);
824 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
825
826 dc->desc = "ISA bridge faked to support IGD PT";
827 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
828 k->vendor_id = PCI_VENDOR_ID_INTEL;
829 k->class_id = PCI_CLASS_BRIDGE_ISA;
830};
831
832static TypeInfo isa_bridge_info = {
833 .name = "igd-passthrough-isa-bridge",
834 .parent = TYPE_PCI_DEVICE,
835 .instance_size = sizeof(PCIDevice),
836 .class_init = isa_bridge_class_init,
837 .interfaces = (InterfaceInfo[]) {
838 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
839 { },
840 },
841};
842
843static void pt_graphics_register_types(void)
844{
845 type_register_static(&isa_bridge_info);
846}
847type_init(pt_graphics_register_types)
848
849void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
850{
851 struct PCIDevice *bridge_dev;
852 int i, num;
853 uint16_t pch_dev_id = 0xffff;
854 uint8_t pch_rev_id = 0;
855
856 num = ARRAY_SIZE(igd_combo_id_infos);
857 for (i = 0; i < num; i++) {
858 if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
859 pch_dev_id = igd_combo_id_infos[i].pch_device_id;
860 pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
861 }
862 }
863
864 if (pch_dev_id == 0xffff) {
865 return;
866 }
867
868
869 bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
870 "igd-passthrough-isa-bridge");
871
872
873
874
875 if (!bridge_dev) {
876 fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
877 return;
878 }
879 pci_config_set_device_id(bridge_dev->config, pch_dev_id);
880 pci_config_set_revision(bridge_dev->config, pch_rev_id);
881}
882
883static void isapc_machine_options(MachineClass *m)
884{
885 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
886 m->desc = "ISA-only PC";
887 m->max_cpus = 1;
888 m->option_rom_has_mr = true;
889 m->rom_file_has_mr = false;
890 pcmc->pci_enabled = false;
891 pcmc->has_acpi_build = false;
892 pcmc->smbios_defaults = false;
893 pcmc->gigabyte_align = false;
894 pcmc->smbios_legacy_mode = true;
895 pcmc->has_reserved_memory = false;
896 pcmc->default_nic_model = "ne2k_isa";
897 m->default_cpu_type = X86_CPU_TYPE_NAME("486");
898}
899
900DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
901 isapc_machine_options);
902
903
904#ifdef CONFIG_XEN
905static void xenfv_4_2_machine_options(MachineClass *m)
906{
907 pc_i440fx_4_2_machine_options(m);
908 m->desc = "Xen Fully-virtualized PC";
909 m->max_cpus = HVM_MAX_VCPUS;
910 m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
911}
912
913DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
914 xenfv_4_2_machine_options);
915
916static void xenfv_3_1_machine_options(MachineClass *m)
917{
918 pc_i440fx_3_1_machine_options(m);
919 m->desc = "Xen Fully-virtualized PC";
920 m->alias = "xenfv";
921 m->max_cpus = HVM_MAX_VCPUS;
922 m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
923}
924
925DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
926 xenfv_3_1_machine_options);
927#endif
928