summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dev/console.cc33
-rw-r--r--dev/console.hh4
-rw-r--r--dev/platform.cc36
-rw-r--r--dev/platform.hh7
-rw-r--r--dev/tsunami.cc19
-rw-r--r--dev/tsunami.hh8
-rw-r--r--dev/tsunami_io.cc47
-rw-r--r--dev/tsunami_uart.cc79
-rw-r--r--dev/tsunami_uart.hh13
-rw-r--r--dev/tsunamireg.h14
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 &section);
};
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 &section);
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 &section);
+
+ 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__