read_only = True))
self.intrctrl = IntrControl()
self.mem_mode = mem_mode
- self.sim_console = SimConsole()
+ self.terminal = Terminal()
self.kernel = binary('vmlinux')
self.pal = binary('ts_osfpal')
self.console = binary('console')
read_only = True))
self.intrctrl = IntrControl()
self.mem_mode = mem_mode
- self.sim_console = SimConsole()
+ self.terminal = Terminal()
self.kernel = binary('mips/vmlinux')
self.console = binary('mips/console')
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
SimObject('Ide.py')
SimObject('Pci.py')
SimObject('Platform.py')
- SimObject('SimConsole.py')
SimObject('SimpleDisk.py')
+ SimObject('Terminal.py')
SimObject('Uart.py')
Source('baddev.cc')
Source('pcidev.cc')
Source('pktfifo.cc')
Source('platform.cc')
- Source('simconsole.cc')
Source('simple_disk.cc')
Source('sinic.cc')
+ Source('terminal.cc')
Source('uart.cc')
Source('uart8250.cc')
- TraceFlag('Console')
- TraceFlag('ConsoleVerbose')
TraceFlag('DiskImageRead')
TraceFlag('DiskImageWrite')
TraceFlag('DMA')
TraceFlag('PciConfigAll')
TraceFlag('SimpleDisk')
TraceFlag('SimpleDiskData')
+ TraceFlag('Terminal')
+ TraceFlag('TerminalVerbose')
TraceFlag('Uart')
CompoundFlag('DiskImageAll', [ 'DiskImageRead', 'DiskImageWrite' ])
+++ /dev/null
-# Copyright (c) 2005-2007 The Regents of The University of Michigan
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Nathan Binkert
-
-from m5.SimObject import SimObject
-from m5.params import *
-from m5.proxy import *
-
-class SimConsole(SimObject):
- type = 'SimConsole'
- append_name = Param.Bool(True, "append name() to filename")
- intr_control = Param.IntrControl(Parent.any, "interrupt controller")
- port = Param.TcpPort(3456, "listen port")
- number = Param.Int(0, "console number")
- output = Param.String('console', "file to dump output to")
--- /dev/null
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+
+class Terminal(SimObject):
+ type = 'Terminal'
+ append_name = Param.Bool(True, "append name() to filename")
+ intr_control = Param.IntrControl(Parent.any, "interrupt controller")
+ port = Param.TcpPort(3456, "listen port")
+ number = Param.Int(0, "terminal number")
+ output = Param.String('console', "file to dump output to")
class Uart(BasicPioDevice):
type = 'Uart'
abstract = True
- sim_console = Param.SimConsole(Parent.any, "The console")
+ terminal = Param.Terminal(Parent.any, "The terminal")
class Uart8250(Uart):
type = 'Uart8250'
type = 'AlphaConsole'
cpu = Param.BaseCPU(Parent.cpu[0], "Processor")
disk = Param.SimpleDisk("Simple Disk")
- sim_console = Param.SimConsole(Parent.any, "The Simulator Console")
+ terminal = Param.Terminal(Parent.any, "The console terminal")
system = Param.AlphaSystem(Parent.any, "system object")
fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer')
io = TsunamiIO(pio_addr=0x801fc000000)
uart = Uart8250(pio_addr=0x801fc0003f8)
- console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk)
+ alpha_console = AlphaConsole(pio_addr=0x80200000000,
+ disk=Parent.simple_disk)
# Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the
self.fb.pio = bus.port
self.io.pio = bus.port
self.uart.pio = bus.port
- self.console.pio = bus.port
+ self.alpha_console.pio = bus.port
#include "cpu/thread_context.hh"
#include "dev/alpha/console.hh"
#include "dev/platform.hh"
-#include "dev/simconsole.hh"
#include "dev/simple_disk.hh"
+#include "dev/terminal.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/physical.hh"
using namespace AlphaISA;
AlphaConsole::AlphaConsole(const Params *p)
- : BasicPioDevice(p), disk(p->disk), console(p->sim_console),
+ : BasicPioDevice(p), disk(p->disk), terminal(p->terminal),
system(p->system), cpu(p->cpu)
{
switch (daddr)
{
case offsetof(AlphaAccess, inputChar):
- pkt->set(console->console_in());
+ pkt->set(terminal->console_in());
break;
case offsetof(AlphaAccess, cpuClock):
pkt->set(alphaAccess->cpuClock);
break;
case offsetof(AlphaAccess, outputChar):
- console->out((char)(val & 0xff));
+ terminal->out((char)(val & 0xff));
break;
default:
#include "sim/sim_object.hh"
class BaseCPU;
-class SimConsole;
+class Terminal;
class AlphaSystem;
class SimpleDisk;
SimpleDisk *disk;
/** the system console (the terminal) is accessable from the console */
- SimConsole *console;
+ Terminal *terminal;
/** a pointer to the system we are running in */
AlphaSystem *system;
#include <vector>
#include "cpu/intr_control.hh"
-#include "dev/simconsole.hh"
#include "dev/alpha/tsunami_cchip.hh"
#include "dev/alpha/tsunami_pchip.hh"
#include "dev/alpha/tsunami_io.hh"
#include "dev/alpha/tsunami.hh"
+#include "dev/terminal.hh"
#include "sim/system.hh"
using namespace std;
type = 'MipsConsole'
cpu = Param.BaseCPU(Parent.cpu[0], "Processor")
disk = Param.SimpleDisk("Simple Disk")
- sim_console = Param.SimConsole(Parent.any, "The Simulator Console")
+ terminal = Param.Terminal(Parent.any, "The console terminal")
system = Param.MipsSystem(Parent.any, "system object")
#include "cpu/thread_context.hh"
#include "dev/mips/console.hh"
#include "dev/platform.hh"
-#include "dev/simconsole.hh"
#include "dev/simple_disk.hh"
+#include "dev/terminal.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/physical.hh"
using namespace MipsISA;
MipsConsole::MipsConsole(const Params *p)
- : BasicPioDevice(p), disk(p->disk), console(p->sim_console),
+ : BasicPioDevice(p), disk(p->disk), terminal(p->terminal),
system(p->system), cpu(p->cpu)
{
pkt->set(mipsAccess->intrClockFrequency);
break;
case offsetof(MipsAccess, inputChar):
- pkt->set(console->console_in());
+ pkt->set(terminal->console_in());
break;
case offsetof(MipsAccess, cpuClock):
pkt->set(mipsAccess->cpuClock);
break;
case offsetof(MipsAccess, outputChar):
- console->out((char)(val & 0xff));
+ terminal->out((char)(val & 0xff));
break;
default:
#include "sim/sim_object.hh"
class BaseCPU;
-class SimConsole;
+class Terminal;
class MipsSystem;
class SimpleDisk;
/** the disk must be accessed from the console */
SimpleDisk *disk;
- /** the system console (the terminal) is accessable from the console */
- SimConsole *console;
+ /** the system terminal is accessable from the console */
+ Terminal *terminal;
/** a pointer to the system we are running in */
MipsSystem *system;
#include <vector>
#include "cpu/intr_control.hh"
-#include "dev/simconsole.hh"
#include "dev/mips/malta_cchip.hh"
#include "dev/mips/malta_pchip.hh"
#include "dev/mips/malta_io.hh"
#include "dev/mips/malta.hh"
+#include "dev/terminal.hh"
#include "params/Malta.hh"
#include "sim/system.hh"
class PciConfigAll;
class IntrControl;
-class SimConsole;
+class Terminal;
class Uart;
class System;
+++ /dev/null
-/*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Nathan Binkert
- * Ali Saidi
- */
-
-/* @file
- * Implements the user interface to a serial console
- */
-
-#include <sys/ioctl.h>
-#include <sys/termios.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <poll.h>
-#include <unistd.h>
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-
-#include "base/misc.hh"
-#include "base/output.hh"
-#include "base/socket.hh"
-#include "base/trace.hh"
-#include "dev/platform.hh"
-#include "dev/simconsole.hh"
-#include "dev/uart.hh"
-
-using namespace std;
-
-
-/*
- * Poll event for the listen socket
- */
-SimConsole::ListenEvent::ListenEvent(SimConsole *c, int fd, int e)
- : PollEvent(fd, e), cons(c)
-{
-}
-
-void
-SimConsole::ListenEvent::process(int revent)
-{
- cons->accept();
-}
-
-/*
- * Poll event for the data socket
- */
-SimConsole::DataEvent::DataEvent(SimConsole *c, int fd, int e)
- : PollEvent(fd, e), cons(c)
-{
-}
-
-void
-SimConsole::DataEvent::process(int revent)
-{
- if (revent & POLLIN)
- cons->data();
- else if (revent & POLLNVAL)
- cons->detach();
-}
-
-/*
- * SimConsole code
- */
-SimConsole::SimConsole(const Params *p)
- : SimObject(p), listenEvent(NULL), dataEvent(NULL), number(p->number),
- data_fd(-1), txbuf(16384), rxbuf(16384), outfile(NULL)
-#if TRACING_ON == 1
- , linebuf(16384)
-#endif
-{
- if (!p->output.empty()) {
- if (p->append_name)
- outfile = simout.find(p->output + "." + p->name);
- else
- outfile = simout.find(p->output);
-
- outfile->setf(ios::unitbuf);
- }
-
- if (p->port)
- listen(p->port);
-}
-
-SimConsole::~SimConsole()
-{
- if (data_fd != -1)
- ::close(data_fd);
-
- if (listenEvent)
- delete listenEvent;
-
- if (dataEvent)
- delete dataEvent;
-}
-
-///////////////////////////////////////////////////////////////////////
-// socket creation and console attach
-//
-
-void
-SimConsole::listen(int port)
-{
- while (!listener.listen(port, true)) {
- DPRINTF(Console,
- ": can't bind address console port %d inuse PID %d\n",
- port, getpid());
- port++;
- }
-
- int p1, p2;
- p2 = name().rfind('.') - 1;
- p1 = name().rfind('.', p2);
- ccprintf(cerr, "Listening for %s connection on port %d\n",
- name().substr(p1+1,p2-p1), port);
-
- listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
- pollQueue.schedule(listenEvent);
-}
-
-void
-SimConsole::accept()
-{
- if (!listener.islistening())
- panic("%s: cannot accept a connection if not listening!", name());
-
- int fd = listener.accept(true);
- if (data_fd != -1) {
- char message[] = "console already attached!\n";
- ::write(fd, message, sizeof(message));
- ::close(fd);
- return;
- }
-
- data_fd = fd;
- dataEvent = new DataEvent(this, data_fd, POLLIN);
- pollQueue.schedule(dataEvent);
-
- stringstream stream;
- ccprintf(stream, "==== m5 slave console: Console %d ====", number);
-
- // we need an actual carriage return followed by a newline for the
- // terminal
- stream << "\r\n";
-
- write((const uint8_t *)stream.str().c_str(), stream.str().size());
-
- DPRINTFN("attach console %d\n", number);
-
- txbuf.readall(data_fd);
-}
-
-void
-SimConsole::detach()
-{
- if (data_fd != -1) {
- ::close(data_fd);
- data_fd = -1;
- }
-
- pollQueue.remove(dataEvent);
- delete dataEvent;
- dataEvent = NULL;
-
- DPRINTFN("detach console %d\n", number);
-}
-
-void
-SimConsole::data()
-{
- uint8_t buf[1024];
- int len;
-
- len = read(buf, sizeof(buf));
- if (len) {
- rxbuf.write((char *)buf, len);
- // Inform the UART there is data available
- uart->dataAvailable();
- }
-}
-
-size_t
-SimConsole::read(uint8_t *buf, size_t len)
-{
- if (data_fd < 0)
- panic("Console not properly attached.\n");
-
- size_t ret;
- do {
- ret = ::read(data_fd, buf, len);
- } while (ret == -1 && errno == EINTR);
-
-
- if (ret < 0)
- DPRINTFN("Read failed.\n");
-
- if (ret <= 0) {
- detach();
- return 0;
- }
-
- return ret;
-}
-
-// Console output.
-size_t
-SimConsole::write(const uint8_t *buf, size_t len)
-{
- if (data_fd < 0)
- panic("Console not properly attached.\n");
-
- size_t ret;
- for (;;) {
- ret = ::write(data_fd, buf, len);
-
- if (ret >= 0)
- break;
-
- if (errno != EINTR)
- detach();
- }
-
- return ret;
-}
-
-#define MORE_PENDING (ULL(1) << 61)
-#define RECEIVE_SUCCESS (ULL(0) << 62)
-#define RECEIVE_NONE (ULL(2) << 62)
-#define RECEIVE_ERROR (ULL(3) << 62)
-
-uint8_t
-SimConsole::in()
-{
- bool empty;
- uint8_t c;
-
- empty = rxbuf.empty();
- assert(!empty);
- rxbuf.read((char *)&c, 1);
- empty = rxbuf.empty();
-
-
- DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x more: %d\n",
- isprint(c) ? c : ' ', c, !empty);
-
- return c;
-}
-
-uint64_t
-SimConsole::console_in()
-{
- uint64_t value;
-
- if (dataAvailable()) {
- value = RECEIVE_SUCCESS | in();
- if (!rxbuf.empty())
- value |= MORE_PENDING;
- } else {
- value = RECEIVE_NONE;
- }
-
- DPRINTF(ConsoleVerbose, "console_in: return: %#x\n", value);
-
- return value;
-}
-
-void
-SimConsole::out(char c)
-{
-#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 (data_fd >= 0)
- write(c);
-
- if (outfile)
- outfile->write(&c, 1);
-
- DPRINTF(ConsoleVerbose, "out: \'%c\' %#02x\n",
- isprint(c) ? c : ' ', (int)c);
-
-}
-
-SimConsole *
-SimConsoleParams::create()
-{
- return new SimConsole(this);
-}
+++ /dev/null
-/*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Nathan Binkert
- * Ali Saidi
- */
-
-/* @file
- * User Console Interface
- */
-
-#ifndef __CONSOLE_HH__
-#define __CONSOLE_HH__
-
-#include <iostream>
-
-#include "base/circlebuf.hh"
-#include "cpu/intr_control.hh"
-#include "base/pollevent.hh"
-#include "base/socket.hh"
-#include "sim/sim_object.hh"
-#include "params/SimConsole.hh"
-
-class ConsoleListener;
-class Uart;
-
-class SimConsole : public SimObject
-{
- public:
- Uart *uart;
-
- protected:
- class ListenEvent : public PollEvent
- {
- protected:
- SimConsole *cons;
-
- public:
- ListenEvent(SimConsole *c, int fd, int e);
- void process(int revent);
- };
-
- friend class ListenEvent;
- ListenEvent *listenEvent;
-
- class DataEvent : public PollEvent
- {
- protected:
- SimConsole *cons;
-
- public:
- DataEvent(SimConsole *c, int fd, int e);
- void process(int revent);
- };
-
- friend class DataEvent;
- DataEvent *dataEvent;
-
- protected:
- int number;
- int data_fd;
-
- public:
- typedef SimConsoleParams Params;
- SimConsole(const Params *p);
- ~SimConsole();
-
- protected:
- ListenSocket listener;
-
- void listen(int port);
- void accept();
-
- protected:
- CircleBuf txbuf;
- CircleBuf rxbuf;
- std::ostream *outfile;
-#if TRACING_ON == 1
- CircleBuf linebuf;
-#endif
-
- public:
- ///////////////////////
- // Terminal Interface
-
- void data();
-
- void read(uint8_t &c) { read(&c, 1); }
- size_t read(uint8_t *buf, size_t len);
- void write(uint8_t c) { write(&c, 1); }
- size_t write(const uint8_t *buf, size_t len);
- void detach();
-
- public:
- /////////////////
- // OS interface
-
- // Get a character from the console.
- uint8_t in();
-
- // get a character from the console in the console specific format
- // corresponds to GETC:
- // retval<63:61>
- // 000: success: character received
- // 001: success: character received, more pending
- // 100: failure: no character ready
- // 110: failure: character received with error
- // 111: failure: character received with error, more pending
- // retval<31:0>
- // character read from console
- //
- // Interrupts are cleared when the buffer is empty.
- uint64_t console_in();
-
- // Send a character to the console
- void out(char c);
-
- //Ask the console if data is available
- bool dataAvailable() { return !rxbuf.empty(); }
-};
-
-#endif // __CONSOLE_HH__
from m5.params import *
from m5.proxy import *
from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr
-from Uart import Uart8250
from Platform import Platform
-from SimConsole import SimConsole
+from Terminal import Terminal
+from Uart import Uart8250
class MmDisk(BasicPioDevice):
fake_ssi = IsaFake(pio_addr=0xff00000000, pio_size=0x10000000)
#warn_access="Accessing SSI -- Unimplemented!")
- hconsole = SimConsole()
+ hterm = Terminal()
hvuart = Uart8250(pio_addr=0xfff0c2c000)
htod = DumbTOD()
- pconsole = SimConsole()
+ pterm = Terminal()
puart0 = Uart8250(pio_addr=0x1f10000000)
iob = Iob()
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
- self.hvuart.sim_console = self.hconsole
- self.puart0.sim_console = self.pconsole
+ self.hvuart.terminal = self.hterm
+ self.puart0.terminal = self.pterm
self.fake_clk.pio = bus.port
self.fake_membnks.pio = bus.port
self.fake_l2_1.pio = bus.port
#include <vector>
#include "cpu/intr_control.hh"
-#include "dev/simconsole.hh"
#include "dev/sparc/t1000.hh"
+#include "dev/terminal.hh"
#include "sim/system.hh"
using namespace std;
--- /dev/null
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Ali Saidi
+ */
+
+/* @file
+ * Implements the user interface to a serial terminal
+ */
+
+#include <sys/ioctl.h>
+#include <sys/termios.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <poll.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+
+#include "base/misc.hh"
+#include "base/output.hh"
+#include "base/socket.hh"
+#include "base/trace.hh"
+#include "dev/platform.hh"
+#include "dev/terminal.hh"
+#include "dev/uart.hh"
+
+using namespace std;
+
+
+/*
+ * Poll event for the listen socket
+ */
+Terminal::ListenEvent::ListenEvent(Terminal *t, int fd, int e)
+ : PollEvent(fd, e), term(t)
+{
+}
+
+void
+Terminal::ListenEvent::process(int revent)
+{
+ term->accept();
+}
+
+/*
+ * Poll event for the data socket
+ */
+Terminal::DataEvent::DataEvent(Terminal *t, int fd, int e)
+ : PollEvent(fd, e), term(t)
+{
+}
+
+void
+Terminal::DataEvent::process(int revent)
+{
+ if (revent & POLLIN)
+ term->data();
+ else if (revent & POLLNVAL)
+ term->detach();
+}
+
+/*
+ * 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)
+#if TRACING_ON == 1
+ , linebuf(16384)
+#endif
+{
+ if (!p->output.empty()) {
+ if (p->append_name)
+ outfile = simout.find(p->output + "." + p->name);
+ else
+ outfile = simout.find(p->output);
+
+ outfile->setf(ios::unitbuf);
+ }
+
+ if (p->port)
+ listen(p->port);
+}
+
+Terminal::~Terminal()
+{
+ if (data_fd != -1)
+ ::close(data_fd);
+
+ if (listenEvent)
+ delete listenEvent;
+
+ if (dataEvent)
+ delete dataEvent;
+}
+
+///////////////////////////////////////////////////////////////////////
+// socket creation and terminal attach
+//
+
+void
+Terminal::listen(int port)
+{
+ while (!listener.listen(port, true)) {
+ DPRINTF(Terminal,
+ ": can't bind address terminal port %d inuse PID %d\n",
+ port, getpid());
+ port++;
+ }
+
+ int p1, p2;
+ p2 = name().rfind('.') - 1;
+ p1 = name().rfind('.', p2);
+ ccprintf(cerr, "Listening for %s connection on port %d\n",
+ name().substr(p1+1,p2-p1), port);
+
+ listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
+ pollQueue.schedule(listenEvent);
+}
+
+void
+Terminal::accept()
+{
+ if (!listener.islistening())
+ panic("%s: cannot accept a connection if not listening!", name());
+
+ int fd = listener.accept(true);
+ if (data_fd != -1) {
+ char message[] = "terminal already attached!\n";
+ ::write(fd, message, sizeof(message));
+ ::close(fd);
+ return;
+ }
+
+ data_fd = fd;
+ dataEvent = new DataEvent(this, data_fd, POLLIN);
+ pollQueue.schedule(dataEvent);
+
+ stringstream stream;
+ ccprintf(stream, "==== m5 slave terminal: Terminal %d ====", number);
+
+ // we need an actual carriage return followed by a newline for the
+ // terminal
+ stream << "\r\n";
+
+ write((const uint8_t *)stream.str().c_str(), stream.str().size());
+
+ DPRINTFN("attach terminal %d\n", number);
+
+ txbuf.readall(data_fd);
+}
+
+void
+Terminal::detach()
+{
+ if (data_fd != -1) {
+ ::close(data_fd);
+ data_fd = -1;
+ }
+
+ pollQueue.remove(dataEvent);
+ delete dataEvent;
+ dataEvent = NULL;
+
+ DPRINTFN("detach terminal %d\n", number);
+}
+
+void
+Terminal::data()
+{
+ uint8_t buf[1024];
+ int len;
+
+ len = read(buf, sizeof(buf));
+ if (len) {
+ rxbuf.write((char *)buf, len);
+ // Inform the UART there is data available
+ uart->dataAvailable();
+ }
+}
+
+size_t
+Terminal::read(uint8_t *buf, size_t len)
+{
+ if (data_fd < 0)
+ panic("Terminal not properly attached.\n");
+
+ size_t ret;
+ do {
+ ret = ::read(data_fd, buf, len);
+ } while (ret == -1 && errno == EINTR);
+
+
+ if (ret < 0)
+ DPRINTFN("Read failed.\n");
+
+ if (ret <= 0) {
+ detach();
+ return 0;
+ }
+
+ return ret;
+}
+
+// Terminal output.
+size_t
+Terminal::write(const uint8_t *buf, size_t len)
+{
+ if (data_fd < 0)
+ panic("Terminal not properly attached.\n");
+
+ size_t ret;
+ for (;;) {
+ ret = ::write(data_fd, buf, len);
+
+ if (ret >= 0)
+ break;
+
+ if (errno != EINTR)
+ detach();
+ }
+
+ return ret;
+}
+
+#define MORE_PENDING (ULL(1) << 61)
+#define RECEIVE_SUCCESS (ULL(0) << 62)
+#define RECEIVE_NONE (ULL(2) << 62)
+#define RECEIVE_ERROR (ULL(3) << 62)
+
+uint8_t
+Terminal::in()
+{
+ bool empty;
+ uint8_t c;
+
+ empty = rxbuf.empty();
+ assert(!empty);
+ rxbuf.read((char *)&c, 1);
+ empty = rxbuf.empty();
+
+
+ DPRINTF(TerminalVerbose, "in: \'%c\' %#02x more: %d\n",
+ isprint(c) ? c : ' ', c, !empty);
+
+ return c;
+}
+
+uint64_t
+Terminal::console_in()
+{
+ uint64_t value;
+
+ if (dataAvailable()) {
+ value = RECEIVE_SUCCESS | in();
+ if (!rxbuf.empty())
+ value |= MORE_PENDING;
+ } else {
+ value = RECEIVE_NONE;
+ }
+
+ DPRINTF(TerminalVerbose, "console_in: return: %#x\n", value);
+
+ return value;
+}
+
+void
+Terminal::out(char c)
+{
+#if TRACING_ON == 1
+ if (DTRACE(Terminal)) {
+ 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(Terminal, "%s\n", buffer);
+ delete [] buffer;
+ } else {
+ linebuf.write(c);
+ }
+ }
+
+ last = c;
+ }
+#endif
+
+ txbuf.write(c);
+
+ if (data_fd >= 0)
+ write(c);
+
+ if (outfile)
+ outfile->write(&c, 1);
+
+ DPRINTF(TerminalVerbose, "out: \'%c\' %#02x\n",
+ isprint(c) ? c : ' ', (int)c);
+
+}
+
+Terminal *
+TerminalParams::create()
+{
+ return new Terminal(this);
+}
--- /dev/null
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Ali Saidi
+ */
+
+/* @file
+ * User Terminal Interface
+ */
+
+#ifndef __DEV_TERMINAL_HH__
+#define __DEV_TERMINAL_HH__
+
+#include <iostream>
+
+#include "base/circlebuf.hh"
+#include "cpu/intr_control.hh"
+#include "base/pollevent.hh"
+#include "base/socket.hh"
+#include "sim/sim_object.hh"
+#include "params/Terminal.hh"
+
+class TerminalListener;
+class Uart;
+
+class Terminal : public SimObject
+{
+ public:
+ Uart *uart;
+
+ protected:
+ class ListenEvent : public PollEvent
+ {
+ protected:
+ Terminal *term;
+
+ public:
+ ListenEvent(Terminal *t, int fd, int e);
+ void process(int revent);
+ };
+
+ friend class ListenEvent;
+ ListenEvent *listenEvent;
+
+ class DataEvent : public PollEvent
+ {
+ protected:
+ Terminal *term;
+
+ public:
+ DataEvent(Terminal *t, int fd, int e);
+ void process(int revent);
+ };
+
+ friend class DataEvent;
+ DataEvent *dataEvent;
+
+ protected:
+ int number;
+ int data_fd;
+
+ public:
+ typedef TerminalParams Params;
+ Terminal(const Params *p);
+ ~Terminal();
+
+ protected:
+ ListenSocket listener;
+
+ void listen(int port);
+ void accept();
+
+ protected:
+ CircleBuf txbuf;
+ CircleBuf rxbuf;
+ std::ostream *outfile;
+#if TRACING_ON == 1
+ CircleBuf linebuf;
+#endif
+
+ public:
+ ///////////////////////
+ // Terminal Interface
+
+ void data();
+
+ void read(uint8_t &c) { read(&c, 1); }
+ size_t read(uint8_t *buf, size_t len);
+ void write(uint8_t c) { write(&c, 1); }
+ size_t write(const uint8_t *buf, size_t len);
+ void detach();
+
+ public:
+ /////////////////
+ // OS interface
+
+ // Get a character from the terminal.
+ uint8_t in();
+
+ // get a character from the terminal in the console specific format
+ // corresponds to GETC:
+ // retval<63:61>
+ // 000: success: character received
+ // 001: success: character received, more pending
+ // 100: failure: no character ready
+ // 110: failure: character received with error
+ // 111: failure: character received with error, more pending
+ // retval<31:0>
+ // character read from console
+ //
+ // Interrupts are cleared when the buffer is empty.
+ uint64_t console_in();
+
+ // Send a character to the terminal
+ void out(char c);
+
+ // Ask the terminal if data is available
+ bool dataAvailable() { return !rxbuf.empty(); }
+};
+
+#endif // __DEV_TERMINAL_HH__
* Implements a base class for UARTs
*/
-#include "dev/simconsole.hh"
-#include "dev/uart.hh"
#include "dev/platform.hh"
+#include "dev/terminal.hh"
+#include "dev/uart.hh"
using namespace std;
Uart::Uart(const Params *p)
- : BasicPioDevice(p), platform(p->platform), cons(p->sim_console)
+ : BasicPioDevice(p), platform(p->platform), term(p->terminal)
{
status = 0;
// set back pointers
- cons->uart = this;
+ term->uart = this;
}
#include "dev/io_device.hh"
#include "params/Uart.hh"
-class SimConsole;
+class Terminal;
class Platform;
const int RX_INT = 0x1;
protected:
int status;
Platform *platform;
- SimConsole *cons;
+ Terminal *term;
public:
typedef UartParams Params;
#include "base/inifile.hh"
#include "base/str.hh" // for to_number
#include "base/trace.hh"
-#include "dev/simconsole.hh"
-#include "dev/uart8250.hh"
#include "dev/platform.hh"
+#include "dev/terminal.hh"
+#include "dev/uart8250.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
switch (daddr) {
case 0x0:
if (!(LCR & 0x80)) { // read byte
- if (cons->dataAvailable())
- pkt->set(cons->in());
+ if (term->dataAvailable())
+ pkt->set(term->in());
else {
pkt->set((uint8_t)0);
// A limited amount of these are ok.
status &= ~RX_INT;
platform->clearConsoleInt();
- if (cons->dataAvailable() && (IER & UART_IER_RDI))
+ if (term->dataAvailable() && (IER & UART_IER_RDI))
rxIntrEvent.scheduleIntr();
} else { // dll divisor latch
;
uint8_t lsr;
lsr = 0;
// check if there are any bytes to be read
- if (cons->dataAvailable())
+ if (term->dataAvailable())
lsr = UART_LSR_DR;
lsr |= UART_LSR_TEMT | UART_LSR_THRE;
pkt->set(lsr);
switch (daddr) {
case 0x0:
if (!(LCR & 0x80)) { // write byte
- cons->out(pkt->get<uint8_t>());
+ term->out(pkt->get<uint8_t>());
platform->clearConsoleInt();
status &= ~TX_INT;
if (UART_IER_THRI & IER)
status &= ~TX_INT;
}
- if ((UART_IER_RDI & IER) && cons->dataAvailable()) {
+ if ((UART_IER_RDI & IER) && term->dataAvailable()) {
DPRINTF(Uart, "IER: IER_RDI set, scheduling RX intrrupt\n");
rxIntrEvent.scheduleIntr();
} else {
const uint8_t UART_MCR_LOOP = 0x10;
-class SimConsole;
+class Terminal;
class Platform;
class Uart8250 : public Uart
from m5.params import *
from m5.proxy import *
-from Uart import Uart8250
+
from Device import IsaFake
-from SouthBridge import SouthBridge
-from Platform import Platform
from Pci import PciConfigAll
-from SimConsole import SimConsole
+from Platform import Platform
+from SouthBridge import SouthBridge
+from Terminal import Terminal
+from Uart import Uart8250
def x86IOAddress(port):
IO_address_space_base = 0x8000000000000000
# but the linux kernel fiddles with them anway.
behind_pci = IsaFake(pio_addr=x86IOAddress(0xcf8), pio_size=8)
- # Serial port and console
- console = SimConsole()
+ # Serial port and terminal
+ terminal = Terminal()
com_1 = Uart8250()
com_1.pio_addr = x86IOAddress(0x3f8)
- com_1.sim_console = console
+ com_1.terminal = terminal
def attachIO(self, bus):
self.south_bridge.pio = bus.port
#include "arch/x86/x86_traits.hh"
#include "dev/intel_8254_timer.hh"
#include "cpu/intr_control.hh"
-#include "dev/simconsole.hh"
+#include "dev/terminal.hh"
#include "dev/x86/pc.hh"
#include "sim/system.hh"