/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.x86;
/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
final class IOAPICRedirectionEntry {
public static final int DELMOD_FIXED = 0x00;
public static final int DELMOD_LOWPRIORITY = 0x01;
public static final int DELMOD_SMI = 0x02;
public static final int DELMOD_NMI = 0x04;
public static final int DELMOD_INIT = 0x05;
public static final int DELMOD_EXTINT = 0x07;
private final int offset;
private final IOAPIC apic;
private int low;
private int high;
// Destination mode
private static final int DESTMOD_MASK = 1 << 11;
/**
* Destination is specified by APIC id
*/
private static final int DESTMOD_PHYSICAL = 0;
/**
* Destination is specified by processor set
*/
private static final int DESTMOD_LOGICAL = DESTMOD_MASK;
//private static final int IRR = 1 << 14;
private static final int TRIGGERMODE = 1 << 15;
private static final int MASK = 1 << 16;
/**
* Initialize this instance.
*
* @param offset
*/
public IOAPICRedirectionEntry(IOAPIC apic, int offset) {
this.apic = apic;
this.offset = offset;
read();
}
/**
* Gets the interrupt vector
*
* @return the interrupt vector
*/
public int getVector() {
return low & 0xFF;
}
/**
* Sets the interrupt vector
*/
public synchronized void setVector(int vector) {
low &= 0xFFFFFF00;
low |= vector & 0xFF;
writeLow();
}
/**
* Gets the delivery mode.
*
* @return the delivery mode
*/
public int getDeliveryMode() {
return (low >> 8) & 0x07;
}
/**
* Sets the delivery mode
*/
public synchronized void setDeliveryMode(int mode) {
low &= ~(0x7 << 8);
low |= (mode & 0x7) << 8;
writeLow();
}
/**
* Is this entry set for physical destination to an APIC ID.
*
* @return True/false
*/
public final boolean isPhysicalDestination() {
return ((low & DESTMOD_MASK) == DESTMOD_PHYSICAL);
}
/**
* Is this entry set for logical destination to set of processors.
*
* @return True/false
*/
public final boolean isLogicalDestination() {
return ((low & DESTMOD_MASK) == DESTMOD_LOGICAL);
}
/**
* Is the type signal that triggers an interrupt level sensative.
*
* @return True/false
*/
public boolean isLevelTriggerMode() {
return ((low & TRIGGERMODE) != 0);
}
/**
* Is the type signal that triggers an interrupt edge sensative.
*
* @return True/false
*/
public boolean isEdgeTriggerMode() {
return ((low & TRIGGERMODE) == 0);
}
/**
* Is this interrupt signal masked.
*
* @return True/false
*/
public boolean isMasked() {
return ((low & MASK) != 0);
}
/**
* Initialize this entry to a masked, cleared state.
*/
public void clear() {
low = MASK;
high = 0;
writeLow();
writeHigh();
}
/**
* Convert to a string representation
*
* @see java.lang.Object#toString()
*/
public String toString() {
return "VECT" + getVector() + ", DELMOD " + getDeliveryMode()
+ ", MASKED " + isMasked() + ", "
+ (isLevelTriggerMode() ? "LEVEL" : "EDGE");
}
private final void read() {
low = apic.getReg(offset);
high = apic.getReg(offset + 1);
}
private final void writeLow() {
apic.setReg(offset, low);
}
private final void writeHigh() {
apic.setReg(offset + 1, high);
}
}