Annotation of qemu/hw/pc_piix.c, revision 1.1.1.4

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);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.