| 1 | #ifndef HW_PC_H |
| 2 | #define HW_PC_H |
| 3 | |
| 4 | #include "qemu/notify.h" |
| 5 | #include "qapi/qapi-types-common.h" |
| 6 | #include "qemu/uuid.h" |
| 7 | #include "hw/core/boards.h" |
| 8 | #include "hw/block/fdc.h" |
| 9 | #include "hw/block/flash.h" |
| 10 | #include "hw/i386/x86.h" |
| 11 | |
| 12 | #include "hw/core/hotplug.h" |
| 13 | #include "qom/object.h" |
| 14 | #include "hw/i386/sgx-epc.h" |
| 15 | #include "hw/cxl/cxl.h" |
| 16 | |
| 17 | #define MAX_IDE_BUS 2 |
| 18 | |
| 19 | /** |
| 20 | * PCMachineState: |
| 21 | * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling |
| 22 | * @boot_cpus: number of present VCPUs |
| 23 | */ |
| 24 | typedef struct PCMachineState { |
| 25 | /*< private >*/ |
| 26 | X86MachineState parent_obj; |
| 27 | |
| 28 | /* <public> */ |
| 29 | |
| 30 | /* State for other subsystems/APIs: */ |
| 31 | Notifier machine_done; |
| 32 | |
| 33 | /* Pointers to devices and objects: */ |
| 34 | PCIBus *pcibus; |
| 35 | I2CBus *smbus; |
| 36 | PFlashCFI01 *flash[2]; |
| 37 | ISADevice *pcspk; |
| 38 | DeviceState *iommu; |
| 39 | BusState *idebus[MAX_IDE_BUS]; |
| 40 | |
| 41 | /* Configuration options: */ |
| 42 | uint64_t max_ram_below_4g; |
| 43 | OnOffAuto vmport; |
| 44 | SmbiosEntryPointType smbios_entry_point_type; |
| 45 | const char *south_bridge; |
| 46 | |
| 47 | bool acpi_build_enabled; |
| 48 | bool wdat_enabled; |
| 49 | bool smbus_enabled; |
| 50 | bool sata_enabled; |
| 51 | bool hpet_enabled; |
| 52 | bool i8042_enabled; |
| 53 | bool default_bus_bypass_iommu; |
| 54 | bool fd_bootchk; |
| 55 | uint64_t max_fw_size; |
| 56 | |
| 57 | /* ACPI Memory hotplug IO base address */ |
| 58 | hwaddr memhp_io_base; |
| 59 | |
| 60 | SGXEPCState sgx_epc; |
| 61 | CXLState cxl_devices_state; |
| 62 | } PCMachineState; |
| 63 | |
| 64 | #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" |
| 65 | #define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" |
| 66 | #define PC_MACHINE_VMPORT "vmport" |
| 67 | #define PC_MACHINE_SMBUS "smbus" |
| 68 | #define PC_MACHINE_SATA "sata" |
| 69 | #define PC_MACHINE_I8042 "i8042" |
| 70 | #define PC_MACHINE_MAX_FW_SIZE "max-fw-size" |
| 71 | #define PC_MACHINE_SMBIOS_EP "smbios-entry-point-type" |
| 72 | |
| 73 | /** |
| 74 | * PCMachineClass: |
| 75 | * |
| 76 | * Compat fields: |
| 77 | * |
| 78 | * @gigabyte_align: Make sure that guest addresses aligned at |
| 79 | * 1Gbyte boundaries get mapped to host |
| 80 | * addresses aligned at 1Gbyte boundaries. This |
| 81 | * way we can use 1GByte pages in the host. |
| 82 | * |
| 83 | */ |
| 84 | struct PCMachineClass { |
| 85 | /*< private >*/ |
| 86 | X86MachineClass parent_class; |
| 87 | |
| 88 | /*< public >*/ |
| 89 | |
| 90 | /* Device configuration: */ |
| 91 | bool pci_enabled; |
| 92 | const char *default_south_bridge; |
| 93 | |
| 94 | /* Compat options: */ |
| 95 | |
| 96 | /* Default CPU model version. See x86_cpu_set_default_version(). */ |
| 97 | int default_cpu_version; |
| 98 | |
| 99 | /* ACPI compat: */ |
| 100 | bool has_acpi_build; |
| 101 | int pci_root_uid; |
| 102 | |
| 103 | /* SMBIOS compat: */ |
| 104 | bool smbios_defaults; |
| 105 | bool smbios_legacy_mode; |
| 106 | SmbiosEntryPointType default_smbios_ep_type; |
| 107 | |
| 108 | /* RAM / address space compat: */ |
| 109 | bool gigabyte_align; |
| 110 | bool has_reserved_memory; |
| 111 | bool enforce_amd_1tb_hole; |
| 112 | bool isa_bios_alias; |
| 113 | |
| 114 | /* create kvmclock device even when KVM PV features are not exposed */ |
| 115 | bool kvmclock_create_always; |
| 116 | |
| 117 | /* |
| 118 | * whether the machine type implements broken 32-bit address space bound |
| 119 | * check for memory. |
| 120 | */ |
| 121 | bool broken_32bit_mem_addr_check; |
| 122 | }; |
| 123 | |
| 124 | #define TYPE_PC_MACHINE "generic-pc-machine" |
| 125 | OBJECT_DECLARE_TYPE(PCMachineState, PCMachineClass, PC_MACHINE) |
| 126 | |
| 127 | /* ioapic.c */ |
| 128 | |
| 129 | GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled); |
| 130 | |
| 131 | /* pc.c */ |
| 132 | |
| 133 | void pc_acpi_smi_interrupt(void *opaque, int irq, int level); |
| 134 | |
| 135 | #define PCI_HOST_PROP_RAM_MEM "ram-mem" |
| 136 | #define PCI_HOST_PROP_PCI_MEM "pci-mem" |
| 137 | #define PCI_HOST_PROP_SYSTEM_MEM "system-mem" |
| 138 | #define PCI_HOST_PROP_IO_MEM "io-mem" |
| 139 | #define PCI_HOST_PROP_PCI_HOLE_START "pci-hole-start" |
| 140 | #define PCI_HOST_PROP_PCI_HOLE_END "pci-hole-end" |
| 141 | #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start" |
| 142 | #define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end" |
| 143 | #define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size" |
| 144 | #define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size" |
| 145 | #define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size" |
| 146 | #define PCI_HOST_PROP_SMM_RANGES "smm-ranges" |
| 147 | |
| 148 | typedef enum { |
| 149 | SEV_DESC_TYPE_UNDEF, |
| 150 | /* The section contains the region that must be validated by the VMM. */ |
| 151 | SEV_DESC_TYPE_SNP_SEC_MEM, |
| 152 | /* The section contains the SNP secrets page */ |
| 153 | SEV_DESC_TYPE_SNP_SECRETS, |
| 154 | /* The section contains address that can be used as a CPUID page */ |
| 155 | SEV_DESC_TYPE_CPUID, |
| 156 | /* The section contains the region for kernel hashes for measured direct boot */ |
| 157 | SEV_DESC_TYPE_SNP_KERNEL_HASHES = 0x10, |
| 158 | |
| 159 | } ovmf_sev_metadata_desc_type; |
| 160 | |
| 161 | typedef struct __attribute__((__packed__)) OvmfSevMetadataDesc { |
| 162 | uint32_t base; |
| 163 | uint32_t len; |
| 164 | ovmf_sev_metadata_desc_type type; |
| 165 | } OvmfSevMetadataDesc; |
| 166 | |
| 167 | typedef struct __attribute__((__packed__)) OvmfSevMetadata { |
| 168 | uint8_t signature[4]; |
| 169 | uint32_t len; |
| 170 | uint32_t version; |
| 171 | uint32_t num_desc; |
| 172 | OvmfSevMetadataDesc descs[]; |
| 173 | } OvmfSevMetadata; |
| 174 | |
| 175 | OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void); |
| 176 | |
| 177 | void pc_pci_as_mapping_init(MemoryRegion *system_memory, |
| 178 | MemoryRegion *pci_address_space); |
| 179 | |
| 180 | void xen_load_linux(PCMachineState *pcms); |
| 181 | void pc_memory_init(PCMachineState *pcms, |
| 182 | MemoryRegion *system_memory, |
| 183 | MemoryRegion *rom_memory, |
| 184 | uint64_t pci_hole64_size); |
| 185 | uint64_t pc_pci_hole64_start(void); |
| 186 | DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); |
| 187 | void pc_basic_device_init(struct PCMachineState *pcms, |
| 188 | ISABus *isa_bus, qemu_irq *gsi, |
| 189 | ISADevice *rtc_state, |
| 190 | bool create_fdctrl, |
| 191 | uint32_t hpet_irqs); |
| 192 | void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus); |
| 193 | |
| 194 | void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs); |
| 195 | |
| 196 | /* port92.c */ |
| 197 | #define PORT92_A20_LINE "a20" |
| 198 | |
| 199 | #define TYPE_PORT92 "port92" |
| 200 | |
| 201 | /* pc_sysfw.c */ |
| 202 | void pc_system_flash_create(PCMachineState *pcms); |
| 203 | void pc_system_flash_cleanup_unused(PCMachineState *pcms); |
| 204 | void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory); |
| 205 | bool pc_system_ovmf_table_find(const char *entry, uint8_t **data, |
| 206 | int *data_len); |
| 207 | void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size); |
| 208 | |
| 209 | /* sgx.c */ |
| 210 | void pc_machine_init_sgx_epc(PCMachineState *pcms); |
| 211 | |
| 212 | extern GlobalProperty pc_compat_11_1[]; |
| 213 | extern const size_t pc_compat_11_1_len; |
| 214 | |
| 215 | extern GlobalProperty pc_compat_11_0[]; |
| 216 | extern const size_t pc_compat_11_0_len; |
| 217 | |
| 218 | extern GlobalProperty pc_compat_10_2[]; |
| 219 | extern const size_t pc_compat_10_2_len; |
| 220 | |
| 221 | extern GlobalProperty pc_compat_10_1[]; |
| 222 | extern const size_t pc_compat_10_1_len; |
| 223 | |
| 224 | extern GlobalProperty pc_compat_10_0[]; |
| 225 | extern const size_t pc_compat_10_0_len; |
| 226 | |
| 227 | extern GlobalProperty pc_compat_9_2[]; |
| 228 | extern const size_t pc_compat_9_2_len; |
| 229 | |
| 230 | extern GlobalProperty pc_compat_9_1[]; |
| 231 | extern const size_t pc_compat_9_1_len; |
| 232 | |
| 233 | extern GlobalProperty pc_compat_9_0[]; |
| 234 | extern const size_t pc_compat_9_0_len; |
| 235 | |
| 236 | extern GlobalProperty pc_compat_8_2[]; |
| 237 | extern const size_t pc_compat_8_2_len; |
| 238 | |
| 239 | extern GlobalProperty pc_compat_8_1[]; |
| 240 | extern const size_t pc_compat_8_1_len; |
| 241 | |
| 242 | extern GlobalProperty pc_compat_8_0[]; |
| 243 | extern const size_t pc_compat_8_0_len; |
| 244 | |
| 245 | extern GlobalProperty pc_compat_7_2[]; |
| 246 | extern const size_t pc_compat_7_2_len; |
| 247 | |
| 248 | extern GlobalProperty pc_compat_7_1[]; |
| 249 | extern const size_t pc_compat_7_1_len; |
| 250 | |
| 251 | extern GlobalProperty pc_compat_7_0[]; |
| 252 | extern const size_t pc_compat_7_0_len; |
| 253 | |
| 254 | extern GlobalProperty pc_compat_6_2[]; |
| 255 | extern const size_t pc_compat_6_2_len; |
| 256 | |
| 257 | extern GlobalProperty pc_compat_6_1[]; |
| 258 | extern const size_t pc_compat_6_1_len; |
| 259 | |
| 260 | extern GlobalProperty pc_compat_6_0[]; |
| 261 | extern const size_t pc_compat_6_0_len; |
| 262 | |
| 263 | extern GlobalProperty pc_compat_5_2[]; |
| 264 | extern const size_t pc_compat_5_2_len; |
| 265 | |
| 266 | extern GlobalProperty pc_compat_5_1[]; |
| 267 | extern const size_t pc_compat_5_1_len; |
| 268 | |
| 269 | extern GlobalProperty pc_compat_5_0[]; |
| 270 | extern const size_t pc_compat_5_0_len; |
| 271 | |
| 272 | extern GlobalProperty pc_compat_4_2[]; |
| 273 | extern const size_t pc_compat_4_2_len; |
| 274 | |
| 275 | extern GlobalProperty pc_compat_4_1[]; |
| 276 | extern const size_t pc_compat_4_1_len; |
| 277 | |
| 278 | #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ |
| 279 | static void pc_machine_##suffix##_class_init(ObjectClass *oc, \ |
| 280 | const void *data) \ |
| 281 | { \ |
| 282 | MachineClass *mc = MACHINE_CLASS(oc); \ |
| 283 | optsfn(mc); \ |
| 284 | mc->init = initfn; \ |
| 285 | } \ |
| 286 | static const TypeInfo pc_machine_type_##suffix = { \ |
| 287 | .name = namestr TYPE_MACHINE_SUFFIX, \ |
| 288 | .parent = TYPE_PC_MACHINE, \ |
| 289 | .class_init = pc_machine_##suffix##_class_init, \ |
| 290 | }; \ |
| 291 | static void pc_machine_init_##suffix(void) \ |
| 292 | { \ |
| 293 | type_register_static(&pc_machine_type_##suffix); \ |
| 294 | } \ |
| 295 | type_init(pc_machine_init_##suffix) |
| 296 | |
| 297 | #define DEFINE_PC_VER_MACHINE(namesym, namestr, initfn, isdefault, malias, ...) \ |
| 298 | static void MACHINE_VER_SYM(init, namesym, __VA_ARGS__)( \ |
| 299 | MachineState *machine) \ |
| 300 | { \ |
| 301 | initfn(machine); \ |
| 302 | } \ |
| 303 | static void MACHINE_VER_SYM(class_init, namesym, __VA_ARGS__)( \ |
| 304 | ObjectClass *oc, \ |
| 305 | const void *data) \ |
| 306 | { \ |
| 307 | MachineClass *mc = MACHINE_CLASS(oc); \ |
| 308 | MACHINE_VER_SYM(options, namesym, __VA_ARGS__)(mc); \ |
| 309 | mc->init = MACHINE_VER_SYM(init, namesym, __VA_ARGS__); \ |
| 310 | MACHINE_VER_DEPRECATION(__VA_ARGS__); \ |
| 311 | mc->is_default = isdefault; \ |
| 312 | mc->alias = malias; \ |
| 313 | } \ |
| 314 | static const TypeInfo MACHINE_VER_SYM(info, namesym, __VA_ARGS__) = \ |
| 315 | { \ |
| 316 | .name = MACHINE_VER_TYPE_NAME(namestr, __VA_ARGS__), \ |
| 317 | .parent = TYPE_PC_MACHINE, \ |
| 318 | .class_init = MACHINE_VER_SYM(class_init, namesym, __VA_ARGS__), \ |
| 319 | }; \ |
| 320 | static void MACHINE_VER_SYM(register, namesym, __VA_ARGS__)(void) \ |
| 321 | { \ |
| 322 | MACHINE_VER_DELETION(__VA_ARGS__); \ |
| 323 | type_register_static(&MACHINE_VER_SYM(info, namesym, __VA_ARGS__)); \ |
| 324 | } \ |
| 325 | type_init(MACHINE_VER_SYM(register, namesym, __VA_ARGS__)); |
| 326 | |
| 327 | #endif |