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

📄 fix-interrupt-routing

📁 xen虚拟机源代码安装包
💻
📖 第 1 页 / 共 2 页
字号:
+    if (version_id != 2)+        return -EINVAL;+    return pci_device_load(d, f);+}++int piix3_init(PCIBus *bus, int devfn)+{+    PCIDevice *d;+    uint8_t *pci_conf;++    d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),+                                    devfn, NULL, piix3_write_config);+    register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);++    piix3_dev = d;+    pci_conf = d->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);+    return d->devfn;+}++/***********************************************************/+/* 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 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] = { 10, 11, 10, 11 };++static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)+{+    PCIBus *s = d->bus;+    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);+    pci_data_write(s, addr, val, 4);+}++static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)+{+    PCIBus *s = d->bus;+    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);+    pci_data_write(s, addr, val, 2);+}++static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)+{+    PCIBus *s = d->bus;+    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);+    pci_data_write(s, addr, val, 1);+}++static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)+{+    PCIBus *s = d->bus;+    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);+    return pci_data_read(s, addr, 4);+}++static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)+{+    PCIBus *s = d->bus;+    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);+    return pci_data_read(s, addr, 2);+}++static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)+{+    PCIBus *s = d->bus;+    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);+    return pci_data_read(s, addr, 1);+}++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 0x0680:+        if (vendor_id == 0x8086 && device_id == 0x7113) {+            /*+             * PIIX4 ACPI PM.+             * Special device with special PCI config space. No ordinary BARs.+             */+            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable+            pci_config_writew(d, 0x22, 0x0000);+            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9+            pci_config_writew(d, 0x3d, 0x0001);+        }+        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)+{+    int i, irq;+    uint8_t elcr[2];++    pci_bios_io_addr = 0xc000;+    pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;++    /* 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(piix3_dev, 0x60 + i, irq);+    }+    isa_outb(elcr[0], 0x4d0);+    isa_outb(elcr[1], 0x4d1);++    pci_for_each_device(pci_bios_init_device);+}+

⌨️ 快捷键说明

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