|
|
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"
35: #include "sysemu.h"
36: #include "sysbus.h"
37:
38: #define MAX_IDE_BUS 2
39:
40: static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
41: static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
42: static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
43:
44: static void ioapic_init(IsaIrqState *isa_irq_state)
45: {
46: DeviceState *dev;
47: SysBusDevice *d;
48: unsigned int i;
49:
50: dev = qdev_create(NULL, "ioapic");
51: qdev_init_nofail(dev);
52: d = sysbus_from_qdev(dev);
53: sysbus_mmio_map(d, 0, 0xfec00000);
54:
55: for (i = 0; i < IOAPIC_NUM_PINS; i++) {
56: isa_irq_state->ioapic[i] = qdev_get_gpio_in(dev, i);
57: }
58: }
59:
60: /* PC hardware initialisation */
61: static void pc_init1(ram_addr_t ram_size,
62: const char *boot_device,
63: const char *kernel_filename,
64: const char *kernel_cmdline,
65: const char *initrd_filename,
66: const char *cpu_model,
67: int pci_enabled)
68: {
69: int i;
70: ram_addr_t below_4g_mem_size, above_4g_mem_size;
71: PCIBus *pci_bus;
72: PCII440FXState *i440fx_state;
73: int piix3_devfn = -1;
74: qemu_irq *cpu_irq;
75: qemu_irq *isa_irq;
76: qemu_irq *i8259;
77: qemu_irq *cmos_s3;
78: qemu_irq *smi_irq;
79: IsaIrqState *isa_irq_state;
80: DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
81: FDCtrl *floppy_controller;
82: BusState *idebus[MAX_IDE_BUS];
83: ISADevice *rtc_state;
84:
85: pc_cpus_init(cpu_model);
86:
87: vmport_init();
88:
89: /* allocate ram and load rom/bios */
90: pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
91: &below_4g_mem_size, &above_4g_mem_size);
92:
93: cpu_irq = pc_allocate_cpu_irq();
94: i8259 = i8259_init(cpu_irq[0]);
95: isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
96: isa_irq_state->i8259 = i8259;
97: if (pci_enabled) {
98: ioapic_init(isa_irq_state);
99: }
100: isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
101:
102: if (pci_enabled) {
103: pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
104: } else {
105: pci_bus = NULL;
106: isa_bus_new(NULL);
107: }
108: isa_bus_irqs(isa_irq);
109:
110: pc_register_ferr_irq(isa_reserve_irq(13));
111:
112: pc_vga_init(pci_enabled? pci_bus: NULL);
113:
114: /* init basic PC hardware */
115: pc_basic_device_init(isa_irq, &floppy_controller, &rtc_state);
116:
117: for(i = 0; i < nb_nics; i++) {
118: NICInfo *nd = &nd_table[i];
119:
120: if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
121: pc_init_ne2k_isa(nd);
122: else
123: pci_nic_init_nofail(nd, "e1000", NULL);
124: }
125:
126: if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
127: fprintf(stderr, "qemu: too many IDE bus\n");
128: exit(1);
129: }
130:
131: for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
132: hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
133: }
134:
135: if (pci_enabled) {
136: PCIDevice *dev;
137: dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
138: idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
139: idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
140: } else {
141: for(i = 0; i < MAX_IDE_BUS; i++) {
142: ISADevice *dev;
143: dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
144: hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
145: idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
146: }
147: }
148:
149: pc_audio_init(pci_enabled ? pci_bus : NULL, isa_irq);
150:
151: pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
152: idebus[0], idebus[1], floppy_controller, rtc_state);
153:
154: if (pci_enabled && usb_enabled) {
155: usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
156: }
157:
158: if (pci_enabled && acpi_enabled) {
159: uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
160: i2c_bus *smbus;
161:
162: cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
163: smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
164: /* TODO: Populate SPD eeprom data. */
165: smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
166: isa_reserve_irq(9), *cmos_s3, *smi_irq,
167: kvm_enabled());
168: for (i = 0; i < 8; i++) {
169: DeviceState *eeprom;
170: eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
171: qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
172: qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
173: qdev_init_nofail(eeprom);
174: }
175: }
176:
177: if (i440fx_state) {
178: i440fx_init_memory_mappings(i440fx_state);
179: }
180:
181: if (pci_enabled) {
182: pc_pci_device_init(pci_bus);
183: }
184: }
185:
186: static void pc_init_pci(ram_addr_t ram_size,
187: const char *boot_device,
188: const char *kernel_filename,
189: const char *kernel_cmdline,
190: const char *initrd_filename,
191: const char *cpu_model)
192: {
193: pc_init1(ram_size, boot_device,
194: kernel_filename, kernel_cmdline,
195: initrd_filename, cpu_model, 1);
196: }
197:
198: static void pc_init_isa(ram_addr_t ram_size,
199: const char *boot_device,
200: const char *kernel_filename,
201: const char *kernel_cmdline,
202: const char *initrd_filename,
203: const char *cpu_model)
204: {
205: if (cpu_model == NULL)
206: cpu_model = "486";
207: pc_init1(ram_size, boot_device,
208: kernel_filename, kernel_cmdline,
209: initrd_filename, cpu_model, 0);
210: }
211:
212: static QEMUMachine pc_machine = {
213: .name = "pc-0.13",
214: .alias = "pc",
215: .desc = "Standard PC",
216: .init = pc_init_pci,
217: .max_cpus = 255,
218: .is_default = 1,
219: };
220:
221: static QEMUMachine pc_machine_v0_12 = {
222: .name = "pc-0.12",
223: .desc = "Standard PC",
224: .init = pc_init_pci,
225: .max_cpus = 255,
226: .compat_props = (GlobalProperty[]) {
227: {
228: .driver = "virtio-serial-pci",
229: .property = "max_ports",
230: .value = stringify(1),
231: },{
232: .driver = "virtio-serial-pci",
233: .property = "vectors",
234: .value = stringify(0),
235: },
236: { /* end of list */ }
237: }
238: };
239:
240: static QEMUMachine pc_machine_v0_11 = {
241: .name = "pc-0.11",
242: .desc = "Standard PC, qemu 0.11",
243: .init = pc_init_pci,
244: .max_cpus = 255,
245: .compat_props = (GlobalProperty[]) {
246: {
247: .driver = "virtio-blk-pci",
248: .property = "vectors",
249: .value = stringify(0),
250: },{
251: .driver = "virtio-serial-pci",
252: .property = "max_ports",
253: .value = stringify(1),
254: },{
255: .driver = "virtio-serial-pci",
256: .property = "vectors",
257: .value = stringify(0),
258: },{
259: .driver = "ide-drive",
260: .property = "ver",
261: .value = "0.11",
262: },{
263: .driver = "scsi-disk",
264: .property = "ver",
265: .value = "0.11",
266: },{
267: .driver = "PCI",
268: .property = "rombar",
269: .value = stringify(0),
270: },
271: { /* end of list */ }
272: }
273: };
274:
275: static QEMUMachine pc_machine_v0_10 = {
276: .name = "pc-0.10",
277: .desc = "Standard PC, qemu 0.10",
278: .init = pc_init_pci,
279: .max_cpus = 255,
280: .compat_props = (GlobalProperty[]) {
281: {
282: .driver = "virtio-blk-pci",
283: .property = "class",
284: .value = stringify(PCI_CLASS_STORAGE_OTHER),
285: },{
286: .driver = "virtio-serial-pci",
287: .property = "class",
288: .value = stringify(PCI_CLASS_DISPLAY_OTHER),
289: },{
290: .driver = "virtio-serial-pci",
291: .property = "max_ports",
292: .value = stringify(1),
293: },{
294: .driver = "virtio-serial-pci",
295: .property = "vectors",
296: .value = stringify(0),
297: },{
298: .driver = "virtio-net-pci",
299: .property = "vectors",
300: .value = stringify(0),
301: },{
302: .driver = "virtio-blk-pci",
303: .property = "vectors",
304: .value = stringify(0),
305: },{
306: .driver = "ide-drive",
307: .property = "ver",
308: .value = "0.10",
309: },{
310: .driver = "scsi-disk",
311: .property = "ver",
312: .value = "0.10",
313: },{
314: .driver = "PCI",
315: .property = "rombar",
316: .value = stringify(0),
317: },
318: { /* end of list */ }
319: },
320: };
321:
322: static QEMUMachine isapc_machine = {
323: .name = "isapc",
324: .desc = "ISA-only PC",
325: .init = pc_init_isa,
326: .max_cpus = 1,
327: };
328:
329: static void pc_machine_init(void)
330: {
331: qemu_register_machine(&pc_machine);
332: qemu_register_machine(&pc_machine_v0_12);
333: qemu_register_machine(&pc_machine_v0_11);
334: qemu_register_machine(&pc_machine_v0_10);
335: qemu_register_machine(&isapc_machine);
336: }
337:
338: machine_init(pc_machine_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.