summaryrefslogtreecommitdiff
path: root/dev/tsunami_uart.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/tsunami_uart.cc')
-rw-r--r--dev/tsunami_uart.cc308
1 files changed, 0 insertions, 308 deletions
diff --git a/dev/tsunami_uart.cc b/dev/tsunami_uart.cc
deleted file mode 100644
index c6da02cf4..000000000
--- a/dev/tsunami_uart.cc
+++ /dev/null
@@ -1,308 +0,0 @@
-/* $Id$ */
-
-/* @file
- * Tsunami UART
- */
-
-/*
- * Copyright (C) 1998 by the Board of Trustees
- * of Leland Stanford Junior University.
- * Copyright (C) 1998 Digital Equipment Corporation
- *
- * This file is part of the SimOS distribution.
- * See LICENSE file for terms of the license.
- *
- */
-
-#include <string>
-#include <vector>
-
-#include "base/inifile.hh"
-#include "base/str.hh" // for to_number
-#include "base/trace.hh"
-#include "dev/console.hh"
-#include "dev/tsunami_uart.hh"
-#include "mem/bus/bus.hh"
-#include "mem/bus/pio_interface.hh"
-#include "mem/bus/pio_interface_impl.hh"
-#include "mem/functional_mem/memory_control.hh"
-#include "sim/builder.hh"
-#include "targetarch/ev5.hh"
-
-using namespace std;
-
-#define CONS_INT_TX 0x01 // interrupt enable / state bits
-#define CONS_INT_RX 0x02
-
-
-TsunamiUart::IntrEvent::IntrEvent(TsunamiUart *u)
- : Event(&mainEventQueue), uart(u)
-{
- DPRINTF(TsunamiUart, "UART Interrupt Event Initilizing\n");
-}
-
-const char *
-TsunamiUart::IntrEvent::description()
-{
- return "tsunami uart interrupt delay event";
-}
-
-void
-TsunamiUart::IntrEvent::process()
-{
- if (UART_IER_THRI & uart->IER) {
- DPRINTF(TsunamiUart, "UART InterEvent, interrupting\n");
- uart->cons->raiseInt(CONS_INT_TX);
- }
- else
- DPRINTF(TsunamiUart, "UART InterEvent, not interrupting\n");
-
-}
-
-void
-TsunamiUart::IntrEvent::scheduleIntr()
-{
- DPRINTF(TsunamiUart, "Scheduling IER interrupt\n");
- if (!scheduled())
- schedule(curTick + 300);
- else
- reschedule(curTick + 300);
-}
-
-
-
-TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
- MemoryController *mmu, Addr a,
- HierParams *hier, Bus *bus)
- : PioDevice(name), addr(a), cons(c), status_store(0), valid_char(false),
- intrEvent(this)
-{
- mmu->add_child(this, Range<Addr>(addr, addr + size));
-
- if (bus) {
- pioInterface = newPioInterface(name, hier, bus, this,
- &TsunamiUart::cacheAccess);
- pioInterface->addAddrRange(addr, addr + size - 1);
- }
-
- IER = 0;
-}
-
-Fault
-TsunamiUart::read(MemReqPtr &req, uint8_t *data)
-{
- Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
- DPRINTF(TsunamiUart, " read register %#x\n", daddr);
-
- switch (req->size) {
- case sizeof(uint64_t):
- *(uint64_t *)data = 0;
- break;
- case sizeof(uint32_t):
- *(uint32_t *)data = 0;
- break;
- case sizeof(uint16_t):
- *(uint16_t *)data = 0;
- break;
- case sizeof(uint8_t):
- *(uint8_t *)data = 0;
- break;
- }
-
-
- switch(daddr) {
- case 0x5: // Status Register
- {
- int status = cons->intStatus();
- if (!valid_char) {
- valid_char = cons->in(next_char);
- if (!valid_char)
- status &= ~CONS_INT_RX;
- } else {
- status |= CONS_INT_RX;
- }
-
- if (status_store == 3) {
- // RR3 stuff? Don't really understand it, btw
- status_store = 0;
- if (status & CONS_INT_TX) {
- *data = (1 << 4);
- return No_Fault;
- } else if (status & CONS_INT_RX) {
- *data = (1 << 5);
- return No_Fault;
- } else {
- DPRINTF(TsunamiUart, "spurious read\n");
- return No_Fault;
- }
- } else {
- int reg = (1 << 2) | (1 << 5) | (1 << 6);
- if (status & CONS_INT_RX)
- reg |= (1 << 0);
- *data = reg;
- return No_Fault;
- }
- break;
- }
-
- case 0x0: // Data register (RX)
- DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
- isprint(next_char) ? next_char : ' ', next_char);
-
- *data = next_char;
- valid_char = false;
- return No_Fault;
-
- case 0x1: // Interrupt Enable Register
- // This is the lovely way linux checks there is actually a serial
- // port at the desired address
- if (IER == 0)
- *data = 0;
- else if (IER == 0x0F)
- *data = 0x0F;
- else
- *data = 0;
- return No_Fault;
- case 0x2:
- // High two bits need to be clear for an 8250 (simple) serial port
- // Low bit of IIR is 0 for a pending interrupt, 1 otherwise.
- int status = cons->intStatus();
- status = (status & 0x1) | (status >> 1);
- *data = (~status) & 0x1 ;
- return No_Fault;
- }
- *data = 0;
- // panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data);
-
- return No_Fault;
-}
-
-Fault
-TsunamiUart::write(MemReqPtr &req, const uint8_t *data)
-{
- Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
-
- DPRINTF(TsunamiUart, " write register %#x value %#x\n", daddr, *(uint8_t*)data);
-
- switch (daddr) {
- case 0x3:
- status_store = *data;
- switch (*data) {
- case 0x03: // going to read RR3
- return No_Fault;
-
- case 0x28: // Ack of TX
- {
- if ((cons->intStatus() & CONS_INT_TX) == 0)
- panic("Ack of transmit, though there was no interrupt");
-
- cons->clearInt(CONS_INT_TX);
- return No_Fault;
- }
-
- case 0x00:
- case 0x01:
- case 0x12:
- // going to write data???
- return No_Fault;
-
- default:
- DPRINTF(TsunamiUart, "writing status register %#x \n",
- *(uint8_t *)data);
- return No_Fault;
- }
-
- case 0x0: // Data register (TX)
- char ourchar;
- ourchar = *(uint8_t *)data;
- if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C))
- cons->out(ourchar);
- cons->clearInt(CONS_INT_TX);
- intrEvent.scheduleIntr();
- return No_Fault;
- break;
- case 0x1: // IER
- IER = *(uint8_t*)data;
- DPRINTF(TsunamiUart, "writing to IER [%#x]\n", IER);
- if (UART_IER_THRI & IER)
- cons->raiseInt(CONS_INT_TX);
- else {
- cons->clearInt(CONS_INT_TX);
- if (intrEvent.scheduled())
- intrEvent.deschedule();
- }
- return No_Fault;
- break;
- case 0x4: // MCR
- DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint8_t*)data);
- return No_Fault;
-
- }
-
- return No_Fault;
-}
-
-Tick
-TsunamiUart::cacheAccess(MemReqPtr &req)
-{
- return curTick + 1000;
-}
-
-void
-TsunamiUart::serialize(ostream &os)
-{
- SERIALIZE_SCALAR(status_store);
- SERIALIZE_SCALAR(next_char);
- SERIALIZE_SCALAR(valid_char);
- SERIALIZE_SCALAR(IER);
- Tick intrwhen;
- if (intrEvent.scheduled())
- intrwhen = intrEvent.when();
- else
- intrwhen = 0;
- SERIALIZE_SCALAR(intrwhen);
-
-
-}
-
-void
-TsunamiUart::unserialize(Checkpoint *cp, const std::string &section)
-{
- UNSERIALIZE_SCALAR(status_store);
- UNSERIALIZE_SCALAR(next_char);
- UNSERIALIZE_SCALAR(valid_char);
- UNSERIALIZE_SCALAR(IER);
- Tick intrwhen;
- UNSERIALIZE_SCALAR(intrwhen);
- if (intrwhen != 0)
- intrEvent.schedule(intrwhen);
-
-}
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)
-
- SimObjectParam<SimConsole *> console;
- SimObjectParam<MemoryController *> mmu;
- Param<Addr> addr;
- SimObjectParam<Bus*> io_bus;
- SimObjectParam<HierParams *> hier;
-
-
-END_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiUart)
-
- INIT_PARAM(console, "The console"),
- INIT_PARAM(mmu, "Memory Controller"),
- INIT_PARAM(addr, "Device Address"),
- INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
- INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
-
-END_INIT_SIM_OBJECT_PARAMS(TsunamiUart)
-
-CREATE_SIM_OBJECT(TsunamiUart)
-{
- return new TsunamiUart(getInstanceName(), console, mmu, addr, hier, io_bus);
-}
-
-REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart)