Merge zizzer:/bk/newmem

into  zeep.eecs.umich.edu:/z/saidi/work/m5.newmem

--HG--
extra : convert_revision : 36da0febc30675e955a10eb8bc45586b6242a8c3
This commit is contained in:
Ali Saidi 2006-04-10 14:14:25 -04:00
commit e17a15f4c5
14 changed files with 729 additions and 862 deletions

View file

@ -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('''

View file

@ -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;

View file

@ -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
*/ */

View file

@ -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)

View file

@ -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__

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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__

View file

@ -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 &section)
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)

View file

@ -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 &section)
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)

View file

@ -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 &section); virtual void unserialize(Checkpoint *cp, const std::string &section);
Tick cacheAccess(MemReqPtr &req);
}; };
#endif // __DEV_TSUNAMI_IO_HH__ #endif // __DEV_TSUNAMI_IO_HH__

View file

@ -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)

View file

@ -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 &section); virtual void unserialize(Checkpoint *cp, const std::string &section);
/**
* 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__