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

📄 pci.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);    d = pci_register_device(s, "i440FX", sizeof(PCIDevice), 0,                             NULL, NULL);    d->config[0x00] = 0x86; // vendor_id    d->config[0x01] = 0x80;    d->config[0x02] = 0x37; // device_id    d->config[0x03] = 0x12;    d->config[0x08] = 0x02; // revision    d->config[0x0a] = 0x00; // class_sub = host2pci    d->config[0x0b] = 0x06; // class_base = PCI_bridge    d->config[0x0e] = 0x00; // header_type    return s;}/* PIIX3 PCI to ISA bridge */typedef struct PIIX3State {    PCIDevice dev;} PIIX3State;PIIX3State *piix3_state;/* return the global irq number corresponding to a given device irq   pin. We could also use the bus number to have a more precise   mapping. */static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num){    int slot_addend;    slot_addend = (pci_dev->devfn >> 3) - 1;    return (irq_num + slot_addend) & 3;}static inline int get_pci_irq_level(int irq_num){    int pic_level;#if (PCI_IRQ_WORDS == 2)    pic_level = ((pci_irq_levels[irq_num][0] |                   pci_irq_levels[irq_num][1]) != 0);#else    {        int i;        pic_level = 0;        for(i = 0; i < PCI_IRQ_WORDS; i++) {            if (pci_irq_levels[irq_num][i]) {                pic_level = 1;                break;            }        }    }#endif    return pic_level;}static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level){    int irq_index, shift, pic_irq, pic_level;    uint32_t *p;    irq_num = pci_slot_get_pirq(pci_dev, irq_num);    irq_index = pci_dev->irq_index;    p = &pci_irq_levels[irq_num][irq_index >> 5];    shift = (irq_index & 0x1f);    *p = (*p & ~(1 << shift)) | (level << shift);    /* now we change the pic irq level according to the piix irq mappings */    /* XXX: optimize */    pic_irq = piix3_state->dev.config[0x60 + irq_num];    if (pic_irq < 16) {        /* the pic level is the logical OR of all the PCI irqs mapped           to it */        pic_level = 0;        if (pic_irq == piix3_state->dev.config[0x60])            pic_level |= get_pci_irq_level(0);        if (pic_irq == piix3_state->dev.config[0x61])            pic_level |= get_pci_irq_level(1);        if (pic_irq == piix3_state->dev.config[0x62])            pic_level |= get_pci_irq_level(2);        if (pic_irq == piix3_state->dev.config[0x63])            pic_level |= get_pci_irq_level(3);        pic_set_irq(pic_irq, pic_level);    }}static void piix3_reset(PIIX3State *d){    uint8_t *pci_conf = d->dev.config;    pci_conf[0x04] = 0x07; // master, memory and I/O    pci_conf[0x05] = 0x00;    pci_conf[0x06] = 0x00;    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium    pci_conf[0x4c] = 0x4d;    pci_conf[0x4e] = 0x03;    pci_conf[0x4f] = 0x00;    pci_conf[0x60] = 0x80;    pci_conf[0x69] = 0x02;    pci_conf[0x70] = 0x80;    pci_conf[0x76] = 0x0c;    pci_conf[0x77] = 0x0c;    pci_conf[0x78] = 0x02;    pci_conf[0x79] = 0x00;    pci_conf[0x80] = 0x00;    pci_conf[0x82] = 0x00;    pci_conf[0xa0] = 0x08;    pci_conf[0xa0] = 0x08;    pci_conf[0xa2] = 0x00;    pci_conf[0xa3] = 0x00;    pci_conf[0xa4] = 0x00;    pci_conf[0xa5] = 0x00;    pci_conf[0xa6] = 0x00;    pci_conf[0xa7] = 0x00;    pci_conf[0xa8] = 0x0f;    pci_conf[0xaa] = 0x00;    pci_conf[0xab] = 0x00;    pci_conf[0xac] = 0x00;    pci_conf[0xae] = 0x00;}void piix3_init(PCIBus *bus){    PIIX3State *d;    uint8_t *pci_conf;    d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),                                          -1, NULL, NULL);    register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);    piix3_state = d;    pci_conf = d->dev.config;    pci_conf[0x00] = 0x86; // Intel    pci_conf[0x01] = 0x80;    pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)    pci_conf[0x03] = 0x70;    pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA    pci_conf[0x0b] = 0x06; // class_base = PCI_bridge    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic    piix3_reset(d);}/* PREP pci init */static inline void set_config(PCIBus *s, target_phys_addr_t addr){    int devfn, i;    for(i = 0; i < 11; i++) {        if ((addr & (1 << (11 + i))) != 0)            break;    }    devfn = ((addr >> 8) & 7) | (i << 3);    s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);}static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val){    PCIBus *s = opaque;    set_config(s, addr);    pci_data_write(s, addr, val, 1);}static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val){    PCIBus *s = opaque;    set_config(s, addr);#ifdef TARGET_WORDS_BIGENDIAN    val = bswap16(val);#endif    pci_data_write(s, addr, val, 2);}static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val){    PCIBus *s = opaque;    set_config(s, addr);#ifdef TARGET_WORDS_BIGENDIAN    val = bswap32(val);#endif    pci_data_write(s, addr, val, 4);}static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    set_config(s, addr);    val = pci_data_read(s, addr, 1);    return val;}static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    set_config(s, addr);    val = pci_data_read(s, addr, 2);#ifdef TARGET_WORDS_BIGENDIAN    val = bswap16(val);#endif    return val;}static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    set_config(s, addr);    val = pci_data_read(s, addr, 4);#ifdef TARGET_WORDS_BIGENDIAN    val = bswap32(val);#endif    return val;}static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {    &PPC_PCIIO_writeb,    &PPC_PCIIO_writew,    &PPC_PCIIO_writel,};static CPUReadMemoryFunc *PPC_PCIIO_read[] = {    &PPC_PCIIO_readb,    &PPC_PCIIO_readw,    &PPC_PCIIO_readl,};static void prep_set_irq(PCIDevice *d, int irq_num, int level){    /* XXX: we do not simulate the hardware - we rely on the BIOS to       set correctly for irq line field */    pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);}PCIBus *pci_prep_init(void){    PCIBus *s;    PCIDevice *d;    int PPC_io_memory;    s = pci_register_bus();    s->set_irq = prep_set_irq;    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);    PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,                                            PPC_PCIIO_write, s);    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);    /* PCI host bridge */     d = pci_register_device(s, "PREP Host Bridge - Motorola Raven",                             sizeof(PCIDevice), 0, NULL, NULL);    d->config[0x00] = 0x57; // vendor_id : Motorola    d->config[0x01] = 0x10;    d->config[0x02] = 0x01; // device_id : Raven    d->config[0x03] = 0x48;    d->config[0x08] = 0x00; // revision    d->config[0x0A] = 0x00; // class_sub = pci host    d->config[0x0B] = 0x06; // class_base = PCI_bridge    d->config[0x0C] = 0x08; // cache_line_size    d->config[0x0D] = 0x10; // latency_timer    d->config[0x0E] = 0x00; // header_type    d->config[0x34] = 0x00; // capabilities_pointer    return s;}/* Grackle PCI host */static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,                                       uint32_t val){    PCIBus *s = opaque;#ifdef TARGET_WORDS_BIGENDIAN    val = bswap32(val);#endif    s->config_reg = val;}static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = s->config_reg;#ifdef TARGET_WORDS_BIGENDIAN    val = bswap32(val);#endif    return val;}static CPUWriteMemoryFunc *pci_grackle_config_write[] = {    &pci_grackle_config_writel,    &pci_grackle_config_writel,    &pci_grackle_config_writel,};static CPUReadMemoryFunc *pci_grackle_config_read[] = {    &pci_grackle_config_readl,    &pci_grackle_config_readl,    &pci_grackle_config_readl,};static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,                                uint32_t val){    PCIBus *s = opaque;    pci_data_write(s, addr, val, 1);}static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,                                uint32_t val){    PCIBus *s = opaque;#ifdef TARGET_WORDS_BIGENDIAN    val = bswap16(val);#endif    pci_data_write(s, addr, val, 2);}static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,                                uint32_t val){    PCIBus *s = opaque;#ifdef TARGET_WORDS_BIGENDIAN    val = bswap32(val);#endif    pci_data_write(s, addr, val, 4);}static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = pci_data_read(s, addr, 1);    return val;}static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = pci_data_read(s, addr, 2);#ifdef TARGET_WORDS_BIGENDIAN    val = bswap16(val);#endif    return val;}static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr){    PCIBus *s = opaque;    uint32_t val;    val = pci_data_read(s, addr, 4);#ifdef TARGET_WORDS_BIGENDIAN    val = bswap32(val);#endif    return val;}static CPUWriteMemoryFunc *pci_grackle_write[] = {    &pci_grackle_writeb,    &pci_grackle_writew,    &pci_grackle_writel,};static CPUReadMemoryFunc *pci_grackle_read[] = {    &pci_grackle_readb,    &pci_grackle_readw,    &pci_grackle_readl,};void pci_set_pic(PCIBus *bus, SetIRQFunc *set_irq, void *irq_opaque){    bus->low_set_irq = set_irq;    bus->irq_opaque = irq_opaque;}/* XXX: we do not simulate the hardware - we rely on the BIOS to   set correctly for irq line field */static void pci_set_irq_simple(PCIDevice *d, int irq_num, int level){    PCIBus *s = d->bus;    s->low_set_irq(s->irq_opaque, d->config[PCI_INTERRUPT_LINE], level);}PCIBus *pci_grackle_init(uint32_t base){    PCIBus *s;    PCIDevice *d;    int pci_mem_config, pci_mem_data;    s = pci_register_bus();    s->set_irq = pci_set_irq_simple;    pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,                                             pci_grackle_config_write, s);    pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,                                          pci_grackle_write, s);    cpu_register_physical_memory(base, 0x1000, pci_mem_config);    cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);    d = pci_register_device(s, "Grackle host bridge", sizeof(PCIDevice),                             0, NULL, NULL);    d->config[0x00] = 0x57; // vendor_id    d->config[0x01] = 0x10;    d->config[0x02] = 0x02; // device_id    d->config[0x03] = 0x00;    d->config[0x08] = 0x00; // revision    d->config[0x09] = 0x01;    d->config[0x0a] = 0x00; // class_sub = host    d->config[0x0b] = 0x06; // class_base = PCI_bridge    d->config[0x0e] = 0x00; // header_type    d->config[0x18] = 0x00;  // primary_bus    d->config[0x19] = 0x01;  // secondary_bus    d->config[0x1a] = 0x00;  // subordinate_bus    d->config[0x1c] = 0x00;    d->config[0x1d] = 0x00;        d->config[0x20] = 0x00; // memory_base    d->config[0x21] = 0x00;    d->config[0x22] = 0x01; // memory_limit    d->config[0x23] = 0x00;        d->config[0x24] = 0x00; // prefetchable_memory_base    d->config[0x25] = 0x00;    d->config[0x26] = 0x00; // prefetchable_memory_limit    d->config[0x27] = 0x00;#if 0    /* PCI2PCI bridge same values as PearPC - check this */    d->config[0x00] = 0x11; // vendor_id    d->config[0x01] = 0x10;    d->config[0x02] = 0x26; // device_id    d->config[0x03] = 0x00;    d->config[0x08] = 0x02; // revision    d->config[0x0a] = 0x04; // class_sub = pci2pci    d->config[0x0b] = 0x06; // class_base = PCI_bridge    d->config[0x0e] = 0x01; // header_type    d->config[0x18] = 0x0;  // primary_bus    d->config[0x19] = 0x1;  // secondary_bus    d->config[0x1a] = 0x1;  // subordinate_bus    d->config[0x1c] = 0x10; // io_base    d->config[0x1d] = 0x20; // io_limit        d->config[0x20] = 0x80; // memory_base

⌨️ 快捷键说明

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