using namespace std;
CircleBuf::CircleBuf(int l)
- : rollover(false), buflen(l), size(0), start(0), stop(0)
-{ buf = new char[buflen]; }
+ : _rollover(false), _buflen(l), _size(0), _start(0), _stop(0)
+{
+ _buf = new char[_buflen];
+}
CircleBuf::~CircleBuf()
-{ if (buf) delete [] buf; }
+{
+ if (_buf)
+ delete [] _buf;
+}
void
CircleBuf::dump()
{
- cprintf("start = %10d, stop = %10d, buflen = %10d\n", start, stop, buflen);
- fflush(stdout);
- ::write(STDOUT_FILENO, buf, buflen);
- ::write(STDOUT_FILENO, "<\n", 2);
+ cprintf("start = %10d, stop = %10d, buflen = %10d\n",
+ _start, _stop, _buflen);
+ fflush(stdout);
+ ::write(STDOUT_FILENO, _buf, _buflen);
+ ::write(STDOUT_FILENO, "<\n", 2);
}
void
CircleBuf::flush()
{
- start = 0;
- stop = 0;
- rollover = false;
+ _start = 0;
+ _stop = 0;
+ _rollover = false;
}
void
CircleBuf::read(char *b, int len)
{
- size -= len;
- if (size < 0)
- size = 0;
-
- if (stop > start) {
- len = min(len, stop - start);
- memcpy(b, buf + start, len);
- start += len;
- }
- else {
- int endlen = buflen - start;
- if (endlen > len) {
- memcpy(b, buf + start, len);
- start += len;
+ _size -= len;
+ if (_size < 0)
+ _size = 0;
+
+ if (_stop > _start) {
+ len = min(len, _stop - _start);
+ memcpy(b, _buf + _start, len);
+ _start += len;
}
else {
- memcpy(b, buf + start, endlen);
- start = min(len - endlen, stop);
- memcpy(b + endlen, buf, start);
+ int endlen = _buflen - _start;
+ if (endlen > len) {
+ memcpy(b, _buf + _start, len);
+ _start += len;
+ }
+ else {
+ memcpy(b, _buf + _start, endlen);
+ _start = min(len - endlen, _stop);
+ memcpy(b + endlen, _buf, _start);
+ }
}
- }
}
void
CircleBuf::read(int fd, int len)
{
- size -= len;
- if (size < 0)
- size = 0;
-
- if (stop > start) {
- len = min(len, stop - start);
- ::write(fd, buf + start, len);
- start += len;
- }
- else {
- int endlen = buflen - start;
- if (endlen > len) {
- ::write(fd, buf + start, len);
- start += len;
+ _size -= len;
+ if (_size < 0)
+ _size = 0;
+
+ if (_stop > _start) {
+ len = min(len, _stop - _start);
+ ::write(fd, _buf + _start, len);
+ _start += len;
}
else {
- ::write(fd, buf + start, endlen);
- start = min(len - endlen, stop);
- ::write(fd, buf, start);
+ int endlen = _buflen - _start;
+ if (endlen > len) {
+ ::write(fd, _buf + _start, len);
+ _start += len;
+ }
+ else {
+ ::write(fd, _buf + _start, endlen);
+ _start = min(len - endlen, _stop);
+ ::write(fd, _buf, _start);
+ }
}
- }
}
void
CircleBuf::read(int fd)
{
- size = 0;
+ _size = 0;
+
+ if (_stop > _start) {
+ ::write(fd, _buf + _start, _stop - _start);
+ }
+ else {
+ ::write(fd, _buf + _start, _buflen - _start);
+ ::write(fd, _buf, _stop);
+ }
+
+ _start = _stop;
+}
+
+void
+CircleBuf::read(ostream &out)
+{
+ _size = 0;
- if (stop > start) {
- ::write(fd, buf + start, stop - start);
- }
- else {
- ::write(fd, buf + start, buflen - start);
- ::write(fd, buf, stop);
- }
+ if (_stop > _start) {
+ out.write(_buf + _start, _stop - _start);
+ }
+ else {
+ out.write(_buf + _start, _buflen - _start);
+ out.write(_buf, _stop);
+ }
- start = stop;
+ _start = _stop;
}
void
CircleBuf::readall(int fd)
{
- if (rollover)
- ::write(fd, buf + stop, buflen - stop);
+ if (_rollover)
+ ::write(fd, _buf + _stop, _buflen - _stop);
- ::write(fd, buf, stop);
- start = stop;
+ ::write(fd, _buf, _stop);
+ _start = _stop;
}
void
CircleBuf::write(char b)
-{ write(&b, 1); }
+{
+ write(&b, 1);
+}
void
CircleBuf::write(const char *b)
-{ write(b, strlen(b)); }
+{
+ write(b, strlen(b));
+}
void
CircleBuf::write(const char *b, int len)
{
- if (len <= 0)
- return;
-
- size += len;
- if (size > buflen)
- size = buflen;
-
- int old_start = start;
- int old_stop = stop;
-
- if (len >= buflen) {
- start = 0;
- stop = buflen;
- rollover = true;
- memcpy(buf, b + (len - buflen), buflen);
- return;
- }
-
- if (stop + len <= buflen) {
- memcpy(buf + stop, b, len);
- stop += len;
- } else {
- int end_len = buflen - old_stop;
- stop = len - end_len;
- memcpy(buf + old_stop, b, end_len);
- memcpy(buf, b + end_len, stop);
- rollover = true;
- }
-
- if (old_start > old_stop && old_start < stop ||
- old_start < old_stop && stop < old_stop)
- start = stop + 1;
+ if (len <= 0)
+ return;
+
+ _size += len;
+ if (_size > _buflen)
+ _size = _buflen;
+
+ int old_start = _start;
+ int old_stop = _stop;
+
+ if (len >= _buflen) {
+ _start = 0;
+ _stop = _buflen;
+ _rollover = true;
+ memcpy(_buf, b + (len - _buflen), _buflen);
+ return;
+ }
+
+ if (_stop + len <= _buflen) {
+ memcpy(_buf + _stop, b, len);
+ _stop += len;
+ } else {
+ int end_len = _buflen - old_stop;
+ _stop = len - end_len;
+ memcpy(_buf + old_stop, b, end_len);
+ memcpy(_buf, b + end_len, _stop);
+ _rollover = true;
+ }
+
+ if (old_start > old_stop && old_start < _stop ||
+ old_start < old_stop && _stop < old_stop)
+ _start = _stop + 1;
}
SimConsole::SimConsole(const string &name, const string &file, int num)
: SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1),
listener(NULL), txbuf(16384), rxbuf(16384), outfile(NULL),
+#if TRACING_ON == 1
+ linebuf(16384),
+#endif
_status(0), _enable(0), intr(NULL)
{
if (!file.empty())
char c;
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);
return c;
void
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);
if (out_fd >= 0)
if (raise_int)
raiseInt(TransmitInterrupt);
- DPRINTF(Console, "out: \'%c\' %#02x",
+ DPRINTF(ConsoleVerbose, "out: \'%c\' %#02x",
isprint(c) ? c : ' ', (int)c);
if (raise_int)
- DPRINTF(Console, "status: %#x\n", _status);
+ DPRINTF(ConsoleVerbose, "status: %#x\n", _status);
else
- DPRINTF(Console, "\n");
+ DPRINTF(ConsoleVerbose, "\n");
}
inline bool
SimObjectParam<ConsoleListener *> listener;
SimObjectParam<IntrControl *> intr_control;
Param<string> output;
+ Param<bool> append_name;
Param<int> number;
END_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
INIT_PARAM(listener, "console listener"),
INIT_PARAM(intr_control, "interrupt controller"),
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)
END_INIT_SIM_OBJECT_PARAMS(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);
((SimConsole *)console)->initInt(intr_control);
((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt |
ConsoleListener::listen(int port)
{
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++;
}
- 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);
pollQueue.schedule(event);
}
ConsoleListener::accept()
{
if (!listener.islistening())
- panic("%s: cannot accept a connection if we're not listening!",
- name());
+ panic("%s: cannot accept a connection if not listening!", name());
int sfd = listener.accept(true);
if (sfd != -1) {