A little bit of code here and there to get more access to

what the console output is.

base/circlebuf.hh:
base/circlebuf.cc:
    add stuff to spit to an ostream
    prepend _ in front of protected member variables
    formatting
dev/console.hh:
dev/console.cc:
    Add DPRINTF to spit out the lines of console data
dev/console.cc:
    little hack to append name() to the file so that we can
    easily get multiple output files.
dev/console.hh:
    TRACING_ON == 1 not defined(TRACING_ON)

--HG--
extra : convert_revision : bbe80715fb97ee4c4ed6b484955ef71289f09fc9
This commit is contained in:
Nathan Binkert 2003-11-04 17:43:41 -05:00
parent a7635fa6ef
commit 247984bc22
4 changed files with 178 additions and 115 deletions

View file

@ -40,148 +40,174 @@
using namespace std; using namespace std;
CircleBuf::CircleBuf(int l) CircleBuf::CircleBuf(int l)
: rollover(false), buflen(l), size(0), start(0), stop(0) : _rollover(false), _buflen(l), _size(0), _start(0), _stop(0)
{ buf = new char[buflen]; } {
_buf = new char[_buflen];
}
CircleBuf::~CircleBuf() CircleBuf::~CircleBuf()
{ if (buf) delete [] buf; } {
if (_buf)
delete [] _buf;
}
void void
CircleBuf::dump() CircleBuf::dump()
{ {
cprintf("start = %10d, stop = %10d, buflen = %10d\n", start, stop, buflen); cprintf("start = %10d, stop = %10d, buflen = %10d\n",
fflush(stdout); _start, _stop, _buflen);
::write(STDOUT_FILENO, buf, buflen); fflush(stdout);
::write(STDOUT_FILENO, "<\n", 2); ::write(STDOUT_FILENO, _buf, _buflen);
::write(STDOUT_FILENO, "<\n", 2);
} }
void void
CircleBuf::flush() CircleBuf::flush()
{ {
start = 0; _start = 0;
stop = 0; _stop = 0;
rollover = false; _rollover = false;
} }
void void
CircleBuf::read(char *b, int len) CircleBuf::read(char *b, int len)
{ {
size -= len; _size -= len;
if (size < 0) if (_size < 0)
size = 0; _size = 0;
if (stop > start) { if (_stop > _start) {
len = min(len, stop - start); len = min(len, _stop - _start);
memcpy(b, buf + start, len); memcpy(b, _buf + _start, len);
start += len; _start += len;
}
else {
int endlen = buflen - start;
if (endlen > len) {
memcpy(b, buf + start, len);
start += len;
} }
else { else {
memcpy(b, buf + start, endlen); int endlen = _buflen - _start;
start = min(len - endlen, stop); if (endlen > len) {
memcpy(b + endlen, buf, start); memcpy(b, _buf + _start, len);
_start += len;
}
else {
memcpy(b, _buf + _start, endlen);
_start = min(len - endlen, _stop);
memcpy(b + endlen, _buf, _start);
}
} }
}
} }
void void
CircleBuf::read(int fd, int len) CircleBuf::read(int fd, int len)
{ {
size -= len; _size -= len;
if (size < 0) if (_size < 0)
size = 0; _size = 0;
if (stop > start) { if (_stop > _start) {
len = min(len, stop - start); len = min(len, _stop - _start);
::write(fd, buf + start, len); ::write(fd, _buf + _start, len);
start += len; _start += len;
}
else {
int endlen = buflen - start;
if (endlen > len) {
::write(fd, buf + start, len);
start += len;
} }
else { else {
::write(fd, buf + start, endlen); int endlen = _buflen - _start;
start = min(len - endlen, stop); if (endlen > len) {
::write(fd, buf, start); ::write(fd, _buf + _start, len);
_start += len;
}
else {
::write(fd, _buf + _start, endlen);
_start = min(len - endlen, _stop);
::write(fd, _buf, _start);
}
} }
}
} }
void void
CircleBuf::read(int fd) CircleBuf::read(int fd)
{ {
size = 0; _size = 0;
if (stop > start) { if (_stop > _start) {
::write(fd, buf + start, stop - start); ::write(fd, _buf + _start, _stop - _start);
} }
else { else {
::write(fd, buf + start, buflen - start); ::write(fd, _buf + _start, _buflen - _start);
::write(fd, buf, stop); ::write(fd, _buf, _stop);
} }
start = stop; _start = _stop;
}
void
CircleBuf::read(ostream &out)
{
_size = 0;
if (_stop > _start) {
out.write(_buf + _start, _stop - _start);
}
else {
out.write(_buf + _start, _buflen - _start);
out.write(_buf, _stop);
}
_start = _stop;
} }
void void
CircleBuf::readall(int fd) CircleBuf::readall(int fd)
{ {
if (rollover) if (_rollover)
::write(fd, buf + stop, buflen - stop); ::write(fd, _buf + _stop, _buflen - _stop);
::write(fd, buf, stop); ::write(fd, _buf, _stop);
start = stop; _start = _stop;
} }
void void
CircleBuf::write(char b) CircleBuf::write(char b)
{ write(&b, 1); } {
write(&b, 1);
}
void void
CircleBuf::write(const char *b) CircleBuf::write(const char *b)
{ write(b, strlen(b)); } {
write(b, strlen(b));
}
void void
CircleBuf::write(const char *b, int len) CircleBuf::write(const char *b, int len)
{ {
if (len <= 0) if (len <= 0)
return; return;
size += len; _size += len;
if (size > buflen) if (_size > _buflen)
size = buflen; _size = _buflen;
int old_start = start; int old_start = _start;
int old_stop = stop; int old_stop = _stop;
if (len >= buflen) { if (len >= _buflen) {
start = 0; _start = 0;
stop = buflen; _stop = _buflen;
rollover = true; _rollover = true;
memcpy(buf, b + (len - buflen), buflen); memcpy(_buf, b + (len - _buflen), _buflen);
return; return;
} }
if (stop + len <= buflen) { if (_stop + len <= _buflen) {
memcpy(buf + stop, b, len); memcpy(_buf + _stop, b, len);
stop += len; _stop += len;
} else { } else {
int end_len = buflen - old_stop; int end_len = _buflen - old_stop;
stop = len - end_len; _stop = len - end_len;
memcpy(buf + old_stop, b, end_len); memcpy(_buf + old_stop, b, end_len);
memcpy(buf, b + end_len, stop); memcpy(_buf, b + end_len, _stop);
rollover = true; _rollover = true;
} }
if (old_start > old_stop && old_start < stop || if (old_start > old_stop && old_start < _stop ||
old_start < old_stop && stop < old_stop) old_start < old_stop && _stop < old_stop)
start = stop + 1; _start = _stop + 1;
} }

View file

@ -29,31 +29,34 @@
#ifndef __CIRCLEBUF_HH__ #ifndef __CIRCLEBUF_HH__
#define __CIRCLEBUF_HH__ #define __CIRCLEBUF_HH__
#include <iosfwd>
class CircleBuf class CircleBuf
{ {
protected: protected:
char *buf; char *_buf;
bool rollover; bool _rollover;
int buflen; int _buflen;
int size; int _size;
int start; int _start;
int stop; int _stop;
public: public:
explicit CircleBuf(int l); explicit CircleBuf(int l);
~CircleBuf(); ~CircleBuf();
bool empty() { return size == 0; } bool empty() const { return _size == 0; }
void dump(); int size() const { return _size; }
void flush(); void dump();
void read(char *b, int len); void flush();
void read(int fd, int len); void read(char *b, int len);
void read(int fd); void read(int fd, int len);
void readall(int fd); void read(int fd);
void write(char b); void read(std::ostream &out);
void write(const char *b); void readall(int fd);
void write(const char *b, int len); void write(char b);
void write(const char *b);
void write(const char *b, int len);
}; };
#endif // __CIRCLEBUF_HH__ #endif // __CIRCLEBUF_HH__

View file

@ -73,6 +73,9 @@ SimConsole::Event::process(int revent)
SimConsole::SimConsole(const string &name, const string &file, int num) SimConsole::SimConsole(const string &name, const string &file, int num)
: SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1), : SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1),
listener(NULL), txbuf(16384), rxbuf(16384), outfile(NULL), listener(NULL), txbuf(16384), rxbuf(16384), outfile(NULL),
#if TRACING_ON == 1
linebuf(16384),
#endif
_status(0), _enable(0), intr(NULL) _status(0), _enable(0), intr(NULL)
{ {
if (!file.empty()) if (!file.empty())
@ -231,7 +234,7 @@ SimConsole::in()
char c; char c;
rxbuf.read(&c, 1); rxbuf.read(&c, 1);
DPRINTF(Console, "in: \'%c\' %#02x status: %#x\n", DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x status: %#x\n",
isprint(c) ? c : ' ', c, _status); isprint(c) ? c : ' ', c, _status);
return c; return c;
@ -240,6 +243,28 @@ SimConsole::in()
void void
SimConsole::out(char c, bool raise_int) SimConsole::out(char c, bool raise_int)
{ {
#if TRACING_ON == 1
if (DTRACE(Console)) {
static char last = '\0';
if (c != '\n' && c != '\r' ||
last != '\n' && last != '\r') {
if (c == '\n' || c == '\r') {
int size = linebuf.size();
char *buffer = new char[size + 1];
linebuf.read(buffer, size);
buffer[size] = '\0';
DPRINTF(Console, "%s\n", buffer);
delete [] buffer;
} else {
linebuf.write(c);
}
}
last = c;
}
#endif
txbuf.write(c); txbuf.write(c);
if (out_fd >= 0) if (out_fd >= 0)
@ -251,13 +276,13 @@ SimConsole::out(char c, bool raise_int)
if (raise_int) if (raise_int)
raiseInt(TransmitInterrupt); raiseInt(TransmitInterrupt);
DPRINTF(Console, "out: \'%c\' %#02x", DPRINTF(ConsoleVerbose, "out: \'%c\' %#02x",
isprint(c) ? c : ' ', (int)c); isprint(c) ? c : ' ', (int)c);
if (raise_int) if (raise_int)
DPRINTF(Console, "status: %#x\n", _status); DPRINTF(ConsoleVerbose, "status: %#x\n", _status);
else else
DPRINTF(Console, "\n"); DPRINTF(ConsoleVerbose, "\n");
} }
inline bool inline bool
@ -329,6 +354,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
SimObjectParam<ConsoleListener *> listener; SimObjectParam<ConsoleListener *> listener;
SimObjectParam<IntrControl *> intr_control; SimObjectParam<IntrControl *> intr_control;
Param<string> output; Param<string> output;
Param<bool> append_name;
Param<int> number; Param<int> number;
END_DECLARE_SIM_OBJECT_PARAMS(SimConsole) END_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
@ -338,13 +364,17 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole)
INIT_PARAM(listener, "console listener"), INIT_PARAM(listener, "console listener"),
INIT_PARAM(intr_control, "interrupt controller"), INIT_PARAM(intr_control, "interrupt controller"),
INIT_PARAM_DFLT(output, "file to dump output to", ""), INIT_PARAM_DFLT(output, "file to dump output to", ""),
INIT_PARAM_DFLT(append_name, "append name() to filename", true),
INIT_PARAM_DFLT(number, "console number", 0) INIT_PARAM_DFLT(number, "console number", 0)
END_INIT_SIM_OBJECT_PARAMS(SimConsole) END_INIT_SIM_OBJECT_PARAMS(SimConsole)
CREATE_SIM_OBJECT(SimConsole) CREATE_SIM_OBJECT(SimConsole)
{ {
SimConsole *console = new SimConsole(getInstanceName(), output, number); string filename = output;
if (!filename.empty() && append_name)
filename += "." + getInstanceName();
SimConsole *console = new SimConsole(getInstanceName(), filename, number);
((ConsoleListener *)listener)->add(console); ((ConsoleListener *)listener)->add(console);
((SimConsole *)console)->initInt(intr_control); ((SimConsole *)console)->initInt(intr_control);
((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt | ((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt |
@ -383,12 +413,14 @@ void
ConsoleListener::listen(int port) ConsoleListener::listen(int port)
{ {
while (!listener.listen(port, true)) { while (!listener.listen(port, true)) {
DPRINTF(Console, ": can't bind address console port %d inuse PID %d\n", DPRINTF(Console,
": can't bind address console port %d inuse PID %d\n",
port, getpid()); port, getpid());
port++; port++;
} }
cerr << "Listening for console connection on port " << port << endl; ccprintf(cerr, "Listening for console connection on port %d\n", port);
event = new Event(this, listener.getfd(), POLLIN); event = new Event(this, listener.getfd(), POLLIN);
pollQueue.schedule(event); pollQueue.schedule(event);
} }
@ -401,8 +433,7 @@ void
ConsoleListener::accept() ConsoleListener::accept()
{ {
if (!listener.islistening()) if (!listener.islistening())
panic("%s: cannot accept a connection if we're not listening!", panic("%s: cannot accept a connection if not listening!", name());
name());
int sfd = listener.accept(true); int sfd = listener.accept(true);
if (sfd != -1) { if (sfd != -1) {

View file

@ -74,6 +74,9 @@ class SimConsole : public SimObject
CircleBuf txbuf; CircleBuf txbuf;
CircleBuf rxbuf; CircleBuf rxbuf;
std::ostream *outfile; std::ostream *outfile;
#if TRACING_ON == 1
CircleBuf linebuf;
#endif
public: public:
/////////////////////// ///////////////////////