⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{    PCIBus *s = opaque;    pci_data_write(s, addr & 7, val, 2);}static void pci_apb_writel (void *opaque, target_phys_addr_t addr,                                uint32_t val){    PCIBus *s = opaque;    pci_data_write(s, addr & 7, val, 4);}static uint32_t pci_apb_readb (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = pci_data_read(s, addr & 7, 1);    return val;}static uint32_t pci_apb_readw (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = pci_data_read(s, addr & 7, 2);    return val;}static uint32_t pci_apb_readl (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = pci_data_read(s, addr, 4);    return val;}static CPUWriteMemoryFunc *pci_apb_write[] = {    &pci_apb_writeb,    &pci_apb_writew,    &pci_apb_writel,};static CPUReadMemoryFunc *pci_apb_read[] = {    &pci_apb_readb,    &pci_apb_readw,    &pci_apb_readl,};static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,                                  uint32_t val){    cpu_outb(NULL, addr & 0xffff, val);}static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,                                  uint32_t val){    cpu_outw(NULL, addr & 0xffff, val);}static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,                                uint32_t val){    cpu_outl(NULL, addr & 0xffff, val);}static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr){    uint32_t val;    val = cpu_inb(NULL, addr & 0xffff);    return val;}static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr){    uint32_t val;    val = cpu_inw(NULL, addr & 0xffff);    return val;}static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr){    uint32_t val;    val = cpu_inl(NULL, addr & 0xffff);    return val;}static CPUWriteMemoryFunc *pci_apb_iowrite[] = {    &pci_apb_iowriteb,    &pci_apb_iowritew,    &pci_apb_iowritel,};static CPUReadMemoryFunc *pci_apb_ioread[] = {    &pci_apb_ioreadb,    &pci_apb_ioreadw,    &pci_apb_ioreadl,};PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base){    PCIBus *s;    PCIDevice *d;    int pci_mem_config, pci_mem_data, apb_config, pci_ioport;    /* Ultrasparc APB main bus */    s = pci_register_bus();    s->set_irq = pci_set_irq_simple;    pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,                                            pci_apb_config_write, s);    apb_config = cpu_register_io_memory(0, apb_config_read,					apb_config_write, s);    pci_mem_data = cpu_register_io_memory(0, pci_apb_read,                                          pci_apb_write, s);    pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,                                          pci_apb_iowrite, s);    cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);    cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);    cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);    cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom    d = pci_register_device(s, "Advanced PCI Bus", sizeof(PCIDevice),                             -1, NULL, NULL);    d->config[0x00] = 0x8e; // vendor_id : Sun    d->config[0x01] = 0x10;    d->config[0x02] = 0x00; // device_id    d->config[0x03] = 0xa0;    d->config[0x04] = 0x06; // command = bus master, pci mem    d->config[0x05] = 0x00;    d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error    d->config[0x07] = 0x03; // status = medium devsel    d->config[0x08] = 0x00; // revision    d->config[0x09] = 0x00; // programming i/f    d->config[0x0A] = 0x00; // class_sub = pci host    d->config[0x0B] = 0x06; // class_base = PCI_bridge    d->config[0x0D] = 0x10; // latency_timer    d->config[0x0E] = 0x00; // header_type    return s;}/***********************************************************//* generic PCI irq support *//* 0 <= irq_num <= 3. level must be 0 or 1 */void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level){    PCIBus *bus = pci_dev->bus;    bus->set_irq(pci_dev, irq_num, level);}/***********************************************************//* monitor info on PCI */static void pci_info_device(PCIDevice *d){    int i, class;    PCIIORegion *r;    term_printf("  Bus %2d, device %3d, function %d:\n",           d->bus->bus_num, d->devfn >> 3, d->devfn & 7);    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));    term_printf("    ");    switch(class) {    case 0x0101:        term_printf("IDE controller");        break;    case 0x0200:        term_printf("Ethernet controller");        break;    case 0x0300:        term_printf("VGA controller");        break;    default:        term_printf("Class %04x", class);        break;    }    term_printf(": PCI device %04x:%04x\n",           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));    if (d->config[PCI_INTERRUPT_PIN] != 0) {        term_printf("      IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);    }    for(i = 0;i < PCI_NUM_REGIONS; i++) {        r = &d->io_regions[i];        if (r->size != 0) {            term_printf("      BAR%d: ", i);            if (r->type & PCI_ADDRESS_SPACE_IO) {                term_printf("I/O at 0x%04x [0x%04x].\n",                        r->addr, r->addr + r->size - 1);            } else {                term_printf("32 bit memory at 0x%08x [0x%08x].\n",                        r->addr, r->addr + r->size - 1);            }        }    }}void pci_info(void){    PCIBus *bus = first_bus;    PCIDevice *d;    int devfn;        if (bus) {        for(devfn = 0; devfn < 256; devfn++) {            d = bus->devices[devfn];            if (d)                pci_info_device(d);        }    }}/***********************************************************//* XXX: the following should be moved to the PC BIOS */static __attribute__((unused)) uint32_t isa_inb(uint32_t addr){    return cpu_inb(NULL, addr);}static void isa_outb(uint32_t val, uint32_t addr){    cpu_outb(NULL, addr, val);}static __attribute__((unused)) uint32_t isa_inw(uint32_t addr){    return cpu_inw(NULL, addr);}static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr){    cpu_outw(NULL, addr, val);}static __attribute__((unused)) uint32_t isa_inl(uint32_t addr){    return cpu_inl(NULL, addr);}static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr){    cpu_outl(NULL, addr, val);}static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val){    PCIBus *s = d->bus;    s->config_reg = 0x80000000 | (s->bus_num << 16) |         (d->devfn << 8) | addr;    pci_data_write(s, 0, val, 4);}static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val){    PCIBus *s = d->bus;    s->config_reg = 0x80000000 | (s->bus_num << 16) |         (d->devfn << 8) | (addr & ~3);    pci_data_write(s, addr & 3, val, 2);}static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val){    PCIBus *s = d->bus;    s->config_reg = 0x80000000 | (s->bus_num << 16) |         (d->devfn << 8) | (addr & ~3);    pci_data_write(s, addr & 3, val, 1);}static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr){    PCIBus *s = d->bus;    s->config_reg = 0x80000000 | (s->bus_num << 16) |         (d->devfn << 8) | addr;    return pci_data_read(s, 0, 4);}static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr){    PCIBus *s = d->bus;    s->config_reg = 0x80000000 | (s->bus_num << 16) |         (d->devfn << 8) | (addr & ~3);    return pci_data_read(s, addr & 3, 2);}static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr){    PCIBus *s = d->bus;    s->config_reg = 0x80000000 | (s->bus_num << 16) |         (d->devfn << 8) | (addr & ~3);    return pci_data_read(s, addr & 3, 1);}static uint32_t pci_bios_io_addr;static uint32_t pci_bios_mem_addr;/* host irqs corresponding to PCI irqs A-D */static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr){    PCIIORegion *r;    uint16_t cmd;    uint32_t ofs;    if ( region_num == PCI_ROM_SLOT ) {        ofs = 0x30;    }else{        ofs = 0x10 + region_num * 4;    }    pci_config_writel(d, ofs, addr);    r = &d->io_regions[region_num];    /* enable memory mappings */    cmd = pci_config_readw(d, PCI_COMMAND);    if ( region_num == PCI_ROM_SLOT )        cmd |= 2;    else if (r->type & PCI_ADDRESS_SPACE_IO)        cmd |= 1;    else        cmd |= 2;    pci_config_writew(d, PCI_COMMAND, cmd);}static void pci_bios_init_device(PCIDevice *d){    int class;    PCIIORegion *r;    uint32_t *paddr;    int i, pin, pic_irq, vendor_id, device_id;    class = pci_config_readw(d, PCI_CLASS_DEVICE);    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);    device_id = pci_config_readw(d, PCI_DEVICE_ID);    switch(class) {    case 0x0101:        if (vendor_id == 0x8086 && device_id == 0x7010) {            /* PIIX3 IDE */            pci_config_writew(d, 0x40, 0x8000); // enable IDE0            pci_config_writew(d, 0x42, 0x8000); // enable IDE1            goto default_map;        } else {            /* IDE: we map it as in ISA mode */            pci_set_io_region_addr(d, 0, 0x1f0);            pci_set_io_region_addr(d, 1, 0x3f4);            pci_set_io_region_addr(d, 2, 0x170);            pci_set_io_region_addr(d, 3, 0x374);        }        break;    case 0x0300:        if (vendor_id != 0x1234)            goto default_map;        /* VGA: map frame buffer to default Bochs VBE address */        pci_set_io_region_addr(d, 0, 0xE0000000);        break;    case 0x0800:        /* PIC */        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);        device_id = pci_config_readw(d, PCI_DEVICE_ID);        if (vendor_id == 0x1014) {            /* IBM */            if (device_id == 0x0046 || device_id == 0xFFFF) {                /* MPIC & MPIC2 */                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);            }        }        break;    case 0xff00:        if (vendor_id == 0x0106b &&            (device_id == 0x0017 || device_id == 0x0022)) {            /* macio bridge */            pci_set_io_region_addr(d, 0, 0x80800000);        }        break;    default:    default_map:        /* default memory mappings */        for(i = 0; i < PCI_NUM_REGIONS; i++) {            r = &d->io_regions[i];            if (r->size) {                if (r->type & PCI_ADDRESS_SPACE_IO)                    paddr = &pci_bios_io_addr;                else                    paddr = &pci_bios_mem_addr;                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);                pci_set_io_region_addr(d, i, *paddr);                *paddr += r->size;            }        }        break;    }    /* map the interrupt */    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);    if (pin != 0) {        pin = pci_slot_get_pirq(d, pin - 1);        pic_irq = pci_irqs[pin];        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);    }}/* * This function initializes the PCI devices as a normal PCI BIOS * would do. It is provided just in case the BIOS has no support for * PCI. */void pci_bios_init(void){    PCIBus *bus;    PCIDevice *d;    int devfn, i, irq;    uint8_t elcr[2];    pci_bios_io_addr = 0xc000;    pci_bios_mem_addr = 0xf0000000;    /* activate IRQ mappings */    elcr[0] = 0x00;    elcr[1] = 0x00;    for(i = 0; i < 4; i++) {        irq = pci_irqs[i];        /* set to trigger level */        elcr[irq >> 3] |= (1 << (irq & 7));        /* activate irq remapping in PIIX */        pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);    }    isa_outb(elcr[0], 0x4d0);    isa_outb(elcr[1], 0x4d1);    bus = first_bus;    if (bus) {        for(devfn = 0; devfn < 256; devfn++) {            d = bus->devices[devfn];            if (d)                pci_bios_init_device(d);        }    }}/* Initialize a PCI NIC.  */void pci_nic_init(PCIBus *bus, NICInfo *nd){    if (strcmp(nd->model, "ne2k_pci") == 0) {        pci_ne2000_init(bus, nd);    } else if (strcmp(nd->model, "rtl8139") == 0) {        pci_rtl8139_init(bus, nd);    } else {        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);        exit (1);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -