mirror of https://github.com/contiki-ng/mspsim
Merge pull request #6 from nfi/PxIV
Bug fixes in the interrupt handling
This commit is contained in:
commit
b9c9fdd5e4
|
|
@ -76,6 +76,6 @@ public class Button extends Chip {
|
|||
|
||||
@Override
|
||||
public String info() {
|
||||
return id + ": " + (isPressed ? "pressed" : "released");
|
||||
return " Button is " + (isPressed ? "pressed" : "not pressed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,9 +69,6 @@ public abstract class Chip implements Loggable, EventSource {
|
|||
|
||||
public Chip(String id, MSP430Core cpu) {
|
||||
this(id, id, cpu);
|
||||
if (cpu != null) {
|
||||
logger = cpu.getLogger();
|
||||
}
|
||||
}
|
||||
|
||||
public Chip(String id, String name, MSP430Core cpu) {
|
||||
|
|
|
|||
|
|
@ -116,9 +116,9 @@ public class IOPort extends IOUnit {
|
|||
String[] specs = specification.split(",");
|
||||
int port = specs[0].charAt(1) - '0';
|
||||
int offset = Integer.parseInt(specs[0].substring(3), 16);
|
||||
|
||||
|
||||
PortReg[] portMap = new PortReg[0x20]; /* Worst case port-map */
|
||||
|
||||
int highest = -1;
|
||||
for (int i = 1; i < specs.length; i++) {
|
||||
String[] preg = specs[i].split(" ");
|
||||
PortReg pr = PortReg.valueOf(preg[0]);
|
||||
|
|
@ -127,6 +127,12 @@ public class IOPort extends IOUnit {
|
|||
portMap = Arrays.copyOf(portMap, offs + 1);
|
||||
}
|
||||
portMap[offs] = pr;
|
||||
if (offs > highest) {
|
||||
highest = offs;
|
||||
}
|
||||
}
|
||||
if (highest + 1 < portMap.length) {
|
||||
portMap = Arrays.copyOf(portMap, highest + 1);
|
||||
}
|
||||
IOPort newPort = new IOPort(cpu, port, interrupt, cpu.memory, offset, portMap);
|
||||
if (last != null && offset == last.offset && offset > 0) {
|
||||
|
|
@ -171,7 +177,7 @@ public class IOPort extends IOUnit {
|
|||
timerCapture[pin] = timer;
|
||||
}
|
||||
|
||||
public void updateIV() {
|
||||
private void updateIV() {
|
||||
int bitval = 0x01;
|
||||
iv = 0;
|
||||
int ie_ifg = ifg & ie;
|
||||
|
|
@ -183,6 +189,7 @@ public class IOPort extends IOUnit {
|
|||
bitval = bitval << 1;
|
||||
}
|
||||
//System.out.println("*** Setting IV to: " + iv + " ifg: " + ifg);
|
||||
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
|
||||
}
|
||||
|
||||
public int getRegister(PortReg register) {
|
||||
|
|
@ -216,7 +223,7 @@ public class IOPort extends IOUnit {
|
|||
}
|
||||
|
||||
/* only byte access!!! */
|
||||
int read_port(PortReg function, long cycles) {
|
||||
private int readPort(PortReg function, long cycles) {
|
||||
switch(function) {
|
||||
case OUT:
|
||||
return out;
|
||||
|
|
@ -238,18 +245,27 @@ public class IOPort extends IOUnit {
|
|||
return sel2;
|
||||
case DS:
|
||||
return ds;
|
||||
case IV_L:
|
||||
return iv & 0xff;
|
||||
case IV_H:
|
||||
int v = iv >> 8;
|
||||
updateIV();
|
||||
case IV_L: {
|
||||
int v = iv & 0xff;
|
||||
// Clear highest interrupt
|
||||
if (iv != 0) {
|
||||
if (iv > 1 && iv < 17) {
|
||||
ifg &= ~(1 << ((iv - 2) / 2));
|
||||
}
|
||||
updateIV();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
case IV_H: {
|
||||
int v = iv >> 8;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
/* default is zero ??? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void write_port(PortReg function, int data, long cycles) {
|
||||
private void writePort(PortReg function, int data, long cycles) {
|
||||
switch(function) {
|
||||
case OUT: {
|
||||
out = data;
|
||||
|
|
@ -279,11 +295,10 @@ public class IOPort extends IOUnit {
|
|||
break;
|
||||
case IFG:
|
||||
if (DEBUG) {
|
||||
log("Clearing IFlag: " + data);
|
||||
log("Setting IFlag: " + data);
|
||||
}
|
||||
ifg &= data;
|
||||
ifg = data;
|
||||
updateIV();
|
||||
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
|
||||
break;
|
||||
case IE:
|
||||
ie = data;
|
||||
|
|
@ -301,15 +316,21 @@ public class IOPort extends IOUnit {
|
|||
case SEL2:
|
||||
sel2 = data;
|
||||
break;
|
||||
/* Can IV be written ? */
|
||||
case DS:
|
||||
ds = data;
|
||||
break;
|
||||
case IV_L:
|
||||
iv = (iv & 0xff00) | data;
|
||||
// IV can not be written but highest interrupt should be cleared
|
||||
// on access.
|
||||
if (iv != 0) {
|
||||
if (iv > 1 && iv < 17) {
|
||||
ifg &= ~(1 << ((iv - 2) / 2));
|
||||
}
|
||||
updateIV();
|
||||
}
|
||||
break;
|
||||
case IV_H:
|
||||
iv = (iv & 0x00ff) | (data << 8);
|
||||
// IV_H can not be written
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -319,22 +340,19 @@ public class IOPort extends IOUnit {
|
|||
PortReg reg = portMap[address - offset];
|
||||
/* only byte read allowed if not having an ioPair */
|
||||
if (word && reg == PortReg.IV_L) {
|
||||
/* Always read low first then high => update on high!!! */
|
||||
return read_port(reg, cycles) | (read_port(PortReg.IV_H, cycles) << 8);
|
||||
/* Read hi first then low => update on low!!! */
|
||||
return (readPort(PortReg.IV_H, cycles) << 8) | readPort(reg, cycles);
|
||||
} else if (word && ioPair != null) {
|
||||
/* read same function from both */
|
||||
return read_port(reg, cycles) | (ioPair.read_port(reg, cycles) << 8);
|
||||
return readPort(reg, cycles) | (ioPair.readPort(reg, cycles) << 8);
|
||||
}
|
||||
/* NOTE: read of PIV might be wrong here - might be word access on IV? */
|
||||
return read_port(reg, cycles);
|
||||
return readPort(reg, cycles);
|
||||
}
|
||||
|
||||
|
||||
public void write(int address, int data, boolean word, long cycles) {
|
||||
int iAddress = address - offset;
|
||||
if (iAddress < 0 || iAddress >= portMap.length) {
|
||||
throw new EmulationException("Writing to illegal IO port address at " + getID() + ": $" + Utils.hex(address, 4));
|
||||
}
|
||||
PortReg fun = portMap[iAddress];
|
||||
if (DEBUG) {
|
||||
log("Writing to " + getID() + fun +
|
||||
|
|
@ -345,10 +363,10 @@ public class IOPort extends IOUnit {
|
|||
|
||||
/* only byte write - need to convert any word write here... */
|
||||
if (word && ioPair != null) {
|
||||
write_port(fun, data & 0xff, cycles);
|
||||
ioPair.write_port(fun, data >> 8, cycles);
|
||||
writePort(fun, data & 0xff, cycles);
|
||||
ioPair.writePort(fun, data >> 8, cycles);
|
||||
} else {
|
||||
write_port(fun, data, cycles);
|
||||
writePort(fun, data, cycles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -370,23 +388,21 @@ public class IOPort extends IOUnit {
|
|||
// LO/HI transition
|
||||
if (state == PinState.HI) {
|
||||
ifg |= bit;
|
||||
updateIV();
|
||||
if (DEBUG) {
|
||||
log("Flagging interrupt (HI): " + bit);
|
||||
}
|
||||
updateIV();
|
||||
}
|
||||
} else {
|
||||
// HI/LO transition
|
||||
if (state == PinState.LOW) {
|
||||
ifg |= bit;
|
||||
updateIV();
|
||||
if (DEBUG) {
|
||||
log("Flagging interrupt (LOW): " + bit);
|
||||
}
|
||||
updateIV();
|
||||
}
|
||||
}
|
||||
// Maybe this is not the only place where we should flag int?
|
||||
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
|
||||
}
|
||||
|
||||
if (timerCapture[pin] != null) {
|
||||
|
|
|
|||
|
|
@ -36,9 +36,6 @@
|
|||
*/
|
||||
|
||||
package se.sics.mspsim.core;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import se.sics.mspsim.core.EmulationLogger.WarningType;
|
||||
|
||||
public abstract class IOUnit implements InterruptHandler, Loggable {
|
||||
|
|
@ -53,11 +50,10 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
|
|||
private StateChangeListener stateListener;
|
||||
private int ioState;
|
||||
protected int logLevel;
|
||||
|
||||
protected EmulationLogger logger;
|
||||
private PrintStream log;
|
||||
protected boolean DEBUG = false;
|
||||
|
||||
protected EmulationLogger logger;
|
||||
|
||||
public IOUnit(String id, MSP430Core cpu, int[] memory, int offset) {
|
||||
this(id, id, cpu, memory, offset);
|
||||
}
|
||||
|
|
@ -79,8 +75,9 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
|
|||
@Override
|
||||
public void setLogLevel(int l) {
|
||||
logLevel = l;
|
||||
DEBUG = logLevel == Loggable.DEBUG;
|
||||
}
|
||||
|
||||
|
||||
public void addStateChangeListener(StateChangeListener listener) {
|
||||
stateListener = StateChangeListener.Proxy.INSTANCE.add(stateListener, listener);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ public class WismoteNode extends GenericNode implements PortListener, USARTListe
|
|||
/* P4.4 - Output: RESET_N to CC2520 */
|
||||
public static final int CC2520_RESET = 1 << 4;
|
||||
|
||||
/* P2.7 - Button */
|
||||
public static final int BUTTON_PIN = 7;
|
||||
/* P1.4 - Button */
|
||||
public static final int BUTTON_PIN = 4;
|
||||
|
||||
/* P8.6 - Red (left) led */
|
||||
private static final int LEDS_CONF_RED2 = 1 << 6;
|
||||
|
|
@ -173,7 +173,7 @@ public class WismoteNode extends GenericNode implements PortListener, USARTListe
|
|||
throw new EmulationException("Could not setup wismote mote - missing USCI B0");
|
||||
}
|
||||
leds = new Leds(cpu, LEDS);
|
||||
button = new Button("Button", cpu, port2, BUTTON_PIN, true);
|
||||
button = new Button("Button", cpu, port1, BUTTON_PIN, true);
|
||||
|
||||
IOUnit usart = cpu.getIOUnit("USCI A1");
|
||||
if (usart instanceof USARTSource) {
|
||||
|
|
|
|||
|
|
@ -27,16 +27,12 @@
|
|||
*
|
||||
* This file is part of MSPSim.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* -----------------------------------------------------------------
|
||||
*
|
||||
* ELF
|
||||
*
|
||||
* Author : Joakim Eriksson
|
||||
* Created : Sun Oct 21 22:00:00 2007
|
||||
* Updated : $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
package se.sics.mspsim.util;
|
||||
|
|
@ -54,7 +50,7 @@ import se.sics.mspsim.debug.StabDebug;
|
|||
|
||||
public class ELF {
|
||||
|
||||
private static final int EI_NIDENT = 16;
|
||||
// private static final int EI_NIDENT = 16;
|
||||
private static final int EI_ENCODING = 5;
|
||||
private static final int[] MAGIC = new int[] {0x7f, 'E', 'L', 'F'};
|
||||
|
||||
|
|
@ -97,28 +93,22 @@ public class ELF {
|
|||
|
||||
/* check if the file exists and is an ELF file */
|
||||
public static boolean isELF(File file) {
|
||||
InputStream input = null;
|
||||
try {
|
||||
input = new BufferedInputStream(new FileInputStream(file));
|
||||
InputStream input = new BufferedInputStream(new FileInputStream(file));
|
||||
for (int i = 0; i < MAGIC.length; i++) {
|
||||
if (MAGIC[i] != input.read()) {
|
||||
input.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
input.close();
|
||||
return true;
|
||||
} catch(IOException ioe) {
|
||||
// ignore and return false - this is not an elf.
|
||||
return false;
|
||||
} finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void readHeader() throws ELFException {
|
||||
for (int i = 0; i < MAGIC.length; i++) {
|
||||
if (elfData[i] != (byte) (MAGIC[i] & 0xff)) {
|
||||
|
|
@ -465,10 +455,10 @@ public class ELF {
|
|||
addr += symTable.getEntrySize();
|
||||
}
|
||||
|
||||
if (sAddrHighest > 0) {
|
||||
System.out.printf("Warning: Unable to parse _end symbol. I'm guessing that heap starts at 0x%05x\n", sAddrHighest);
|
||||
map.setHeapStart(sAddrHighest);
|
||||
}
|
||||
if (map.getHeapStart() <= 0 && sAddrHighest > 0) {
|
||||
System.err.printf("Warning: Unable to parse _end symbol. I'm guessing that heap starts at 0x%05x\n", sAddrHighest);
|
||||
map.setHeapStart(sAddrHighest);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
|
@ -530,26 +520,24 @@ public class ELF {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void setPos(int pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
public int getPos() {
|
||||
public int getPos() {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileInfo {
|
||||
public final String name;
|
||||
public final int start;
|
||||
public final int end;
|
||||
|
||||
class FileInfo {
|
||||
String name;
|
||||
int start;
|
||||
int end;
|
||||
|
||||
FileInfo(String name, int start, int end) {
|
||||
this.name = name;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
FileInfo(String name, int start, int end) {
|
||||
this.name = name;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -248,10 +248,18 @@ public class MapTable {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public int getStackStart() {
|
||||
return stackStartAddress;
|
||||
}
|
||||
|
||||
public void setStackStart(int start) {
|
||||
stackStartAddress = start;
|
||||
}
|
||||
|
||||
public int getHeapStart() {
|
||||
return heapStartAddress;
|
||||
}
|
||||
|
||||
public void setHeapStart(int start) {
|
||||
heapStartAddress = start;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue