diff options
-rw-r--r-- | dev/console.cc | 33 | ||||
-rw-r--r-- | dev/console.hh | 4 | ||||
-rw-r--r-- | dev/platform.cc | 36 | ||||
-rw-r--r-- | dev/platform.hh | 7 | ||||
-rw-r--r-- | dev/tsunami.cc | 19 | ||||
-rw-r--r-- | dev/tsunami.hh | 8 | ||||
-rw-r--r-- | dev/tsunami_io.cc | 47 | ||||
-rw-r--r-- | dev/tsunami_uart.cc | 79 | ||||
-rw-r--r-- | dev/tsunami_uart.hh | 13 | ||||
-rw-r--r-- | dev/tsunamireg.h | 14 |
10 files changed, 205 insertions, 55 deletions
diff --git a/dev/console.cc b/dev/console.cc index fb74c388a..ef3f64d8d 100644 --- a/dev/console.cc +++ b/dev/console.cc @@ -49,6 +49,7 @@ #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" #include "targetarch/ev5.hh" +#include "dev/platform.hh" using namespace std; @@ -76,7 +77,7 @@ SimConsole::SimConsole(const string &name, const string &file, int num) #if TRACING_ON == 1 linebuf(16384), #endif - _status(0), _enable(0), intr(NULL) + _status(0), _enable(0), intr(NULL), platform(NULL) { if (!file.empty()) outfile = new ofstream(file.c_str()); @@ -322,8 +323,8 @@ SimConsole::clearInt(int i) { int old = _status; _status &= ~i; - if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr) - intr->clear(TheISA::INTLEVEL_IRQ0); + //if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr) + platform->clearConsoleInt(); return old; } @@ -331,10 +332,10 @@ SimConsole::clearInt(int i) void SimConsole::raiseInt(int i) { - int old = _status; + //int old = _status; _status |= i; - if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr) - intr->post(TheISA::INTLEVEL_IRQ0); + //if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr) + platform->postConsoleInt(); } void @@ -357,14 +358,21 @@ SimConsole::setInt(int bits) old = _enable; _enable |= bits; - if (MaskStatus(_status, old) != MaskStatus(_status, _enable) && intr) { + //if (MaskStatus(_status, old) != MaskStatus(_status, _enable) && intr) { + if (intr) { if (MaskStatus(_status, _enable)) - intr->post(TheISA::INTLEVEL_IRQ0); + platform->postConsoleInt(); else - intr->clear(TheISA::INTLEVEL_IRQ0); + platform->clearConsoleInt(); } } +void +SimConsole::setPlatform(Platform *p) +{ + platform = p; + platform->cons = this; +} void SimConsole::serialize(ostream &os) @@ -381,6 +389,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimConsole) SimObjectParam<ConsoleListener *> listener; SimObjectParam<IntrControl *> intr_control; + SimObjectParam<Platform *> platform; Param<string> output; Param<bool> append_name; Param<int> number; @@ -391,6 +400,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole) INIT_PARAM(listener, "console listener"), INIT_PARAM(intr_control, "interrupt controller"), + INIT_PARAM(platform, "platform"), 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) @@ -413,8 +423,9 @@ CREATE_SIM_OBJECT(SimConsole) SimConsole *console = new SimConsole(getInstanceName(), filename, number); ((ConsoleListener *)listener)->add(console); ((SimConsole *)console)->initInt(intr_control); -// ((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt | -// SimConsole::ReceiveInterrupt); + ((SimConsole *)console)->setPlatform(platform); + //((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt | + // SimConsole::ReceiveInterrupt); return console; } diff --git a/dev/console.hh b/dev/console.hh index d2bba4612..703d05d51 100644 --- a/dev/console.hh +++ b/dev/console.hh @@ -103,6 +103,8 @@ class SimConsole : public SimObject // interrupt handle IntrControl *intr; + // Platform so we can post interrupts + Platform *platform; public: ///////////////// @@ -143,6 +145,8 @@ class SimConsole : public SimObject void initInt(IntrControl *i); void setInt(int bits); + void setPlatform(Platform *p); + virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); }; diff --git a/dev/platform.cc b/dev/platform.cc new file mode 100644 index 000000000..c39849162 --- /dev/null +++ b/dev/platform.cc @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2003 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. + */ + +#include "dev/platform.hh" +#include "sim/builder.hh" +#include "sim/sim_exit.hh" + +using namespace std; + +DEFINE_SIM_OBJECT_CLASS_NAME("Platform", Platform) + diff --git a/dev/platform.hh b/dev/platform.hh index db6a489ad..407f58406 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -53,10 +53,13 @@ class Platform : public SimObject int interrupt_frequency; public: - Platform(const std::string &name, SimConsole *con, IntrControl *intctrl, + Platform(const std::string &name, IntrControl *intctrl, PciConfigAll *pci, int intrFreq) - : SimObject(name), intrctrl(intctrl), cons(con), pciconfig(pci), + : SimObject(name), intrctrl(intctrl), pciconfig(pci), interrupt_frequency(intrFreq) {} + virtual ~Platform() {} + virtual void postConsoleInt() = 0; + virtual void clearConsoleInt() = 0; }; #endif // __PLATFORM_HH_ diff --git a/dev/tsunami.cc b/dev/tsunami.cc index 252f9f1cc..8956ee557 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -37,6 +37,7 @@ #include "dev/tlaser_clock.hh" #include "dev/tsunami_cchip.hh" #include "dev/tsunami_pchip.hh" +#include "dev/tsunami_io.hh" #include "dev/tsunami.hh" #include "dev/pciconfigall.hh" #include "sim/builder.hh" @@ -44,9 +45,9 @@ using namespace std; -Tsunami::Tsunami(const string &name, System *s, SimConsole *con, +Tsunami::Tsunami(const string &name, System *s, IntrControl *ic, PciConfigAll *pci, int intr_freq) - : Platform(name, con, ic, pci, intr_freq), system(s) + : Platform(name, ic, pci, intr_freq), system(s) { // set the back pointer from the system to myself system->platform = this; @@ -56,6 +57,18 @@ Tsunami::Tsunami(const string &name, System *s, SimConsole *con, } void +Tsunami::postConsoleInt() +{ + io->postPIC(0x10); +} + +void +Tsunami::clearConsoleInt() +{ + io->clearPIC(0x10); +} + +void Tsunami::serialize(std::ostream &os) { SERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); @@ -89,7 +102,7 @@ END_INIT_SIM_OBJECT_PARAMS(Tsunami) CREATE_SIM_OBJECT(Tsunami) { - return new Tsunami(getInstanceName(), system, cons, intrctrl, pciconfig, + return new Tsunami(getInstanceName(), system, intrctrl, pciconfig, interrupt_frequency); } diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 2cbacc50b..f619e4cff 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -92,9 +92,11 @@ class Tsunami : public Platform * @param intrcontrol pointer to the interrupt controller * @param intrFreq frequency that interrupts happen */ - Tsunami(const std::string &name, System *s, SimConsole *con, - IntrControl *intctrl, PciConfigAll *pci, - int intrFreq); + Tsunami(const std::string &name, System *s, IntrControl *intctrl, + PciConfigAll *pci, int intrFreq); + + virtual void postConsoleInt(); + virtual void clearConsoleInt(); virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index d32291d0d..2dda86fbc 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -151,12 +151,21 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) req->vaddr, req->size, req->vaddr & 0xfff); Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)); -// ExecContext *xc = req->xc; -// int cpuid = xc->cpu_id; + switch(req->size) { case sizeof(uint8_t): switch(daddr) { + case TSDEV_PIC1_ISR: + // !!! If this is modified 64bit case needs to be too + // Pal code has to do a 64 bit physical read because there is + // no load physical byte instruction + *(uint8_t*)data = picr; + return No_Fault; + case TSDEV_PIC2_ISR: + // PIC2 not implemnted... just return 0 + *(uint8_t*)data = 0x00; + return No_Fault; case TSDEV_TMR_CTL: *(uint8_t*)data = timer2.Status(); return No_Fault; @@ -206,7 +215,22 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) } case sizeof(uint16_t): case sizeof(uint32_t): + panic("I/O Read - invalid size - va %#x size %d\n", + req->vaddr, req->size); + case sizeof(uint64_t): + switch(daddr) { + case TSDEV_PIC1_ISR: + // !!! If this is modified 8bit case needs to be too + // Pal code has to do a 64 bit physical read because there is + // no load physical byte instruction + *(uint64_t*)data = (uint64_t)picr; + return No_Fault; + default: + panic("I/O Read - invalid size - va %#x size %d\n", + req->vaddr, req->size); + } + default: panic("I/O Read - invalid size - va %#x size %d\n", req->vaddr, req->size); @@ -231,17 +255,30 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) case sizeof(uint8_t): switch(daddr) { case TSDEV_PIC1_MASK: - mask1 = *(uint8_t*)data; + mask1 = ~(*(uint8_t*)data); if ((picr & mask1) && !picInterrupting) { picInterrupting = true; tsunami->cchip->postDRIR(55); DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); } + if ((!(picr & mask1)) && picInterrupting) { + picInterrupting = false; + tsunami->cchip->clearDRIR(55); + DPRINTF(Tsunami, "clearing pic interrupt\n"); + } return No_Fault; case TSDEV_PIC2_MASK: mask2 = *(uint8_t*)data; //PIC2 Not implemented to interrupt return No_Fault; + case TSDEV_PIC1_ACK: + // clear the interrupt on the PIC + picr &= ~(1 << (*(uint8_t*)data & 0xF)); + if (!(picr & mask1)) + tsunami->cchip->clearDRIR(55); + return No_Fault; + case TSDEV_PIC2_ACK: + return No_Fault; case TSDEV_DMA1_RESET: return No_Fault; case TSDEV_DMA2_RESET: @@ -321,8 +358,7 @@ TsunamiIO::postPIC(uint8_t bitvector) { //PIC2 Is not implemented, because nothing of interest there picr |= bitvector; - if ((picr & mask1) && !picInterrupting) { - picInterrupting = true; + if (picr & mask1) { tsunami->cchip->postDRIR(55); DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); } @@ -334,7 +370,6 @@ TsunamiIO::clearPIC(uint8_t bitvector) //PIC2 Is not implemented, because nothing of interest there picr &= ~bitvector; if (!(picr & mask1)) { - picInterrupting = false; tsunami->cchip->clearDRIR(55); DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); } diff --git a/dev/tsunami_uart.cc b/dev/tsunami_uart.cc index 6f15c5ee0..6c4c30e7d 100644 --- a/dev/tsunami_uart.cc +++ b/dev/tsunami_uart.cc @@ -22,6 +22,9 @@ #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" @@ -31,13 +34,19 @@ 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 a, - MemoryController *mmu) - : FunctionalMemory(name), addr(a), cons(c), status_store(0), - valid_char(false) +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) { 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; } @@ -62,7 +71,8 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data) break; } - switch (daddr) { + + switch(daddr) { case 0x5: // Status Register { int status = cons->intStatus(); @@ -134,41 +144,51 @@ 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 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"); + 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; - } + cons->clearInt(CONS_INT_TX); + return No_Fault; + } - case 0x00: - case 0x01: - case 0x12: - // going to write data??? - return No_Fault; + case 0x00: + case 0x01: + case 0x12: + // going to write data??? + return No_Fault; - default: + default: DPRINTF(TsunamiUart, "writing status register %#x \n", *(uint8_t *)data); return No_Fault; } case 0x0: // Data register (TX) - cons->out(*(uint64_t *)data); - return No_Fault; + char ourchar; + ourchar = *(uint64_t *)data; + if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C)) + cons->out(ourchar); + if (UART_IER_THRI & IER) + cons->setInt(CONS_INT_TX); + return No_Fault; + break; case 0x1: // DLM DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data); IER = *(uint8_t*)data; + if (UART_IER_THRI & IER) + cons->setInt(CONS_INT_TX); return No_Fault; + break; case 0x4: // MCR DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint8_t*)data); return No_Fault; @@ -178,6 +198,12 @@ TsunamiUart::write(MemReqPtr &req, const uint8_t *data) return No_Fault; } +Tick +TsunamiUart::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; +} + void TsunamiUart::serialize(ostream &os) { @@ -201,6 +227,9 @@ 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) @@ -208,13 +237,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiUart) INIT_PARAM(console, "The console"), INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address") + 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, addr, mmu); + return new TsunamiUart(getInstanceName(), console, mmu, addr, hier, io_bus); } REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart) diff --git a/dev/tsunami_uart.hh b/dev/tsunami_uart.hh index f0a9b644b..d57b255ae 100644 --- a/dev/tsunami_uart.hh +++ b/dev/tsunami_uart.hh @@ -33,14 +33,16 @@ #ifndef __TSUNAMI_UART_HH__ #define __TSUNAMI_UART_HH__ -#include "mem/functional_mem/functional_memory.hh" +#include "dev/tsunamireg.h" +#include "base/range.hh" +#include "dev/io_device.hh" class SimConsole; /* * Tsunami UART */ -class TsunamiUart : public FunctionalMemory +class TsunamiUart : public PioDevice { private: Addr addr; @@ -54,8 +56,8 @@ class TsunamiUart : public FunctionalMemory uint8_t IER; public: - TsunamiUart(const std::string &name, SimConsole *c, Addr a, - MemoryController *mmu); + TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu, + Addr a, HierParams *hier, Bus *bus); Fault read(MemReqPtr &req, uint8_t *data); Fault write(MemReqPtr &req, const uint8_t *data); @@ -63,6 +65,9 @@ class TsunamiUart : public FunctionalMemory virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + + public: + Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_UART_HH__ diff --git a/dev/tsunamireg.h b/dev/tsunamireg.h index 1207ebf9f..927dd60c9 100644 --- a/dev/tsunamireg.h +++ b/dev/tsunamireg.h @@ -70,6 +70,10 @@ // I/O Ports #define TSDEV_PIC1_MASK 0x21 #define TSDEV_PIC2_MASK 0xA1 +#define TSDEV_PIC1_ISR 0x20 +#define TSDEV_PIC2_ISR 0xA0 +#define TSDEV_PIC1_ACK 0x20 +#define TSDEV_PIC2_ACK 0xA0 #define TSDEV_DMA1_RESET 0x0D #define TSDEV_DMA2_RESET 0xDA #define TSDEV_DMA1_MODE 0x0B @@ -101,10 +105,16 @@ #define RTC_CONTROL_REGISTERD 13 // control register D #define RTC_REGNUMBER_RTC_CR1 0x6A // control register 1 -#define PCHIP_PCI0_MEMORY 0x10000000000ULL -#define PCHIP_PCI0_IO 0x101FC000000ULL +#define PCHIP_PCI0_MEMORY ULL(0x10000000000) +#define PCHIP_PCI0_IO ULL(0x101FC000000) #define TSUNAMI_PCI0_MEMORY ALPHA_K0SEG_BASE + PCHIP_PCI0_MEMORY #define TSUNAMI_PCI0_IO ALPHA_K0SEG_BASE + PCHIP_PCI0_IO +// UART Defines + + +#define UART_IER_THRI 0x02 +#define UART_IER_RLSI 0x04 + #endif // __TSUNAMIREG_H__ |