summaryrefslogtreecommitdiff
path: root/src/dev
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 /src/dev
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.
Diffstat (limited to 'src/dev')
-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__