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