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 + -
显示快捷键?