📄 pcibus.java
字号:
int busNumber = (address >>> 16) & 0xff; if (0 != busNumber) return null; return this.devices[(address >>> 8) & 0xff]; } public void writePCIDataByte(int address, byte data) { PCIDevice device = this.validPCIDataAccess(address); if(null == device) return; if (device.configWriteByte(address & 0xff, data)) this.updateMappings(device); } public void writePCIDataWord(int address, short data) { PCIDevice device = this.validPCIDataAccess(address); if(null == device) return; if (device.configWriteWord(address & 0xff, data)) this.updateMappings(device); } public void writePCIDataLong(int address, int data) { PCIDevice device = this.validPCIDataAccess(address); if(null == device) return; if (device.configWriteLong(address & 0xff, data)) this.updateMappings(device); } public byte readPCIDataByte(int address) { PCIDevice device = this.validPCIDataAccess(address); if(null == device) return (byte)0xff; return device.configReadByte(address & 0xff); } public short readPCIDataWord(int address) { PCIDevice device = this.validPCIDataAccess(address); if (null == device) return (short)0xffff; return device.configReadWord(address & 0xff); } public int readPCIDataLong(int address) { PCIDevice device = this.validPCIDataAccess(address); if (null == device) return (int)0xffffffff; return device.configReadLong(address & 0xff); } private int getBusNumber() { return busNumber; } //Bad BIOS? These methods help initialise Bus (also useful to use unconnected bus) private static final byte[] pciIRQs = new byte[]{11, 9, 11, 9}; private int biosIOAddress; private int biosMemoryAddress; public void biosInit() { biosIOAddress = 0xc000; biosMemoryAddress = 0xf0000000; byte elcr[] = new byte[2]; /* activate IRQ mappings */ elcr[0] = 0x00; elcr[1] = 0x00; for(int i = 0; i < 4; i++) { byte irq = pciIRQs[i]; /* set to trigger level */ elcr[irq >> 3] |= (1 << (irq & 7)); /* activate irq remapping in PIIX */ this.configWriteByte(isaBridge, 0x60 + i, irq); } ioportHandler.ioPortWriteByte(0x4d0, elcr[0]); // setup io master ioportHandler.ioPortWriteByte(0x4d1, elcr[1]); // setup io slave for(int devFN = 0; devFN < 256; devFN++) { PCIDevice device = devices[devFN]; if (device != null) biosInitDevice(device); } } private final void biosInitDevice(PCIDevice device) { int deviceClass = 0xffff & configReadWord(device, PCI_CLASS_DEVICE); int vendorID = 0xffff & configReadWord(device, PCI_VENDOR_ID); int deviceID = 0xffff & configReadWord(device, PCI_DEVICE_ID); switch(deviceClass) { case 0x0101: if ((0xffff & vendorID) == 0x8086 && (0xffff & deviceID) == 0x7010) { /* PIIX3 IDE */ this.configWriteWord(device, 0x40, (short)0x8000); this.configWriteWord(device, 0x42, (short)0x8000); this.defaultIOMap(device); } else { /* IDE: we map it as in ISA mode */ this.setIORegionAddress(device, 0, 0x1f0); this.setIORegionAddress(device, 1, 0x3f4); this.setIORegionAddress(device, 2, 0x170); this.setIORegionAddress(device, 3, 0x374); } break; case 0x0300: if (vendorID != 0x1234) { this.defaultIOMap(device); break; } /* VGA: map frame buffer to default Bochs VBE address */ this.setIORegionAddress(device, 0, 0xe0000000); break; case 0x0800: /* PIC */ if (vendorID == 0x1014) { /* IBM */ if (deviceID == 0x0046 || deviceID == 0xffff) { /* MPIC & MPIC2 */ this.setIORegionAddress(device, 0, 0x80800000 + 0x00040000); } } break; case 0xff00: if (vendorID == 0x0106b && (deviceID == 0x0017 || deviceID == 0x0022)) { /* macio bridge */ this.setIORegionAddress(device, 0, 0x80800000); } break; default: this.defaultIOMap(device); break; } /* map the interrupt */ int pin = configReadByte(device, PCI_INTERRUPT_PIN); if (pin != 0) { pin = isaBridge.slotGetPIRQ(device, pin - 1); this.configWriteByte(device, PCI_INTERRUPT_LINE, pciIRQs[pin]); } } private void defaultIOMap(PCIDevice device) { IORegion[] regions = device.getIORegions(); if (regions == null) return; for (int i=0; i < regions.length; i++) { if (regions[i] == null) continue; if (regions[i] instanceof IOPortIORegion) { int paddr = biosIOAddress; paddr = (int)((paddr + regions[i].getSize() - 1) & ~(regions[i].getSize() - 1)); this.setIORegionAddress(device, regions[i].getRegionNumber(), paddr); biosIOAddress += regions[i].getSize(); } else if (regions[i] instanceof MemoryMappedIORegion) { int paddr = biosMemoryAddress; paddr = (int)((paddr + regions[i].getSize() - 1) & ~(regions[i].getSize() - 1)); this.setIORegionAddress(device, regions[i].getRegionNumber(), paddr); biosMemoryAddress += regions[i].getSize(); } } } private void configWriteByte(PCIDevice device, int address, byte data) { address |= (getBusNumber() << 16) | (device.getCurrentDevFN() << 8); writePCIDataByte(address, data); } private byte configReadByte(PCIDevice device, int address) { address |= (getBusNumber() << 16) | (device.getCurrentDevFN() << 8); return readPCIDataByte(address); } private void configWriteWord(PCIDevice device, int address, short data) { address |= (getBusNumber() << 16) | (device.getCurrentDevFN() << 8); writePCIDataWord(address, data); } private short configReadWord(PCIDevice device, int address) { address |= (getBusNumber() << 16) | (device.getCurrentDevFN() << 8); return readPCIDataWord(address); } private void configWriteLong(PCIDevice device, int address, int data) { address |= (getBusNumber() << 16) | (device.getCurrentDevFN() << 8); writePCIDataLong(address, data); } private void setIORegionAddress(PCIDevice device, int regionNumber, int address) { int offset; if (regionNumber == PCIDevice.PCI_ROM_SLOT) { offset = 0x30; } else { offset = 0x10 + regionNumber * 4; } this.configWriteLong(device, offset, address); /* enable memory mappings */ IORegion region = device.getIORegion(regionNumber); if (region == null) return; short command = configReadWord(device, PCI_COMMAND); if (region.getRegionNumber() == PCIDevice.PCI_ROM_SLOT) command |= 0x2; else if (region instanceof IOPortIORegion) command |= 0x1; else command |= 0x2; configWriteWord(device, PCI_COMMAND, (short)command); } public void reset() { isaBridge = null; ioportHandler = null; memory = null; pciIRQIndex = 0; devices = new PCIDevice[256]; pciIRQLevels = new int[4][PCI_IRQ_WORDS]; } public boolean initialised() { return ((isaBridge != null) && (ioportHandler != null) && (memory != null)); } public void timerCallback() {} public void acceptComponent(HardwareComponent component) { if (component instanceof PCIISABridge) isaBridge = (PCIISABridge)component; if ((component instanceof IOPortHandler) && component.initialised()) ioportHandler = (IOPortHandler)component; if ((component instanceof PhysicalAddressSpace) && component.initialised()) { memory = (PhysicalAddressSpace)component; } if (component instanceof VGACard) updateMappings((VGACard) component); } public boolean updated() { return updated; } public void updateComponent(HardwareComponent component) { if ((component instanceof VGACard) && component.updated()) { updateMappings((VGACard) component); updated = true; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -