1 #ifndef HW_PC_H 2 #define HW_PC_H 3 4 #include "qemu-common.h" 5 #include "exec/memory.h" 6 #include "hw/isa/isa.h" 7 #include "hw/block/fdc.h" 8 #include "net/net.h" 9 #include "hw/i386/ioapic.h" 10 11 #include "qemu/range.h" 12 #include "qemu/bitmap.h" 13 #include "sysemu/sysemu.h" 14 #include "hw/pci/pci.h" 15 #include "hw/boards.h" 16 17 #define HPET_INTCAP "hpet-intcap" 18 19 /** 20 * PCMachineState: 21 * @hotplug_memory_base: address in guest RAM address space where hotplug memory 22 * address space begins. 23 * @hotplug_memory: hotplug memory addess space container 24 */ 25 struct PCMachineState { 26 /*< private >*/ 27 MachineState parent_obj; 28 29 /* <public> */ 30 ram_addr_t hotplug_memory_base; 31 MemoryRegion hotplug_memory; 32 }; 33 34 /** 35 * PCMachineClass: 36 * @get_hotplug_handler: pointer to parent class callback @get_hotplug_handler 37 */ 38 struct PCMachineClass { 39 /*< private >*/ 40 MachineClass parent_class; 41 42 /*< public >*/ 43 HotplugHandler *(*get_hotplug_handler)(MachineState *machine, 44 DeviceState *dev); 45 }; 46 47 typedef struct PCMachineState PCMachineState; 48 typedef struct PCMachineClass PCMachineClass; 49 50 #define TYPE_PC_MACHINE "generic-pc-machine" 51 #define PC_MACHINE(obj) \ 52 OBJECT_CHECK(PCMachineState, (obj), TYPE_PC_MACHINE) 53 #define PC_MACHINE_GET_CLASS(obj) \ 54 OBJECT_GET_CLASS(PCMachineClass, (obj), TYPE_PC_MACHINE) 55 #define PC_MACHINE_CLASS(klass) \ 56 OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE) 57 58 void qemu_register_pc_machine(QEMUMachine *m); 59 60 /* PC-style peripherals (also used by other machines). */ 61 62 typedef struct PcPciInfo { 63 Range w32; 64 Range w64; 65 } PcPciInfo; 66 67 #define ACPI_PM_PROP_S3_DISABLED "disable_s3" 68 #define ACPI_PM_PROP_S4_DISABLED "disable_s4" 69 #define ACPI_PM_PROP_S4_VAL "s4_val" 70 #define ACPI_PM_PROP_SCI_INT "sci_int" 71 #define ACPI_PM_PROP_ACPI_ENABLE_CMD "acpi_enable_cmd" 72 #define ACPI_PM_PROP_ACPI_DISABLE_CMD "acpi_disable_cmd" 73 #define ACPI_PM_PROP_PM_IO_BASE "pm_io_base" 74 #define ACPI_PM_PROP_GPE0_BLK "gpe0_blk" 75 #define ACPI_PM_PROP_GPE0_BLK_LEN "gpe0_blk_len" 76 77 struct PcGuestInfo { 78 bool has_pci_info; 79 bool isapc_ram_fw; 80 hwaddr ram_size, ram_size_below_4g; 81 unsigned apic_id_limit; 82 bool apic_xrupt_override; 83 uint64_t numa_nodes; 84 uint64_t *node_mem; 85 uint64_t *node_cpu; 86 FWCfgState *fw_cfg; 87 bool has_acpi_build; 88 bool has_reserved_memory; 89 }; 90 91 /* parallel.c */ 92 static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr) 93 { 94 DeviceState *dev; 95 ISADevice *isadev; 96 97 isadev = isa_try_create(bus, "isa-parallel"); 98 if (!isadev) { 99 return false; 100 } 101 dev = DEVICE(isadev); 102 qdev_prop_set_uint32(dev, "index", index); 103 qdev_prop_set_chr(dev, "chardev", chr); 104 if (qdev_init(dev) < 0) { 105 return false; 106 } 107 return true; 108 } 109 110 bool parallel_mm_init(MemoryRegion *address_space, 111 hwaddr base, int it_shift, qemu_irq irq, 112 CharDriverState *chr); 113 114 /* i8259.c */ 115 116 extern DeviceState *isa_pic; 117 qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq); 118 qemu_irq *kvm_i8259_init(ISABus *bus); 119 int pic_read_irq(DeviceState *d); 120 int pic_get_output(DeviceState *d); 121 void pic_info(Monitor *mon, const QDict *qdict); 122 void irq_info(Monitor *mon, const QDict *qdict); 123 124 /* Global System Interrupts */ 125 126 #define GSI_NUM_PINS IOAPIC_NUM_PINS 127 128 typedef struct GSIState { 129 qemu_irq i8259_irq[ISA_NUM_IRQS]; 130 qemu_irq ioapic_irq[IOAPIC_NUM_PINS]; 131 } GSIState; 132 133 void gsi_handler(void *opaque, int n, int level); 134 135 /* vmport.c */ 136 typedef uint32_t (VMPortReadFunc)(void *opaque, uint32_t address); 137 138 static inline void vmport_init(ISABus *bus) 139 { 140 isa_create_simple(bus, "vmport"); 141 } 142 143 void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque); 144 void vmmouse_get_data(uint32_t *data); 145 void vmmouse_set_data(const uint32_t *data); 146 147 /* pckbd.c */ 148 149 void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base); 150 void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, 151 MemoryRegion *region, ram_addr_t size, 152 hwaddr mask); 153 void i8042_isa_mouse_fake_event(void *opaque); 154 void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out); 155 156 /* pc.c */ 157 extern int fd_bootchk; 158 159 void pc_register_ferr_irq(qemu_irq irq); 160 void pc_acpi_smi_interrupt(void *opaque, int irq, int level); 161 162 void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); 163 void pc_hot_add_cpu(const int64_t id, Error **errp); 164 void pc_acpi_init(const char *default_dsdt); 165 166 PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, 167 ram_addr_t above_4g_mem_size); 168 169 #define PCI_HOST_PROP_PCI_HOLE_START "pci-hole-start" 170 #define PCI_HOST_PROP_PCI_HOLE_END "pci-hole-end" 171 #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start" 172 #define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end" 173 #define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size" 174 #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL) 175 176 177 void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory, 178 MemoryRegion *pci_address_space); 179 180 FWCfgState *pc_memory_init(MemoryRegion *system_memory, 181 const char *kernel_filename, 182 const char *kernel_cmdline, 183 const char *initrd_filename, 184 ram_addr_t below_4g_mem_size, 185 ram_addr_t above_4g_mem_size, 186 MemoryRegion *rom_memory, 187 MemoryRegion **ram_memory, 188 PcGuestInfo *guest_info); 189 qemu_irq *pc_allocate_cpu_irq(void); 190 DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); 191 void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, 192 ISADevice **rtc_state, 193 ISADevice **floppy, 194 bool no_vmport, 195 uint32 hpet_irqs); 196 void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd); 197 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, 198 const char *boot_device, 199 ISADevice *floppy, BusState *ide0, BusState *ide1, 200 ISADevice *s); 201 void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus); 202 void pc_pci_device_init(PCIBus *pci_bus); 203 204 typedef void (*cpu_set_smm_t)(int smm, void *arg); 205 void cpu_smm_register(cpu_set_smm_t callback, void *arg); 206 207 void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); 208 209 /* acpi_piix.c */ 210 211 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, 212 qemu_irq sci_irq, qemu_irq smi_irq, 213 int kvm_enabled, FWCfgState *fw_cfg); 214 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); 215 216 /* hpet.c */ 217 extern int no_hpet; 218 219 /* piix_pci.c */ 220 struct PCII440FXState; 221 typedef struct PCII440FXState PCII440FXState; 222 223 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, 224 ISABus **isa_bus, qemu_irq *pic, 225 MemoryRegion *address_space_mem, 226 MemoryRegion *address_space_io, 227 ram_addr_t ram_size, 228 ram_addr_t below_4g_mem_size, 229 ram_addr_t above_4g_mem_size, 230 MemoryRegion *pci_memory, 231 MemoryRegion *ram_memory); 232 233 PCIBus *find_i440fx(void); 234 /* piix4.c */ 235 extern PCIDevice *piix4_dev; 236 int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn); 237 238 /* vga.c */ 239 enum vga_retrace_method { 240 VGA_RETRACE_DUMB, 241 VGA_RETRACE_PRECISE 242 }; 243 244 extern enum vga_retrace_method vga_retrace_method; 245 246 int isa_vga_mm_init(hwaddr vram_base, 247 hwaddr ctrl_base, int it_shift, 248 MemoryRegion *address_space); 249 250 /* ne2000.c */ 251 static inline bool isa_ne2000_init(ISABus *bus, int base, int irq, NICInfo *nd) 252 { 253 DeviceState *dev; 254 ISADevice *isadev; 255 256 qemu_check_nic_model(nd, "ne2k_isa"); 257 258 isadev = isa_try_create(bus, "ne2k_isa"); 259 if (!isadev) { 260 return false; 261 } 262 dev = DEVICE(isadev); 263 qdev_prop_set_uint32(dev, "iobase", base); 264 qdev_prop_set_uint32(dev, "irq", irq); 265 qdev_set_nic_properties(dev, nd); 266 qdev_init_nofail(dev); 267 return true; 268 } 269 270 /* pc_sysfw.c */ 271 void pc_system_firmware_init(MemoryRegion *rom_memory, 272 bool isapc_ram_fw); 273 274 /* pvpanic.c */ 275 uint16_t pvpanic_port(void); 276 277 /* e820 types */ 278 #define E820_RAM 1 279 #define E820_RESERVED 2 280 #define E820_ACPI 3 281 #define E820_NVS 4 282 #define E820_UNUSABLE 5 283 284 int e820_add_entry(uint64_t, uint64_t, uint32_t); 285 int e820_get_num_entries(void); 286 bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); 287 288 #define PC_Q35_COMPAT_2_0 \ 289 PC_COMPAT_2_0 290 291 #define PC_Q35_COMPAT_1_7 \ 292 PC_COMPAT_1_7, \ 293 PC_Q35_COMPAT_2_0, \ 294 {\ 295 .driver = "hpet",\ 296 .property = HPET_INTCAP,\ 297 .value = stringify(4),\ 298 } 299 300 #define PC_Q35_COMPAT_1_6 \ 301 PC_COMPAT_1_6, \ 302 PC_Q35_COMPAT_1_7 303 304 #define PC_Q35_COMPAT_1_5 \ 305 PC_COMPAT_1_5, \ 306 PC_Q35_COMPAT_1_6 307 308 #define PC_Q35_COMPAT_1_4 \ 309 PC_COMPAT_1_4, \ 310 PC_Q35_COMPAT_1_5 311 312 #define PC_COMPAT_2_0 \ 313 {\ 314 .driver = "apic",\ 315 .property = "version",\ 316 .value = stringify(0x11),\ 317 },{\ 318 .driver = "nec-usb-xhci",\ 319 .property = "superspeed-ports-first",\ 320 .value = "off",\ 321 },\ 322 {\ 323 .driver = "pci-serial",\ 324 .property = "prog_if",\ 325 .value = stringify(0),\ 326 },\ 327 {\ 328 .driver = "pci-serial-2x",\ 329 .property = "prof_if",\ 330 .value = stringify(0),\ 331 },\ 332 {\ 333 .driver = "pci-serial-4x",\ 334 .property = "prog_if",\ 335 .value = stringify(0),\ 336 } 337 338 #define PC_COMPAT_1_7 \ 339 PC_COMPAT_2_0, \ 340 {\ 341 .driver = TYPE_USB_DEVICE,\ 342 .property = "msos-desc",\ 343 .value = "no",\ 344 },\ 345 {\ 346 .driver = "PIIX4_PM",\ 347 .property = "acpi-pci-hotplug-with-bridge-support",\ 348 .value = "off",\ 349 } 350 351 #define PC_COMPAT_1_6 \ 352 PC_COMPAT_1_7, \ 353 {\ 354 .driver = "e1000",\ 355 .property = "mitigation",\ 356 .value = "off",\ 357 },{\ 358 .driver = "qemu64-" TYPE_X86_CPU,\ 359 .property = "model",\ 360 .value = stringify(2),\ 361 },{\ 362 .driver = "qemu32-" TYPE_X86_CPU,\ 363 .property = "model",\ 364 .value = stringify(3),\ 365 },{\ 366 .driver = "i440FX-pcihost",\ 367 .property = "short_root_bus",\ 368 .value = stringify(1),\ 369 },{\ 370 .driver = "q35-pcihost",\ 371 .property = "short_root_bus",\ 372 .value = stringify(1),\ 373 } 374 375 #define PC_COMPAT_1_5 \ 376 PC_COMPAT_1_6, \ 377 {\ 378 .driver = "Conroe-" TYPE_X86_CPU,\ 379 .property = "model",\ 380 .value = stringify(2),\ 381 },{\ 382 .driver = "Conroe-" TYPE_X86_CPU,\ 383 .property = "level",\ 384 .value = stringify(2),\ 385 },{\ 386 .driver = "Penryn-" TYPE_X86_CPU,\ 387 .property = "model",\ 388 .value = stringify(2),\ 389 },{\ 390 .driver = "Penryn-" TYPE_X86_CPU,\ 391 .property = "level",\ 392 .value = stringify(2),\ 393 },{\ 394 .driver = "Nehalem-" TYPE_X86_CPU,\ 395 .property = "model",\ 396 .value = stringify(2),\ 397 },{\ 398 .driver = "Nehalem-" TYPE_X86_CPU,\ 399 .property = "level",\ 400 .value = stringify(2),\ 401 },{\ 402 .driver = "virtio-net-pci",\ 403 .property = "any_layout",\ 404 .value = "off",\ 405 },{\ 406 .driver = TYPE_X86_CPU,\ 407 .property = "pmu",\ 408 .value = "on",\ 409 },{\ 410 .driver = "i440FX-pcihost",\ 411 .property = "short_root_bus",\ 412 .value = stringify(0),\ 413 },{\ 414 .driver = "q35-pcihost",\ 415 .property = "short_root_bus",\ 416 .value = stringify(0),\ 417 } 418 419 #define PC_COMPAT_1_4 \ 420 PC_COMPAT_1_5, \ 421 {\ 422 .driver = "scsi-hd",\ 423 .property = "discard_granularity",\ 424 .value = stringify(0),\ 425 },{\ 426 .driver = "scsi-cd",\ 427 .property = "discard_granularity",\ 428 .value = stringify(0),\ 429 },{\ 430 .driver = "scsi-disk",\ 431 .property = "discard_granularity",\ 432 .value = stringify(0),\ 433 },{\ 434 .driver = "ide-hd",\ 435 .property = "discard_granularity",\ 436 .value = stringify(0),\ 437 },{\ 438 .driver = "ide-cd",\ 439 .property = "discard_granularity",\ 440 .value = stringify(0),\ 441 },{\ 442 .driver = "ide-drive",\ 443 .property = "discard_granularity",\ 444 .value = stringify(0),\ 445 },{\ 446 .driver = "virtio-blk-pci",\ 447 .property = "discard_granularity",\ 448 .value = stringify(0),\ 449 },{\ 450 .driver = "virtio-serial-pci",\ 451 .property = "vectors",\ 452 /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\ 453 .value = stringify(0xFFFFFFFF),\ 454 },{ \ 455 .driver = "virtio-net-pci", \ 456 .property = "ctrl_guest_offloads", \ 457 .value = "off", \ 458 },{\ 459 .driver = "e1000",\ 460 .property = "romfile",\ 461 .value = "pxe-e1000.rom",\ 462 },{\ 463 .driver = "ne2k_pci",\ 464 .property = "romfile",\ 465 .value = "pxe-ne2k_pci.rom",\ 466 },{\ 467 .driver = "pcnet",\ 468 .property = "romfile",\ 469 .value = "pxe-pcnet.rom",\ 470 },{\ 471 .driver = "rtl8139",\ 472 .property = "romfile",\ 473 .value = "pxe-rtl8139.rom",\ 474 },{\ 475 .driver = "virtio-net-pci",\ 476 .property = "romfile",\ 477 .value = "pxe-virtio.rom",\ 478 },{\ 479 .driver = "486-" TYPE_X86_CPU,\ 480 .property = "model",\ 481 .value = stringify(0),\ 482 } 483 484 #define PC_COMMON_MACHINE_OPTIONS \ 485 .default_boot_order = "cad" 486 487 #define PC_DEFAULT_MACHINE_OPTIONS \ 488 PC_COMMON_MACHINE_OPTIONS, \ 489 .hot_add_cpu = pc_hot_add_cpu, \ 490 .max_cpus = 255 491 492 #endif 493