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

📄 pcibus.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License along    with this program; if not, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.pci;import org.jpc.emulator.motherboard.*;import org.jpc.emulator.memory.*;import org.jpc.emulator.pci.peripheral.*;import org.jpc.emulator.*;import java.io.*;public class PCIBus implements HardwareComponent{    private int busNumber;    private int devFNMinimum;    private boolean updated;    //openpic_t openpic; // Neccessary?    private PCIDevice devices[];    private PCIISABridge isaBridge;    private IOPortHandler ioportHandler;    private PhysicalAddressSpace memory;    //pci_mem_base?    private int pciIRQIndex;    private int pciIRQLevels[][];    public static final int PCI_COMMAND = 0x04;    final static private int PCI_VENDOR_ID = 0x00;    final static private int PCI_DEVICE_ID = 0x02;    final static private int PCI_COMMAND_IO = 0x1;    final static private int PCI_COMMAND_MEMORY = 0x2;    final static private int PCI_CLASS_DEVICE = 0x0a;    final static private int PCI_INTERRUPT_LINE = 0x3c;    final static private int PCI_INTERRUPT_PIN = 0x3d;    final static private int PCI_MIN_GNT = 0x3e;    final static private int PCI_MAX_LAT = 0x3f;    final static private int PCI_DEVICES_MAX = 64;    public static final int PCI_IRQ_WORDS = ((PCI_DEVICES_MAX + 31) / 32);    public PCIBus()    {	busNumber = 0;        pciIRQIndex = 0;	devices = new PCIDevice[256];	pciIRQLevels = new int[4][PCI_IRQ_WORDS];	devFNMinimum = 8;    }    public void dumpState(DataOutput output) throws IOException    {        output.writeInt(busNumber);        output.writeInt(devFNMinimum);        output.writeInt(pciIRQIndex);        output.writeInt(pciIRQLevels.length);        output.writeInt(pciIRQLevels[0].length);        for (int i=0; i < pciIRQLevels.length; i++)            for (int j=0; j < pciIRQLevels[0].length; j++)                output.writeInt(pciIRQLevels[i][j]);        output.writeInt(biosIOAddress);        output.writeInt(biosMemoryAddress);    }    public void loadState(DataInput input) throws IOException    {        updated = false;	devices = new PCIDevice[256];        busNumber  = input.readInt();        devFNMinimum  = input.readInt();        pciIRQIndex  = input.readInt();        int len1  = input.readInt();        int len2 = input.readInt();        pciIRQLevels = new int[len1][len2];        for (int i=0; i < pciIRQLevels.length; i++)            for (int j=0; j < pciIRQLevels[0].length; j++)                pciIRQLevels[i][j] = input.readInt();        biosIOAddress = input.readInt();        biosMemoryAddress = input.readInt();    }    public boolean registerDevice(PCIDevice device)    {	if (pciIRQIndex >= PCI_DEVICES_MAX) {	    return false;	}	/*	if (device instanceof PCIISABridge)	    devFNMinimum = 8;	else	    devFNMinimum = 16;	*/	if (device.autoAssignDevFN()) {	    int devFN = findFreeDevFN();	    if (0 <= devFN) {		device.assignDevFN(devFN);	    }	} else {	    PCIDevice oldDevice = devices[device.getCurrentDevFN()];	    if (oldDevice != null) {		System.err.println("Trying to temporarily unregister a pci device, this may not work.");		oldDevice.deassignDevFN();	    }	}	device.setIRQIndex(pciIRQIndex++);	this.addDevice(device);	IRQBouncer bouncer = isaBridge.makeBouncer(device);	device.addIRQBouncer(bouncer);	return this.registerPCIIORegions(device);    }    private int findFreeDevFN()    {	    for(int i = devFNMinimum; i < 256; i += 8) {		if (null == devices[i])		    return i;	    }	    return -1;    }    private boolean registerPCIIORegions(PCIDevice device)    {	IORegion[] regions = device.getIORegions();	if (regions == null) return true;	boolean ret = true;	for (int i = 0; i < regions.length; i++) {	    IORegion region = regions[i];	    if (PCIDevice.PCI_NUM_REGIONS <= region.getRegionNumber()) {		ret = false;		continue;	    }	    region.setAddress(-1);	    if (region.getRegionNumber() == PCIDevice.PCI_ROM_SLOT)		device.putConfigInt(0x30, region.getType());	    else		device.putConfigInt(0x10 + region.getRegionNumber() * 4, region.getType());	}	return ret;    }    private void updateMappings(PCIDevice device)    {	int lastAddress, newAddress, configOffset;		IORegion[] regions = device.getIORegions();	if (regions == null) return;	short command = device.getConfigShort(PCI_COMMAND);	for(int i = 0; i < regions.length; i++)         {	    IORegion r = regions[i];	    if (null == r)		continue;	    if (PCIDevice.PCI_NUM_REGIONS <= r.getRegionNumber())		continue;	    if (PCIDevice.PCI_ROM_SLOT == r.getRegionNumber())		configOffset = 0x30;	    else		configOffset = 0x10 + r.getRegionNumber() * 4;	    	    	    if (r instanceof IOPortIORegion) {		if (0 != (command & PCI_COMMAND_IO)) {		    newAddress = device.getConfigInt(configOffset);		    newAddress &= ~(r.getSize() - 1);		    lastAddress = newAddress + (int)r.getSize() - 1;		    		    if (lastAddress <= (0xffffffffl & newAddress) || 0 == newAddress || 0x10000 <= (0xffffffffl & lastAddress))			newAddress = -1;		}		else 		    newAddress = -1;	    } else if (r instanceof MemoryMappedIORegion) {	        if (0 != (command & PCI_COMMAND_MEMORY)) {		    newAddress = device.getConfigInt(configOffset);		    if (PCIDevice.PCI_ROM_SLOT == r.getRegionNumber()			&& (0 == (newAddress & 1))) {			newAddress = -1;		    } else {			newAddress &= ~(r.getSize() - 1);			lastAddress = newAddress + (int)r.getSize() - 1;			if (lastAddress <= newAddress || 0 == newAddress || -1 == lastAddress)			    newAddress = -1;		    } 		}		else 		    newAddress = -1;	    } else {		throw new IllegalStateException("Unknown IORegion Type");	    }	    if (r.getAddress() != newAddress) 	    {		if (r.getAddress() != -1) 		{		    if (r instanceof IOPortIORegion) {			int deviceClass;			deviceClass = device.getConfigByte(0x0a) | (device.getConfigByte(0x0b) << 8);			if (0x0101 == deviceClass && 4 == r.getSize()) 			{			    //r.unmap(); must actually be partial			    System.err.println("Supposed to partially unmap");			    ioportHandler.deregisterIOPortCapable((IOPortIORegion)r);			} else {			    //r.unmap();			    ioportHandler.deregisterIOPortCapable((IOPortIORegion)r);			}		    } else if (r instanceof MemoryMappedIORegion) {			memory.unmap(r.getAddress(), (int)r.getSize());		    }		}		r.setAddress(newAddress);		if (r.getAddress() != -1)                 {		    if (r instanceof IOPortIORegion)                     {                        IOPortIORegion pr = (IOPortIORegion) r;			ioportHandler.registerIOPortCapable((IOPortIORegion)r);                    }		    else if (r instanceof MemoryMappedIORegion)                     {                        MemoryMappedIORegion mmap = (MemoryMappedIORegion) r;                        memory.mapMemoryRegion(mmap, r.getAddress(), (int)r.getSize());		    }		}	    }	}    }    private void addDevice(PCIDevice device)    {	devices[device.getCurrentDevFN()] = device;    }    //PCIHostBridge shifted functionality    private PCIDevice validPCIDataAccess(int address)    {

⌨️ 快捷键说明

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