summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2014-09-20 17:17:50 -0400
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2014-09-20 17:17:50 -0400
commit0c5139310d634d6d366f4120d88deef66c9266af (patch)
treec86dc547b8eeb36f3e6d78589889e4e2335d7f9f
parent0fa128bbd0a53a3428fa2028b8754e15c9ef7c38 (diff)
downloadgem5-0c5139310d634d6d366f4120d88deef66c9266af.tar.xz
dev: Refactor terminal<->UART interface to make it more generic
The terminal currently assumes that the transport to the guest always inherits from the Uart class. This assumption breaks when implementing, for example, a VirtIO consoles. This patch removes this assumption by adding pointer to the from the terminal to the uart and replacing it with a more general callback interface. The Uart, or any other class using the terminal, class implements an instance of the callbacks class and registers it with the terminal.
-rw-r--r--src/dev/terminal.cc18
-rw-r--r--src/dev/terminal.hh17
-rw-r--r--src/dev/uart.cc8
-rw-r--r--src/dev/uart.hh6
4 files changed, 39 insertions, 10 deletions
diff --git a/src/dev/terminal.cc b/src/dev/terminal.cc
index e70a8775f..895069774 100644
--- a/src/dev/terminal.cc
+++ b/src/dev/terminal.cc
@@ -99,8 +99,8 @@ Terminal::DataEvent::process(int revent)
* Terminal code
*/
Terminal::Terminal(const Params *p)
- : SimObject(p), listenEvent(NULL), dataEvent(NULL), number(p->number),
- data_fd(-1), txbuf(16384), rxbuf(16384), outfile(NULL)
+ : SimObject(p), termDataAvail(NULL), listenEvent(NULL), dataEvent(NULL),
+ number(p->number), data_fd(-1), txbuf(16384), rxbuf(16384), outfile(NULL)
#if TRACING_ON == 1
, linebuf(16384)
#endif
@@ -129,6 +129,17 @@ Terminal::~Terminal()
delete dataEvent;
}
+void
+Terminal::regDataAvailCallback(Callback *c)
+{
+ // This can happen if the user has connected multiple UARTs to the
+ // same terminal. In that case, each of them tries to register
+ // callbacks.
+ if (termDataAvail)
+ fatal("Terminal already has already been associated with a UART.\n");
+ termDataAvail = c;
+}
+
///////////////////////////////////////////////////////////////////////
// socket creation and terminal attach
//
@@ -215,7 +226,8 @@ Terminal::data()
if (len) {
rxbuf.write((char *)buf, len);
// Inform the UART there is data available
- uart->dataAvailable();
+ assert(termDataAvail);
+ termDataAvail->process();
}
}
diff --git a/src/dev/terminal.hh b/src/dev/terminal.hh
index e2322d7c2..f7a860ac5 100644
--- a/src/dev/terminal.hh
+++ b/src/dev/terminal.hh
@@ -38,6 +38,7 @@
#include <iostream>
+#include "base/callback.hh"
#include "base/circlebuf.hh"
#include "base/pollevent.hh"
#include "base/socket.hh"
@@ -46,12 +47,24 @@
#include "sim/sim_object.hh"
class TerminalListener;
-class Uart;
class Terminal : public SimObject
{
public:
- Uart *uart;
+ /**
+ * Register a data available callback into the transport layer.
+ *
+ * The terminal needs to call the underlying transport layer to
+ * inform it of available data. The transport layer uses this
+ * method to register a callback that informs it of pending data.
+ *
+ * @param c Callback instance from transport layer.
+ */
+ void regDataAvailCallback(Callback *c);
+
+ protected:
+ /** Currently registered transport layer callbacks */
+ Callback *termDataAvail;
protected:
class ListenEvent : public PollEvent
diff --git a/src/dev/uart.cc b/src/dev/uart.cc
index 084511444..f232f0f28 100644
--- a/src/dev/uart.cc
+++ b/src/dev/uart.cc
@@ -39,10 +39,12 @@
using namespace std;
Uart::Uart(const Params *p, Addr pio_size)
- : BasicPioDevice(p, pio_size), platform(p->platform), term(p->terminal)
+ : BasicPioDevice(p, pio_size),
+ platform(p->platform), term(p->terminal),
+ callbackDataAvail(this)
{
status = 0;
- // set back pointers
- term->uart = this;
+ // setup terminal callbacks
+ term->regDataAvailCallback(&callbackDataAvail);
}
diff --git a/src/dev/uart.hh b/src/dev/uart.hh
index f1a26fda8..6c9c08ee7 100644
--- a/src/dev/uart.hh
+++ b/src/dev/uart.hh
@@ -36,9 +36,9 @@
#define __UART_HH__
#include "dev/io_device.hh"
+#include "dev/terminal.hh"
#include "params/Uart.hh"
-class Terminal;
class Platform;
const int RX_INT = 0x1;
@@ -46,7 +46,6 @@ const int TX_INT = 0x2;
class Uart : public BasicPioDevice
{
-
protected:
int status;
Platform *platform;
@@ -72,6 +71,9 @@ class Uart : public BasicPioDevice
* @return interrupt status
*/
bool intStatus() { return status ? true : false; }
+
+ protected:
+ MakeCallback<Uart, &Uart::dataAvailable> callbackDataAvail;
};
#endif // __UART_HH__