From 648a70893907a9cb446f1546d4fd39cf6457f0e8 Mon Sep 17 00:00:00 2001 From: oharboe Date: Fri, 22 Feb 2008 12:38:46 +0000 Subject: * Hooked up support for the simulator to the Zylin Embedded CDT --- zpu/sw/simulator/.classpath | 1 + zpu/sw/simulator/.project | 11 + zpu/sw/simulator/ChangeLog | 2 + zpu/sw/simulator/META-INF/MANIFEST.MF | 11 + zpu/sw/simulator/build.properties | 3 + zpu/sw/simulator/com/zylin/zpu/simulator/Phi.java | 2 +- .../simulator/com/zylin/zpu/simulator/SimApp.java | 93 +++++- .../com/zylin/zpu/simulator/Simulator.java | 2 + .../simulator/exceptions/EndSessionException.java | 24 ++ .../com/zylin/zpu/simulator/gdb/GDBServer.java | 313 +++------------------ .../com/zylin/zpu/simulator/gdb/Packet.java | 23 +- 11 files changed, 188 insertions(+), 297 deletions(-) create mode 100644 zpu/sw/simulator/META-INF/MANIFEST.MF create mode 100644 zpu/sw/simulator/build.properties (limited to 'zpu/sw') diff --git a/zpu/sw/simulator/.classpath b/zpu/sw/simulator/.classpath index 617be7e..5e4fa9f 100644 --- a/zpu/sw/simulator/.classpath +++ b/zpu/sw/simulator/.classpath @@ -2,5 +2,6 @@ + diff --git a/zpu/sw/simulator/.project b/zpu/sw/simulator/.project index 9cd2fd7..29c7a4f 100644 --- a/zpu/sw/simulator/.project +++ b/zpu/sw/simulator/.project @@ -10,8 +10,19 @@ + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature diff --git a/zpu/sw/simulator/ChangeLog b/zpu/sw/simulator/ChangeLog index c645841..18b0981 100644 --- a/zpu/sw/simulator/ChangeLog +++ b/zpu/sw/simulator/ChangeLog @@ -1,2 +1,4 @@ +2008-02-22 Øyvind Harboe + * Hooked up support for the simulator to the Zylin Embedded CDT 2007-08-04 Øyvind Harboe * First version after open sourcing ZPU diff --git a/zpu/sw/simulator/META-INF/MANIFEST.MF b/zpu/sw/simulator/META-INF/MANIFEST.MF new file mode 100644 index 0000000..b0ad5b9 --- /dev/null +++ b/zpu/sw/simulator/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: ZPU simulator +Bundle-SymbolicName: com.zylin.zpu.simulator +Bundle-Version: 1.0.0 +Export-Package: com.zylin.zpu.simulator, + com.zylin.zpu.simulator.applet, + com.zylin.zpu.simulator.exceptions, + com.zylin.zpu.simulator.gdb, + com.zylin.zpu.simulator.tools, + com.zylin.zpu.stats diff --git a/zpu/sw/simulator/build.properties b/zpu/sw/simulator/build.properties new file mode 100644 index 0000000..19c7019 --- /dev/null +++ b/zpu/sw/simulator/build.properties @@ -0,0 +1,3 @@ +source.. = . +bin.includes = META-INF/,\ + . diff --git a/zpu/sw/simulator/com/zylin/zpu/simulator/Phi.java b/zpu/sw/simulator/com/zylin/zpu/simulator/Phi.java index 862deae..0e3e7a1 100644 --- a/zpu/sw/simulator/com/zylin/zpu/simulator/Phi.java +++ b/zpu/sw/simulator/com/zylin/zpu/simulator/Phi.java @@ -98,7 +98,7 @@ public class Phi extends Simulator } } - Phi() throws CPUException + public Phi() throws CPUException { } diff --git a/zpu/sw/simulator/com/zylin/zpu/simulator/SimApp.java b/zpu/sw/simulator/com/zylin/zpu/simulator/SimApp.java index 8008275..3f6e1a9 100644 --- a/zpu/sw/simulator/com/zylin/zpu/simulator/SimApp.java +++ b/zpu/sw/simulator/com/zylin/zpu/simulator/SimApp.java @@ -2,6 +2,8 @@ package com.zylin.zpu.simulator; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; import java.nio.channels.ServerSocketChannel; import com.zylin.zpu.simulator.exceptions.CPUException; @@ -10,7 +12,6 @@ import com.zylin.zpu.simulator.gdb.GDBServer; public class SimApp { private static Simulator simulator; - public ServerSocketChannel channel; private String[] args; private int portNumber; private SimFactory simFactory; @@ -40,39 +41,65 @@ public class SimApp void run(String[] args) { this.args=args; + createSimulator(); parseArgs(); + moreParse(); + runSimAndGDB(); + } + Object launched=new Object(); + private boolean doneLaunching; + private boolean manyGDBSessions; + public ServerSocket serverSocket; + public void runSimAndGDB() + { try { - channel = ServerSocketChannel.open(); + serverSocket = new ServerSocket(portNumber); try { + serverSocket.setReuseAddress(true); System.out.println("Listening on port " + portNumber); - channel.socket().bind(new InetSocketAddress(portNumber)); - for (;;) - { + setLaunchedFlag(); + do + { try { - simulator=simFactory.create(); - simulator.suspend(); - moreParse(); - run(); + runGDBServer(); } catch (CPUException e) { e.printStackTrace(); - } - } + } + } while (manyGDBSessions); } finally { - channel.close(); + serverSocket.close(); } } catch (IOException e1) { e1.printStackTrace(); + } finally + { + setLaunchedFlag(); } } - private void run() throws CPUException + private void setLaunchedFlag() + { + synchronized(launched) + { + doneLaunching=true; + launched.notify(); + } + } + + public void createSimulator() + { + simulator=simFactory.create(); + simulator.suspend(); + } + + private void runGDBServer() throws CPUException { final GDBServer gdbServer=new GDBServer(simulator, this); simulator.setSyscall(gdbServer); @@ -98,7 +125,6 @@ public class SimApp } finally { - try { thread.join(); @@ -109,4 +135,43 @@ public class SimApp } } + + public Simulator getSimulator() + { + return simulator; + } + + public void setPort(int i) + { + portNumber=i; + } + + /** synchronous launch of GDB server */ + public void launchGDBServer() + { + Thread t=new Thread(new Runnable() + { + + public void run() + { + runSimAndGDB(); + } + }); + t.start(); + synchronized (launched) + { + while (!doneLaunching) + { + try + { + launched.wait(2000); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } + + + } } diff --git a/zpu/sw/simulator/com/zylin/zpu/simulator/Simulator.java b/zpu/sw/simulator/com/zylin/zpu/simulator/Simulator.java index c1b86d4..791e253 100644 --- a/zpu/sw/simulator/com/zylin/zpu/simulator/Simulator.java +++ b/zpu/sw/simulator/com/zylin/zpu/simulator/Simulator.java @@ -268,6 +268,8 @@ public class Simulator implements ZPU, Machine, Sim **/ private void dumpGmon() { + if (memory==null) + return; try { ByteArrayOutputStream b=new ByteArrayOutputStream(); diff --git a/zpu/sw/simulator/com/zylin/zpu/simulator/exceptions/EndSessionException.java b/zpu/sw/simulator/com/zylin/zpu/simulator/exceptions/EndSessionException.java index 7dd27e0..13fc875 100644 --- a/zpu/sw/simulator/com/zylin/zpu/simulator/exceptions/EndSessionException.java +++ b/zpu/sw/simulator/com/zylin/zpu/simulator/exceptions/EndSessionException.java @@ -15,6 +15,30 @@ package com.zylin.zpu.simulator.exceptions; public class EndSessionException extends Exception { + public EndSessionException() + { + super(); + // TODO Auto-generated constructor stub + } + + public EndSessionException(String arg0, Throwable arg1) + { + super(arg0, arg1); + // TODO Auto-generated constructor stub + } + + public EndSessionException(String arg0) + { + super(arg0); + // TODO Auto-generated constructor stub + } + + public EndSessionException(Throwable arg0) + { + super(arg0); + // TODO Auto-generated constructor stub + } + /** * */ diff --git a/zpu/sw/simulator/com/zylin/zpu/simulator/gdb/GDBServer.java b/zpu/sw/simulator/com/zylin/zpu/simulator/gdb/GDBServer.java index 2580ded..182e426 100644 --- a/zpu/sw/simulator/com/zylin/zpu/simulator/gdb/GDBServer.java +++ b/zpu/sw/simulator/com/zylin/zpu/simulator/gdb/GDBServer.java @@ -5,6 +5,7 @@ package com.zylin.zpu.simulator.gdb; import java.io.IOException; +import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; @@ -23,30 +24,25 @@ import com.zylin.zpu.simulator.exceptions.UnsupportedSyscallException; public class GDBServer implements Host { + /* logging filter */ static final boolean UNKNOWN=false; static final boolean ALL=false; static final boolean CPUEXCEPTION = false; static protected boolean MINIMAL=true; - static boolean PACKET=false; - static boolean REPLY=false; + static boolean PACKET=true; + static boolean REPLY=true; static protected boolean IGNOREDEXCEPTIONS=false; + + + protected Throwable packetException; protected Object packetReady=new Object(); private Packet packet; boolean done; - private Thread asyncMessage; - private Object listenBreak=new Object(); - private boolean listenForBreak; - private boolean sleeping; - private ByteBuffer readBuffer; - private ByteBuffer writeBuffer; - private SocketChannel sc; - private Selector selectorRead; - private Selector selectorWrite; + private Socket sc; public boolean alive; static private int sessionNr; private SimApp app; - private boolean stopAsyncMessage; Sim simulator; public GDBServer(Sim simulator, SimApp app) @@ -66,39 +62,10 @@ public class GDBServer implements Host /** infinite loop that waits for debug sessions to be initiated via TCP/IP */ public void gdbServer() throws MemoryAccessException, IOException, GDBServerException, EndSessionException { + sc=app.serverSocket.accept(); try { - asyncMessage = new Thread(new Runnable() - { - public void run() - { - asyncMessage(); - } - }); - asyncMessage.start(); - try - { - readBuffer = ByteBuffer.allocate(1); - writeBuffer = ByteBuffer.allocate(128); - debugSession(); - } - finally - { - /* tell it to stop waiting for break chars and wake up the thread */ - stopAsyncMessage = true; - synchronized(listenBreak) - { - listenBreak.notify(); - } - - try - { - asyncMessage.join(); - } catch (InterruptedException e3) - { - e3.printStackTrace(); - } - } + debugSession(); } catch (IOException e) { // the session failed... @@ -119,111 +86,12 @@ public class GDBServer implements Host { // some terrible unforseen failure. e.printStackTrace(); - } - } - - /** - * We have to wait for break, but as soon as the main thread wants to wait - * for packets again, we have to stop waiting for a break. - * - * Tricky.... - */ - private void asyncMessage() - { - for (;;) + } finally { - synchronized(listenBreak) - { - if (stopAsyncMessage) - { - /* shutting down */ - return; - } - try - { - sleeping=true; - listenBreak.notify(); - - listenBreak.wait(); - sleeping=false; - listenBreak.notify(); - } catch (InterruptedException e) - { - e.printStackTrace(); - } - if (stopAsyncMessage) - { - /* shutting down */ - return; - } - } - - while (listenForBreak) - { - try - { - if (waitSelect(selectorRead, true)) - { - int t = read(); - if (t == 0x03) - { - // We received a ctrl-c while processing a package, - // this - // would be a suspend - simulator.suspend(); - } else - { - // ignore garbage. Shouldn't happen. - } - } else - { - // we've been awoken since we're ready to send - // the reply to the package... -// int x=0; - } - } catch (IOException e) - { - // Perfectly normal. This would happen if the connection - // is terminated. - } - } + sc.close(); } } - /** wait for read/write ready */ - private boolean waitSelect(Selector selector, boolean read) throws IOException - { - boolean gotit=false; - - selector.select(1000); - if (!sc.isOpen()) - { - throw new IOException("Channel closed"); - } - if (!sc.isConnected()) - { - throw new IOException("Channel not connected"); - } - - // Get list of selection keys with pending events - Iterator it = selector.selectedKeys().iterator(); - // Process each key at a time - while (it.hasNext()) - { - // Get the selection key - SelectionKey selKey = (SelectionKey) it.next(); - // Remove it from the list to indicate that it is being - // processed - it.remove(); - if (selKey.isValid() && - ((read && selKey.isReadable()) || (!read && selKey.isWritable()))) - { - gotit=true; - } - - } - return gotit; - } protected void sleepABit() @@ -243,44 +111,18 @@ public class GDBServer implements Host { print(MINIMAL, "GDB server waiting for connection " + sessionNr++ + "..."); - writeBuffer.clear(); - readBuffer.clear(); - - - selectorRead = Selector.open(); try { - selectorWrite = Selector.open(); - try - { - sc = app.channel.accept(); - try - { - sc.socket().setKeepAlive(true); - sc.configureBlocking(false); - sc.register(selectorRead, SelectionKey.OP_READ); - sc.register(selectorWrite, SelectionKey.OP_WRITE); - - sessionStarted(); - - expect('+'); // connection ack. - - sessionLoop(); - } finally - { - sc.close(); - - print(MINIMAL, "Session ended"); - } - } finally - { - selectorWrite.close(); - } + sessionStarted(); + + expect('+'); // connection ack. + + sessionLoop(); } finally { - selectorRead.close(); + print(MINIMAL, "Session ended"); } - + } private void sessionStarted() @@ -301,19 +143,8 @@ public class GDBServer implements Host packet=new Packet(this); packet.receive(); - enterListenForCtrlC(); - - try - { - // During execution we can receive an abort/suspend command... - packet.parseAndExecute(); - } - finally - { - leaveListenForCtrlC(); - } - - packet.sendReply(); + // During execution we can receive an abort/suspend command... + packet.parseAndExecute(); if (!alive) throw new EndSessionException(); @@ -337,41 +168,6 @@ public class GDBServer implements Host } } - private void enterListenForCtrlC() - { - setBreakListen(true); - } - - private void leaveListenForCtrlC() - { - /* we don't want to wait for the select to time out as that would make - * the protocol excruciatingly slow */ - setBreakListen(false); - selectorRead.wakeup(); - synchronized(listenBreak) - { - try - { - while (!sleeping) - { - listenBreak.notify(); - listenBreak.wait(); - } - } catch (InterruptedException e) - { - e.printStackTrace(); - } - } - } - - private void setBreakListen(boolean state) - { - synchronized(listenBreak) - { - listenForBreak=state; - listenBreak.notify(); - } - } @@ -387,19 +183,9 @@ public class GDBServer implements Host int read() throws IOException { flush(); - readBuffer.clear(); - for (;;) - { - int n; - n = sc.read(readBuffer); - if (n == 1) - { - break; - } - while (!waitSelect(selectorRead, true)); - } - readBuffer.flip(); - int t = readBuffer.get(0); + int t=sc.getInputStream().read(); + if (t==-1) + throw new IOException(); return t; } @@ -429,42 +215,12 @@ public class GDBServer implements Host public void write(byte[] bytes) throws IOException { - int i=0; - while (i0) - { - writeBuffer.flip(); - int len=writeBuffer.limit(); - - int j=0; - while (j