pc_piix.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  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 <glib.h>
  25. #include "hw.h"
  26. #include "pc.h"
  27. #include "apic.h"
  28. #include "pci.h"
  29. #include "usb-uhci.h"
  30. #include "usb-ohci.h"
  31. #include "net.h"
  32. #include "boards.h"
  33. #include "ide.h"
  34. #include "kvm.h"
  35. #include "kvmclock.h"
  36. #include "sysemu.h"
  37. #include "sysbus.h"
  38. #include "arch_init.h"
  39. #include "blockdev.h"
  40. #include "smbus.h"
  41. #include "xen.h"
  42. #include "memory.h"
  43. #include "exec-memory.h"
  44. #ifdef CONFIG_XEN
  45. # include <xen/hvm/hvm_info_table.h>
  46. #endif
  47. #define MAX_IDE_BUS 2
  48. static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
  49. static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
  50. static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
  51. static void ioapic_init(GSIState *gsi_state)
  52. {
  53. DeviceState *dev;
  54. SysBusDevice *d;
  55. unsigned int i;
  56. dev = qdev_create(NULL, "ioapic");
  57. qdev_init_nofail(dev);
  58. d = sysbus_from_qdev(dev);
  59. sysbus_mmio_map(d, 0, 0xfec00000);
  60. for (i = 0; i < IOAPIC_NUM_PINS; i++) {
  61. gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
  62. }
  63. }
  64. /* PC hardware initialisation */
  65. static void pc_init1(MemoryRegion *system_memory,
  66. MemoryRegion *system_io,
  67. ram_addr_t ram_size,
  68. const char *boot_device,
  69. const char *kernel_filename,
  70. const char *kernel_cmdline,
  71. const char *initrd_filename,
  72. const char *cpu_model,
  73. int pci_enabled,
  74. int kvmclock_enabled)
  75. {
  76. int i;
  77. ram_addr_t below_4g_mem_size, above_4g_mem_size;
  78. PCIBus *pci_bus;
  79. PCII440FXState *i440fx_state;
  80. int piix3_devfn = -1;
  81. qemu_irq *cpu_irq;
  82. qemu_irq *gsi;
  83. qemu_irq *i8259;
  84. qemu_irq *cmos_s3;
  85. qemu_irq *smi_irq;
  86. GSIState *gsi_state;
  87. DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
  88. BusState *idebus[MAX_IDE_BUS];
  89. ISADevice *rtc_state;
  90. ISADevice *floppy;
  91. MemoryRegion *ram_memory;
  92. MemoryRegion *pci_memory;
  93. MemoryRegion *rom_memory;
  94. pc_cpus_init(cpu_model);
  95. if (kvmclock_enabled) {
  96. kvmclock_create();
  97. }
  98. if (ram_size >= 0xe0000000 ) {
  99. above_4g_mem_size = ram_size - 0xe0000000;
  100. below_4g_mem_size = 0xe0000000;
  101. } else {
  102. above_4g_mem_size = 0;
  103. below_4g_mem_size = ram_size;
  104. }
  105. if (pci_enabled) {
  106. pci_memory = g_new(MemoryRegion, 1);
  107. memory_region_init(pci_memory, "pci", INT64_MAX);
  108. rom_memory = pci_memory;
  109. } else {
  110. pci_memory = NULL;
  111. rom_memory = system_memory;
  112. }
  113. /* allocate ram and load rom/bios */
  114. if (!xen_enabled()) {
  115. pc_memory_init(system_memory,
  116. kernel_filename, kernel_cmdline, initrd_filename,
  117. below_4g_mem_size, above_4g_mem_size,
  118. pci_enabled ? rom_memory : system_memory, &ram_memory);
  119. }
  120. gsi_state = g_malloc0(sizeof(*gsi_state));
  121. gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
  122. if (pci_enabled) {
  123. pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, gsi,
  124. system_memory, system_io, ram_size,
  125. below_4g_mem_size,
  126. 0x100000000ULL - below_4g_mem_size,
  127. 0x100000000ULL + above_4g_mem_size,
  128. (sizeof(target_phys_addr_t) == 4
  129. ? 0
  130. : ((uint64_t)1 << 62)),
  131. pci_memory, ram_memory);
  132. } else {
  133. pci_bus = NULL;
  134. i440fx_state = NULL;
  135. isa_bus_new(NULL, system_io);
  136. no_hpet = 1;
  137. }
  138. isa_bus_irqs(gsi);
  139. if (!xen_enabled()) {
  140. cpu_irq = pc_allocate_cpu_irq();
  141. i8259 = i8259_init(cpu_irq[0]);
  142. } else {
  143. i8259 = xen_interrupt_controller_init();
  144. }
  145. for (i = 0; i < ISA_NUM_IRQS; i++) {
  146. gsi_state->i8259_irq[i] = i8259[i];
  147. }
  148. if (pci_enabled) {
  149. ioapic_init(gsi_state);
  150. }
  151. pc_register_ferr_irq(gsi[13]);
  152. pc_vga_init(pci_enabled? pci_bus: NULL);
  153. if (xen_enabled()) {
  154. pci_create_simple(pci_bus, -1, "xen-platform");
  155. }
  156. /* init basic PC hardware */
  157. pc_basic_device_init(gsi, &rtc_state, &floppy, xen_enabled());
  158. for(i = 0; i < nb_nics; i++) {
  159. NICInfo *nd = &nd_table[i];
  160. if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
  161. pc_init_ne2k_isa(nd);
  162. else
  163. pci_nic_init_nofail(nd, "e1000", NULL);
  164. }
  165. ide_drive_get(hd, MAX_IDE_BUS);
  166. if (pci_enabled) {
  167. PCIDevice *dev;
  168. if (xen_enabled()) {
  169. dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
  170. } else {
  171. dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
  172. }
  173. idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
  174. idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
  175. } else {
  176. for(i = 0; i < MAX_IDE_BUS; i++) {
  177. ISADevice *dev;
  178. dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
  179. hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
  180. idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
  181. }
  182. }
  183. audio_init(gsi, pci_enabled ? pci_bus : NULL);
  184. pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
  185. floppy, idebus[0], idebus[1], rtc_state);
  186. if (pci_enabled && usb_enabled) {
  187. usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
  188. }
  189. if (pci_enabled && acpi_enabled) {
  190. i2c_bus *smbus;
  191. if (!xen_enabled()) {
  192. cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
  193. } else {
  194. cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1);
  195. }
  196. smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
  197. /* TODO: Populate SPD eeprom data. */
  198. smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
  199. gsi[9], *cmos_s3, *smi_irq,
  200. kvm_enabled());
  201. smbus_eeprom_init(smbus, 8, NULL, 0);
  202. }
  203. if (pci_enabled) {
  204. pc_pci_device_init(pci_bus);
  205. }
  206. }
  207. static void pc_init_pci(ram_addr_t ram_size,
  208. const char *boot_device,
  209. const char *kernel_filename,
  210. const char *kernel_cmdline,
  211. const char *initrd_filename,
  212. const char *cpu_model)
  213. {
  214. pc_init1(get_system_memory(),
  215. get_system_io(),
  216. ram_size, boot_device,
  217. kernel_filename, kernel_cmdline,
  218. initrd_filename, cpu_model, 1, 1);
  219. }
  220. static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
  221. const char *boot_device,
  222. const char *kernel_filename,
  223. const char *kernel_cmdline,
  224. const char *initrd_filename,
  225. const char *cpu_model)
  226. {
  227. pc_init1(get_system_memory(),
  228. get_system_io(),
  229. ram_size, boot_device,
  230. kernel_filename, kernel_cmdline,
  231. initrd_filename, cpu_model, 1, 0);
  232. }
  233. static void pc_init_isa(ram_addr_t ram_size,
  234. const char *boot_device,
  235. const char *kernel_filename,
  236. const char *kernel_cmdline,
  237. const char *initrd_filename,
  238. const char *cpu_model)
  239. {
  240. if (cpu_model == NULL)
  241. cpu_model = "486";
  242. pc_init1(get_system_memory(),
  243. get_system_io(),
  244. ram_size, boot_device,
  245. kernel_filename, kernel_cmdline,
  246. initrd_filename, cpu_model, 0, 1);
  247. }
  248. #ifdef CONFIG_XEN
  249. static void pc_xen_hvm_init(ram_addr_t ram_size,
  250. const char *boot_device,
  251. const char *kernel_filename,
  252. const char *kernel_cmdline,
  253. const char *initrd_filename,
  254. const char *cpu_model)
  255. {
  256. if (xen_hvm_init() != 0) {
  257. hw_error("xen hardware virtual machine initialisation failed");
  258. }
  259. pc_init_pci_no_kvmclock(ram_size, boot_device,
  260. kernel_filename, kernel_cmdline,
  261. initrd_filename, cpu_model);
  262. xen_vcpu_init();
  263. }
  264. #endif
  265. static QEMUMachine pc_machine_v1_0 = {
  266. .name = "pc-1.0",
  267. .alias = "pc",
  268. .desc = "Standard PC",
  269. .init = pc_init_pci,
  270. .max_cpus = 255,
  271. .is_default = 1,
  272. };
  273. static QEMUMachine pc_machine_v0_15 = {
  274. .name = "pc-0.15",
  275. .desc = "Standard PC",
  276. .init = pc_init_pci,
  277. .max_cpus = 255,
  278. .is_default = 1,
  279. };
  280. static QEMUMachine pc_machine_v0_14 = {
  281. .name = "pc-0.14",
  282. .desc = "Standard PC",
  283. .init = pc_init_pci,
  284. .max_cpus = 255,
  285. .compat_props = (GlobalProperty[]) {
  286. {
  287. .driver = "qxl",
  288. .property = "revision",
  289. .value = stringify(2),
  290. },{
  291. .driver = "qxl-vga",
  292. .property = "revision",
  293. .value = stringify(2),
  294. },{
  295. .driver = "virtio-blk-pci",
  296. .property = "event_idx",
  297. .value = "off",
  298. },{
  299. .driver = "virtio-serial-pci",
  300. .property = "event_idx",
  301. .value = "off",
  302. },{
  303. .driver = "virtio-net-pci",
  304. .property = "event_idx",
  305. .value = "off",
  306. },{
  307. .driver = "virtio-balloon-pci",
  308. .property = "event_idx",
  309. .value = "off",
  310. },
  311. { /* end of list */ }
  312. },
  313. };
  314. static QEMUMachine pc_machine_v0_13 = {
  315. .name = "pc-0.13",
  316. .desc = "Standard PC",
  317. .init = pc_init_pci_no_kvmclock,
  318. .max_cpus = 255,
  319. .compat_props = (GlobalProperty[]) {
  320. {
  321. .driver = "virtio-9p-pci",
  322. .property = "vectors",
  323. .value = stringify(0),
  324. },{
  325. .driver = "VGA",
  326. .property = "rombar",
  327. .value = stringify(0),
  328. },{
  329. .driver = "vmware-svga",
  330. .property = "rombar",
  331. .value = stringify(0),
  332. },{
  333. .driver = "PCI",
  334. .property = "command_serr_enable",
  335. .value = "off",
  336. },{
  337. .driver = "virtio-blk-pci",
  338. .property = "event_idx",
  339. .value = "off",
  340. },{
  341. .driver = "virtio-serial-pci",
  342. .property = "event_idx",
  343. .value = "off",
  344. },{
  345. .driver = "virtio-net-pci",
  346. .property = "event_idx",
  347. .value = "off",
  348. },{
  349. .driver = "virtio-balloon-pci",
  350. .property = "event_idx",
  351. .value = "off",
  352. },{
  353. .driver = "AC97",
  354. .property = "use_broken_id",
  355. .value = stringify(1),
  356. },
  357. { /* end of list */ }
  358. },
  359. };
  360. static QEMUMachine pc_machine_v0_12 = {
  361. .name = "pc-0.12",
  362. .desc = "Standard PC",
  363. .init = pc_init_pci_no_kvmclock,
  364. .max_cpus = 255,
  365. .compat_props = (GlobalProperty[]) {
  366. {
  367. .driver = "virtio-serial-pci",
  368. .property = "max_ports",
  369. .value = stringify(1),
  370. },{
  371. .driver = "virtio-serial-pci",
  372. .property = "vectors",
  373. .value = stringify(0),
  374. },{
  375. .driver = "VGA",
  376. .property = "rombar",
  377. .value = stringify(0),
  378. },{
  379. .driver = "vmware-svga",
  380. .property = "rombar",
  381. .value = stringify(0),
  382. },{
  383. .driver = "PCI",
  384. .property = "command_serr_enable",
  385. .value = "off",
  386. },{
  387. .driver = "virtio-blk-pci",
  388. .property = "event_idx",
  389. .value = "off",
  390. },{
  391. .driver = "virtio-serial-pci",
  392. .property = "event_idx",
  393. .value = "off",
  394. },{
  395. .driver = "virtio-net-pci",
  396. .property = "event_idx",
  397. .value = "off",
  398. },{
  399. .driver = "virtio-balloon-pci",
  400. .property = "event_idx",
  401. .value = "off",
  402. },{
  403. .driver = "AC97",
  404. .property = "use_broken_id",
  405. .value = stringify(1),
  406. },
  407. { /* end of list */ }
  408. }
  409. };
  410. static QEMUMachine pc_machine_v0_11 = {
  411. .name = "pc-0.11",
  412. .desc = "Standard PC, qemu 0.11",
  413. .init = pc_init_pci_no_kvmclock,
  414. .max_cpus = 255,
  415. .compat_props = (GlobalProperty[]) {
  416. {
  417. .driver = "virtio-blk-pci",
  418. .property = "vectors",
  419. .value = stringify(0),
  420. },{
  421. .driver = "virtio-serial-pci",
  422. .property = "max_ports",
  423. .value = stringify(1),
  424. },{
  425. .driver = "virtio-serial-pci",
  426. .property = "vectors",
  427. .value = stringify(0),
  428. },{
  429. .driver = "ide-drive",
  430. .property = "ver",
  431. .value = "0.11",
  432. },{
  433. .driver = "scsi-disk",
  434. .property = "ver",
  435. .value = "0.11",
  436. },{
  437. .driver = "PCI",
  438. .property = "rombar",
  439. .value = stringify(0),
  440. },{
  441. .driver = "PCI",
  442. .property = "command_serr_enable",
  443. .value = "off",
  444. },{
  445. .driver = "virtio-blk-pci",
  446. .property = "event_idx",
  447. .value = "off",
  448. },{
  449. .driver = "virtio-serial-pci",
  450. .property = "event_idx",
  451. .value = "off",
  452. },{
  453. .driver = "virtio-net-pci",
  454. .property = "event_idx",
  455. .value = "off",
  456. },{
  457. .driver = "virtio-balloon-pci",
  458. .property = "event_idx",
  459. .value = "off",
  460. },{
  461. .driver = "AC97",
  462. .property = "use_broken_id",
  463. .value = stringify(1),
  464. },
  465. { /* end of list */ }
  466. }
  467. };
  468. static QEMUMachine pc_machine_v0_10 = {
  469. .name = "pc-0.10",
  470. .desc = "Standard PC, qemu 0.10",
  471. .init = pc_init_pci_no_kvmclock,
  472. .max_cpus = 255,
  473. .compat_props = (GlobalProperty[]) {
  474. {
  475. .driver = "virtio-blk-pci",
  476. .property = "class",
  477. .value = stringify(PCI_CLASS_STORAGE_OTHER),
  478. },{
  479. .driver = "virtio-serial-pci",
  480. .property = "class",
  481. .value = stringify(PCI_CLASS_DISPLAY_OTHER),
  482. },{
  483. .driver = "virtio-serial-pci",
  484. .property = "max_ports",
  485. .value = stringify(1),
  486. },{
  487. .driver = "virtio-serial-pci",
  488. .property = "vectors",
  489. .value = stringify(0),
  490. },{
  491. .driver = "virtio-net-pci",
  492. .property = "vectors",
  493. .value = stringify(0),
  494. },{
  495. .driver = "virtio-blk-pci",
  496. .property = "vectors",
  497. .value = stringify(0),
  498. },{
  499. .driver = "ide-drive",
  500. .property = "ver",
  501. .value = "0.10",
  502. },{
  503. .driver = "scsi-disk",
  504. .property = "ver",
  505. .value = "0.10",
  506. },{
  507. .driver = "PCI",
  508. .property = "rombar",
  509. .value = stringify(0),
  510. },{
  511. .driver = "PCI",
  512. .property = "command_serr_enable",
  513. .value = "off",
  514. },{
  515. .driver = "virtio-blk-pci",
  516. .property = "event_idx",
  517. .value = "off",
  518. },{
  519. .driver = "virtio-serial-pci",
  520. .property = "event_idx",
  521. .value = "off",
  522. },{
  523. .driver = "virtio-net-pci",
  524. .property = "event_idx",
  525. .value = "off",
  526. },{
  527. .driver = "virtio-balloon-pci",
  528. .property = "event_idx",
  529. .value = "off",
  530. },{
  531. .driver = "AC97",
  532. .property = "use_broken_id",
  533. .value = stringify(1),
  534. },
  535. { /* end of list */ }
  536. },
  537. };
  538. static QEMUMachine isapc_machine = {
  539. .name = "isapc",
  540. .desc = "ISA-only PC",
  541. .init = pc_init_isa,
  542. .max_cpus = 1,
  543. };
  544. #ifdef CONFIG_XEN
  545. static QEMUMachine xenfv_machine = {
  546. .name = "xenfv",
  547. .desc = "Xen Fully-virtualized PC",
  548. .init = pc_xen_hvm_init,
  549. .max_cpus = HVM_MAX_VCPUS,
  550. .default_machine_opts = "accel=xen",
  551. };
  552. #endif
  553. static void pc_machine_init(void)
  554. {
  555. qemu_register_machine(&pc_machine_v1_0);
  556. qemu_register_machine(&pc_machine_v0_15);
  557. qemu_register_machine(&pc_machine_v0_14);
  558. qemu_register_machine(&pc_machine_v0_13);
  559. qemu_register_machine(&pc_machine_v0_12);
  560. qemu_register_machine(&pc_machine_v0_11);
  561. qemu_register_machine(&pc_machine_v0_10);
  562. qemu_register_machine(&isapc_machine);
  563. #ifdef CONFIG_XEN
  564. qemu_register_machine(&xenfv_machine);
  565. #endif
  566. }
  567. machine_init(pc_machine_init);