irqmanager.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 234 行
JAVA
234 行
/*
* $Id: IRQManager.java,v 1.2 2003/12/02 19:08:33 epr Exp $
*/
package org.jnode.vm;
import javax.naming.NameNotFoundException;
import org.jnode.naming.InitialNaming;
import org.jnode.system.IOResource;
import org.jnode.system.IRQHandler;
import org.jnode.system.IRQResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.system.ResourceOwner;
import org.jnode.system.SimpleResourceOwner;
/**
* IRQ manager implementation.
*
* @author epr
*/
public final class IRQManager {
private final Object LOCK = new Object();
private final ResourceOwner IRQ_MANAGER = new SimpleResourceOwner("system");
private final IRQThread[] handlers;
private final IOResource io8259_A;
private final IOResource io8259_B;
private final int count;
private final int[] irqCount;
/**
* Initialize a new instance
*
* @param irqCount
*/
IRQManager(int[] irqCount) {
this.irqCount = irqCount;
this.count = irqCount.length;
this.handlers = new IRQThread[count];
try {
final ResourceManager rm = (ResourceManager) InitialNaming.lookup(ResourceManager.NAME);
io8259_A = rm.claimIOResource(IRQ_MANAGER, 0x20, 1); // 0xA0
io8259_B = rm.claimIOResource(IRQ_MANAGER, 0xA0, 1);
} catch (NameNotFoundException ex) {
throw new Error("Cannot find ResourceManager", ex);
} catch (ResourceNotFreeException ex) {
throw new Error("Cannot claim PIC0-IO ports", ex);
}
}
/**
* Gets the IRQ counter value for the given IRQ
* @param irq
* @return The irq count
*/
public final int getIrqCount(int irq) {
return irqCount[irq];
}
/**
* Gets the number of IRQ's this processor supports.
* @return int
*/
public final int getNumIRQs() {
return count;
}
public Object getHandlerInfo(int irq) {
return handlers[irq];
}
/**
* Register an interrupt handler for a given irq number.
*
* @param owner
* @param irq
* @param handler
* @param shared
* @return True is the handler was set, false if there was already a handler for the given irq
* number set.
* @throws ResourceNotFreeException
*/
final IRQResource claimIRQ(ResourceOwner owner, int irq, IRQHandler handler, boolean shared) throws ResourceNotFreeException {
synchronized (LOCK) {
if (handlers[irq] == null) {
IRQThread thread = new IRQThread(this, irq, owner, handler, shared);
thread.start();
handlers[irq] = thread;
return new IRQResourceImpl(owner, irq, handler, shared);
} else {
final IRQThread thread = handlers[irq];
if (thread.isShared()) {
if (shared) {
thread.addHandler(owner, handler);
return new IRQResourceImpl(owner, irq, handler, shared);
} else {
throw new ResourceNotFreeException("IRQ " + irq + " is already claimed, but you don't want to share");
}
} else {
if (shared) {
throw new ResourceNotFreeException("IRQ " + irq + " is already claimed, but not shared");
} else {
//Unsafe.debug("IRQ was already claim");
throw new ResourceNotFreeException("IRQ " + irq + " is not free");
}
}
}
}
}
/**
* Unregister a given interrupt handler for a given irq number. If the current handler for the
* given irq number is not equal to the given handler, nothing is done.
*
* @param res
* The IRQ resource
*/
final void releaseIRQ(IRQResourceImpl res) {
final int irq = res.getIRQ();
synchronized (LOCK) {
final IRQThread thread = handlers[irq];
if (thread != null) {
thread.remove(res.getHandler());
if (thread.isEmpty()) {
handlers[irq] = null;
thread.stopThread();
}
}
}
}
/**
* Dispatch IRQ events to their corresponding threads. This method should only be called by the
* Thread scheduler.
* @param current
* @throws PragmaUninterruptible
*/
final void dispatchInterrupts(VmThread current) throws PragmaUninterruptible {
final IRQThread[] hlist = handlers;
final int[] irqCount = this.irqCount;
final int max = this.count;
for (int irq = 0; irq < max; irq++) {
final IRQThread thread = hlist[irq];
if (thread != null) {
thread.signalIRQ(irqCount[irq], current);
} else {
// No handler, signal and End of Interrupt
eoi(irq);
}
}
}
/**
* Set an End Of Interrupt message to the 8259 interrupt controller(s).
*
* @param irq
* @throws PragmaUninterruptible
*/
final void eoi(int irq) throws PragmaUninterruptible {
if (irq < 8) {
io8259_A.outPortByte(0x20, 0x60 + irq);
} else {
/*
* if (irq == 10) { Screen.debug(" <EOI 10/> ");
*/
io8259_B.outPortByte(0xA0, 0x60 + irq - 8);
/* EOI of cascade */
io8259_A.outPortByte(0x20, 0x60 + 2);
}
}
final class IRQResourceImpl implements IRQResource {
/** The owner of this resource */
private final ResourceOwner owner;
/** The IRQ number */
private final int irq;
/** The handler */
private final IRQHandler handler;
private final boolean shared;
/**
* Create a new instance
*
* @param owner
* @param irq
* @param handler
* @param shared
*/
public IRQResourceImpl(ResourceOwner owner, int irq, IRQHandler handler, boolean shared) {
this.owner = owner;
this.irq = irq;
this.handler = handler;
this.shared = shared;
}
/**
* @see org.jnode.system.IRQResource#getIRQ()
* @return int
*/
public int getIRQ() {
return irq;
}
/**
* Is this a shared interrupt?
* @return boolean
*/
public boolean isShared() {
return shared;
}
/**
* @see org.jnode.system.Resource#getOwner()
* @return The owner
*/
public ResourceOwner getOwner() {
return owner;
}
public IRQHandler getHandler() {
return handler;
}
/**
* @see org.jnode.system.Resource#release()
*/
public void release() {
releaseIRQ(this);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?