pcidriver.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 392 行
JAVA
392 行
/*
* $Id: PCIDriver.java,v 1.1 2003/11/25 11:41:21 epr Exp $
*/
package org.jnode.driver.pci;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.naming.NameNotFoundException;
import org.apache.log4j.Logger;
import org.jnode.driver.Device;
import org.jnode.driver.DeviceAlreadyRegisteredException;
import org.jnode.driver.DeviceManager;
import org.jnode.driver.DeviceUtils;
import org.jnode.driver.Driver;
import org.jnode.driver.DriverException;
import org.jnode.naming.InitialNaming;
import org.jnode.system.IOResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.util.NumberUtils;
/**
* Driver for the PCI bus itself.
*
* @author epr
*/
final class PCIDriver extends Driver implements PCIBusAPI, PCIConstants {
/** My logger */
private final Logger log = Logger.getLogger(getClass());
/** IO space of the PCI configuration registers */
private IOResource pciConfigIO;
/** All pci devices */
private List devices;
/** Global lock used to protected access to the configuration space */
private static final Object CONFIG_LOCK = new Object();
private final PCIBus rootBus;
/**
* Create a new instance
*/
protected PCIDriver(Device pciDevice) throws DriverException {
this.rootBus = new PCIBus(pciDevice.getBus(), this);
}
/**
* Register all PCI devices with the device manager.
*/
public void startDevice() throws DriverException {
try {
final Device pciBusDevice = getDevice();
final ResourceManager rm = (ResourceManager) InitialNaming.lookup(ResourceManager.NAME);
pciConfigIO = rm.claimIOResource(pciBusDevice, PCI_FIRST_PORT, PCI_LAST_PORT - PCI_FIRST_PORT + 1);
pciBusDevice.registerAPI(PCIBusAPI.class, this);
devices = probeDevices();
int count = 0;
// List all devices
for (Iterator i = devices.iterator(); i.hasNext();) {
final PCIDevice dev = (PCIDevice) i.next();
final PCIDeviceConfig cfg = dev.getConfig();
log.debug(
"PCI "
+ dev.getPCIName()
+ "\t"
+ NumberUtils.hex(cfg.getVendorID(), 4)
+ ":"
+ NumberUtils.hex(cfg.getDeviceID(), 4)
+ ":"
+ NumberUtils.hex(cfg.getRevision(), 2)
+ " "
+ NumberUtils.hex(cfg.getBaseClass(), 2)
+ ":"
+ NumberUtils.hex(cfg.getSubClass(), 2)
+ ":"
+ NumberUtils.hex(cfg.getMinorClass(), 2)
+ "\tIRQ"
+ cfg.getInterruptLine()
+ ":"
+ cfg.getInterruptPin()
+ "\tCMD "
+ NumberUtils.hex(cfg.getCommand(), 4));
}
// Register all bridges
final DeviceManager devMan = DeviceUtils.getDeviceManager();
for (Iterator i = devices.iterator(); i.hasNext();) {
final PCIDevice dev = (PCIDevice) i.next();
if (dev.isBridge()) {
devMan.register(dev);
count++;
}
}
// Register all non-bridges
for (Iterator i = devices.iterator(); i.hasNext();) {
final PCIDevice dev = (PCIDevice) i.next();
if (!dev.isBridge()) {
devMan.register(dev);
count++;
}
}
log.debug("Registered " + count + " PCI devices");
} catch (ResourceNotFreeException ex) {
throw new DriverException("Cannot claim IO ports", ex);
} catch (DeviceAlreadyRegisteredException ex) {
throw new DriverException("Device already registered", ex);
} catch (DriverException ex) {
throw new DriverException("Driver exception during register", ex);
} catch (NameNotFoundException ex) {
throw new DriverException("Cannot find resource or device manager", ex);
}
}
/**
* Unregister all PCI devices from the device manager.
*/
public void stopDevice() throws DriverException {
// Stop & unregister all PCI devices
DeviceManager devMan;
try {
devMan = (DeviceManager) InitialNaming.lookup(DeviceManager.NAME);
} catch (NameNotFoundException ex) {
throw new DriverException("Cannot find device manager", ex);
}
for (Iterator i = devices.iterator(); i.hasNext();) {
final PCIDevice dev = (PCIDevice) i.next();
log.debug("Stopping and unregistering device " + dev.getId());
try {
devMan.unregister(dev);
} catch (DriverException ex) {
throw new DriverException("Driver exception during unregister", ex);
}
}
// Remove the API
final Device pciBusDevice = getDevice();
pciBusDevice.unregisterAPI(PCIBusAPI.class);
// Release the resources
pciConfigIO.release();
pciConfigIO = null;
}
/**
* Return the list of connection PCI devices.
*
* @return A List containing all connected devices as instanceof PCIDevice.
*/
public List getDevices() {
return devices;
}
/**
* Find a device with a given vendor and device id.
*
* @param vendorId
* @param deviceId
* @return The found device, of null if not found.
*/
public PCIDevice findDevice(int vendorId, int deviceId) {
for (Iterator i = devices.iterator(); i.hasNext();) {
final PCIDevice dev = (PCIDevice) i.next();
final PCIDeviceConfig cfg = dev.getConfig();
if (cfg.getVendorID() == vendorId) {
if (cfg.getDeviceID() == deviceId) {
return dev;
}
}
}
return null;
}
/**
* Probe the PCI bus for a list of all connected devices.
*
* @return A List containing all connected devices as instanceof PCIDevice.
*/
protected List probeDevices() {
ArrayList result = new ArrayList();
rootBus.probeDevices(result);
return result;
}
/**
* Read a PCI configuration register
*
* @param bus
* (0..255)
* @param unit
* (0.31)
* @param func
* (0..7)
* @param register
* (0..63)
* @param type
* (0..3)
*/
protected int readConfigDword(int bus, int unit, int func, int register, int type) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((register < 0) || (register > 63)) {
throw new IllegalArgumentException("Invalid register value");
}
if ((type < 0) || (type > 3)) {
throw new IllegalArgumentException("Invalid type value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (register << 2) | (type);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
return pciConfigIO.inPortDword(PRW32_CONFIG_DATA);
}
}
/**
* Read a PCI configuration register
*
* @param bus
* (0..255)
* @param unit
* (0.31)
* @param func
* (0..7)
* @param offset
* (0..255)
*
*/
protected int readConfigByte(int bus, int unit, int func, int offset) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((offset < 0) || (offset > 255)) {
throw new IllegalArgumentException("Invalid offset value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (offset & ~3);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
return pciConfigIO.inPortByte(PRW32_CONFIG_DATA + (offset & 3)) & 0xFF;
}
}
protected int readConfigDword(int bus, int unit, int func, int offset) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((offset < 0) || (offset > 255)) {
throw new IllegalArgumentException("Invalid offset value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | offset;
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
return pciConfigIO.inPortDword(PRW32_CONFIG_DATA);
}
}
protected int readConfigWord(int bus, int unit, int func, int offset) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((offset < 0) || (offset > 255)) {
throw new IllegalArgumentException("Invalid offset value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (offset & ~3);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
return pciConfigIO.inPortWord(PRW32_CONFIG_DATA + (offset & 2));
}
}
/**
* Write a PCI configuration register
*
* @param bus
* (0..255)
* @param unit
* (0.31)
* @param func
* (0..7)
* @param register
* (0..63)
* @param type
* (0..3)
* @param value
*/
protected void writeConfigDword(int bus, int unit, int func, int register, int type, int value) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((register < 0) || (register > 63)) {
throw new IllegalArgumentException("Invalid register value");
}
if ((type < 0) || (type > 3)) {
throw new IllegalArgumentException("Invalid type value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (register << 2) | (type);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
pciConfigIO.outPortDword(PRW32_CONFIG_DATA, value);
}
}
protected void writeConfigDword(int bus, int unit, int func, int offset, int value) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((offset < 0) || (offset > 255)) {
throw new IllegalArgumentException("Invalid register value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (offset & ~3);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
pciConfigIO.outPortDword(PRW32_CONFIG_DATA, value);
}
}
protected void writeConfigWord(int bus, int unit, int func, int offset, int value) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((offset < 0) || (offset > 255)) {
throw new IllegalArgumentException("Invalid register value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (offset & ~3);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
pciConfigIO.outPortWord(PRW32_CONFIG_DATA + (offset & 2), value);
}
}
protected void writeConfigByte(int bus, int unit, int func, int offset, int value) {
if ((bus < 0) || (bus > 255)) {
throw new IllegalArgumentException("Invalid bus value");
}
if ((unit < 0) || (unit > 31)) {
throw new IllegalArgumentException("Invalid unit value");
}
if ((func < 0) || (func > 7)) {
throw new IllegalArgumentException("Invalid func value");
}
if ((offset < 0) || (offset > 255)) {
throw new IllegalArgumentException("Invalid register value");
}
int address = 0x80000000 | (bus << 16) | (unit << 11) | (func << 8) | (offset & ~3);
synchronized (CONFIG_LOCK) {
pciConfigIO.outPortDword(PW32_CONFIG_ADDRESS, address);
pciConfigIO.outPortByte(PRW32_CONFIG_DATA + (offset & 3), value);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?