diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2004-01-26 13:26:34 -0500 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2004-01-26 13:26:34 -0500 |
commit | b7f44f6e0676a933c5aa4d892d789c46daeaaa27 (patch) | |
tree | 1e48e5b6614ec85f5ee9d3d2254f90814ae88e0b /dev/tsunami_uart.cc | |
parent | 9b397ce7f45fc275f9004d78520628e2e7c0dd16 (diff) | |
download | gem5-b7f44f6e0676a933c5aa4d892d789c46daeaaa27.tar.xz |
Support for Tsunami coming along... RTC, PIC working, UART in progress
dev/tsunami_io.cc:
PIC, PIT, RTC implementation for tsunami working so far
dev/tsunami_io.hh:
PIT, PIC, RTC implementation for tlaser working so far
dev/tsunamireg.h:
Added RTC defines
kern/linux/linux_system.cc:
wrote cycle frequency into variable so linux doesn't probe for it.
The support exists, but it takes two seconds of time to do on a real
machine, so forever in the simulator.
--HG--
extra : convert_revision : e0ed7f271ece4ed69c06af35d1b0e8ed848cd138
Diffstat (limited to 'dev/tsunami_uart.cc')
-rw-r--r-- | dev/tsunami_uart.cc | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/dev/tsunami_uart.cc b/dev/tsunami_uart.cc new file mode 100644 index 000000000..88f6a6f8a --- /dev/null +++ b/dev/tsunami_uart.cc @@ -0,0 +1,199 @@ +/* $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/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::TsunamiUart(const string &name, SimConsole *c, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), + cons(c), status_store(0), next_char(-1) +{ +} + +Fault +TsunamiUart::read(MemReqPtr req, uint8_t *data) +{ + Addr daddr = req->paddr & addr_mask; + + 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 0xD: // Status Register + { + int status = cons->intStatus(); + if (next_char < 0) { + next_char = cons->in(); + if (next_char < 0) { + 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); + if (status & CONS_INT_RX) + reg |= (1 << 0); + *data = reg; + return No_Fault; + } + break; + } + + case 0x8: // Data register (RX) + if (next_char < 0) + panic("Invalid character"); + + DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n", + isprint(next_char) ? next_char : ' ', next_char); + + *data = next_char; + next_char = -1; +// cons.next(); + return No_Fault; + } + + 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_mask; + switch (daddr) { + case 0xb: + 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", + *(uint64_t *)data); + return No_Fault; + } + + case 0x8: // Data register (TX) + cons->out(*(uint64_t *)data); + return No_Fault; + case 0x9: // DLM + DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint64_t*)data); + return No_Fault; + case 0xc: // MCR + DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint64_t*)data); + return No_Fault; + + } + + return No_Fault; +} + +void +TsunamiUart::serialize(ostream &os) +{ + SERIALIZE_SCALAR(status_store); + SERIALIZE_SCALAR(next_char); +} + +void +TsunamiUart::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(status_store); + UNSERIALIZE_SCALAR(next_char); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart) + + SimObjectParam<SimConsole *> console; + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + +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(mask, "Address Mask") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiUart) + +CREATE_SIM_OBJECT(TsunamiUart) +{ + return new TsunamiUart(getInstanceName(), console, addr, mask, mmu); +} + +REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart) |