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
This commit is contained in:
parent
9b397ce7f4
commit
b7f44f6e06
6 changed files with 393 additions and 42 deletions
|
@ -1,9 +1,11 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
/* @file
|
/* @file
|
||||||
* Tsunami DMA fake
|
* Tsunami I/O including PIC, PIT, RTC, DMA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -11,50 +13,43 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
#include "dev/console.hh"
|
#include "dev/console.hh"
|
||||||
#include "dev/etherdev.hh"
|
|
||||||
#include "dev/scsi_ctrl.hh"
|
|
||||||
#include "dev/tlaser_clock.hh"
|
#include "dev/tlaser_clock.hh"
|
||||||
#include "dev/tsunami_io.hh"
|
#include "dev/tsunami_io.hh"
|
||||||
#include "dev/tsunamireg.h"
|
#include "dev/tsunamireg.h"
|
||||||
#include "dev/tsunami.hh"
|
#include "dev/tsunami.hh"
|
||||||
#include "mem/functional_mem/memory_control.hh"
|
#include "mem/functional_mem/memory_control.hh"
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
#include "sim/system.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#define UNIX_YEAR_OFFSET 52
|
||||||
|
|
||||||
|
//This will have to be dynamic if we want support usermode access of the RTC
|
||||||
|
#define RTC_RATE 1024
|
||||||
|
|
||||||
|
// Timer Event for Periodic interrupt of RTC
|
||||||
TsunamiIO::RTCEvent::RTCEvent()
|
TsunamiIO::RTCEvent::RTCEvent()
|
||||||
: Event(&mainEventQueue)
|
: Event(&mainEventQueue)
|
||||||
{
|
{
|
||||||
DPRINTF(Tsunami, "RTC Event Initilizing\n");
|
DPRINTF(MC146818, "RTC Event Initilizing\n");
|
||||||
rtc_uip = 0;
|
schedule(curTick + ticksPerSecond/RTC_RATE);
|
||||||
schedule(curTick + (curTick % ticksPerSecond));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiIO::RTCEvent::process()
|
TsunamiIO::RTCEvent::process()
|
||||||
{
|
{
|
||||||
DPRINTF(Tsunami, "Timer Interrupt\n");
|
DPRINTF(MC146818, "Timer Interrupt\n");
|
||||||
if (rtc_uip == 0) {
|
schedule(curTick + ticksPerSecond/RTC_RATE);
|
||||||
rtc_uip = 1; //Signal a second has occured
|
//Actually interrupt the processor here
|
||||||
schedule(curTick + (curTick % ticksPerSecond) - 10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rtc_uip = 0; //Done signaling second has occured
|
|
||||||
schedule(curTick + (curTick % ticksPerSecond));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
TsunamiIO::RTCEvent::description()
|
TsunamiIO::RTCEvent::description()
|
||||||
{
|
{
|
||||||
return "tsunami RTC changte second";
|
return "tsunami RTC 1024Hz interrupt";
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
TsunamiIO::RTCEvent::rtc_uip_value()
|
|
||||||
{
|
|
||||||
return rtc_uip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Timer Event for PIT Timers
|
||||||
TsunamiIO::ClockEvent::ClockEvent()
|
TsunamiIO::ClockEvent::ClockEvent()
|
||||||
: Event(&mainEventQueue)
|
: Event(&mainEventQueue)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +71,8 @@ void
|
||||||
TsunamiIO::ClockEvent::Program(int count)
|
TsunamiIO::ClockEvent::Program(int count)
|
||||||
{
|
{
|
||||||
DPRINTF(Tsunami, "Timer set to curTick + %d\n", count);
|
DPRINTF(Tsunami, "Timer set to curTick + %d\n", count);
|
||||||
interval = count * ticksPerSecond/1193180UL; // should be count * (cpufreq/pitfreq)
|
// should be count * (cpufreq/pitfreq)
|
||||||
|
interval = count * ticksPerSecond/1193180UL;
|
||||||
schedule(curTick + interval);
|
schedule(curTick + interval);
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
|
@ -100,11 +96,22 @@ TsunamiIO::ClockEvent::Status()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TsunamiIO::TsunamiIO(const string &name, /*Tsunami *t,*/
|
|
||||||
|
|
||||||
|
TsunamiIO::TsunamiIO(const string &name, /*Tsunami *t,*/ time_t init_time,
|
||||||
Addr addr, Addr mask, MemoryController *mmu)
|
Addr addr, Addr mask, MemoryController *mmu)
|
||||||
: MmapDevice(name, addr, mask, mmu)/*, tsunami(t) */
|
: MmapDevice(name, addr, mask, mmu)/*, tsunami(t) */
|
||||||
{
|
{
|
||||||
timerData = 0;
|
timerData = 0;
|
||||||
|
set_time(init_time == 0 ? time(NULL) : init_time);
|
||||||
|
uip = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TsunamiIO::set_time(time_t t)
|
||||||
|
{
|
||||||
|
gmtime_r(&t, &tm);
|
||||||
|
DPRINTFN("Real-time clock set to %s", asctime(&tm));
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
|
@ -123,6 +130,47 @@ TsunamiIO::read(MemReqPtr req, uint8_t *data)
|
||||||
case TSDEV_TMR_CTL:
|
case TSDEV_TMR_CTL:
|
||||||
*(uint8_t*)data = timer2.Status();
|
*(uint8_t*)data = timer2.Status();
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
|
case TSDEV_RTC_DATA:
|
||||||
|
switch(RTCAddress) {
|
||||||
|
case RTC_CONTROL_REGISTERA:
|
||||||
|
*(uint8_t*)data = uip << 7 | 0x26;
|
||||||
|
uip = !uip;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_CONTROL_REGISTERB:
|
||||||
|
// DM and 24/12 and UIE
|
||||||
|
*(uint8_t*)data = 0x46;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_CONTROL_REGISTERC:
|
||||||
|
// If we want to support RTC user access in linux
|
||||||
|
// This won't work, but for now it's fine
|
||||||
|
*(uint8_t*)data = 0x00;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_CONTROL_REGISTERD:
|
||||||
|
panic("RTC Control Register D not implemented");
|
||||||
|
case RTC_SECOND:
|
||||||
|
*(uint8_t *)data = tm.tm_sec;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_MINUTE:
|
||||||
|
*(uint8_t *)data = tm.tm_min;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_HOUR:
|
||||||
|
*(uint8_t *)data = tm.tm_hour;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_DAY_OF_WEEK:
|
||||||
|
*(uint8_t *)data = tm.tm_wday;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_DAY_OF_MONTH:
|
||||||
|
*(uint8_t *)data = tm.tm_mday;
|
||||||
|
case RTC_MONTH:
|
||||||
|
*(uint8_t *)data = tm.tm_mon + 1;
|
||||||
|
return No_Fault;
|
||||||
|
case RTC_YEAR:
|
||||||
|
*(uint8_t *)data = tm.tm_year - UNIX_YEAR_OFFSET;
|
||||||
|
return No_Fault;
|
||||||
|
default:
|
||||||
|
panic("Unknown RTC Address\n");
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
||||||
}
|
}
|
||||||
|
@ -177,13 +225,9 @@ TsunamiIO::write(MemReqPtr req, const uint8_t *data)
|
||||||
case 0:
|
case 0:
|
||||||
timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
|
||||||
timer1.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
||||||
break;
|
break;
|
||||||
case 3:
|
|
||||||
default:
|
default:
|
||||||
panic("Read Back Command not implemented\n");
|
panic("Read Back Command not implemented\n");
|
||||||
}
|
}
|
||||||
|
@ -212,6 +256,11 @@ TsunamiIO::write(MemReqPtr req, const uint8_t *data)
|
||||||
timerData |= 0x1000;
|
timerData |= 0x1000;
|
||||||
}
|
}
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
|
case TSDEV_RTC_ADDR:
|
||||||
|
RTCAddress = *(uint8_t*)data;
|
||||||
|
return No_Fault;
|
||||||
|
case TSDEV_RTC_DATA:
|
||||||
|
panic("RTC Write not implmented (rtc.o won't work)\n");
|
||||||
default:
|
default:
|
||||||
panic("I/O Write - va%#x size %d\n", req->vaddr, req->size);
|
panic("I/O Write - va%#x size %d\n", req->vaddr, req->size);
|
||||||
}
|
}
|
||||||
|
@ -241,6 +290,7 @@ TsunamiIO::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
// SimObjectParam<Tsunami *> tsunami;
|
// SimObjectParam<Tsunami *> tsunami;
|
||||||
|
Param<time_t> time;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
SimObjectParam<MemoryController *> mmu;
|
||||||
Param<Addr> addr;
|
Param<Addr> addr;
|
||||||
Param<Addr> mask;
|
Param<Addr> mask;
|
||||||
|
@ -250,6 +300,8 @@ END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
// INIT_PARAM(tsunami, "Tsunami"),
|
// INIT_PARAM(tsunami, "Tsunami"),
|
||||||
|
INIT_PARAM_DFLT(time, "System time to use "
|
||||||
|
"(0 for actual time, default is 1/1/06", ULL(1136073600)),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(mmu, "Memory Controller"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(addr, "Device Address"),
|
||||||
INIT_PARAM(mask, "Address Mask")
|
INIT_PARAM(mask, "Address Mask")
|
||||||
|
@ -258,7 +310,7 @@ END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(TsunamiIO)
|
CREATE_SIM_OBJECT(TsunamiIO)
|
||||||
{
|
{
|
||||||
return new TsunamiIO(getInstanceName(), /*tsunami,*/ addr, mask, mmu);
|
return new TsunamiIO(getInstanceName(), /*tsunami,*/ time, addr, mask, mmu);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)
|
REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)
|
||||||
|
|
|
@ -42,7 +42,13 @@
|
||||||
class TsunamiIO : public MmapDevice
|
class TsunamiIO : public MmapDevice
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
private:
|
||||||
|
struct tm tm;
|
||||||
|
|
||||||
|
// In Tsunami RTC only has two i/o ports
|
||||||
|
// one for data and one for address, so you
|
||||||
|
// write the address and then read/write the data
|
||||||
|
uint8_t RTCAddress;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -66,33 +72,43 @@ class TsunamiIO : public MmapDevice
|
||||||
|
|
||||||
class RTCEvent : public Event
|
class RTCEvent : public Event
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
Tick interval;
|
|
||||||
uint8_t rtc_uip;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RTCEvent();
|
RTCEvent();
|
||||||
|
|
||||||
virtual void process();
|
virtual void process();
|
||||||
virtual const char *description();
|
virtual const char *description();
|
||||||
uint8_t rtc_uip_value();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint8_t uip;
|
||||||
|
|
||||||
uint8_t mask1;
|
uint8_t mask1;
|
||||||
uint8_t mask2;
|
uint8_t mask2;
|
||||||
uint8_t mode1;
|
uint8_t mode1;
|
||||||
uint8_t mode2;
|
uint8_t mode2;
|
||||||
|
|
||||||
|
/* This timer is initilized, but after I wrote the code
|
||||||
|
it doesn't seem to be used again, and best I can tell
|
||||||
|
it too is not connected to any interrupt port */
|
||||||
ClockEvent timer0;
|
ClockEvent timer0;
|
||||||
ClockEvent timer1;
|
|
||||||
|
/* This timer is used to control the speaker, which
|
||||||
|
we normally could care less about, however it is
|
||||||
|
also used to calculated the clockspeed and hense
|
||||||
|
bogomips which is kinda important to the scheduler
|
||||||
|
so we need to implemnt it although after boot I can't
|
||||||
|
imagine we would be playing with the PC speaker much */
|
||||||
ClockEvent timer2;
|
ClockEvent timer2;
|
||||||
|
|
||||||
|
RTCEvent rtc;
|
||||||
|
|
||||||
uint32_t timerData;
|
uint32_t timerData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TsunamiIO(const std::string &name, /*Tsunami *t,*/
|
TsunamiIO(const std::string &name, /*Tsunami *t,*/ time_t init_time,
|
||||||
Addr addr, Addr mask, MemoryController *mmu);
|
Addr addr, Addr mask, MemoryController *mmu);
|
||||||
|
|
||||||
|
void set_time(time_t t);
|
||||||
|
|
||||||
virtual Fault read(MemReqPtr req, uint8_t *data);
|
virtual Fault read(MemReqPtr req, uint8_t *data);
|
||||||
virtual Fault write(MemReqPtr req, const uint8_t *data);
|
virtual Fault write(MemReqPtr req, const uint8_t *data);
|
||||||
|
|
||||||
|
|
199
dev/tsunami_uart.cc
Normal file
199
dev/tsunami_uart.cc
Normal file
|
@ -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)
|
62
dev/tsunami_uart.hh
Normal file
62
dev/tsunami_uart.hh
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @file
|
||||||
|
* Tsunami UART
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TSUNAMI_UART_HH__
|
||||||
|
#define __TSUNAMI_UART_HH__
|
||||||
|
|
||||||
|
#include "mem/functional_mem/mmap_device.hh"
|
||||||
|
|
||||||
|
class SimConsole;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tsunami UART
|
||||||
|
*/
|
||||||
|
class TsunamiUart : public MmapDevice
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
SimConsole *cons;
|
||||||
|
int status_store;
|
||||||
|
int next_char;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TsunamiUart(const std::string &name, SimConsole *c,
|
||||||
|
Addr addr, Addr mask, MemoryController *mmu);
|
||||||
|
|
||||||
|
Fault read(MemReqPtr req, uint8_t *data);
|
||||||
|
Fault write(MemReqPtr req, const uint8_t *data);
|
||||||
|
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __TSUNAMI_UART_HH__
|
|
@ -78,4 +78,26 @@
|
||||||
#define TSDEV_TMR2_CTL 0x43
|
#define TSDEV_TMR2_CTL 0x43
|
||||||
#define TSDEV_TMR2_DATA 0x42
|
#define TSDEV_TMR2_DATA 0x42
|
||||||
#define TSDEV_TMR0_DATA 0x40
|
#define TSDEV_TMR0_DATA 0x40
|
||||||
|
|
||||||
|
#define TSDEV_RTC_ADDR 0x70
|
||||||
|
#define TSDEV_RTC_DATA 0x71
|
||||||
|
|
||||||
|
// RTC defines
|
||||||
|
#define RTC_SECOND 0 // second of minute [0..59]
|
||||||
|
#define RTC_SECOND_ALARM 1 // seconds to alarm
|
||||||
|
#define RTC_MINUTE 2 // minute of hour [0..59]
|
||||||
|
#define RTC_MINUTE_ALARM 3 // minutes to alarm
|
||||||
|
#define RTC_HOUR 4 // hour of day [0..23]
|
||||||
|
#define RTC_HOUR_ALARM 5 // hours to alarm
|
||||||
|
#define RTC_DAY_OF_WEEK 6 // day of week [1..7]
|
||||||
|
#define RTC_DAY_OF_MONTH 7 // day of month [1..31]
|
||||||
|
#define RTC_MONTH 8 // month of year [1..12]
|
||||||
|
#define RTC_YEAR 9 // year [00..99]
|
||||||
|
#define RTC_CONTROL_REGISTERA 10 // control register A
|
||||||
|
#define RTC_CONTROL_REGISTERB 11 // control register B
|
||||||
|
#define RTC_CONTROL_REGISTERC 12 // control register C
|
||||||
|
#define RTC_CONTROL_REGISTERD 13 // control register D
|
||||||
|
#define RTC_REGNUMBER_RTC_CR1 0x6A // control register 1
|
||||||
|
|
||||||
|
|
||||||
#endif // __TSUNAMIREG_H__
|
#endif // __TSUNAMIREG_H__
|
||||||
|
|
|
@ -265,13 +265,13 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
||||||
#endif //FS_MEASURE
|
#endif //FS_MEASURE
|
||||||
|
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
if (kernelSymtab->findAddress("est_cycle_freq", addr)) {
|
||||||
Addr paddr = vtophys(physmem, addr);
|
Addr paddr = vtophys(physmem, addr);
|
||||||
uint8_t *enable_async_printf =
|
uint8_t *est_cycle_frequency =
|
||||||
physmem->dma_addr(paddr, sizeof(uint32_t));
|
physmem->dma_addr(paddr, sizeof(uint64_t));
|
||||||
|
|
||||||
if (enable_async_printf)
|
if (est_cycle_frequency)
|
||||||
*(uint32_t *)enable_async_printf = 0;
|
*(uint64_t *)est_cycle_frequency = ticksPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
||||||
|
|
Loading…
Reference in a new issue