Rename cycles() function to ticks()
[gem5.git] / src / dev / simconsole.cc
index e33fa18b55aaff090109c0c81dae469ed7d65739..e8dc1b2102b33cf3db0cbd447557d11c3895ed69 100644 (file)
@@ -24,6 +24,9 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ *          Ali Saidi
  */
 
 /* @file
 #include "dev/platform.hh"
 #include "dev/simconsole.hh"
 #include "dev/uart.hh"
-#include "sim/builder.hh"
 
 using namespace std;
 
-////////////////////////////////////////////////////////////////////////
-//
-//
 
-SimConsole::Event::Event(SimConsole *c, int fd, int e)
+/*
+ * Poll event for the listen socket
+ */
+SimConsole::ListenEvent::ListenEvent(SimConsole *c, int fd, int e)
+    : PollEvent(fd, e), cons(c)
+{
+}
+
+void
+SimConsole::ListenEvent::process(int revent)
+{
+    cons->accept();
+}
+
+/*
+ * Poll event for the data socket
+ */
+SimConsole::DataEvent::DataEvent(SimConsole *c, int fd, int e)
     : PollEvent(fd, e), cons(c)
 {
 }
 
 void
-SimConsole::Event::process(int revent)
+SimConsole::DataEvent::process(int revent)
 {
     if (revent & POLLIN)
         cons->data();
@@ -71,41 +87,82 @@ SimConsole::Event::process(int revent)
         cons->detach();
 }
 
-SimConsole::SimConsole(const string &name, ostream *os, int num)
-    : SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1),
-      listener(NULL), txbuf(16384), rxbuf(16384), outfile(os)
+/*
+ * SimConsole code
+ */
+SimConsole::SimConsole(const Params *p)
+    : SimObject(p), listenEvent(NULL), dataEvent(NULL), number(p->number),
+      data_fd(-1), txbuf(16384), rxbuf(16384), outfile(NULL)
 #if TRACING_ON == 1
       , linebuf(16384)
 #endif
 {
-    if (outfile)
+    if (!p->output.empty()) {
+        if (p->append_name)
+            outfile = simout.find(p->output + "." + p->name);
+        else
+            outfile = simout.find(p->output);
+
         outfile->setf(ios::unitbuf);
+    }
+
+    if (p->port)
+        listen(p->port);
 }
 
 SimConsole::~SimConsole()
 {
-    close();
+    if (data_fd != -1)
+        ::close(data_fd);
+
+    if (listenEvent)
+        delete listenEvent;
+
+    if (dataEvent)
+        delete dataEvent;
 }
 
+///////////////////////////////////////////////////////////////////////
+// socket creation and console attach
+//
+
 void
-SimConsole::close()
+SimConsole::listen(int port)
 {
-    if (in_fd != -1)
-        ::close(in_fd);
+    while (!listener.listen(port, true)) {
+        DPRINTF(Console,
+                ": can't bind address console port %d inuse PID %d\n",
+                port, getpid());
+        port++;
+    }
+
+    int p1, p2;
+    p2 = name().rfind('.') - 1;
+    p1 = name().rfind('.', p2);
+    ccprintf(cerr, "Listening for %s connection on port %d\n",
+            name().substr(p1+1,p2-p1), port);
 
-    if (out_fd != in_fd && out_fd != -1)
-        ::close(out_fd);
+    listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
+    pollQueue.schedule(listenEvent);
 }
 
 void
-SimConsole::attach(int in, int out, ConsoleListener *l)
+SimConsole::accept()
 {
-    in_fd = in;
-    out_fd = out;
-    listener = l;
+    if (!listener.islistening())
+        panic("%s: cannot accept a connection if not listening!", name());
+
+    int fd = listener.accept(true);
+    if (data_fd != -1) {
+        char message[] = "console already attached!\n";
+        ::write(fd, message, sizeof(message));
+        ::close(fd);
+        return;
+    }
 
-    event = new Event(this, in, POLLIN);
-    pollQueue.schedule(event);
+    data_fd = fd;
+    dataEvent = new DataEvent(this, data_fd, POLLIN);
+    pollQueue.schedule(dataEvent);
 
     stringstream stream;
     ccprintf(stream, "==== m5 slave console: Console %d ====", number);
@@ -116,26 +173,23 @@ SimConsole::attach(int in, int out, ConsoleListener *l)
 
     write((const uint8_t *)stream.str().c_str(), stream.str().size());
 
-
     DPRINTFN("attach console %d\n", number);
 
-    txbuf.readall(out);
+    txbuf.readall(data_fd);
 }
 
 void
 SimConsole::detach()
 {
-    close();
-    in_fd = -1;
-    out_fd = -1;
-
-    pollQueue.remove(event);
-
-    if (listener) {
-        listener->add(this);
-        listener = NULL;
+    if (data_fd != -1) {
+        ::close(data_fd);
+        data_fd = -1;
     }
 
+    pollQueue.remove(dataEvent);
+    delete dataEvent;
+    dataEvent = NULL;
+
     DPRINTFN("detach console %d\n", number);
 }
 
@@ -156,12 +210,12 @@ SimConsole::data()
 size_t
 SimConsole::read(uint8_t *buf, size_t len)
 {
-    if (in_fd < 0)
+    if (data_fd < 0)
         panic("Console not properly attached.\n");
 
     size_t ret;
     do {
-      ret = ::read(in_fd, buf, len);
+      ret = ::read(data_fd, buf, len);
     } while (ret == -1 && errno == EINTR);
 
 
@@ -180,12 +234,12 @@ SimConsole::read(uint8_t *buf, size_t len)
 size_t
 SimConsole::write(const uint8_t *buf, size_t len)
 {
-    if (out_fd < 0)
+    if (data_fd < 0)
         panic("Console not properly attached.\n");
 
     size_t ret;
     for (;;) {
-      ret = ::write(out_fd, buf, len);
+      ret = ::write(data_fd, buf, len);
 
       if (ret >= 0)
         break;
@@ -265,7 +319,7 @@ SimConsole::out(char c)
 
     txbuf.write(c);
 
-    if (out_fd >= 0)
+    if (data_fd >= 0)
         write(c);
 
     if (outfile)
@@ -276,138 +330,8 @@ SimConsole::out(char c)
 
 }
 
-
-void
-SimConsole::serialize(ostream &os)
-{
-}
-
-void
-SimConsole::unserialize(Checkpoint *cp, const std::string &section)
-{
-}
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
-
-    SimObjectParam<ConsoleListener *> listener;
-    SimObjectParam<IntrControl *> intr_control;
-    Param<string> output;
-    Param<bool> append_name;
-    Param<int> number;
-
-END_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole)
-
-    INIT_PARAM(listener, "console listener"),
-    INIT_PARAM(intr_control, "interrupt controller"),
-    INIT_PARAM(output, "file to dump output to"),
-    INIT_PARAM_DFLT(append_name, "append name() to filename", true),
-    INIT_PARAM_DFLT(number, "console number", 0)
-
-END_INIT_SIM_OBJECT_PARAMS(SimConsole)
-
-CREATE_SIM_OBJECT(SimConsole)
-{
-    string filename = output;
-    ostream *stream = NULL;
-
-    if (!filename.empty()) {
-        if (append_name)
-            filename += "." + getInstanceName();
-        stream = simout.find(filename);
-    }
-
-    SimConsole *console = new SimConsole(getInstanceName(), stream, number);
-    ((ConsoleListener *)listener)->add(console);
-
-    return console;
-}
-
-REGISTER_SIM_OBJECT("SimConsole", SimConsole)
-
-////////////////////////////////////////////////////////////////////////
-//
-//
-
-ConsoleListener::ConsoleListener(const string &name)
-    : SimObject(name), event(NULL)
-{}
-
-ConsoleListener::~ConsoleListener()
-{
-    if (event)
-        delete event;
-}
-
-void
-ConsoleListener::Event::process(int revent)
-{
-    listener->accept();
-}
-
-///////////////////////////////////////////////////////////////////////
-// socket creation and console attach
-//
-
-void
-ConsoleListener::listen(int port)
-{
-    while (!listener.listen(port, true)) {
-        DPRINTF(Console,
-                ": can't bind address console port %d inuse PID %d\n",
-                port, getpid());
-        port++;
-    }
-
-    ccprintf(cerr, "Listening for console connection on port %d\n", port);
-
-    event = new Event(this, listener.getfd(), POLLIN);
-    pollQueue.schedule(event);
-}
-
-void
-ConsoleListener::add(SimConsole *cons)
-{ ConsoleList.push_back(cons);}
-
-void
-ConsoleListener::accept()
-{
-    if (!listener.islistening())
-        panic("%s: cannot accept a connection if not listening!", name());
-
-    int sfd = listener.accept(true);
-    if (sfd != -1) {
-        iter_t i = ConsoleList.begin();
-        iter_t end = ConsoleList.end();
-        if (i == end) {
-            close(sfd);
-        } else {
-            (*i)->attach(sfd, this);
-            i = ConsoleList.erase(i);
-        }
-    }
-}
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(ConsoleListener)
-
-    Param<int> port;
-
-END_DECLARE_SIM_OBJECT_PARAMS(ConsoleListener)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(ConsoleListener)
-
-    INIT_PARAM_DFLT(port, "listen port", 3456)
-
-END_INIT_SIM_OBJECT_PARAMS(ConsoleListener)
-
-CREATE_SIM_OBJECT(ConsoleListener)
+SimConsole *
+SimConsoleParams::create()
 {
-    ConsoleListener *listener = new ConsoleListener(getInstanceName());
-    listener->listen(port);
-
-    return listener;
+    return new SimConsole(this);
 }
-
-REGISTER_SIM_OBJECT("ConsoleListener", ConsoleListener)