From 0c5139310d634d6d366f4120d88deef66c9266af Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Sat, 20 Sep 2014 17:17:50 -0400 Subject: [PATCH] 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. --- src/dev/terminal.cc | 18 +++++++++++++++--- src/dev/terminal.hh | 17 +++++++++++++++-- src/dev/uart.cc | 8 +++++--- src/dev/uart.hh | 6 ++++-- 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 +#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 callbackDataAvail; }; #endif // __UART_HH__ -- 2.30.2