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

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

unix.superglobalmegacorp.com

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