Merge zizzer:/bk/newmem
into zeep.eecs.umich.edu:/z/saidi/work/m5.newmem --HG-- extra : convert_revision : 36da0febc30675e955a10eb8bc45586b6242a8c3
This commit is contained in:
commit
e17a15f4c5
14 changed files with 729 additions and 862 deletions
14
SConscript
14
SConscript
|
@ -184,11 +184,19 @@ full_system_sources = Split('''
|
||||||
cpu/profile.cc
|
cpu/profile.cc
|
||||||
|
|
||||||
dev/alpha_console.cc
|
dev/alpha_console.cc
|
||||||
|
dev/baddev.cc
|
||||||
dev/disk_image.cc
|
dev/disk_image.cc
|
||||||
dev/io_device.cc
|
dev/io_device.cc
|
||||||
|
dev/isa_fake.cc
|
||||||
dev/platform.cc
|
dev/platform.cc
|
||||||
dev/simconsole.cc
|
dev/simconsole.cc
|
||||||
dev/simple_disk.cc
|
dev/simple_disk.cc
|
||||||
|
dev/tsunami.cc
|
||||||
|
dev/tsunami_cchip.cc
|
||||||
|
dev/tsunami_io.cc
|
||||||
|
dev/tsunami_fake.cc
|
||||||
|
dev/tsunami_pchip.cc
|
||||||
|
|
||||||
dev/uart.cc
|
dev/uart.cc
|
||||||
dev/uart8250.cc
|
dev/uart8250.cc
|
||||||
|
|
||||||
|
@ -204,7 +212,6 @@ full_system_sources = Split('''
|
||||||
sim/pseudo_inst.cc
|
sim/pseudo_inst.cc
|
||||||
''')
|
''')
|
||||||
|
|
||||||
# dev/baddev.cc
|
|
||||||
# dev/etherbus.cc
|
# dev/etherbus.cc
|
||||||
# dev/etherdump.cc
|
# dev/etherdump.cc
|
||||||
# dev/etherint.cc
|
# dev/etherint.cc
|
||||||
|
@ -219,11 +226,6 @@ full_system_sources = Split('''
|
||||||
# dev/pcifake.cc
|
# dev/pcifake.cc
|
||||||
# dev/pktfifo.cc
|
# dev/pktfifo.cc
|
||||||
# dev/sinic.cc
|
# dev/sinic.cc
|
||||||
# dev/tsunami.cc
|
|
||||||
# dev/tsunami_cchip.cc
|
|
||||||
# dev/isa_fake.cc
|
|
||||||
# dev/tsunami_io.cc
|
|
||||||
# dev/tsunami_pchip.cc
|
|
||||||
|
|
||||||
if env['TARGET_ISA'] == 'alpha':
|
if env['TARGET_ISA'] == 'alpha':
|
||||||
full_system_sources += Split('''
|
full_system_sources += Split('''
|
||||||
|
|
|
@ -87,15 +87,6 @@ AlphaConsole::startup()
|
||||||
alphaAccess->intrClockFrequency = params()->platform->intrFrequency();
|
alphaAccess->intrClockFrequency = params()->platform->intrFrequency();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AlphaConsole::addressRanges(AddrRangeList &range_list)
|
|
||||||
{
|
|
||||||
assert(pioSize != 0);
|
|
||||||
range_list.clear();
|
|
||||||
range_list.push_back(RangeSize(pioAddr, sizeof(struct AlphaAccess)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Tick
|
Tick
|
||||||
AlphaConsole::read(Packet &pkt)
|
AlphaConsole::read(Packet &pkt)
|
||||||
{
|
{
|
||||||
|
@ -325,7 +316,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
||||||
SimObjectParam<SimConsole *> sim_console;
|
SimObjectParam<SimConsole *> sim_console;
|
||||||
SimObjectParam<SimpleDisk *> disk;
|
SimObjectParam<SimpleDisk *> disk;
|
||||||
Param<Addr> addr;
|
Param<Addr> pio_addr;
|
||||||
SimObjectParam<AlphaSystem *> system;
|
SimObjectParam<AlphaSystem *> system;
|
||||||
SimObjectParam<BaseCPU *> cpu;
|
SimObjectParam<BaseCPU *> cpu;
|
||||||
SimObjectParam<Platform *> platform;
|
SimObjectParam<Platform *> platform;
|
||||||
|
@ -337,7 +328,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
||||||
INIT_PARAM(sim_console, "The Simulator Console"),
|
INIT_PARAM(sim_console, "The Simulator Console"),
|
||||||
INIT_PARAM(disk, "Simple Disk"),
|
INIT_PARAM(disk, "Simple Disk"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(pio_addr, "Device Address"),
|
||||||
INIT_PARAM(system, "system object"),
|
INIT_PARAM(system, "system object"),
|
||||||
INIT_PARAM(cpu, "Processor"),
|
INIT_PARAM(cpu, "Processor"),
|
||||||
INIT_PARAM(platform, "platform"),
|
INIT_PARAM(platform, "platform"),
|
||||||
|
@ -350,7 +341,7 @@ CREATE_SIM_OBJECT(AlphaConsole)
|
||||||
AlphaConsole::Params *p = new AlphaConsole::Params;
|
AlphaConsole::Params *p = new AlphaConsole::Params;
|
||||||
p->name = getInstanceName();
|
p->name = getInstanceName();
|
||||||
p->platform = platform;
|
p->platform = platform;
|
||||||
p->pio_addr = addr;
|
p->pio_addr = pio_addr;
|
||||||
p->pio_delay = pio_latency;
|
p->pio_delay = pio_latency;
|
||||||
p->cons = sim_console;
|
p->cons = sim_console;
|
||||||
p->disk = disk;
|
p->disk = disk;
|
||||||
|
|
|
@ -119,9 +119,6 @@ class AlphaConsole : public BasicPioDevice
|
||||||
virtual Tick read(Packet &pkt);
|
virtual Tick read(Packet &pkt);
|
||||||
virtual Tick write(Packet &pkt);
|
virtual Tick write(Packet &pkt);
|
||||||
|
|
||||||
/** Address ranges this device is sensitive to. */
|
|
||||||
virtual void addressRanges(AddrRangeList &range_list);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* standard serialization routines for checkpointing
|
* standard serialization routines for checkpointing
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,69 +48,54 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu,
|
BadDevice::BadDevice(Params *p)
|
||||||
HierParams *hier, Bus *pio_bus, const string &devicename)
|
: BasicPioDevice(p), devname(p->devic_ename)
|
||||||
: PioDevice(name, NULL), addr(a), devname(devicename)
|
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
pioSize = 0xf;
|
||||||
|
|
||||||
if (pio_bus) {
|
|
||||||
pioInterface = newPioInterface(name, hier, pio_bus, this,
|
|
||||||
&BadDevice::cacheAccess);
|
|
||||||
pioInterface->addAddrRange(RangeSize(addr, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
|
||||||
BadDevice::read(MemReqPtr &req, uint8_t *data)
|
|
||||||
{
|
|
||||||
|
|
||||||
panic("Device %s not imlpmented\n", devname);
|
|
||||||
return NoFault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
|
||||||
BadDevice::write(MemReqPtr &req, const uint8_t *data)
|
|
||||||
{
|
|
||||||
panic("Device %s not imlpmented\n", devname);
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tick
|
Tick
|
||||||
BadDevice::cacheAccess(MemReqPtr &req)
|
BadDevice::read(Packet &pkt)
|
||||||
{
|
{
|
||||||
return curTick;
|
panic("Device %s not imlpmented\n", devname);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tick
|
||||||
|
BadDevice::write(Packet &pkt)
|
||||||
|
{
|
||||||
|
panic("Device %s not imlpmented\n", devname);
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
SimObjectParam<Platform *> platform;
|
|
||||||
SimObjectParam<MemoryController *> mmu;
|
|
||||||
Param<Addr> addr;
|
|
||||||
SimObjectParam<HierParams *> hier;
|
|
||||||
SimObjectParam<Bus*> pio_bus;
|
|
||||||
Param<Tick> pio_latency;
|
|
||||||
Param<string> devicename;
|
Param<string> devicename;
|
||||||
|
Param<Addr> pio_addr;
|
||||||
|
SimObjectParam<AlphaSystem *> system;
|
||||||
|
SimObjectParam<Platform *> platform;
|
||||||
|
Param<Tick> pio_latency;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
END_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
INIT_PARAM(platform, "Platform"),
|
INIT_PARAM(devicename, "Name of device to error on"),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(pio_addr, "Device Address"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(system, "system object"),
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
INIT_PARAM(platform, "platform"),
|
||||||
INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL),
|
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000)
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
|
|
||||||
INIT_PARAM(devicename, "Name of device to error on")
|
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
END_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(BadDevice)
|
CREATE_SIM_OBJECT(BadDevice)
|
||||||
{
|
{
|
||||||
return new BadDevice(getInstanceName(), addr, mmu, hier, pio_bus,
|
BadDevice::Params *p = new BadDevice::Params;
|
||||||
devicename);
|
p->name =getInstanceName();
|
||||||
|
p->platform = platform;
|
||||||
|
p->pio_addr = pio_addr;
|
||||||
|
p->pio_delay = pio_latency;
|
||||||
|
p->system = system;
|
||||||
|
p->devicename = devicename;
|
||||||
|
return new BadDevice(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("BadDevice", BadDevice)
|
REGISTER_SIM_OBJECT("BadDevice", BadDevice)
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "base/range.hh"
|
#include "base/range.hh"
|
||||||
#include "dev/io_device.hh"
|
#include "dev/io_device.hh"
|
||||||
|
|
||||||
class MemoryController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BadDevice
|
* BadDevice
|
||||||
|
@ -45,51 +44,29 @@ class MemoryController;
|
||||||
* the user that the kernel they are running has unsupported
|
* the user that the kernel they are running has unsupported
|
||||||
* options (i.e. frame buffer)
|
* options (i.e. frame buffer)
|
||||||
*/
|
*/
|
||||||
class BadDevice : public PioDevice
|
class BadDevice : public BasicPioDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Addr addr;
|
|
||||||
static const Addr size = 0xf;
|
|
||||||
|
|
||||||
std::string devname;
|
std::string devname;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct Params : public BasicPioDevice::Params
|
||||||
|
{
|
||||||
|
std::string device_name;
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
const Params *params() const { return (const Params *)_params; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor for the Baddev Class.
|
* Constructor for the Baddev Class.
|
||||||
* @param name name of the object
|
* @param p object parameters
|
||||||
* @param a base address of the write
|
* @param a base address of the write
|
||||||
* @param mmu the memory controller
|
|
||||||
* @param hier object to store parameters universal the device hierarchy
|
|
||||||
* @param bus The bus that this device is attached to
|
|
||||||
* @param devicename device that is not implemented
|
|
||||||
*/
|
*/
|
||||||
BadDevice(const std::string &name, Addr a, MemoryController *mmu,
|
BadDevice(Params *p);
|
||||||
HierParams *hier, Bus *bus, const std::string &devicename);
|
|
||||||
|
|
||||||
/**
|
virtual Tick read(Packet &pkt);
|
||||||
* On a read event we just panic aand hopefully print a
|
virtual Tick write(Packet &pkt);
|
||||||
* meaningful error message.
|
|
||||||
* @param req Contains the address to read from.
|
|
||||||
* @param data A pointer to write the read data to.
|
|
||||||
* @return The fault condition of the access.
|
|
||||||
*/
|
|
||||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On a write event we just panic aand hopefully print a
|
|
||||||
* meaningful error message.
|
|
||||||
* @param req Contains the address to write to.
|
|
||||||
* @param data The data to write.
|
|
||||||
* @return The fault condition of the access.
|
|
||||||
*/
|
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return how long this access will take.
|
|
||||||
* @param req the memory request to calcuate
|
|
||||||
* @return Tick when the request is done
|
|
||||||
*/
|
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __DEV_BADDEV_HH__
|
#endif // __DEV_BADDEV_HH__
|
||||||
|
|
|
@ -88,6 +88,14 @@ PioDevice::~PioDevice()
|
||||||
delete pioPort;
|
delete pioPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BasicPioDevice::addressRanges(AddrRangeList &range_list)
|
||||||
|
{
|
||||||
|
assert(pioSize != 0);
|
||||||
|
range_list.clear();
|
||||||
|
range_list.push_back(RangeSize(pioAddr, pioSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DmaPort::DmaPort(DmaDevice *dev)
|
DmaPort::DmaPort(DmaDevice *dev)
|
||||||
: device(dev)
|
: device(dev)
|
||||||
|
|
|
@ -267,6 +267,11 @@ class BasicPioDevice : public PioDevice
|
||||||
: PioDevice(p), pioAddr(p->pio_addr), pioSize(0), pioDelay(p->pio_delay)
|
: PioDevice(p), pioAddr(p->pio_addr), pioSize(0), pioDelay(p->pio_delay)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/** return the address ranges that this device responds to.
|
||||||
|
* @params range_list range list to populate with ranges
|
||||||
|
*/
|
||||||
|
addressRanges(AddrRangeList &range_list);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DmaDevice : public PioDevice
|
class DmaDevice : public PioDevice
|
||||||
|
|
156
dev/isa_fake.cc
156
dev/isa_fake.cc
|
@ -37,7 +37,7 @@
|
||||||
#include "arch/alpha/ev5.hh"
|
#include "arch/alpha/ev5.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
#include "dev/isa_fake.hh"
|
#include "dev/tsunami_fake.hh"
|
||||||
#include "mem/bus/bus.hh"
|
#include "mem/bus/bus.hh"
|
||||||
#include "mem/bus/pio_interface.hh"
|
#include "mem/bus/pio_interface.hh"
|
||||||
#include "mem/bus/pio_interface_impl.hh"
|
#include "mem/bus/pio_interface_impl.hh"
|
||||||
|
@ -46,96 +46,112 @@
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace TheISA;
|
|
||||||
|
|
||||||
IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu,
|
IsaFake::IsaFake(Params *p)
|
||||||
HierParams *hier, Bus *pio_bus, Addr size)
|
: BasicPioDevice(p)
|
||||||
: PioDevice(name, NULL), addr(a)
|
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
pioSize = p->pio_size;
|
||||||
|
|
||||||
if (pio_bus) {
|
|
||||||
pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this,
|
|
||||||
&IsaFake::cacheAccess);
|
|
||||||
pioInterface->addAddrRange(RangeSize(addr, size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
|
||||||
IsaFake::read(MemReqPtr &req, uint8_t *data)
|
|
||||||
{
|
|
||||||
DPRINTF(Tsunami, "read va=%#x size=%d\n",
|
|
||||||
req->vaddr, req->size);
|
|
||||||
|
|
||||||
#if TRACING_ON
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (req->size) {
|
|
||||||
|
|
||||||
case sizeof(uint64_t):
|
|
||||||
*(uint64_t*)data = 0xFFFFFFFFFFFFFFFFULL;
|
|
||||||
return NoFault;
|
|
||||||
case sizeof(uint32_t):
|
|
||||||
*(uint32_t*)data = 0xFFFFFFFF;
|
|
||||||
return NoFault;
|
|
||||||
case sizeof(uint16_t):
|
|
||||||
*(uint16_t*)data = 0xFFFF;
|
|
||||||
return NoFault;
|
|
||||||
case sizeof(uint8_t):
|
|
||||||
*(uint8_t*)data = 0xFF;
|
|
||||||
return NoFault;
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("invalid access size(?) for PCI configspace!\n");
|
|
||||||
}
|
|
||||||
DPRINTFN("Isa FakeSMC ERROR: read daddr=%#x size=%d\n", daddr, req->size);
|
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
|
||||||
IsaFake::write(MemReqPtr &req, const uint8_t *data)
|
|
||||||
{
|
|
||||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n",
|
|
||||||
req->vaddr, req->size);
|
|
||||||
|
|
||||||
//:Addr daddr = (req->paddr & addr_mask) >> 6;
|
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tick
|
Tick
|
||||||
IsaFake::cacheAccess(MemReqPtr &req)
|
IsaFake::read(Packet &pkt)
|
||||||
{
|
{
|
||||||
return curTick;
|
assert(pkt.result == Unknown);
|
||||||
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
|
|
||||||
|
pkt.time = curTick + pioDelay;
|
||||||
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
|
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
|
||||||
|
|
||||||
|
uint8_t *data8;
|
||||||
|
uint16_t *data16;
|
||||||
|
uint32_t *data32;
|
||||||
|
uint64_t *data64;
|
||||||
|
|
||||||
|
switch (req->size) {
|
||||||
|
case sizeof(uint64_t):
|
||||||
|
if (!pkt.data) {
|
||||||
|
data64 = new uint64_t;
|
||||||
|
pkt.data = (uint8_t*)data64;
|
||||||
|
} else {
|
||||||
|
data64 = (uint64_t*)pkt.data;
|
||||||
|
}
|
||||||
|
*data64 = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
|
break;
|
||||||
|
case sizeof(uint32_t):
|
||||||
|
if (!pkt.data) {
|
||||||
|
data32 = new uint32_t;
|
||||||
|
pkt.data = (uint8_t*)data32;
|
||||||
|
} else {
|
||||||
|
data32 = (uint64_t*)pkt.data;
|
||||||
|
}
|
||||||
|
*data32 = 0xFFFFFFFF;
|
||||||
|
break;
|
||||||
|
case sizeof(uint16_t):
|
||||||
|
if (!pkt.data) {
|
||||||
|
data16 = new uint16_t;
|
||||||
|
pkt.data = (uint8_t*)data16;
|
||||||
|
} else {
|
||||||
|
data16 = (uint64_t*)pkt.data;
|
||||||
|
}
|
||||||
|
*data16 = 0xFFFF;
|
||||||
|
break;
|
||||||
|
case sizeof(uint8_t):
|
||||||
|
if (!pkt.data) {
|
||||||
|
data8 = new uint8_t;
|
||||||
|
pkt.data = data8;
|
||||||
|
} else {
|
||||||
|
data8 = (uint8_t*)pkt.data;
|
||||||
|
}
|
||||||
|
*data8 = 0xFF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("invalid access size(?) for PCI configspace!\n");
|
||||||
|
}
|
||||||
|
pkt.result = Success;
|
||||||
|
return pioDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fault
|
||||||
|
IsaFake::write(Packet &pkt)
|
||||||
|
{
|
||||||
|
pkt.time = curTick + pioDelay;
|
||||||
|
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size);
|
||||||
|
pkt.result = Success;
|
||||||
|
return pioDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake)
|
||||||
|
|
||||||
SimObjectParam<MemoryController *> mmu;
|
Param<Addr> pio_addr;
|
||||||
Param<Addr> addr;
|
|
||||||
SimObjectParam<Bus*> pio_bus;
|
|
||||||
Param<Tick> pio_latency;
|
Param<Tick> pio_latency;
|
||||||
SimObjectParam<HierParams *> hier;
|
Param<Addr> pio_size;
|
||||||
Param<Addr> size;
|
SimObjectParam<Platform *> platform;
|
||||||
|
SimObjectParam<System *> system;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(IsaFake)
|
END_DECLARE_SIM_OBJECT_PARAMS(IsaFake)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(IsaFake)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(IsaFake)
|
||||||
|
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(pio_addr, "Device Address"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(pio_latency, "Programmed IO latency"),
|
||||||
INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL),
|
INIT_PARAM(pio_size, "Size of address range"),
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
|
INIT_PARAM(platform, "platform"),
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
INIT_PARAM(system, "system object")
|
||||||
INIT_PARAM_DFLT(size, "Size of address range", 0x8)
|
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(IsaFake)
|
END_INIT_SIM_OBJECT_PARAMS(IsaFake)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(IsaFake)
|
CREATE_SIM_OBJECT(IsaFake)
|
||||||
{
|
{
|
||||||
return new IsaFake(getInstanceName(), addr, mmu, hier, pio_bus, size);
|
IsaFake::Params *p = new IsaFake::Params;
|
||||||
|
p->name = getInstanceName();
|
||||||
|
p->pio_addr = pio_addr;
|
||||||
|
p->pio_delay = pio_latency;
|
||||||
|
p->pio_size = pio_size;
|
||||||
|
p->platform = platform;
|
||||||
|
p->system = system;
|
||||||
|
return new IsaFake(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("IsaFake", IsaFake)
|
REGISTER_SIM_OBJECT("IsaFake", IsaFake)
|
||||||
|
|
|
@ -37,51 +37,42 @@
|
||||||
#include "base/range.hh"
|
#include "base/range.hh"
|
||||||
#include "dev/io_device.hh"
|
#include "dev/io_device.hh"
|
||||||
|
|
||||||
class MemoryController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsaFake is a device that returns -1 on all reads and
|
* IsaFake is a device that returns -1 on all reads and
|
||||||
* accepts all writes. It is meant to be placed at an address range
|
* accepts all writes. It is meant to be placed at an address range
|
||||||
* so that an mcheck doesn't occur when an os probes a piece of hw
|
* so that an mcheck doesn't occur when an os probes a piece of hw
|
||||||
* that doesn't exist (e.g. UARTs1-3).
|
* that doesn't exist (e.g. UARTs1-3).
|
||||||
*/
|
*/
|
||||||
class IsaFake : public PioDevice
|
class IsaFake : public BasicPioDevice
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
/** The address in memory that we respond to */
|
struct Params : public BasicPioDevice::Params
|
||||||
Addr addr;
|
{
|
||||||
|
Addr pio_size;
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
const Params *params() const { return (const Params*)_params; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The constructor for Tsunmami Fake just registers itself with the MMU.
|
* The constructor for Tsunmami Fake just registers itself with the MMU.
|
||||||
* @param name name of this device.
|
* @param p params structure
|
||||||
* @param a address to respond to.
|
|
||||||
* @param mmu the mmu we register with.
|
|
||||||
* @param size number of addresses to respond to
|
|
||||||
*/
|
*/
|
||||||
IsaFake(const std::string &name, Addr a, MemoryController *mmu,
|
IsaFake(Params *p);
|
||||||
HierParams *hier, Bus *pio_bus, Addr size = 0x8);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This read always returns -1.
|
* This read always returns -1.
|
||||||
* @param req The memory request.
|
* @param req The memory request.
|
||||||
* @param data Where to put the data.
|
* @param data Where to put the data.
|
||||||
*/
|
*/
|
||||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
virtual Tick read(Packet &pkt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All writes are simply ignored.
|
* All writes are simply ignored.
|
||||||
* @param req The memory request.
|
* @param req The memory request.
|
||||||
* @param data the data to not write.
|
* @param data the data to not write.
|
||||||
*/
|
*/
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
virtual Tick write(Packet &pkt);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return how long this access will take.
|
|
||||||
* @param req the memory request to calcuate
|
|
||||||
* @return Tick when the request is done
|
|
||||||
*/
|
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ISA_FAKE_HH__
|
#endif // __TSUNAMI_FAKE_HH__
|
||||||
|
|
|
@ -195,21 +195,17 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
Addr daddr = pkt.addr - pioAddr;
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
Addr regnum = (pkt.addr - pioAddr) >> 6 ;
|
||||||
|
|
||||||
|
|
||||||
uint64_t val = *(uint64_t *)pkt.data;
|
uint64_t val = *(uint64_t *)pkt.data;
|
||||||
assert(pkt.size == sizeof(uint64_t));
|
assert(pkt.size == sizeof(uint64_t));
|
||||||
|
|
||||||
DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n",
|
DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", req->addr, val);
|
||||||
req->vaddr, *(uint64_t*)data, req->size);
|
|
||||||
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
|
|
||||||
Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
|
|
||||||
|
|
||||||
bool supportedWrite = false;
|
bool supportedWrite = false;
|
||||||
|
|
||||||
switch (req->size) {
|
|
||||||
|
|
||||||
case sizeof(uint64_t):
|
|
||||||
if (daddr & TSDEV_CC_BDIMS)
|
if (daddr & TSDEV_CC_BDIMS)
|
||||||
{
|
{
|
||||||
int number = (daddr >> 4) & 0x3F;
|
int number = (daddr >> 4) & 0x3F;
|
||||||
|
@ -220,7 +216,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
olddim = dim[number];
|
olddim = dim[number];
|
||||||
olddir = dir[number];
|
olddir = dir[number];
|
||||||
dim[number] = *(uint64_t*)data;
|
dim[number] = val;
|
||||||
dir[number] = dim[number] & drir;
|
dir[number] = dim[number] & drir;
|
||||||
for(int x = 0; x < Tsunami::Max_CPUs; x++)
|
for(int x = 0; x < Tsunami::Max_CPUs; x++)
|
||||||
{
|
{
|
||||||
|
@ -249,19 +245,15 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NoFault;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
switch(regnum) {
|
switch(regnum) {
|
||||||
case TSDEV_CC_CSR:
|
case TSDEV_CC_CSR:
|
||||||
panic("TSDEV_CC_CSR write\n");
|
panic("TSDEV_CC_CSR write\n");
|
||||||
return NoFault;
|
|
||||||
case TSDEV_CC_MTR:
|
case TSDEV_CC_MTR:
|
||||||
panic("TSDEV_CC_MTR write not implemented\n");
|
panic("TSDEV_CC_MTR write not implemented\n");
|
||||||
return NoFault;
|
|
||||||
case TSDEV_CC_MISC:
|
case TSDEV_CC_MISC:
|
||||||
uint64_t ipreq;
|
uint64_t ipreq;
|
||||||
ipreq = (*(uint64_t*)data >> 12) & 0xF;
|
ipreq = (val >> 12) & 0xF;
|
||||||
//If it is bit 12-15, this is an IPI post
|
//If it is bit 12-15, this is an IPI post
|
||||||
if (ipreq) {
|
if (ipreq) {
|
||||||
reqIPI(ipreq);
|
reqIPI(ipreq);
|
||||||
|
@ -270,7 +262,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
//If it is bit 8-11, this is an IPI clear
|
//If it is bit 8-11, this is an IPI clear
|
||||||
uint64_t ipintr;
|
uint64_t ipintr;
|
||||||
ipintr = (*(uint64_t*)data >> 8) & 0xF;
|
ipintr = (val >> 8) & 0xF;
|
||||||
if (ipintr) {
|
if (ipintr) {
|
||||||
clearIPI(ipintr);
|
clearIPI(ipintr);
|
||||||
supportedWrite = true;
|
supportedWrite = true;
|
||||||
|
@ -278,20 +270,20 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
//If it is the 4-7th bit, clear the RTC interrupt
|
//If it is the 4-7th bit, clear the RTC interrupt
|
||||||
uint64_t itintr;
|
uint64_t itintr;
|
||||||
itintr = (*(uint64_t*)data >> 4) & 0xF;
|
itintr = (val >> 4) & 0xF;
|
||||||
if (itintr) {
|
if (itintr) {
|
||||||
clearITI(itintr);
|
clearITI(itintr);
|
||||||
supportedWrite = true;
|
supportedWrite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore NXMs
|
// ignore NXMs
|
||||||
if (*(uint64_t*)data & 0x10000000)
|
if (val & 0x10000000)
|
||||||
supportedWrite = true;
|
supportedWrite = true;
|
||||||
|
|
||||||
if(!supportedWrite)
|
if(!supportedWrite)
|
||||||
panic("TSDEV_CC_MISC write not implemented\n");
|
panic("TSDEV_CC_MISC write not implemented\n");
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_CC_AAR0:
|
case TSDEV_CC_AAR0:
|
||||||
case TSDEV_CC_AAR1:
|
case TSDEV_CC_AAR1:
|
||||||
case TSDEV_CC_AAR2:
|
case TSDEV_CC_AAR2:
|
||||||
|
@ -318,7 +310,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
olddim = dim[number];
|
olddim = dim[number];
|
||||||
olddir = dir[number];
|
olddir = dir[number];
|
||||||
dim[number] = *(uint64_t*)data;
|
dim[number] = val;
|
||||||
dir[number] = dim[number] & drir;
|
dir[number] = dim[number] & drir;
|
||||||
for(int x = 0; x < 64; x++)
|
for(int x = 0; x < 64; x++)
|
||||||
{
|
{
|
||||||
|
@ -347,7 +339,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_CC_DIR0:
|
case TSDEV_CC_DIR0:
|
||||||
case TSDEV_CC_DIR1:
|
case TSDEV_CC_DIR1:
|
||||||
case TSDEV_CC_DIR2:
|
case TSDEV_CC_DIR2:
|
||||||
|
@ -368,29 +360,20 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
case TSDEV_CC_MPR3:
|
case TSDEV_CC_MPR3:
|
||||||
panic("TSDEV_CC_MPRx write not implemented\n");
|
panic("TSDEV_CC_MPRx write not implemented\n");
|
||||||
case TSDEV_CC_IPIR:
|
case TSDEV_CC_IPIR:
|
||||||
clearIPI(*(uint64_t*)data);
|
clearIPI(val);
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_CC_ITIR:
|
case TSDEV_CC_ITIR:
|
||||||
clearITI(*(uint64_t*)data);
|
clearITI(val);
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_CC_IPIQ:
|
case TSDEV_CC_IPIQ:
|
||||||
reqIPI(*(uint64_t*)data);
|
reqIPI(val);
|
||||||
return NoFault;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("default in cchip read reached, accessing 0x%x\n");
|
panic("default in cchip read reached, accessing 0x%x\n");
|
||||||
}
|
} // swtich(regnum)
|
||||||
|
} // not BIG_TSUNAMI write
|
||||||
break;
|
pkt.result = Success;
|
||||||
case sizeof(uint32_t):
|
return pioDelay;
|
||||||
case sizeof(uint16_t):
|
|
||||||
case sizeof(uint8_t):
|
|
||||||
default:
|
|
||||||
panic("invalid access size(?) for tsunami register!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size);
|
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -554,30 +537,34 @@ TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
|
||||||
|
|
||||||
SimObjectParam<Tsunami *> tsunami;
|
Param<Addr> pio_addr;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
|
||||||
Param<Addr> addr;
|
|
||||||
SimObjectParam<Bus*> pio_bus;
|
|
||||||
Param<Tick> pio_latency;
|
Param<Tick> pio_latency;
|
||||||
SimObjectParam<HierParams *> hier;
|
SimObjectParam<Platform *> platform;
|
||||||
|
SimObjectParam<System *> system;
|
||||||
|
SimObjectParam<Tsunami *> tsunami;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
|
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
|
||||||
|
|
||||||
INIT_PARAM(tsunami, "Tsunami"),
|
INIT_PARAM(pio_addr, "Device Address"),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(pio_latency, "Programmed IO latency"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(platform, "platform"),
|
||||||
INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL),
|
INIT_PARAM(system, "system object"),
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
INIT_PARAM(tsunami, "Tsunami")
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
|
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
|
END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(TsunamiCChip)
|
CREATE_SIM_OBJECT(TsunamiCChip)
|
||||||
{
|
{
|
||||||
return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier,
|
TsunamiCChip::Params *p = new TsunamiCChip::Params;
|
||||||
pio_bus, pio_latency);
|
p->name = getInstanceName();
|
||||||
|
p->pio_addr = pio_addr;
|
||||||
|
p->pio_delay = pio_latency;
|
||||||
|
p->platform = platform;
|
||||||
|
p->system = system;
|
||||||
|
p->tsunami = tsunami;
|
||||||
|
return new TsunamiCChip(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip)
|
REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip)
|
||||||
|
|
|
@ -41,14 +41,11 @@
|
||||||
#include "dev/tsunami_io.hh"
|
#include "dev/tsunami_io.hh"
|
||||||
#include "dev/tsunami.hh"
|
#include "dev/tsunami.hh"
|
||||||
#include "dev/pitreg.h"
|
#include "dev/pitreg.h"
|
||||||
#include "mem/bus/bus.hh"
|
#include "mem/bus/port.hh"
|
||||||
#include "mem/bus/pio_interface.hh"
|
|
||||||
#include "mem/bus/pio_interface_impl.hh"
|
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
#include "dev/tsunami_cchip.hh"
|
#include "dev/tsunami_cchip.hh"
|
||||||
#include "dev/tsunamireg.h"
|
#include "dev/tsunamireg.h"
|
||||||
#include "dev/rtcreg.h"
|
#include "dev/rtcreg.h"
|
||||||
#include "mem/functional/memory_control.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
//Should this be AlphaISA?
|
//Should this be AlphaISA?
|
||||||
|
@ -80,28 +77,28 @@ TsunamiIO::RTC::set_time(time_t t)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiIO::RTC::writeAddr(const uint8_t *data)
|
TsunamiIO::RTC::writeAddr(const uint8_t data)
|
||||||
{
|
{
|
||||||
if (*data <= RTC_STAT_REGD)
|
if (*data <= RTC_STAT_REGD)
|
||||||
addr = *data;
|
addr = data;
|
||||||
else
|
else
|
||||||
panic("RTC addresses over 0xD are not implemented.\n");
|
panic("RTC addresses over 0xD are not implemented.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiIO::RTC::writeData(const uint8_t *data)
|
TsunamiIO::RTC::writeData(const uint8_t data)
|
||||||
{
|
{
|
||||||
if (addr < RTC_STAT_REGA)
|
if (addr < RTC_STAT_REGA)
|
||||||
clock_data[addr] = *data;
|
clock_data[addr] = data;
|
||||||
else {
|
else {
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case RTC_STAT_REGA:
|
case RTC_STAT_REGA:
|
||||||
if (*data != (RTCA_32768HZ | RTCA_1024HZ))
|
if (data != (RTCA_32768HZ | RTCA_1024HZ))
|
||||||
panic("Unimplemented RTC register A value write!\n");
|
panic("Unimplemented RTC register A value write!\n");
|
||||||
stat_regA = *data;
|
stat_regA = *data;
|
||||||
break;
|
break;
|
||||||
case RTC_STAT_REGB:
|
case RTC_STAT_REGB:
|
||||||
if ((*data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR))
|
if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR))
|
||||||
panic("Write to RTC reg B bits that are not implemented!\n");
|
panic("Write to RTC reg B bits that are not implemented!\n");
|
||||||
|
|
||||||
if (*data & RTCB_PRDC_IE) {
|
if (*data & RTCB_PRDC_IE) {
|
||||||
|
@ -111,7 +108,7 @@ TsunamiIO::RTC::writeData(const uint8_t *data)
|
||||||
if (event.scheduled())
|
if (event.scheduled())
|
||||||
event.deschedule();
|
event.deschedule();
|
||||||
}
|
}
|
||||||
stat_regB = *data;
|
stat_regB = data;
|
||||||
break;
|
break;
|
||||||
case RTC_STAT_REGC:
|
case RTC_STAT_REGC:
|
||||||
case RTC_STAT_REGD:
|
case RTC_STAT_REGD:
|
||||||
|
@ -207,12 +204,12 @@ TsunamiIO::PITimer::PITimer(const string &name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiIO::PITimer::writeControl(const uint8_t *data)
|
TsunamiIO::PITimer::writeControl(const uint8_t data)
|
||||||
{
|
{
|
||||||
int rw;
|
int rw;
|
||||||
int sel;
|
int sel;
|
||||||
|
|
||||||
sel = GET_CTRL_SEL(*data);
|
sel = GET_CTRL_SEL(data);
|
||||||
|
|
||||||
if (sel == PIT_READ_BACK)
|
if (sel == PIT_READ_BACK)
|
||||||
panic("PITimer Read-Back Command is not implemented.\n");
|
panic("PITimer Read-Back Command is not implemented.\n");
|
||||||
|
@ -223,8 +220,8 @@ TsunamiIO::PITimer::writeControl(const uint8_t *data)
|
||||||
counter[sel]->latchCount();
|
counter[sel]->latchCount();
|
||||||
else {
|
else {
|
||||||
counter[sel]->setRW(rw);
|
counter[sel]->setRW(rw);
|
||||||
counter[sel]->setMode(GET_CTRL_MODE(*data));
|
counter[sel]->setMode(GET_CTRL_MODE(data));
|
||||||
counter[sel]->setBCD(GET_CTRL_BCD(*data));
|
counter[sel]->setBCD(GET_CTRL_BCD(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,11 +293,11 @@ TsunamiIO::PITimer::Counter::read(uint8_t *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiIO::PITimer::Counter::write(const uint8_t *data)
|
TsunamiIO::PITimer::Counter::write(const uint8_t data)
|
||||||
{
|
{
|
||||||
switch (write_byte) {
|
switch (write_byte) {
|
||||||
case LSB:
|
case LSB:
|
||||||
count = (count & 0xFF00) | *data;
|
count = (count & 0xFF00) | data;
|
||||||
|
|
||||||
if (event.scheduled())
|
if (event.scheduled())
|
||||||
event.deschedule();
|
event.deschedule();
|
||||||
|
@ -309,7 +306,7 @@ TsunamiIO::PITimer::Counter::write(const uint8_t *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSB:
|
case MSB:
|
||||||
count = (count & 0x00FF) | (*data << 8);
|
count = (count & 0x00FF) | (data << 8);
|
||||||
period = count;
|
period = count;
|
||||||
|
|
||||||
if (period > 0) {
|
if (period > 0) {
|
||||||
|
@ -417,26 +414,17 @@ TsunamiIO::PITimer::Counter::CounterEvent::description()
|
||||||
return "tsunami 8254 Interval timer";
|
return "tsunami 8254 Interval timer";
|
||||||
}
|
}
|
||||||
|
|
||||||
TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
|
TsunamiIO::TsunamiIO(Params *p)
|
||||||
Addr a, MemoryController *mmu, HierParams *hier,
|
: BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"),
|
||||||
Bus *pio_bus, Tick pio_latency, Tick ci)
|
rtc(name + ".rtc", p->tsunami, p->frequency)
|
||||||
: PioDevice(name, t), addr(a), clockInterval(ci), tsunami(t),
|
|
||||||
pitimer(name + "pitimer"), rtc(name + ".rtc", t, ci)
|
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
pioSize = 0xff;
|
||||||
|
|
||||||
if (pio_bus) {
|
|
||||||
pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this,
|
|
||||||
&TsunamiIO::cacheAccess);
|
|
||||||
pioInterface->addAddrRange(RangeSize(addr, size));
|
|
||||||
pioLatency = pio_latency * pio_bus->clockRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the back pointer from tsunami to myself
|
// set the back pointer from tsunami to myself
|
||||||
tsunami->io = this;
|
tsunami->io = this;
|
||||||
|
|
||||||
timerData = 0;
|
timerData = 0;
|
||||||
rtc.set_time(init_time == 0 ? time(NULL) : init_time);
|
rtc.set_time(p->init_time == 0 ? time(NULL) : init_time);
|
||||||
picr = 0;
|
picr = 0;
|
||||||
picInterrupting = false;
|
picInterrupting = false;
|
||||||
}
|
}
|
||||||
|
@ -444,105 +432,112 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
|
||||||
Tick
|
Tick
|
||||||
TsunamiIO::frequency() const
|
TsunamiIO::frequency() const
|
||||||
{
|
{
|
||||||
return Clock::Frequency / clockInterval;
|
return Clock::Frequency / params()->frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
TsunamiIO::read(MemReqPtr &req, uint8_t *data)
|
TsunamiIO::read(Packet &pkt)
|
||||||
{
|
{
|
||||||
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n",
|
assert(pkt.result == Unknown);
|
||||||
req->vaddr, req->size, req->vaddr & 0xfff);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
|
pkt.time = curTick + pioDelay;
|
||||||
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
|
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr,
|
||||||
|
pkt.size, daddr);
|
||||||
|
|
||||||
|
|
||||||
switch(req->size) {
|
uint8_t *data8;
|
||||||
case sizeof(uint8_t):
|
uint64_t *data64;
|
||||||
|
|
||||||
|
if (pkt.size == sizeof(uint8_t)) {
|
||||||
|
|
||||||
|
if (!pkt.data) {
|
||||||
|
data8 = new uint8_t;
|
||||||
|
pkt.data = data8;
|
||||||
|
} else
|
||||||
|
data8 = pkt.data;
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
// PIC1 mask read
|
// PIC1 mask read
|
||||||
case TSDEV_PIC1_MASK:
|
case TSDEV_PIC1_MASK:
|
||||||
*(uint8_t*)data = ~mask1;
|
*data8 = ~mask1;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PIC2_MASK:
|
case TSDEV_PIC2_MASK:
|
||||||
*(uint8_t*)data = ~mask2;
|
*data8 = ~mask2;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PIC1_ISR:
|
case TSDEV_PIC1_ISR:
|
||||||
// !!! If this is modified 64bit case needs to be too
|
// !!! If this is modified 64bit case needs to be too
|
||||||
// Pal code has to do a 64 bit physical read because there is
|
// Pal code has to do a 64 bit physical read because there is
|
||||||
// no load physical byte instruction
|
// no load physical byte instruction
|
||||||
*(uint8_t*)data = picr;
|
*data8 = picr;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PIC2_ISR:
|
case TSDEV_PIC2_ISR:
|
||||||
// PIC2 not implemnted... just return 0
|
// PIC2 not implemnted... just return 0
|
||||||
*(uint8_t*)data = 0x00;
|
*data8 = 0x00;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_TMR0_DATA:
|
case TSDEV_TMR0_DATA:
|
||||||
pitimer.counter0.read(data);
|
pitimer.counter0.read(data8);
|
||||||
return NoFault;
|
return NoFault;
|
||||||
case TSDEV_TMR1_DATA:
|
case TSDEV_TMR1_DATA:
|
||||||
pitimer.counter1.read(data);
|
pitimer.counter1.read(data8);
|
||||||
return NoFault;
|
return NoFault;
|
||||||
case TSDEV_TMR2_DATA:
|
case TSDEV_TMR2_DATA:
|
||||||
pitimer.counter2.read(data);
|
pitimer.counter2.read(data8);
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_RTC_DATA:
|
case TSDEV_RTC_DATA:
|
||||||
rtc.readData(data);
|
rtc.readData(data8);
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_CTRL_PORTB:
|
case TSDEV_CTRL_PORTB:
|
||||||
if (pitimer.counter2.outputHigh())
|
if (pitimer.counter2.outputHigh())
|
||||||
*data = PORTB_SPKR_HIGH;
|
*data8 = PORTB_SPKR_HIGH;
|
||||||
else
|
else
|
||||||
*data = 0x00;
|
*data8 = 0x00;
|
||||||
return NoFault;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size);
|
||||||
}
|
}
|
||||||
case sizeof(uint16_t):
|
} else if (pkt.size == sizeof(uint64_t)) {
|
||||||
case sizeof(uint32_t):
|
if (!pkt.data) {
|
||||||
panic("I/O Read - invalid size - va %#x size %d\n",
|
data64 = new uint64_t;
|
||||||
req->vaddr, req->size);
|
pkt.data = (uint8_t*)data64;
|
||||||
|
} else
|
||||||
|
data8 = (uint64_t*)pkt.data;
|
||||||
|
|
||||||
case sizeof(uint64_t):
|
if (daddr == TSDEV_PIC1_ISR)
|
||||||
switch(daddr) {
|
data64 = (uint64_t)picr;
|
||||||
case TSDEV_PIC1_ISR:
|
else
|
||||||
// !!! If this is modified 8bit case needs to be too
|
panic("I/O Read - invalid addr - va %#x size %d\n",
|
||||||
// Pal code has to do a 64 bit physical read because there is
|
req.addr, req.size);
|
||||||
// no load physical byte instruction
|
} else {
|
||||||
*(uint64_t*)data = (uint64_t)picr;
|
panic("I/O Read - invalid size - va %#x size %d\n", req.addr, req.size);
|
||||||
return NoFault;
|
|
||||||
default:
|
|
||||||
panic("I/O Read - invalid size - va %#x size %d\n",
|
|
||||||
req->vaddr, req->size);
|
|
||||||
}
|
}
|
||||||
|
pkt.result = Success;
|
||||||
default:
|
return pioDelay;
|
||||||
panic("I/O Read - invalid size - va %#x size %d\n",
|
|
||||||
req->vaddr, req->size);
|
|
||||||
}
|
|
||||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Tick
|
||||||
TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
TsunamiIO::write(Packet &pkt)
|
||||||
{
|
{
|
||||||
|
pkt.time = curTick + pioDelay;
|
||||||
|
|
||||||
|
assert(pkt.result == Unknown);
|
||||||
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
uint8_t val = *pkt.data;
|
||||||
|
|
||||||
#if TRACING_ON
|
#if TRACING_ON
|
||||||
uint8_t dt = *(uint8_t*)data;
|
uint64_t dt64 = val;
|
||||||
uint64_t dt64 = dt;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
|
DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
|
||||||
req->vaddr, req->size, req->vaddr & 0xfff, dt64);
|
req->vaddr, req->size, req->vaddr & 0xfff, dt64);
|
||||||
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
|
assert(pkt.size == sizeof(uint8_t));
|
||||||
|
|
||||||
switch(req->size) {
|
|
||||||
case sizeof(uint8_t):
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PIC1_MASK:
|
case TSDEV_PIC1_MASK:
|
||||||
mask1 = ~(*(uint8_t*)data);
|
mask1 = ~(val);
|
||||||
if ((picr & mask1) && !picInterrupting) {
|
if ((picr & mask1) && !picInterrupting) {
|
||||||
picInterrupting = true;
|
picInterrupting = true;
|
||||||
tsunami->cchip->postDRIR(55);
|
tsunami->cchip->postDRIR(55);
|
||||||
|
@ -553,76 +548,59 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
||||||
tsunami->cchip->clearDRIR(55);
|
tsunami->cchip->clearDRIR(55);
|
||||||
DPRINTF(Tsunami, "clearing pic interrupt\n");
|
DPRINTF(Tsunami, "clearing pic interrupt\n");
|
||||||
}
|
}
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PIC2_MASK:
|
case TSDEV_PIC2_MASK:
|
||||||
mask2 = *(uint8_t*)data;
|
mask2 = val;
|
||||||
//PIC2 Not implemented to interrupt
|
//PIC2 Not implemented to interrupt
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PIC1_ACK:
|
case TSDEV_PIC1_ACK:
|
||||||
// clear the interrupt on the PIC
|
// clear the interrupt on the PIC
|
||||||
picr &= ~(1 << (*(uint8_t*)data & 0xF));
|
picr &= ~(1 << (val & 0xF));
|
||||||
if (!(picr & mask1))
|
if (!(picr & mask1))
|
||||||
tsunami->cchip->clearDRIR(55);
|
tsunami->cchip->clearDRIR(55);
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_DMA1_CMND:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_DMA2_CMND:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_DMA1_MMASK:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_DMA2_MMASK:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_PIC2_ACK:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_DMA1_RESET:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_DMA2_RESET:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_DMA1_MODE:
|
case TSDEV_DMA1_MODE:
|
||||||
mode1 = *(uint8_t*)data;
|
mode1 = val;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_DMA2_MODE:
|
case TSDEV_DMA2_MODE:
|
||||||
mode2 = *(uint8_t*)data;
|
mode2 = val;
|
||||||
return NoFault;
|
break;
|
||||||
|
case TSDEV_TMR0_DATA:
|
||||||
|
pitimer.counter0.write(val);
|
||||||
|
break;
|
||||||
|
case TSDEV_TMR1_DATA:
|
||||||
|
pitimer.counter1.write(val);
|
||||||
|
break;
|
||||||
|
case TSDEV_TMR2_DATA:
|
||||||
|
pitimer.counter2.write(val);
|
||||||
|
break;
|
||||||
|
case TSDEV_TMR_CTRL:
|
||||||
|
pitimer.writeControl(val);
|
||||||
|
break;
|
||||||
|
case TSDEV_RTC_ADDR:
|
||||||
|
rtc.writeAddr(val);
|
||||||
|
break;
|
||||||
|
case TSDEV_RTC_DATA:
|
||||||
|
rtc.writeData(val);
|
||||||
|
break;
|
||||||
|
case TSDEV_KBD:
|
||||||
|
case TSDEV_DMA1_CMND:
|
||||||
|
case TSDEV_DMA2_CMND:
|
||||||
|
case TSDEV_DMA1_MMASK:
|
||||||
|
case TSDEV_DMA2_MMASK:
|
||||||
|
case TSDEV_PIC2_ACK:
|
||||||
|
case TSDEV_DMA1_RESET:
|
||||||
|
case TSDEV_DMA2_RESET:
|
||||||
case TSDEV_DMA1_MASK:
|
case TSDEV_DMA1_MASK:
|
||||||
case TSDEV_DMA2_MASK:
|
case TSDEV_DMA2_MASK:
|
||||||
return NoFault;
|
|
||||||
case TSDEV_TMR0_DATA:
|
|
||||||
pitimer.counter0.write(data);
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_TMR1_DATA:
|
|
||||||
pitimer.counter1.write(data);
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_TMR2_DATA:
|
|
||||||
pitimer.counter2.write(data);
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_TMR_CTRL:
|
|
||||||
pitimer.writeControl(data);
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_RTC_ADDR:
|
|
||||||
rtc.writeAddr(data);
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_KBD:
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_RTC_DATA:
|
|
||||||
rtc.writeData(data);
|
|
||||||
return NoFault;
|
|
||||||
case TSDEV_CTRL_PORTB:
|
case TSDEV_CTRL_PORTB:
|
||||||
// System Control Port B not implemented
|
break;
|
||||||
return NoFault;
|
|
||||||
default:
|
default:
|
||||||
panic("I/O Write - va%#x size %d data %#x\n", req->vaddr, req->size, (int)*data);
|
panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, val);
|
||||||
}
|
|
||||||
case sizeof(uint16_t):
|
|
||||||
case sizeof(uint32_t):
|
|
||||||
case sizeof(uint64_t):
|
|
||||||
default:
|
|
||||||
panic("I/O Write - invalid size - va %#x size %d\n",
|
|
||||||
req->vaddr, req->size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkt.result = Success;
|
||||||
return NoFault;
|
return pioDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -647,12 +625,6 @@ TsunamiIO::clearPIC(uint8_t bitvector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tick
|
|
||||||
TsunamiIO::cacheAccess(MemReqPtr &req)
|
|
||||||
{
|
|
||||||
return curTick + pioLatency;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiIO::serialize(ostream &os)
|
TsunamiIO::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
|
@ -687,34 +659,41 @@ TsunamiIO::unserialize(Checkpoint *cp, const string §ion)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
SimObjectParam<Tsunami *> tsunami;
|
Param<Addr> pio_addr;
|
||||||
Param<time_t> time;
|
|
||||||
SimObjectParam<MemoryController *> mmu;
|
|
||||||
Param<Addr> addr;
|
|
||||||
SimObjectParam<Bus*> pio_bus;
|
|
||||||
Param<Tick> pio_latency;
|
Param<Tick> pio_latency;
|
||||||
SimObjectParam<HierParams *> hier;
|
|
||||||
Param<Tick> frequency;
|
Param<Tick> frequency;
|
||||||
|
SimObjectParam<Platform *> platform;
|
||||||
|
SimObjectParam<System *> system;
|
||||||
|
Param<time_t> time;
|
||||||
|
SimObjectParam<Tsunami *> tsunami;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
INIT_PARAM(tsunami, "Tsunami"),
|
INIT_PARAM(frequency, "clock interrupt frequency"),
|
||||||
|
INIT_PARAM(pio_addr, "Device Address"),
|
||||||
|
INIT_PARAM(pio_latency, "Programmed IO latency"),
|
||||||
|
INIT_PARAM(pio_size, "Size of address range"),
|
||||||
|
INIT_PARAM(platform, "platform"),
|
||||||
|
INIT_PARAM(system, "system object"),
|
||||||
INIT_PARAM(time, "System time to use (0 for actual time"),
|
INIT_PARAM(time, "System time to use (0 for actual time"),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(tsunami, "Tsunami")
|
||||||
INIT_PARAM(addr, "Device Address"),
|
|
||||||
INIT_PARAM(pio_bus, "The IO Bus to attach to"),
|
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
|
||||||
INIT_PARAM(frequency, "clock interrupt frequency")
|
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(TsunamiIO)
|
CREATE_SIM_OBJECT(TsunamiIO)
|
||||||
{
|
{
|
||||||
return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier,
|
TsunamiIO::Params *p = new TsunamiIO::Params;
|
||||||
pio_bus, pio_latency, frequency);
|
p->frequency = frequency;
|
||||||
|
p->name = getInstanceName();
|
||||||
|
p->pio_addr = pio_addr;
|
||||||
|
p->pio_delay = pio_latency;
|
||||||
|
p->platform = platform;
|
||||||
|
p->system = system;
|
||||||
|
p->init_time = time;
|
||||||
|
p->tsunami = tsunami;
|
||||||
|
return new TsunamiIO(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)
|
REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
#include "dev/tsunami.hh"
|
#include "dev/tsunami.hh"
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
class MemoryController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tsunami I/O device is a catch all for all the south bridge stuff we care
|
* Tsunami I/O device is a catch all for all the south bridge stuff we care
|
||||||
* to implement.
|
* to implement.
|
||||||
|
@ -47,12 +45,6 @@ class MemoryController;
|
||||||
class TsunamiIO : public PioDevice
|
class TsunamiIO : public PioDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** The base address of this device */
|
|
||||||
Addr addr;
|
|
||||||
|
|
||||||
/** The size of mappad from the above address */
|
|
||||||
static const Addr size = 0xff;
|
|
||||||
|
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -120,10 +112,10 @@ class TsunamiIO : public PioDevice
|
||||||
void set_time(time_t t);
|
void set_time(time_t t);
|
||||||
|
|
||||||
/** RTC address port: write address of RTC RAM data to access */
|
/** RTC address port: write address of RTC RAM data to access */
|
||||||
void writeAddr(const uint8_t *data);
|
void writeAddr(const uint8_t data);
|
||||||
|
|
||||||
/** RTC write data */
|
/** RTC write data */
|
||||||
void writeData(const uint8_t *data);
|
void writeData(const uint8_t data);
|
||||||
|
|
||||||
/** RTC read data */
|
/** RTC read data */
|
||||||
void readData(uint8_t *data);
|
void readData(uint8_t *data);
|
||||||
|
@ -218,7 +210,7 @@ class TsunamiIO : public PioDevice
|
||||||
void read(uint8_t *data);
|
void read(uint8_t *data);
|
||||||
|
|
||||||
/** Write a count byte */
|
/** Write a count byte */
|
||||||
void write(const uint8_t *data);
|
void write(const uint8_t data);
|
||||||
|
|
||||||
/** Is the output high? */
|
/** Is the output high? */
|
||||||
bool outputHigh();
|
bool outputHigh();
|
||||||
|
@ -254,7 +246,7 @@ class TsunamiIO : public PioDevice
|
||||||
PITimer(const std::string &name);
|
PITimer(const std::string &name);
|
||||||
|
|
||||||
/** Write control word */
|
/** Write control word */
|
||||||
void writeControl(const uint8_t* data);
|
void writeControl(const uint8_t data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize this object to the given output stream.
|
* Serialize this object to the given output stream.
|
||||||
|
@ -289,8 +281,6 @@ class TsunamiIO : public PioDevice
|
||||||
/** Is the pic interrupting right now or not. */
|
/** Is the pic interrupting right now or not. */
|
||||||
bool picInterrupting;
|
bool picInterrupting;
|
||||||
|
|
||||||
Tick clockInterval;
|
|
||||||
|
|
||||||
/** A pointer to the Tsunami device which be belong to */
|
/** A pointer to the Tsunami device which be belong to */
|
||||||
Tsunami *tsunami;
|
Tsunami *tsunami;
|
||||||
|
|
||||||
|
@ -312,33 +302,24 @@ class TsunamiIO : public PioDevice
|
||||||
*/
|
*/
|
||||||
Tick frequency() const;
|
Tick frequency() const;
|
||||||
|
|
||||||
|
struct Params : public BasicPioDevice::Params
|
||||||
|
{
|
||||||
|
Tick frequency;
|
||||||
|
Tsunami *tsunami;
|
||||||
|
time_t init_time;
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
const Params *params() const { return (const Params*)_params; }
|
||||||
|
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* Initialize all the data for devices supported by Tsunami I/O.
|
* Initialize all the data for devices supported by Tsunami I/O.
|
||||||
* @param name name of this device.
|
* @param p pointer to Params struct
|
||||||
* @param t pointer back to the Tsunami object that we belong to.
|
|
||||||
* @param init_time Time (as in seconds since 1970) to set RTC to.
|
|
||||||
* @param a address we are mapped at.
|
|
||||||
* @param mmu pointer to the memory controller that sends us events.
|
|
||||||
*/
|
*/
|
||||||
TsunamiIO(const std::string &name, Tsunami *t, time_t init_time,
|
TsunamiIO(Params *p);
|
||||||
Addr a, MemoryController *mmu, HierParams *hier, Bus *pio_bus,
|
|
||||||
Tick pio_latency, Tick ci);
|
|
||||||
|
|
||||||
/**
|
virtual Fault read(Packet &pkt);
|
||||||
* Process a read to one of the devices we are emulating.
|
virtual Fault write(Packet &pkt);
|
||||||
* @param req Contains the address to read from.
|
|
||||||
* @param data A pointer to write the read data to.
|
|
||||||
* @return The fault condition of the access.
|
|
||||||
*/
|
|
||||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a write to one of the devices we emulate.
|
|
||||||
* @param req Contains the address to write to.
|
|
||||||
* @param data The data to write.
|
|
||||||
* @return The fault condition of the access.
|
|
||||||
*/
|
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post an PIC interrupt to the CPU via the CChip
|
* Post an PIC interrupt to the CPU via the CChip
|
||||||
|
@ -365,7 +346,6 @@ class TsunamiIO : public PioDevice
|
||||||
*/
|
*/
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __DEV_TSUNAMI_IO_HH__
|
#endif // __DEV_TSUNAMI_IO_HH__
|
||||||
|
|
|
@ -51,12 +51,10 @@ using namespace std;
|
||||||
//Should this be AlphaISA?
|
//Should this be AlphaISA?
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
|
TsunamiPChip::TsunamiPChip(Params *p)
|
||||||
MemoryController *mmu, HierParams *hier,
|
: BasicPioDevice(p),
|
||||||
Bus *pio_bus, Tick pio_latency)
|
|
||||||
: PioDevice(name, t), addr(a), tsunami(t)
|
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
pioSize = 0xfff;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
wsba[i] = 0;
|
wsba[i] = 0;
|
||||||
|
@ -64,167 +62,161 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
|
||||||
tba[i] = 0;
|
tba[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pio_bus) {
|
|
||||||
pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this,
|
|
||||||
&TsunamiPChip::cacheAccess);
|
|
||||||
pioInterface->addAddrRange(RangeSize(addr, size));
|
|
||||||
pioLatency = pio_latency * pio_bus->clockRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// initialize pchip control register
|
// initialize pchip control register
|
||||||
pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36);
|
pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36);
|
||||||
|
|
||||||
//Set back pointer in tsunami
|
//Set back pointer in tsunami
|
||||||
tsunami->pchip = this;
|
p->tsunami->pchip = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Tick
|
||||||
TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
|
TsunamiPChip::read(Packet &pkt)
|
||||||
{
|
{
|
||||||
DPRINTF(Tsunami, "read va=%#x size=%d\n",
|
assert(pkt.result == Unknown);
|
||||||
req->vaddr, req->size);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
|
pkt.time = curTick + pioDelay;
|
||||||
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
switch (req->size) {
|
uint64_t *data64;
|
||||||
|
|
||||||
|
if (!pkt.data) {
|
||||||
|
data64 = new uint64_t;
|
||||||
|
pkt.data = (uint8_t*)data64;
|
||||||
|
} else
|
||||||
|
data64 = (uint64_t*)pkt.data;
|
||||||
|
|
||||||
|
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
|
||||||
|
|
||||||
case sizeof(uint64_t):
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PC_WSBA0:
|
case TSDEV_PC_WSBA0:
|
||||||
*(uint64_t*)data = wsba[0];
|
*data64 = wsba[0];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSBA1:
|
case TSDEV_PC_WSBA1:
|
||||||
*(uint64_t*)data = wsba[1];
|
*data64 = wsba[1];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSBA2:
|
case TSDEV_PC_WSBA2:
|
||||||
*(uint64_t*)data = wsba[2];
|
*data64 = wsba[2];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSBA3:
|
case TSDEV_PC_WSBA3:
|
||||||
*(uint64_t*)data = wsba[3];
|
*data64 = wsba[3];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM0:
|
case TSDEV_PC_WSM0:
|
||||||
*(uint64_t*)data = wsm[0];
|
*data64 = wsm[0];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM1:
|
case TSDEV_PC_WSM1:
|
||||||
*(uint64_t*)data = wsm[1];
|
*data64 = wsm[1];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM2:
|
case TSDEV_PC_WSM2:
|
||||||
*(uint64_t*)data = wsm[2];
|
*data64 = wsm[2];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM3:
|
case TSDEV_PC_WSM3:
|
||||||
*(uint64_t*)data = wsm[3];
|
*data64 = wsm[3];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA0:
|
case TSDEV_PC_TBA0:
|
||||||
*(uint64_t*)data = tba[0];
|
*data64 = tba[0];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA1:
|
case TSDEV_PC_TBA1:
|
||||||
*(uint64_t*)data = tba[1];
|
*data64 = tba[1];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA2:
|
case TSDEV_PC_TBA2:
|
||||||
*(uint64_t*)data = tba[2];
|
*data64 = tba[2];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA3:
|
case Tbreak;
|
||||||
*(uint64_t*)data = tba[3];
|
*data64 = tba[3];
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PCTL:
|
case TSDEV_PC_PCTL:
|
||||||
*(uint64_t*)data = pctl;
|
*data64 = pctl;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PLAT:
|
case TSDEV_PC_PLAT:
|
||||||
panic("PC_PLAT not implemented\n");
|
panic("PC_PLAT not implemented\n");
|
||||||
case TSDEV_PC_RES:
|
case TSDEV_PC_RES:
|
||||||
panic("PC_RES not implemented\n");
|
panic("PC_RES not implemented\n");
|
||||||
case TSDEV_PC_PERROR:
|
case TSDEV_PC_PERROR:
|
||||||
*(uint64_t*)data = 0x00;
|
*data64 = 0x00;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PERRMASK:
|
case TSDEV_PC_PERRMASK:
|
||||||
*(uint64_t*)data = 0x00;
|
*data64 = 0x00;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PERRSET:
|
case TSDEV_PC_PERRSET:
|
||||||
panic("PC_PERRSET not implemented\n");
|
panic("PC_PERRSET not implemented\n");
|
||||||
case TSDEV_PC_TLBIV:
|
case TSDEV_PC_TLBIV:
|
||||||
panic("PC_TLBIV not implemented\n");
|
panic("PC_TLBIV not implemented\n");
|
||||||
case TSDEV_PC_TLBIA:
|
case TSDEV_PC_TLBIA:
|
||||||
*(uint64_t*)data = 0x00; // shouldn't be readable, but linux
|
*data64 = 0x00; // shouldn't be readable, but linux
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PMONCTL:
|
case TSDEV_PC_PMONCTL:
|
||||||
panic("PC_PMONCTL not implemented\n");
|
panic("PC_PMONCTL not implemented\n");
|
||||||
case TSDEV_PC_PMONCNT:
|
case TSDEV_PC_PMONCNT:
|
||||||
panic("PC_PMONCTN not implemented\n");
|
panic("PC_PMONCTN not implemented\n");
|
||||||
default:
|
default:
|
||||||
panic("Default in PChip Read reached reading 0x%x\n", daddr);
|
panic("Default in PChip Read reached reading 0x%x\n", daddr);
|
||||||
|
|
||||||
} // uint64_t
|
|
||||||
|
|
||||||
break;
|
|
||||||
case sizeof(uint32_t):
|
|
||||||
case sizeof(uint16_t):
|
|
||||||
case sizeof(uint8_t):
|
|
||||||
default:
|
|
||||||
panic("invalid access size(?) for tsunami register!\n\n");
|
|
||||||
}
|
}
|
||||||
DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size);
|
pkt.result = Success;
|
||||||
|
return pioDelay;
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
TsunamiPChip::write(Packet &pkt)
|
||||||
{
|
{
|
||||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n",
|
pkt.time = curTick + pioDelay;
|
||||||
req->vaddr, req->size);
|
|
||||||
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6;
|
assert(pkt.result == Unknown);
|
||||||
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
switch (req->size) {
|
uint64_t val = *(uint64_t *)pkt.data;
|
||||||
|
assert(pkt.size == sizeof(uint64_t));
|
||||||
|
|
||||||
|
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size);
|
||||||
|
|
||||||
case sizeof(uint64_t):
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PC_WSBA0:
|
case TSDEV_PC_WSBA0:
|
||||||
wsba[0] = *(uint64_t*)data;
|
wsba[0] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSBA1:
|
case TSDEV_PC_WSBA1:
|
||||||
wsba[1] = *(uint64_t*)data;
|
wsba[1] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSBA2:
|
case TSDEV_PC_WSBA2:
|
||||||
wsba[2] = *(uint64_t*)data;
|
wsba[2] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSBA3:
|
case TSDEV_PC_WSBA3:
|
||||||
wsba[3] = *(uint64_t*)data;
|
wsba[3] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM0:
|
case TSDEV_PC_WSM0:
|
||||||
wsm[0] = *(uint64_t*)data;
|
wsm[0] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM1:
|
case TSDEV_PC_WSM1:
|
||||||
wsm[1] = *(uint64_t*)data;
|
wsm[1] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM2:
|
case TSDEV_PC_WSM2:
|
||||||
wsm[2] = *(uint64_t*)data;
|
wsm[2] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_WSM3:
|
case TSDEV_PC_WSM3:
|
||||||
wsm[3] = *(uint64_t*)data;
|
wsm[3] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA0:
|
case TSDEV_PC_TBA0:
|
||||||
tba[0] = *(uint64_t*)data;
|
tba[0] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA1:
|
case TSDEV_PC_TBA1:
|
||||||
tba[1] = *(uint64_t*)data;
|
tba[1] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA2:
|
case TSDEV_PC_TBA2:
|
||||||
tba[2] = *(uint64_t*)data;
|
tba[2] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_TBA3:
|
case TSDEV_PC_TBA3:
|
||||||
tba[3] = *(uint64_t*)data;
|
tba[3] = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PCTL:
|
case TSDEV_PC_PCTL:
|
||||||
pctl = *(uint64_t*)data;
|
pctl = data64;
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PLAT:
|
case TSDEV_PC_PLAT:
|
||||||
panic("PC_PLAT not implemented\n");
|
panic("PC_PLAT not implemented\n");
|
||||||
case TSDEV_PC_RES:
|
case TSDEV_PC_RES:
|
||||||
panic("PC_RES not implemented\n");
|
panic("PC_RES not implemented\n");
|
||||||
case TSDEV_PC_PERROR:
|
case TSDEV_PC_PERROR:
|
||||||
return NoFault;
|
break;
|
||||||
case TSDEV_PC_PERRMASK:
|
case TSDEV_PC_PERRMASK:
|
||||||
panic("PC_PERRMASK not implemented\n");
|
panic("PC_PERRMASK not implemented\n");
|
||||||
case TSDEV_PC_PERRSET:
|
case TSDEV_PC_PERRSET:
|
||||||
|
@ -232,7 +224,7 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
||||||
case TSDEV_PC_TLBIV:
|
case TSDEV_PC_TLBIV:
|
||||||
panic("PC_TLBIV not implemented\n");
|
panic("PC_TLBIV not implemented\n");
|
||||||
case TSDEV_PC_TLBIA:
|
case TSDEV_PC_TLBIA:
|
||||||
return NoFault; // value ignored, supposted to invalidate SG TLB
|
break; // value ignored, supposted to invalidate SG TLB
|
||||||
case TSDEV_PC_PMONCTL:
|
case TSDEV_PC_PMONCTL:
|
||||||
panic("PC_PMONCTL not implemented\n");
|
panic("PC_PMONCTL not implemented\n");
|
||||||
case TSDEV_PC_PMONCNT:
|
case TSDEV_PC_PMONCNT:
|
||||||
|
@ -242,17 +234,8 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
||||||
|
|
||||||
} // uint64_t
|
} // uint64_t
|
||||||
|
|
||||||
break;
|
pkt.result = Success;
|
||||||
case sizeof(uint32_t):
|
return pioDelay;
|
||||||
case sizeof(uint16_t):
|
|
||||||
case sizeof(uint8_t):
|
|
||||||
default:
|
|
||||||
panic("invalid access size(?) for tsunami register!\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size);
|
|
||||||
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DMA_ADDR_MASK ULL(0x3ffffffff)
|
#define DMA_ADDR_MASK ULL(0x3ffffffff)
|
||||||
|
@ -312,10 +295,7 @@ TsunamiPChip::translatePciToDma(Addr busAddr)
|
||||||
baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13);
|
baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13);
|
||||||
pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
|
pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
|
||||||
|
|
||||||
memcpy((void *)&pteEntry,
|
pioPort->readBlob(&pteEntry, pteAddr, sizeof(uint64_t));
|
||||||
tsunami->system->
|
|
||||||
physmem->dma_addr(pteAddr, sizeof(uint64_t)),
|
|
||||||
sizeof(uint64_t));
|
|
||||||
|
|
||||||
dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff));
|
dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff));
|
||||||
|
|
||||||
|
@ -360,30 +340,34 @@ TsunamiPChip::cacheAccess(MemReqPtr &req)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
||||||
|
|
||||||
SimObjectParam<Tsunami *> tsunami;
|
Param<Addr> pio_addr;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
|
||||||
Param<Addr> addr;
|
|
||||||
SimObjectParam<Bus*> pio_bus;
|
|
||||||
Param<Tick> pio_latency;
|
Param<Tick> pio_latency;
|
||||||
SimObjectParam<HierParams *> hier;
|
SimObjectParam<Platform *> platform;
|
||||||
|
SimObjectParam<System *> system;
|
||||||
|
SimObjectParam<Tsunami *> tsunami;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
|
||||||
|
|
||||||
INIT_PARAM(tsunami, "Tsunami"),
|
INIT_PARAM(pio_addr, "Device Address"),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(pio_latency, "Programmed IO latency"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(platform, "platform"),
|
||||||
INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL),
|
INIT_PARAM(system, "system object"),
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
INIT_PARAM(tsunami, "Tsunami")
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
|
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
|
END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(TsunamiPChip)
|
CREATE_SIM_OBJECT(TsunamiPChip)
|
||||||
{
|
{
|
||||||
return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier,
|
TsunamiPChip::Params *p = new TsunamiPChip::Params;
|
||||||
pio_bus, pio_latency);
|
p->name = getInstanceName();
|
||||||
|
p->pio_addr = pio_addr;
|
||||||
|
p->pio_delay = pio_latency;
|
||||||
|
p->platform = platform;
|
||||||
|
p->system = system;
|
||||||
|
p->tsunami = tsunami;
|
||||||
|
return new TsunamiPChip(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip)
|
REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip)
|
||||||
|
|
|
@ -37,28 +37,12 @@
|
||||||
#include "base/range.hh"
|
#include "base/range.hh"
|
||||||
#include "dev/io_device.hh"
|
#include "dev/io_device.hh"
|
||||||
|
|
||||||
class MemoryController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A very simple implementation of the Tsunami PCI interface chips.
|
* A very simple implementation of the Tsunami PCI interface chips.
|
||||||
*/
|
*/
|
||||||
class TsunamiPChip : public PioDevice
|
class TsunamiPChip : public BasicPioDevice
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
/** The base address of this device */
|
|
||||||
Addr addr;
|
|
||||||
|
|
||||||
/** The size of mappad from the above address */
|
|
||||||
static const Addr size = 0xfff;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
|
||||||
* pointer to the tsunami object.
|
|
||||||
* This is our access to all the other tsunami
|
|
||||||
* devices.
|
|
||||||
*/
|
|
||||||
Tsunami *tsunami;
|
|
||||||
|
|
||||||
/** Pchip control register */
|
/** Pchip control register */
|
||||||
uint64_t pctl;
|
uint64_t pctl;
|
||||||
|
|
||||||
|
@ -71,19 +55,20 @@ class TsunamiPChip : public PioDevice
|
||||||
/** Translated Base Addresses */
|
/** Translated Base Addresses */
|
||||||
uint64_t tba[4];
|
uint64_t tba[4];
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct Params : public BasicPioDevice::Params
|
||||||
|
{
|
||||||
|
Tsunami *tsunami;
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
const Params *params() const { return (const Params*)_params; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Register the PChip with the mmu and init all wsba, wsm, and tba to 0
|
* Register the PChip with the mmu and init all wsba, wsm, and tba to 0
|
||||||
* @param name the name of thes device
|
* @param p pointer to the parameters struct
|
||||||
* @param t a pointer to the tsunami device
|
|
||||||
* @param a the address which we respond to
|
|
||||||
* @param mmu the mmu we are to register with
|
|
||||||
* @param hier object to store parameters universal the device hierarchy
|
|
||||||
* @param bus The bus that this device is attached to
|
|
||||||
*/
|
*/
|
||||||
TsunamiPChip(const std::string &name, Tsunami *t, Addr a,
|
TsunamiPChip(Params *p);
|
||||||
MemoryController *mmu, HierParams *hier, Bus *pio_bus,
|
|
||||||
Tick pio_latency);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate a PCI bus address to a memory address for DMA.
|
* Translate a PCI bus address to a memory address for DMA.
|
||||||
|
@ -93,21 +78,8 @@ class TsunamiPChip : public PioDevice
|
||||||
*/
|
*/
|
||||||
Addr translatePciToDma(Addr busAddr);
|
Addr translatePciToDma(Addr busAddr);
|
||||||
|
|
||||||
/**
|
virtual Fault read(Packet &pkt);
|
||||||
* Process a read to the PChip.
|
virtual Fault write(Packet &pkt);
|
||||||
* @param req Contains the address to read from.
|
|
||||||
* @param data A pointer to write the read data to.
|
|
||||||
* @return The fault condition of the access.
|
|
||||||
*/
|
|
||||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a write to the PChip.
|
|
||||||
* @param req Contains the address to write to.
|
|
||||||
* @param data The data to write.
|
|
||||||
* @return The fault condition of the access.
|
|
||||||
*/
|
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize this object to the given output stream.
|
* Serialize this object to the given output stream.
|
||||||
|
@ -121,13 +93,6 @@ class TsunamiPChip : public PioDevice
|
||||||
* @param section The section name of this object
|
* @param section The section name of this object
|
||||||
*/
|
*/
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return how long this access will take.
|
|
||||||
* @param req the memory request to calcuate
|
|
||||||
* @return Tick when the request is done
|
|
||||||
*/
|
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __TSUNAMI_PCHIP_HH__
|
#endif // __TSUNAMI_PCHIP_HH__
|
||||||
|
|
Loading…
Reference in a new issue