2
0

pc_piix.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  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. #include "qemu/osdep.h"
  25. #include CONFIG_DEVICES
  26. #include "qemu/units.h"
  27. #include "hw/char/parallel-isa.h"
  28. #include "hw/dma/i8257.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/rtc/mc146818rtc.h"
  35. #include "hw/southbridge/piix.h"
  36. #include "hw/display/ramfb.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/isa.h"
  42. #include "hw/ide/pci.h"
  43. #include "hw/irq.h"
  44. #include "system/kvm.h"
  45. #include "hw/i386/kvm/clock.h"
  46. #include "hw/sysbus.h"
  47. #include "hw/i2c/smbus_eeprom.h"
  48. #include "exec/memory.h"
  49. #include "hw/acpi/acpi.h"
  50. #include "qapi/error.h"
  51. #include "qemu/error-report.h"
  52. #include "system/xen.h"
  53. #ifdef CONFIG_XEN
  54. #include <xen/hvm/hvm_info_table.h>
  55. #include "hw/xen/xen_pt.h"
  56. #include "hw/xen/xen_igd.h"
  57. #endif
  58. #include "hw/xen/xen-x86.h"
  59. #include "hw/xen/xen.h"
  60. #include "migration/global_state.h"
  61. #include "migration/misc.h"
  62. #include "system/runstate.h"
  63. #include "system/numa.h"
  64. #include "hw/hyperv/vmbus-bridge.h"
  65. #include "hw/mem/nvdimm.h"
  66. #include "hw/uefi/var-service-api.h"
  67. #include "hw/i386/acpi-build.h"
  68. #include "target/i386/cpu.h"
  69. #define XEN_IOAPIC_NUM_PIRQS 128ULL
  70. #ifdef CONFIG_IDE_ISA
  71. static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
  72. static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
  73. static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
  74. #endif
  75. /*
  76. * Return the global irq number corresponding to a given device irq
  77. * pin. We could also use the bus number to have a more precise mapping.
  78. */
  79. static int pc_pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
  80. {
  81. int slot_addend;
  82. slot_addend = PCI_SLOT(pci_dev->devfn) - 1;
  83. return (pci_intx + slot_addend) & 3;
  84. }
  85. static void piix_intx_routing_notifier_xen(PCIDevice *dev)
  86. {
  87. int i;
  88. /* Scan for updates to PCI link routes. */
  89. for (i = 0; i < PIIX_NUM_PIRQS; i++) {
  90. const PCIINTxRoute route = pci_device_route_intx_to_irq(dev, i);
  91. const uint8_t v = route.mode == PCI_INTX_ENABLED ? route.irq : 0;
  92. xen_set_pci_link_route(i, v);
  93. }
  94. }
  95. /* PC hardware initialisation */
  96. static void pc_init1(MachineState *machine, const char *pci_type)
  97. {
  98. PCMachineState *pcms = PC_MACHINE(machine);
  99. PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
  100. X86MachineState *x86ms = X86_MACHINE(machine);
  101. MemoryRegion *system_memory = get_system_memory();
  102. MemoryRegion *system_io = get_system_io();
  103. Object *phb = NULL;
  104. ISABus *isa_bus;
  105. Object *piix4_pm = NULL;
  106. qemu_irq smi_irq;
  107. GSIState *gsi_state;
  108. MemoryRegion *ram_memory;
  109. MemoryRegion *pci_memory = NULL;
  110. MemoryRegion *rom_memory = system_memory;
  111. ram_addr_t lowmem;
  112. uint64_t hole64_size = 0;
  113. /*
  114. * Calculate ram split, for memory below and above 4G. It's a bit
  115. * complicated for backward compatibility reasons ...
  116. *
  117. * - Traditional split is 3.5G (lowmem = 0xe0000000). This is the
  118. * default value for max_ram_below_4g now.
  119. *
  120. * - Then, to gigabyte align the memory, we move the split to 3G
  121. * (lowmem = 0xc0000000). But only in case we have to split in
  122. * the first place, i.e. ram_size is larger than (traditional)
  123. * lowmem. And for new machine types (gigabyte_align = true)
  124. * only, for live migration compatibility reasons.
  125. *
  126. * - Next the max-ram-below-4g option was added, which allowed to
  127. * reduce lowmem to a smaller value, to allow a larger PCI I/O
  128. * window below 4G. qemu doesn't enforce gigabyte alignment here,
  129. * but prints a warning.
  130. *
  131. * - Finally max-ram-below-4g got updated to also allow raising lowmem,
  132. * so legacy non-PAE guests can get as much memory as possible in
  133. * the 32bit address space below 4G.
  134. *
  135. * - Note that Xen has its own ram setup code in xen_ram_init(),
  136. * called via xen_hvm_init_pc().
  137. *
  138. * Examples:
  139. * qemu -M pc-1.7 -m 4G (old default) -> 3584M low, 512M high
  140. * qemu -M pc -m 4G (new default) -> 3072M low, 1024M high
  141. * qemu -M pc,max-ram-below-4g=2G -m 4G -> 2048M low, 2048M high
  142. * qemu -M pc,max-ram-below-4g=4G -m 3968M -> 3968M low (=4G-128M)
  143. */
  144. if (xen_enabled()) {
  145. xen_hvm_init_pc(pcms, &ram_memory);
  146. } else {
  147. ram_memory = machine->ram;
  148. if (!pcms->max_ram_below_4g) {
  149. pcms->max_ram_below_4g = 0xe0000000; /* default: 3.5G */
  150. }
  151. lowmem = pcms->max_ram_below_4g;
  152. if (machine->ram_size >= pcms->max_ram_below_4g) {
  153. if (pcmc->gigabyte_align) {
  154. if (lowmem > 0xc0000000) {
  155. lowmem = 0xc0000000;
  156. }
  157. if (lowmem & (1 * GiB - 1)) {
  158. warn_report("Large machine and max_ram_below_4g "
  159. "(%" PRIu64 ") not a multiple of 1G; "
  160. "possible bad performance.",
  161. pcms->max_ram_below_4g);
  162. }
  163. }
  164. }
  165. if (machine->ram_size >= lowmem) {
  166. x86ms->above_4g_mem_size = machine->ram_size - lowmem;
  167. x86ms->below_4g_mem_size = lowmem;
  168. } else {
  169. x86ms->above_4g_mem_size = 0;
  170. x86ms->below_4g_mem_size = machine->ram_size;
  171. }
  172. }
  173. pc_machine_init_sgx_epc(pcms);
  174. x86_cpus_init(x86ms, pcmc->default_cpu_version);
  175. if (kvm_enabled()) {
  176. kvmclock_create(pcmc->kvmclock_create_always);
  177. }
  178. if (pcmc->pci_enabled) {
  179. pci_memory = g_new(MemoryRegion, 1);
  180. memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
  181. rom_memory = pci_memory;
  182. phb = OBJECT(qdev_new(TYPE_I440FX_PCI_HOST_BRIDGE));
  183. object_property_add_child(OBJECT(machine), "i440fx", phb);
  184. object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
  185. OBJECT(ram_memory), &error_fatal);
  186. object_property_set_link(phb, PCI_HOST_PROP_PCI_MEM,
  187. OBJECT(pci_memory), &error_fatal);
  188. object_property_set_link(phb, PCI_HOST_PROP_SYSTEM_MEM,
  189. OBJECT(system_memory), &error_fatal);
  190. object_property_set_link(phb, PCI_HOST_PROP_IO_MEM,
  191. OBJECT(system_io), &error_fatal);
  192. object_property_set_uint(phb, PCI_HOST_BELOW_4G_MEM_SIZE,
  193. x86ms->below_4g_mem_size, &error_fatal);
  194. object_property_set_uint(phb, PCI_HOST_ABOVE_4G_MEM_SIZE,
  195. x86ms->above_4g_mem_size, &error_fatal);
  196. object_property_set_str(phb, I440FX_HOST_PROP_PCI_TYPE, pci_type,
  197. &error_fatal);
  198. sysbus_realize_and_unref(SYS_BUS_DEVICE(phb), &error_fatal);
  199. pcms->pcibus = PCI_BUS(qdev_get_child_bus(DEVICE(phb), "pci.0"));
  200. pci_bus_map_irqs(pcms->pcibus,
  201. xen_enabled() ? xen_pci_slot_get_pirq
  202. : pc_pci_slot_get_pirq);
  203. hole64_size = object_property_get_uint(phb,
  204. PCI_HOST_PROP_PCI_HOLE64_SIZE,
  205. &error_abort);
  206. }
  207. /* allocate ram and load rom/bios */
  208. if (!xen_enabled()) {
  209. pc_memory_init(pcms, system_memory, rom_memory, hole64_size);
  210. } else {
  211. assert(machine->ram_size == x86ms->below_4g_mem_size +
  212. x86ms->above_4g_mem_size);
  213. pc_system_flash_cleanup_unused(pcms);
  214. if (machine->kernel_filename != NULL) {
  215. /* For xen HVM direct kernel boot, load linux here */
  216. xen_load_linux(pcms);
  217. }
  218. }
  219. gsi_state = pc_gsi_create(&x86ms->gsi, pcmc->pci_enabled);
  220. if (pcmc->pci_enabled) {
  221. PCIDevice *pci_dev;
  222. DeviceState *dev;
  223. size_t i;
  224. pci_dev = pci_new_multifunction(-1, pcms->south_bridge);
  225. object_property_set_bool(OBJECT(pci_dev), "has-usb",
  226. machine_usb(machine), &error_abort);
  227. object_property_set_bool(OBJECT(pci_dev), "has-acpi",
  228. x86_machine_is_acpi_enabled(x86ms),
  229. &error_abort);
  230. object_property_set_bool(OBJECT(pci_dev), "has-pic", false,
  231. &error_abort);
  232. object_property_set_bool(OBJECT(pci_dev), "has-pit", false,
  233. &error_abort);
  234. qdev_prop_set_uint32(DEVICE(pci_dev), "smb_io_base", 0xb100);
  235. object_property_set_bool(OBJECT(pci_dev), "smm-enabled",
  236. x86_machine_is_smm_enabled(x86ms),
  237. &error_abort);
  238. dev = DEVICE(pci_dev);
  239. for (i = 0; i < ISA_NUM_IRQS; i++) {
  240. qdev_connect_gpio_out_named(dev, "isa-irqs", i, x86ms->gsi[i]);
  241. }
  242. pci_realize_and_unref(pci_dev, pcms->pcibus, &error_fatal);
  243. if (xen_enabled()) {
  244. pci_device_set_intx_routing_notifier(
  245. pci_dev, piix_intx_routing_notifier_xen);
  246. /*
  247. * Xen supports additional interrupt routes from the PCI devices to
  248. * the IOAPIC: the four pins of each PCI device on the bus are also
  249. * connected to the IOAPIC directly.
  250. * These additional routes can be discovered through ACPI.
  251. */
  252. pci_bus_irqs(pcms->pcibus, xen_intx_set_irq, pci_dev,
  253. XEN_IOAPIC_NUM_PIRQS);
  254. }
  255. isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"));
  256. x86ms->rtc = ISA_DEVICE(object_resolve_path_component(OBJECT(pci_dev),
  257. "rtc"));
  258. piix4_pm = object_resolve_path_component(OBJECT(pci_dev), "pm");
  259. dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
  260. pci_ide_create_devs(PCI_DEVICE(dev));
  261. pcms->idebus[0] = qdev_get_child_bus(dev, "ide.0");
  262. pcms->idebus[1] = qdev_get_child_bus(dev, "ide.1");
  263. } else {
  264. isa_bus = isa_bus_new(NULL, system_memory, system_io,
  265. &error_abort);
  266. isa_bus_register_input_irqs(isa_bus, x86ms->gsi);
  267. x86ms->rtc = isa_new(TYPE_MC146818_RTC);
  268. qdev_prop_set_int32(DEVICE(x86ms->rtc), "base_year", 2000);
  269. isa_realize_and_unref(x86ms->rtc, isa_bus, &error_fatal);
  270. i8257_dma_init(OBJECT(machine), isa_bus, 0);
  271. pcms->hpet_enabled = false;
  272. }
  273. if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
  274. pc_i8259_create(isa_bus, gsi_state->i8259_irq);
  275. }
  276. if (phb) {
  277. ioapic_init_gsi(gsi_state, phb);
  278. }
  279. if (tcg_enabled()) {
  280. x86_register_ferr_irq(x86ms->gsi[13]);
  281. }
  282. pc_vga_init(isa_bus, pcmc->pci_enabled ? pcms->pcibus : NULL);
  283. /* init basic PC hardware */
  284. pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc,
  285. !MACHINE_CLASS(pcmc)->no_floppy, 0x4);
  286. pc_nic_init(pcmc, isa_bus, pcms->pcibus);
  287. #ifdef CONFIG_IDE_ISA
  288. if (!pcmc->pci_enabled) {
  289. DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
  290. int i;
  291. ide_drive_get(hd, ARRAY_SIZE(hd));
  292. for (i = 0; i < MAX_IDE_BUS; i++) {
  293. ISADevice *dev;
  294. char busname[] = "ide.0";
  295. dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
  296. ide_irq[i],
  297. hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
  298. /*
  299. * The ide bus name is ide.0 for the first bus and ide.1 for the
  300. * second one.
  301. */
  302. busname[4] = '0' + i;
  303. pcms->idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
  304. }
  305. }
  306. #endif
  307. if (piix4_pm) {
  308. smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
  309. qdev_connect_gpio_out_named(DEVICE(piix4_pm), "smi-irq", 0, smi_irq);
  310. pcms->smbus = I2C_BUS(qdev_get_child_bus(DEVICE(piix4_pm), "i2c"));
  311. /* TODO: Populate SPD eeprom data. */
  312. smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
  313. object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
  314. TYPE_HOTPLUG_HANDLER,
  315. (Object **)&x86ms->acpi_dev,
  316. object_property_allow_set_link,
  317. OBJ_PROP_LINK_STRONG);
  318. object_property_set_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
  319. piix4_pm, &error_abort);
  320. }
  321. if (machine->nvdimms_state->is_enabled) {
  322. nvdimm_init_acpi_state(machine->nvdimms_state, system_io,
  323. x86_nvdimm_acpi_dsmio,
  324. x86ms->fw_cfg, OBJECT(pcms));
  325. }
  326. }
  327. typedef enum PCSouthBridgeOption {
  328. PC_SOUTH_BRIDGE_OPTION_PIIX3,
  329. PC_SOUTH_BRIDGE_OPTION_PIIX4,
  330. PC_SOUTH_BRIDGE_OPTION_MAX,
  331. } PCSouthBridgeOption;
  332. static const QEnumLookup PCSouthBridgeOption_lookup = {
  333. .array = (const char *const[]) {
  334. [PC_SOUTH_BRIDGE_OPTION_PIIX3] = TYPE_PIIX3_DEVICE,
  335. [PC_SOUTH_BRIDGE_OPTION_PIIX4] = TYPE_PIIX4_PCI_DEVICE,
  336. },
  337. .size = PC_SOUTH_BRIDGE_OPTION_MAX
  338. };
  339. static int pc_get_south_bridge(Object *obj, Error **errp)
  340. {
  341. PCMachineState *pcms = PC_MACHINE(obj);
  342. int i;
  343. for (i = 0; i < PCSouthBridgeOption_lookup.size; i++) {
  344. if (g_strcmp0(PCSouthBridgeOption_lookup.array[i],
  345. pcms->south_bridge) == 0) {
  346. return i;
  347. }
  348. }
  349. error_setg(errp, "Invalid south bridge value set");
  350. return 0;
  351. }
  352. static void pc_set_south_bridge(Object *obj, int value, Error **errp)
  353. {
  354. PCMachineState *pcms = PC_MACHINE(obj);
  355. if (value < 0) {
  356. error_setg(errp, "Value can't be negative");
  357. return;
  358. }
  359. if (value >= PCSouthBridgeOption_lookup.size) {
  360. error_setg(errp, "Value too big");
  361. return;
  362. }
  363. pcms->south_bridge = PCSouthBridgeOption_lookup.array[value];
  364. }
  365. #ifdef CONFIG_ISAPC
  366. static void pc_init_isa(MachineState *machine)
  367. {
  368. pc_init1(machine, NULL);
  369. }
  370. #endif
  371. #ifdef CONFIG_XEN
  372. static void pc_xen_hvm_init_pci(MachineState *machine)
  373. {
  374. const char *pci_type = xen_igd_gfx_pt_enabled() ?
  375. TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
  376. pc_init1(machine, pci_type);
  377. }
  378. static void pc_xen_hvm_init(MachineState *machine)
  379. {
  380. PCMachineState *pcms = PC_MACHINE(machine);
  381. if (!xen_enabled()) {
  382. error_report("xenfv machine requires the xen accelerator");
  383. exit(1);
  384. }
  385. pc_xen_hvm_init_pci(machine);
  386. xen_igd_reserve_slot(pcms->pcibus);
  387. pci_create_simple(pcms->pcibus, -1, "xen-platform");
  388. }
  389. #endif
  390. static void pc_i440fx_init(MachineState *machine)
  391. {
  392. pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
  393. }
  394. #define DEFINE_I440FX_MACHINE(major, minor) \
  395. DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor);
  396. #define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
  397. DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor);
  398. static void pc_i440fx_machine_options(MachineClass *m)
  399. {
  400. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  401. ObjectClass *oc = OBJECT_CLASS(m);
  402. pcmc->default_south_bridge = TYPE_PIIX3_DEVICE;
  403. pcmc->pci_root_uid = 0;
  404. pcmc->default_cpu_version = 1;
  405. m->family = "pc_piix";
  406. m->desc = "Standard PC (i440FX + PIIX, 1996)";
  407. m->default_machine_opts = "firmware=bios-256k.bin";
  408. m->default_display = "std";
  409. m->default_nic = "e1000";
  410. m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
  411. m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
  412. machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
  413. machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
  414. machine_class_allow_dynamic_sysbus_dev(m, TYPE_UEFI_VARS_X64);
  415. object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption",
  416. &PCSouthBridgeOption_lookup,
  417. pc_get_south_bridge,
  418. pc_set_south_bridge);
  419. object_class_property_set_description(oc, "x-south-bridge",
  420. "Use a different south bridge than PIIX3");
  421. }
  422. static void pc_i440fx_machine_10_0_options(MachineClass *m)
  423. {
  424. pc_i440fx_machine_options(m);
  425. }
  426. DEFINE_I440FX_MACHINE_AS_LATEST(10, 0);
  427. static void pc_i440fx_machine_9_2_options(MachineClass *m)
  428. {
  429. pc_i440fx_machine_10_0_options(m);
  430. compat_props_add(m->compat_props, hw_compat_9_2, hw_compat_9_2_len);
  431. compat_props_add(m->compat_props, pc_compat_9_2, pc_compat_9_2_len);
  432. }
  433. DEFINE_I440FX_MACHINE(9, 2);
  434. static void pc_i440fx_machine_9_1_options(MachineClass *m)
  435. {
  436. pc_i440fx_machine_9_2_options(m);
  437. compat_props_add(m->compat_props, hw_compat_9_1, hw_compat_9_1_len);
  438. compat_props_add(m->compat_props, pc_compat_9_1, pc_compat_9_1_len);
  439. }
  440. DEFINE_I440FX_MACHINE(9, 1);
  441. static void pc_i440fx_machine_9_0_options(MachineClass *m)
  442. {
  443. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  444. pc_i440fx_machine_9_1_options(m);
  445. m->smbios_memory_device_size = 16 * GiB;
  446. compat_props_add(m->compat_props, hw_compat_9_0, hw_compat_9_0_len);
  447. compat_props_add(m->compat_props, pc_compat_9_0, pc_compat_9_0_len);
  448. pcmc->isa_bios_alias = false;
  449. }
  450. DEFINE_I440FX_MACHINE(9, 0);
  451. static void pc_i440fx_machine_8_2_options(MachineClass *m)
  452. {
  453. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  454. pc_i440fx_machine_9_0_options(m);
  455. compat_props_add(m->compat_props, hw_compat_8_2, hw_compat_8_2_len);
  456. compat_props_add(m->compat_props, pc_compat_8_2, pc_compat_8_2_len);
  457. /* For pc-i44fx-8.2 and 8.1, use SMBIOS 3.X by default */
  458. pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
  459. }
  460. DEFINE_I440FX_MACHINE(8, 2);
  461. static void pc_i440fx_machine_8_1_options(MachineClass *m)
  462. {
  463. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  464. pc_i440fx_machine_8_2_options(m);
  465. pcmc->broken_32bit_mem_addr_check = true;
  466. compat_props_add(m->compat_props, hw_compat_8_1, hw_compat_8_1_len);
  467. compat_props_add(m->compat_props, pc_compat_8_1, pc_compat_8_1_len);
  468. }
  469. DEFINE_I440FX_MACHINE(8, 1);
  470. static void pc_i440fx_machine_8_0_options(MachineClass *m)
  471. {
  472. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  473. pc_i440fx_machine_8_1_options(m);
  474. compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
  475. compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);
  476. /* For pc-i44fx-8.0 and older, use SMBIOS 2.8 by default */
  477. pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
  478. }
  479. DEFINE_I440FX_MACHINE(8, 0);
  480. static void pc_i440fx_machine_7_2_options(MachineClass *m)
  481. {
  482. pc_i440fx_machine_8_0_options(m);
  483. compat_props_add(m->compat_props, hw_compat_7_2, hw_compat_7_2_len);
  484. compat_props_add(m->compat_props, pc_compat_7_2, pc_compat_7_2_len);
  485. }
  486. DEFINE_I440FX_MACHINE(7, 2)
  487. static void pc_i440fx_machine_7_1_options(MachineClass *m)
  488. {
  489. pc_i440fx_machine_7_2_options(m);
  490. compat_props_add(m->compat_props, hw_compat_7_1, hw_compat_7_1_len);
  491. compat_props_add(m->compat_props, pc_compat_7_1, pc_compat_7_1_len);
  492. }
  493. DEFINE_I440FX_MACHINE(7, 1);
  494. static void pc_i440fx_machine_7_0_options(MachineClass *m)
  495. {
  496. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  497. pc_i440fx_machine_7_1_options(m);
  498. pcmc->enforce_amd_1tb_hole = false;
  499. compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
  500. compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
  501. }
  502. DEFINE_I440FX_MACHINE(7, 0);
  503. static void pc_i440fx_machine_6_2_options(MachineClass *m)
  504. {
  505. pc_i440fx_machine_7_0_options(m);
  506. compat_props_add(m->compat_props, hw_compat_6_2, hw_compat_6_2_len);
  507. compat_props_add(m->compat_props, pc_compat_6_2, pc_compat_6_2_len);
  508. }
  509. DEFINE_I440FX_MACHINE(6, 2);
  510. static void pc_i440fx_machine_6_1_options(MachineClass *m)
  511. {
  512. pc_i440fx_machine_6_2_options(m);
  513. compat_props_add(m->compat_props, hw_compat_6_1, hw_compat_6_1_len);
  514. compat_props_add(m->compat_props, pc_compat_6_1, pc_compat_6_1_len);
  515. m->smp_props.prefer_sockets = true;
  516. }
  517. DEFINE_I440FX_MACHINE(6, 1);
  518. static void pc_i440fx_machine_6_0_options(MachineClass *m)
  519. {
  520. pc_i440fx_machine_6_1_options(m);
  521. compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
  522. compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
  523. }
  524. DEFINE_I440FX_MACHINE(6, 0);
  525. static void pc_i440fx_machine_5_2_options(MachineClass *m)
  526. {
  527. pc_i440fx_machine_6_0_options(m);
  528. compat_props_add(m->compat_props, hw_compat_5_2, hw_compat_5_2_len);
  529. compat_props_add(m->compat_props, pc_compat_5_2, pc_compat_5_2_len);
  530. }
  531. DEFINE_I440FX_MACHINE(5, 2);
  532. static void pc_i440fx_machine_5_1_options(MachineClass *m)
  533. {
  534. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  535. pc_i440fx_machine_5_2_options(m);
  536. compat_props_add(m->compat_props, hw_compat_5_1, hw_compat_5_1_len);
  537. compat_props_add(m->compat_props, pc_compat_5_1, pc_compat_5_1_len);
  538. pcmc->kvmclock_create_always = false;
  539. pcmc->pci_root_uid = 1;
  540. }
  541. DEFINE_I440FX_MACHINE(5, 1);
  542. static void pc_i440fx_machine_5_0_options(MachineClass *m)
  543. {
  544. pc_i440fx_machine_5_1_options(m);
  545. m->numa_mem_supported = true;
  546. compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
  547. compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
  548. m->auto_enable_numa_with_memdev = false;
  549. }
  550. DEFINE_I440FX_MACHINE(5, 0);
  551. static void pc_i440fx_machine_4_2_options(MachineClass *m)
  552. {
  553. pc_i440fx_machine_5_0_options(m);
  554. compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
  555. compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len);
  556. }
  557. DEFINE_I440FX_MACHINE(4, 2);
  558. static void pc_i440fx_machine_4_1_options(MachineClass *m)
  559. {
  560. pc_i440fx_machine_4_2_options(m);
  561. compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len);
  562. compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len);
  563. }
  564. DEFINE_I440FX_MACHINE(4, 1);
  565. static void pc_i440fx_machine_4_0_options(MachineClass *m)
  566. {
  567. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  568. pc_i440fx_machine_4_1_options(m);
  569. pcmc->default_cpu_version = CPU_VERSION_LEGACY;
  570. compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
  571. compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
  572. }
  573. DEFINE_I440FX_MACHINE(4, 0);
  574. static void pc_i440fx_machine_3_1_options(MachineClass *m)
  575. {
  576. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  577. pc_i440fx_machine_4_0_options(m);
  578. m->smbus_no_migration_support = true;
  579. pcmc->pvh_enabled = false;
  580. compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
  581. compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
  582. }
  583. DEFINE_I440FX_MACHINE(3, 1);
  584. static void pc_i440fx_machine_3_0_options(MachineClass *m)
  585. {
  586. pc_i440fx_machine_3_1_options(m);
  587. compat_props_add(m->compat_props, hw_compat_3_0, hw_compat_3_0_len);
  588. compat_props_add(m->compat_props, pc_compat_3_0, pc_compat_3_0_len);
  589. }
  590. DEFINE_I440FX_MACHINE(3, 0);
  591. static void pc_i440fx_machine_2_12_options(MachineClass *m)
  592. {
  593. pc_i440fx_machine_3_0_options(m);
  594. compat_props_add(m->compat_props, hw_compat_2_12, hw_compat_2_12_len);
  595. compat_props_add(m->compat_props, pc_compat_2_12, pc_compat_2_12_len);
  596. }
  597. DEFINE_I440FX_MACHINE(2, 12);
  598. static void pc_i440fx_machine_2_11_options(MachineClass *m)
  599. {
  600. pc_i440fx_machine_2_12_options(m);
  601. compat_props_add(m->compat_props, hw_compat_2_11, hw_compat_2_11_len);
  602. compat_props_add(m->compat_props, pc_compat_2_11, pc_compat_2_11_len);
  603. }
  604. DEFINE_I440FX_MACHINE(2, 11);
  605. static void pc_i440fx_machine_2_10_options(MachineClass *m)
  606. {
  607. pc_i440fx_machine_2_11_options(m);
  608. compat_props_add(m->compat_props, hw_compat_2_10, hw_compat_2_10_len);
  609. compat_props_add(m->compat_props, pc_compat_2_10, pc_compat_2_10_len);
  610. m->auto_enable_numa_with_memhp = false;
  611. }
  612. DEFINE_I440FX_MACHINE(2, 10);
  613. static void pc_i440fx_machine_2_9_options(MachineClass *m)
  614. {
  615. pc_i440fx_machine_2_10_options(m);
  616. compat_props_add(m->compat_props, hw_compat_2_9, hw_compat_2_9_len);
  617. compat_props_add(m->compat_props, pc_compat_2_9, pc_compat_2_9_len);
  618. }
  619. DEFINE_I440FX_MACHINE(2, 9);
  620. static void pc_i440fx_machine_2_8_options(MachineClass *m)
  621. {
  622. pc_i440fx_machine_2_9_options(m);
  623. compat_props_add(m->compat_props, hw_compat_2_8, hw_compat_2_8_len);
  624. compat_props_add(m->compat_props, pc_compat_2_8, pc_compat_2_8_len);
  625. }
  626. DEFINE_I440FX_MACHINE(2, 8);
  627. static void pc_i440fx_machine_2_7_options(MachineClass *m)
  628. {
  629. pc_i440fx_machine_2_8_options(m);
  630. compat_props_add(m->compat_props, hw_compat_2_7, hw_compat_2_7_len);
  631. compat_props_add(m->compat_props, pc_compat_2_7, pc_compat_2_7_len);
  632. }
  633. DEFINE_I440FX_MACHINE(2, 7);
  634. static void pc_i440fx_machine_2_6_options(MachineClass *m)
  635. {
  636. X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
  637. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  638. pc_i440fx_machine_2_7_options(m);
  639. pcmc->legacy_cpu_hotplug = true;
  640. x86mc->fwcfg_dma_enabled = false;
  641. compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
  642. compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
  643. }
  644. DEFINE_I440FX_MACHINE(2, 6);
  645. static void pc_i440fx_machine_2_5_options(MachineClass *m)
  646. {
  647. X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
  648. pc_i440fx_machine_2_6_options(m);
  649. x86mc->save_tsc_khz = false;
  650. m->legacy_fw_cfg_order = 1;
  651. compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len);
  652. compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len);
  653. }
  654. DEFINE_I440FX_MACHINE(2, 5);
  655. static void pc_i440fx_machine_2_4_options(MachineClass *m)
  656. {
  657. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  658. pc_i440fx_machine_2_5_options(m);
  659. m->hw_version = "2.4.0";
  660. pcmc->broken_reserved_end = true;
  661. compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len);
  662. compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len);
  663. }
  664. DEFINE_I440FX_MACHINE(2, 4);
  665. #ifdef CONFIG_ISAPC
  666. static void isapc_machine_options(MachineClass *m)
  667. {
  668. PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
  669. m->desc = "ISA-only PC";
  670. m->max_cpus = 1;
  671. m->option_rom_has_mr = true;
  672. m->rom_file_has_mr = false;
  673. pcmc->pci_enabled = false;
  674. pcmc->has_acpi_build = false;
  675. pcmc->smbios_defaults = false;
  676. pcmc->gigabyte_align = false;
  677. pcmc->smbios_legacy_mode = true;
  678. pcmc->has_reserved_memory = false;
  679. m->default_nic = "ne2k_isa";
  680. m->default_cpu_type = X86_CPU_TYPE_NAME("486");
  681. m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
  682. m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
  683. }
  684. DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
  685. isapc_machine_options);
  686. #endif
  687. #ifdef CONFIG_XEN
  688. static void xenfv_machine_4_2_options(MachineClass *m)
  689. {
  690. pc_i440fx_machine_4_2_options(m);
  691. m->desc = "Xen Fully-virtualized PC";
  692. m->max_cpus = HVM_MAX_VCPUS;
  693. m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
  694. }
  695. DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
  696. xenfv_machine_4_2_options);
  697. static void xenfv_machine_3_1_options(MachineClass *m)
  698. {
  699. pc_i440fx_machine_3_1_options(m);
  700. m->desc = "Xen Fully-virtualized PC";
  701. m->alias = "xenfv";
  702. m->max_cpus = HVM_MAX_VCPUS;
  703. m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
  704. }
  705. DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
  706. xenfv_machine_3_1_options);
  707. #endif