1 /* 2 * QEMU PC System Emulator 3 * 4 * Copyright (c) 2003-2004 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include <glib.h> 26 27 #include "hw/hw.h" 28 #include "hw/loader.h" 29 #include "hw/i386/pc.h" 30 #include "hw/i386/apic.h" 31 #include "hw/i386/smbios.h" 32 #include "hw/pci/pci.h" 33 #include "hw/pci/pci_ids.h" 34 #include "hw/usb.h" 35 #include "net/net.h" 36 #include "hw/boards.h" 37 #include "hw/ide.h" 38 #include "sysemu/kvm.h" 39 #include "hw/kvm/clock.h" 40 #include "sysemu/sysemu.h" 41 #include "hw/sysbus.h" 42 #include "hw/cpu/icc_bus.h" 43 #include "sysemu/arch_init.h" 44 #include "sysemu/blockdev.h" 45 #include "hw/i2c/smbus.h" 46 #include "hw/xen/xen.h" 47 #include "exec/memory.h" 48 #include "exec/address-spaces.h" 49 #include "hw/acpi/acpi.h" 50 #include "cpu.h" 51 #ifdef CONFIG_XEN 52 # include <xen/hvm/hvm_info_table.h> 53 #endif 54 55 #define MAX_IDE_BUS 2 56 57 static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; 58 static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; 59 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; 60 61 static bool has_pci_info; 62 static bool has_acpi_build = true; 63 static bool smbios_defaults = true; 64 static bool smbios_legacy_mode; 65 /* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to 66 * host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte 67 * pages in the host. 68 */ 69 static bool gigabyte_align = true; 70 static bool has_reserved_memory = true; 71 72 /* PC hardware initialisation */ 73 static void pc_init1(MachineState *machine, 74 int pci_enabled, 75 int kvmclock_enabled) 76 { 77 MemoryRegion *system_memory = get_system_memory(); 78 MemoryRegion *system_io = get_system_io(); 79 int i; 80 ram_addr_t below_4g_mem_size, above_4g_mem_size; 81 PCIBus *pci_bus; 82 ISABus *isa_bus; 83 PCII440FXState *i440fx_state; 84 int piix3_devfn = -1; 85 qemu_irq *cpu_irq; 86 qemu_irq *gsi; 87 qemu_irq *i8259; 88 qemu_irq *smi_irq; 89 GSIState *gsi_state; 90 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; 91 BusState *idebus[MAX_IDE_BUS]; 92 ISADevice *rtc_state; 93 ISADevice *floppy; 94 MemoryRegion *ram_memory; 95 MemoryRegion *pci_memory; 96 MemoryRegion *rom_memory; 97 DeviceState *icc_bridge; 98 FWCfgState *fw_cfg = NULL; 99 PcGuestInfo *guest_info; 100 101 if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) { 102 fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); 103 exit(1); 104 } 105 106 icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); 107 object_property_add_child(qdev_get_machine(), "icc-bridge", 108 OBJECT(icc_bridge), NULL); 109 110 pc_cpus_init(machine->cpu_model, icc_bridge); 111 112 if (kvm_enabled() && kvmclock_enabled) { 113 kvmclock_create(); 114 } 115 116 /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). 117 * If it doesn't, we need to split it in chunks below and above 4G. 118 * In any case, try to make sure that guest addresses aligned at 119 * 1G boundaries get mapped to host addresses aligned at 1G boundaries. 120 * For old machine types, use whatever split we used historically to avoid 121 * breaking migration. 122 */ 123 if (machine->ram_size >= 0xe0000000) { 124 ram_addr_t lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000; 125 above_4g_mem_size = machine->ram_size - lowmem; 126 below_4g_mem_size = lowmem; 127 } else { 128 above_4g_mem_size = 0; 129 below_4g_mem_size = machine->ram_size; 130 } 131 132 if (pci_enabled) { 133 pci_memory = g_new(MemoryRegion, 1); 134 memory_region_init(pci_memory, NULL, "pci", UINT64_MAX); 135 rom_memory = pci_memory; 136 } else { 137 pci_memory = NULL; 138 rom_memory = system_memory; 139 } 140 141 guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size); 142 143 guest_info->has_acpi_build = has_acpi_build; 144 145 guest_info->has_pci_info = has_pci_info; 146 guest_info->isapc_ram_fw = !pci_enabled; 147 guest_info->has_reserved_memory = has_reserved_memory; 148 149 if (smbios_defaults) { 150 MachineClass *mc = MACHINE_GET_CLASS(machine); 151 /* These values are guest ABI, do not change */ 152 smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)", 153 mc->name, smbios_legacy_mode); 154 } 155 156 /* allocate ram and load rom/bios */ 157 if (!xen_enabled()) { 158 fw_cfg = pc_memory_init(system_memory, 159 machine->kernel_filename, machine->kernel_cmdline, 160 machine->initrd_filename, 161 below_4g_mem_size, above_4g_mem_size, 162 rom_memory, &ram_memory, guest_info); 163 } 164 165 gsi_state = g_malloc0(sizeof(*gsi_state)); 166 if (kvm_irqchip_in_kernel()) { 167 kvm_pc_setup_irq_routing(pci_enabled); 168 gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state, 169 GSI_NUM_PINS); 170 } else { 171 gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS); 172 } 173 174 if (pci_enabled) { 175 pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi, 176 system_memory, system_io, machine->ram_size, 177 below_4g_mem_size, 178 above_4g_mem_size, 179 pci_memory, ram_memory); 180 } else { 181 pci_bus = NULL; 182 i440fx_state = NULL; 183 isa_bus = isa_bus_new(NULL, system_io); 184 no_hpet = 1; 185 } 186 isa_bus_irqs(isa_bus, gsi); 187 188 if (kvm_irqchip_in_kernel()) { 189 i8259 = kvm_i8259_init(isa_bus); 190 } else if (xen_enabled()) { 191 i8259 = xen_interrupt_controller_init(); 192 } else { 193 cpu_irq = pc_allocate_cpu_irq(); 194 i8259 = i8259_init(isa_bus, cpu_irq[0]); 195 } 196 197 for (i = 0; i < ISA_NUM_IRQS; i++) { 198 gsi_state->i8259_irq[i] = i8259[i]; 199 } 200 if (pci_enabled) { 201 ioapic_init_gsi(gsi_state, "i440fx"); 202 } 203 qdev_init_nofail(icc_bridge); 204 205 pc_register_ferr_irq(gsi[13]); 206 207 pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); 208 209 /* init basic PC hardware */ 210 pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled(), 211 0x4); 212 213 pc_nic_init(isa_bus, pci_bus); 214 215 ide_drive_get(hd, MAX_IDE_BUS); 216 if (pci_enabled) { 217 PCIDevice *dev; 218 if (xen_enabled()) { 219 dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); 220 } else { 221 dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); 222 } 223 idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); 224 idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); 225 } else { 226 for(i = 0; i < MAX_IDE_BUS; i++) { 227 ISADevice *dev; 228 char busname[] = "ide.0"; 229 dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], 230 ide_irq[i], 231 hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); 232 /* 233 * The ide bus name is ide.0 for the first bus and ide.1 for the 234 * second one. 235 */ 236 busname[4] = '0' + i; 237 idebus[i] = qdev_get_child_bus(DEVICE(dev), busname); 238 } 239 } 240 241 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order, 242 floppy, idebus[0], idebus[1], rtc_state); 243 244 if (pci_enabled && usb_enabled(false)) { 245 pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci"); 246 } 247 248 if (pci_enabled && acpi_enabled) { 249 I2CBus *smbus; 250 251 smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); 252 /* TODO: Populate SPD eeprom data. */ 253 smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, 254 gsi[9], *smi_irq, 255 kvm_enabled(), fw_cfg); 256 smbus_eeprom_init(smbus, 8, NULL, 0); 257 } 258 259 if (pci_enabled) { 260 pc_pci_device_init(pci_bus); 261 } 262 } 263 264 static void pc_init_pci(MachineState *machine) 265 { 266 pc_init1(machine, 1, 1); 267 } 268 269 static void pc_compat_2_0(MachineState *machine) 270 { 271 smbios_legacy_mode = true; 272 has_reserved_memory = false; 273 } 274 275 static void pc_compat_1_7(MachineState *machine) 276 { 277 pc_compat_2_0(machine); 278 smbios_defaults = false; 279 gigabyte_align = false; 280 option_rom_has_mr = true; 281 x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC); 282 } 283 284 static void pc_compat_1_6(MachineState *machine) 285 { 286 pc_compat_1_7(machine); 287 has_pci_info = false; 288 rom_file_has_mr = false; 289 has_acpi_build = false; 290 } 291 292 static void pc_compat_1_5(MachineState *machine) 293 { 294 pc_compat_1_6(machine); 295 } 296 297 static void pc_compat_1_4(MachineState *machine) 298 { 299 pc_compat_1_5(machine); 300 x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE); 301 x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ); 302 } 303 304 static void pc_compat_1_3(MachineState *machine) 305 { 306 pc_compat_1_4(machine); 307 enable_compat_apic_id_mode(); 308 } 309 310 /* PC compat function for pc-0.14 to pc-1.2 */ 311 static void pc_compat_1_2(MachineState *machine) 312 { 313 pc_compat_1_3(machine); 314 x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI); 315 } 316 317 static void pc_init_pci_2_0(MachineState *machine) 318 { 319 pc_compat_2_0(machine); 320 pc_init_pci(machine); 321 } 322 323 static void pc_init_pci_1_7(MachineState *machine) 324 { 325 pc_compat_1_7(machine); 326 pc_init_pci(machine); 327 } 328 329 static void pc_init_pci_1_6(MachineState *machine) 330 { 331 pc_compat_1_6(machine); 332 pc_init_pci(machine); 333 } 334 335 static void pc_init_pci_1_5(MachineState *machine) 336 { 337 pc_compat_1_5(machine); 338 pc_init_pci(machine); 339 } 340 341 static void pc_init_pci_1_4(MachineState *machine) 342 { 343 pc_compat_1_4(machine); 344 pc_init_pci(machine); 345 } 346 347 static void pc_init_pci_1_3(MachineState *machine) 348 { 349 pc_compat_1_3(machine); 350 pc_init_pci(machine); 351 } 352 353 /* PC machine init function for pc-0.14 to pc-1.2 */ 354 static void pc_init_pci_1_2(MachineState *machine) 355 { 356 pc_compat_1_2(machine); 357 pc_init_pci(machine); 358 } 359 360 /* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */ 361 static void pc_init_pci_no_kvmclock(MachineState *machine) 362 { 363 has_pci_info = false; 364 has_acpi_build = false; 365 smbios_defaults = false; 366 x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI); 367 enable_compat_apic_id_mode(); 368 pc_init1(machine, 1, 0); 369 } 370 371 static void pc_init_isa(MachineState *machine) 372 { 373 has_pci_info = false; 374 has_acpi_build = false; 375 smbios_defaults = false; 376 if (!machine->cpu_model) { 377 machine->cpu_model = "486"; 378 } 379 x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI); 380 enable_compat_apic_id_mode(); 381 pc_init1(machine, 0, 1); 382 } 383 384 #ifdef CONFIG_XEN 385 static void pc_xen_hvm_init(MachineState *machine) 386 { 387 PCIBus *bus; 388 389 pc_init_pci(machine); 390 391 bus = pci_find_primary_bus(); 392 if (bus != NULL) { 393 pci_create_simple(bus, -1, "xen-platform"); 394 } 395 } 396 #endif 397 398 #define PC_I440FX_MACHINE_OPTIONS \ 399 PC_DEFAULT_MACHINE_OPTIONS, \ 400 .desc = "Standard PC (i440FX + PIIX, 1996)", \ 401 .hot_add_cpu = pc_hot_add_cpu 402 403 #define PC_I440FX_2_1_MACHINE_OPTIONS \ 404 PC_I440FX_MACHINE_OPTIONS, \ 405 .default_machine_opts = "firmware=bios-256k.bin" 406 407 static QEMUMachine pc_i440fx_machine_v2_1 = { 408 PC_I440FX_2_1_MACHINE_OPTIONS, 409 .name = "pc-i440fx-2.1", 410 .alias = "pc", 411 .init = pc_init_pci, 412 .is_default = 1, 413 }; 414 415 #define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS 416 417 static QEMUMachine pc_i440fx_machine_v2_0 = { 418 PC_I440FX_2_0_MACHINE_OPTIONS, 419 .name = "pc-i440fx-2.0", 420 .init = pc_init_pci_2_0, 421 .compat_props = (GlobalProperty[]) { 422 PC_COMPAT_2_0, 423 { /* end of list */ } 424 }, 425 }; 426 427 #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS 428 429 static QEMUMachine pc_i440fx_machine_v1_7 = { 430 PC_I440FX_1_7_MACHINE_OPTIONS, 431 .name = "pc-i440fx-1.7", 432 .init = pc_init_pci_1_7, 433 .compat_props = (GlobalProperty[]) { 434 PC_COMPAT_1_7, 435 { /* end of list */ } 436 }, 437 }; 438 439 #define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS 440 441 static QEMUMachine pc_i440fx_machine_v1_6 = { 442 PC_I440FX_1_6_MACHINE_OPTIONS, 443 .name = "pc-i440fx-1.6", 444 .init = pc_init_pci_1_6, 445 .compat_props = (GlobalProperty[]) { 446 PC_COMPAT_1_6, 447 { /* end of list */ } 448 }, 449 }; 450 451 static QEMUMachine pc_i440fx_machine_v1_5 = { 452 PC_I440FX_1_6_MACHINE_OPTIONS, 453 .name = "pc-i440fx-1.5", 454 .init = pc_init_pci_1_5, 455 .compat_props = (GlobalProperty[]) { 456 PC_COMPAT_1_5, 457 { /* end of list */ } 458 }, 459 }; 460 461 #define PC_I440FX_1_4_MACHINE_OPTIONS \ 462 PC_I440FX_1_6_MACHINE_OPTIONS, \ 463 .hot_add_cpu = NULL 464 465 static QEMUMachine pc_i440fx_machine_v1_4 = { 466 PC_I440FX_1_4_MACHINE_OPTIONS, 467 .name = "pc-i440fx-1.4", 468 .init = pc_init_pci_1_4, 469 .compat_props = (GlobalProperty[]) { 470 PC_COMPAT_1_4, 471 { /* end of list */ } 472 }, 473 }; 474 475 #define PC_COMPAT_1_3 \ 476 PC_COMPAT_1_4, \ 477 {\ 478 .driver = "usb-tablet",\ 479 .property = "usb_version",\ 480 .value = stringify(1),\ 481 },{\ 482 .driver = "virtio-net-pci",\ 483 .property = "ctrl_mac_addr",\ 484 .value = "off", \ 485 },{ \ 486 .driver = "virtio-net-pci", \ 487 .property = "mq", \ 488 .value = "off", \ 489 }, {\ 490 .driver = "e1000",\ 491 .property = "autonegotiation",\ 492 .value = "off",\ 493 } 494 495 static QEMUMachine pc_machine_v1_3 = { 496 PC_I440FX_1_4_MACHINE_OPTIONS, 497 .name = "pc-1.3", 498 .init = pc_init_pci_1_3, 499 .compat_props = (GlobalProperty[]) { 500 PC_COMPAT_1_3, 501 { /* end of list */ } 502 }, 503 }; 504 505 #define PC_COMPAT_1_2 \ 506 PC_COMPAT_1_3,\ 507 {\ 508 .driver = "nec-usb-xhci",\ 509 .property = "msi",\ 510 .value = "off",\ 511 },{\ 512 .driver = "nec-usb-xhci",\ 513 .property = "msix",\ 514 .value = "off",\ 515 },{\ 516 .driver = "ivshmem",\ 517 .property = "use64",\ 518 .value = "0",\ 519 },{\ 520 .driver = "qxl",\ 521 .property = "revision",\ 522 .value = stringify(3),\ 523 },{\ 524 .driver = "qxl-vga",\ 525 .property = "revision",\ 526 .value = stringify(3),\ 527 },{\ 528 .driver = "VGA",\ 529 .property = "mmio",\ 530 .value = "off",\ 531 } 532 533 #define PC_I440FX_1_2_MACHINE_OPTIONS \ 534 PC_I440FX_1_4_MACHINE_OPTIONS, \ 535 .init = pc_init_pci_1_2 536 537 static QEMUMachine pc_machine_v1_2 = { 538 PC_I440FX_1_2_MACHINE_OPTIONS, 539 .name = "pc-1.2", 540 .compat_props = (GlobalProperty[]) { 541 PC_COMPAT_1_2, 542 { /* end of list */ } 543 }, 544 }; 545 546 #define PC_COMPAT_1_1 \ 547 PC_COMPAT_1_2,\ 548 {\ 549 .driver = "virtio-scsi-pci",\ 550 .property = "hotplug",\ 551 .value = "off",\ 552 },{\ 553 .driver = "virtio-scsi-pci",\ 554 .property = "param_change",\ 555 .value = "off",\ 556 },{\ 557 .driver = "VGA",\ 558 .property = "vgamem_mb",\ 559 .value = stringify(8),\ 560 },{\ 561 .driver = "vmware-svga",\ 562 .property = "vgamem_mb",\ 563 .value = stringify(8),\ 564 },{\ 565 .driver = "qxl-vga",\ 566 .property = "vgamem_mb",\ 567 .value = stringify(8),\ 568 },{\ 569 .driver = "qxl",\ 570 .property = "vgamem_mb",\ 571 .value = stringify(8),\ 572 },{\ 573 .driver = "virtio-blk-pci",\ 574 .property = "config-wce",\ 575 .value = "off",\ 576 } 577 578 static QEMUMachine pc_machine_v1_1 = { 579 PC_I440FX_1_2_MACHINE_OPTIONS, 580 .name = "pc-1.1", 581 .compat_props = (GlobalProperty[]) { 582 PC_COMPAT_1_1, 583 { /* end of list */ } 584 }, 585 }; 586 587 #define PC_COMPAT_1_0 \ 588 PC_COMPAT_1_1,\ 589 {\ 590 .driver = TYPE_ISA_FDC,\ 591 .property = "check_media_rate",\ 592 .value = "off",\ 593 }, {\ 594 .driver = "virtio-balloon-pci",\ 595 .property = "class",\ 596 .value = stringify(PCI_CLASS_MEMORY_RAM),\ 597 },{\ 598 .driver = "apic",\ 599 .property = "vapic",\ 600 .value = "off",\ 601 },{\ 602 .driver = TYPE_USB_DEVICE,\ 603 .property = "full-path",\ 604 .value = "no",\ 605 } 606 607 static QEMUMachine pc_machine_v1_0 = { 608 PC_I440FX_1_2_MACHINE_OPTIONS, 609 .name = "pc-1.0", 610 .compat_props = (GlobalProperty[]) { 611 PC_COMPAT_1_0, 612 { /* end of list */ } 613 }, 614 .hw_version = "1.0", 615 }; 616 617 #define PC_COMPAT_0_15 \ 618 PC_COMPAT_1_0 619 620 static QEMUMachine pc_machine_v0_15 = { 621 PC_I440FX_1_2_MACHINE_OPTIONS, 622 .name = "pc-0.15", 623 .compat_props = (GlobalProperty[]) { 624 PC_COMPAT_0_15, 625 { /* end of list */ } 626 }, 627 .hw_version = "0.15", 628 }; 629 630 #define PC_COMPAT_0_14 \ 631 PC_COMPAT_0_15,\ 632 {\ 633 .driver = "virtio-blk-pci",\ 634 .property = "event_idx",\ 635 .value = "off",\ 636 },{\ 637 .driver = "virtio-serial-pci",\ 638 .property = "event_idx",\ 639 .value = "off",\ 640 },{\ 641 .driver = "virtio-net-pci",\ 642 .property = "event_idx",\ 643 .value = "off",\ 644 },{\ 645 .driver = "virtio-balloon-pci",\ 646 .property = "event_idx",\ 647 .value = "off",\ 648 } 649 650 static QEMUMachine pc_machine_v0_14 = { 651 PC_I440FX_1_2_MACHINE_OPTIONS, 652 .name = "pc-0.14", 653 .compat_props = (GlobalProperty[]) { 654 PC_COMPAT_0_14, 655 { 656 .driver = "qxl", 657 .property = "revision", 658 .value = stringify(2), 659 },{ 660 .driver = "qxl-vga", 661 .property = "revision", 662 .value = stringify(2), 663 }, 664 { /* end of list */ } 665 }, 666 .hw_version = "0.14", 667 }; 668 669 #define PC_COMPAT_0_13 \ 670 PC_COMPAT_0_14,\ 671 {\ 672 .driver = TYPE_PCI_DEVICE,\ 673 .property = "command_serr_enable",\ 674 .value = "off",\ 675 },{\ 676 .driver = "AC97",\ 677 .property = "use_broken_id",\ 678 .value = stringify(1),\ 679 } 680 681 #define PC_I440FX_0_13_MACHINE_OPTIONS \ 682 PC_I440FX_1_2_MACHINE_OPTIONS, \ 683 .init = pc_init_pci_no_kvmclock 684 685 static QEMUMachine pc_machine_v0_13 = { 686 PC_I440FX_0_13_MACHINE_OPTIONS, 687 .name = "pc-0.13", 688 .compat_props = (GlobalProperty[]) { 689 PC_COMPAT_0_13, 690 { 691 .driver = "virtio-9p-pci", 692 .property = "vectors", 693 .value = stringify(0), 694 },{ 695 .driver = "VGA", 696 .property = "rombar", 697 .value = stringify(0), 698 },{ 699 .driver = "vmware-svga", 700 .property = "rombar", 701 .value = stringify(0), 702 }, 703 { /* end of list */ } 704 }, 705 .hw_version = "0.13", 706 }; 707 708 #define PC_COMPAT_0_12 \ 709 PC_COMPAT_0_13,\ 710 {\ 711 .driver = "virtio-serial-pci",\ 712 .property = "max_ports",\ 713 .value = stringify(1),\ 714 },{\ 715 .driver = "virtio-serial-pci",\ 716 .property = "vectors",\ 717 .value = stringify(0),\ 718 },{\ 719 .driver = "usb-mouse",\ 720 .property = "serial",\ 721 .value = "1",\ 722 },{\ 723 .driver = "usb-tablet",\ 724 .property = "serial",\ 725 .value = "1",\ 726 },{\ 727 .driver = "usb-kbd",\ 728 .property = "serial",\ 729 .value = "1",\ 730 } 731 732 static QEMUMachine pc_machine_v0_12 = { 733 PC_I440FX_0_13_MACHINE_OPTIONS, 734 .name = "pc-0.12", 735 .compat_props = (GlobalProperty[]) { 736 PC_COMPAT_0_12, 737 { 738 .driver = "VGA", 739 .property = "rombar", 740 .value = stringify(0), 741 },{ 742 .driver = "vmware-svga", 743 .property = "rombar", 744 .value = stringify(0), 745 }, 746 { /* end of list */ } 747 }, 748 .hw_version = "0.12", 749 }; 750 751 #define PC_COMPAT_0_11 \ 752 PC_COMPAT_0_12,\ 753 {\ 754 .driver = "virtio-blk-pci",\ 755 .property = "vectors",\ 756 .value = stringify(0),\ 757 },{\ 758 .driver = TYPE_PCI_DEVICE,\ 759 .property = "rombar",\ 760 .value = stringify(0),\ 761 } 762 763 static QEMUMachine pc_machine_v0_11 = { 764 PC_I440FX_0_13_MACHINE_OPTIONS, 765 .name = "pc-0.11", 766 .compat_props = (GlobalProperty[]) { 767 PC_COMPAT_0_11, 768 { 769 .driver = "ide-drive", 770 .property = "ver", 771 .value = "0.11", 772 },{ 773 .driver = "scsi-disk", 774 .property = "ver", 775 .value = "0.11", 776 }, 777 { /* end of list */ } 778 }, 779 .hw_version = "0.11", 780 }; 781 782 static QEMUMachine pc_machine_v0_10 = { 783 PC_I440FX_0_13_MACHINE_OPTIONS, 784 .name = "pc-0.10", 785 .compat_props = (GlobalProperty[]) { 786 PC_COMPAT_0_11, 787 { 788 .driver = "virtio-blk-pci", 789 .property = "class", 790 .value = stringify(PCI_CLASS_STORAGE_OTHER), 791 },{ 792 .driver = "virtio-serial-pci", 793 .property = "class", 794 .value = stringify(PCI_CLASS_DISPLAY_OTHER), 795 },{ 796 .driver = "virtio-net-pci", 797 .property = "vectors", 798 .value = stringify(0), 799 },{ 800 .driver = "ide-drive", 801 .property = "ver", 802 .value = "0.10", 803 },{ 804 .driver = "scsi-disk", 805 .property = "ver", 806 .value = "0.10", 807 }, 808 { /* end of list */ } 809 }, 810 .hw_version = "0.10", 811 }; 812 813 static QEMUMachine isapc_machine = { 814 PC_COMMON_MACHINE_OPTIONS, 815 .name = "isapc", 816 .desc = "ISA-only PC", 817 .init = pc_init_isa, 818 .max_cpus = 1, 819 .compat_props = (GlobalProperty[]) { 820 { /* end of list */ } 821 }, 822 }; 823 824 #ifdef CONFIG_XEN 825 static QEMUMachine xenfv_machine = { 826 PC_COMMON_MACHINE_OPTIONS, 827 .name = "xenfv", 828 .desc = "Xen Fully-virtualized PC", 829 .init = pc_xen_hvm_init, 830 .max_cpus = HVM_MAX_VCPUS, 831 .default_machine_opts = "accel=xen", 832 .hot_add_cpu = pc_hot_add_cpu, 833 .compat_props = (GlobalProperty[]) { 834 /* xenfv has no fwcfg and so does not load acpi from QEMU. 835 * as such new acpi features don't work. 836 */ 837 { 838 .driver = "PIIX4_PM", 839 .property = "acpi-pci-hotplug-with-bridge-support", 840 .value = "off", 841 }, 842 { /* end of list */ } 843 }, 844 }; 845 #endif 846 847 static void pc_machine_init(void) 848 { 849 qemu_register_pc_machine(&pc_i440fx_machine_v2_1); 850 qemu_register_pc_machine(&pc_i440fx_machine_v2_0); 851 qemu_register_pc_machine(&pc_i440fx_machine_v1_7); 852 qemu_register_pc_machine(&pc_i440fx_machine_v1_6); 853 qemu_register_pc_machine(&pc_i440fx_machine_v1_5); 854 qemu_register_pc_machine(&pc_i440fx_machine_v1_4); 855 qemu_register_pc_machine(&pc_machine_v1_3); 856 qemu_register_pc_machine(&pc_machine_v1_2); 857 qemu_register_pc_machine(&pc_machine_v1_1); 858 qemu_register_pc_machine(&pc_machine_v1_0); 859 qemu_register_pc_machine(&pc_machine_v0_15); 860 qemu_register_pc_machine(&pc_machine_v0_14); 861 qemu_register_pc_machine(&pc_machine_v0_13); 862 qemu_register_pc_machine(&pc_machine_v0_12); 863 qemu_register_pc_machine(&pc_machine_v0_11); 864 qemu_register_pc_machine(&pc_machine_v0_10); 865 qemu_register_pc_machine(&isapc_machine); 866 #ifdef CONFIG_XEN 867 qemu_register_pc_machine(&xenfv_machine); 868 #endif 869 } 870 871 machine_init(pc_machine_init); 872