Merge m5.eecs.umich.edu:/bk/newmem

into  ewok.(none):/home/gblack/m5/newmem

--HG--
extra : convert_revision : 7866241cf43416636cbd6a3a4f6eeda561ed2e27
This commit is contained in:
Gabe Black 2006-03-29 17:40:09 -05:00
commit 2177d822ce
7 changed files with 142 additions and 101 deletions

View file

@ -75,6 +75,11 @@ class SyscallReturn {
#endif #endif
#if FULL_SYSTEM
#include "arch/alpha/isa_fullsys_traits.hh"
#endif
namespace AlphaISA namespace AlphaISA
{ {
@ -83,12 +88,6 @@ using namespace LittleEndianGuest;
// redirected register map, really only used for the full system case. // redirected register map, really only used for the full system case.
extern const int reg_redir[NumIntRegs]; extern const int reg_redir[NumIntRegs];
#if FULL_SYSTEM
#include "arch/alpha/isa_fullsys_traits.hh"
#endif
StaticInstPtr decodeInst(ExtMachInst); StaticInstPtr decodeInst(ExtMachInst);
#if !FULL_SYSTEM #if !FULL_SYSTEM

View file

@ -5,7 +5,8 @@ class HelloWorld(AlphaLiveProcess):
cmd = 'hello' cmd = 'hello'
magicbus = Bus() magicbus = Bus()
mem = PhysicalMemory(bus=magicbus) mem = PhysicalMemory()
cpu = SimpleCPU(workload=HelloWorld(), mem=magicbus) cpu = SimpleCPU(workload=HelloWorld(), mem=magicbus)
system = System(physmem=mem, cpu=cpu) system = System(physmem=mem, cpu=cpu)
system.c1 = Connector(side_a=mem, side_b=magicbus)
root = Root(system=system) root = Root(system=system)

View file

@ -34,7 +34,6 @@
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include "arch/alpha/ev5.hh"
#include "arch/alpha/system.hh" #include "arch/alpha/system.hh"
#include "base/inifile.hh" #include "base/inifile.hh"
#include "base/str.hh" #include "base/str.hh"
@ -45,30 +44,17 @@
#include "dev/simconsole.hh" #include "dev/simconsole.hh"
#include "dev/simple_disk.hh" #include "dev/simple_disk.hh"
#include "dev/tsunami_io.hh" #include "dev/tsunami_io.hh"
#include "mem/bus/bus.hh"
#include "mem/bus/pio_interface.hh"
#include "mem/bus/pio_interface_impl.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "sim/builder.hh" #include "sim/builder.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
using namespace std; using namespace std;
using namespace AlphaISA; using namespace AlphaISA;
AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, AlphaConsole::AlphaConsole(Params *p)
AlphaSystem *s, BaseCPU *c, Platform *p, : PioDevice(p->name, p->platform), disk(p->disk),
MemoryController *mmu, Addr a, console(params()->cons), system(params()->sys), cpu(params()->cpu),
HierParams *hier, Bus *pio_bus) pioSize(sizeof(struct alphaAccess))
: PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a)
{ {
mmu->add_child(this, RangeSize(addr, size));
if (pio_bus) {
pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this,
&AlphaConsole::cacheAccess);
pioInterface->addAddrRange(RangeSize(addr, size));
}
alphaAccess = new Access; alphaAccess = new Access;
alphaAccess->last_offset = size - 1; alphaAccess->last_offset = size - 1;
@ -99,115 +85,117 @@ AlphaConsole::startup()
alphaAccess->intrClockFrequency = platform->intrFrequency(); alphaAccess->intrClockFrequency = platform->intrFrequency();
} }
Fault Tick
AlphaConsole::read(MemReqPtr &req, uint8_t *data) AlphaConsole::read(Packet &pkt)
{ {
memset(data, 0, req->size); pkt.time = curTick + pioDelay;
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); /** XXX Do we want to push the addr munging to a bus brige or something? So
* the device has it's physical address and then the bridge adds on whatever
* machine dependent address swizzle is required?
*/
switch (req->size) assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
Addr daddr = req.addr - pioAddr;
switch (req.size)
{ {
case sizeof(uint32_t): case sizeof(uint32_t):
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, if (!pkt.data) pkt.pkt.data = new uint32_t;
*(uint32_t*)data);
switch (daddr) switch (daddr)
{ {
case offsetof(AlphaAccess, last_offset): case offsetof(AlphaAccess, last_offset):
*(uint32_t*)data = alphaAccess->last_offset; *(uint32_t*)pkt.data = alphaAccess->last_offset;
break; break;
case offsetof(AlphaAccess, version): case offsetof(AlphaAccess, version):
*(uint32_t*)data = alphaAccess->version; *(uint32_t*)pkt.data = alphaAccess->version;
break; break;
case offsetof(AlphaAccess, numCPUs): case offsetof(AlphaAccess, numCPUs):
*(uint32_t*)data = alphaAccess->numCPUs; *(uint32_t*)pkt.data = alphaAccess->numCPUs;
break; break;
case offsetof(AlphaAccess, intrClockFrequency): case offsetof(AlphaAccess, intrClockFrequency):
*(uint32_t*)data = alphaAccess->intrClockFrequency; *(uint32_t*)pkt.data = alphaAccess->intrClockFrequency;
break; break;
default: default:
// Old console code read in everyting as a 32bit int /* Old console code read in everyting as a 32bit int
*(uint32_t*)data = *(uint32_t*)(consoleData + daddr); * we now break that for better error checking.
*/
pkt.result = BadAddress;
} }
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
*(uint32_t*)pkt.data);
break; break;
case sizeof(uint64_t): case sizeof(uint64_t):
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, if (!pkt.data) pkt.pkt.data = new uint64_t;
*(uint64_t*)data);
switch (daddr) switch (daddr)
{ {
case offsetof(AlphaAccess, inputChar): case offsetof(AlphaAccess, inputChar):
*(uint64_t*)data = console->console_in(); *(uint64_t*)pkt.data = console->console_in();
break; break;
case offsetof(AlphaAccess, cpuClock): case offsetof(AlphaAccess, cpuClock):
*(uint64_t*)data = alphaAccess->cpuClock; *(uint64_t*)pkt.data = alphaAccess->cpuClock;
break; break;
case offsetof(AlphaAccess, mem_size): case offsetof(AlphaAccess, mem_size):
*(uint64_t*)data = alphaAccess->mem_size; *(uint64_t*)pkt.data = alphaAccess->mem_size;
break; break;
case offsetof(AlphaAccess, kernStart): case offsetof(AlphaAccess, kernStart):
*(uint64_t*)data = alphaAccess->kernStart; *(uint64_t*)pkt.data = alphaAccess->kernStart;
break; break;
case offsetof(AlphaAccess, kernEnd): case offsetof(AlphaAccess, kernEnd):
*(uint64_t*)data = alphaAccess->kernEnd; *(uint64_t*)pkt.data = alphaAccess->kernEnd;
break; break;
case offsetof(AlphaAccess, entryPoint): case offsetof(AlphaAccess, entryPoint):
*(uint64_t*)data = alphaAccess->entryPoint; *(uint64_t*)pkt.data = alphaAccess->entryPoint;
break; break;
case offsetof(AlphaAccess, diskUnit): case offsetof(AlphaAccess, diskUnit):
*(uint64_t*)data = alphaAccess->diskUnit; *(uint64_t*)pkt.data = alphaAccess->diskUnit;
break; break;
case offsetof(AlphaAccess, diskCount): case offsetof(AlphaAccess, diskCount):
*(uint64_t*)data = alphaAccess->diskCount; *(uint64_t*)pkt.data = alphaAccess->diskCount;
break; break;
case offsetof(AlphaAccess, diskPAddr): case offsetof(AlphaAccess, diskPAddr):
*(uint64_t*)data = alphaAccess->diskPAddr; *(uint64_t*)pkt.data = alphaAccess->diskPAddr;
break; break;
case offsetof(AlphaAccess, diskBlock): case offsetof(AlphaAccess, diskBlock):
*(uint64_t*)data = alphaAccess->diskBlock; *(uint64_t*)pkt.data = alphaAccess->diskBlock;
break; break;
case offsetof(AlphaAccess, diskOperation): case offsetof(AlphaAccess, diskOperation):
*(uint64_t*)data = alphaAccess->diskOperation; *(uint64_t*)pkt.data = alphaAccess->diskOperation;
break; break;
case offsetof(AlphaAccess, outputChar): case offsetof(AlphaAccess, outputChar):
*(uint64_t*)data = alphaAccess->outputChar; *(uint64_t*)pkt.data = alphaAccess->outputChar;
break; break;
default: default:
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
sizeof(alphaAccess->cpuStack[0]); sizeof(alphaAccess->cpuStack[0]);
if (cpunum >= 0 && cpunum < 64) if (cpunum >= 0 && cpunum < 64)
*(uint64_t*)data = alphaAccess->cpuStack[cpunum]; *(uint64_t*)pkt.data = alphaAccess->cpuStack[cpunum];
else else
panic("Unknown 64bit access, %#x\n", daddr); panic("Unknown 64bit access, %#x\n", daddr);
} }
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
*(uint64_t*)data);
break; break;
default: default:
return genMachineCheckFault(); pkt.result = BadAddress;
}
if (pkt.result == Unknown) pkt.result = Success;
return pioDelay;
} }
return NoFault; Tick
}
Fault
AlphaConsole::write(MemReqPtr &req, const uint8_t *data) AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
{ {
uint64_t val; pkt.time = curTick + pioDelay;
switch (req->size) { assert(pkt.result == Unknown);
case sizeof(uint32_t): assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
val = *(uint32_t *)data; Addr daddr = req.addr - pioAddr;
break;
case sizeof(uint64_t): uint64_t val = *(uint64_t *)data;
val = *(uint64_t *)data; assert(pkt.size == sizeof(uint64_t));
break;
default:
return genMachineCheckFault();
}
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
ExecContext *other_xc;
switch (daddr) { switch (daddr) {
case offsetof(AlphaAccess, diskUnit): case offsetof(AlphaAccess, diskUnit):
@ -239,9 +227,6 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
console->out((char)(val & 0xff)); console->out((char)(val & 0xff));
break; break;
other_xc->activate(); //Start the cpu
break;
default: default:
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
sizeof(alphaAccess->cpuStack[0]); sizeof(alphaAccess->cpuStack[0]);
@ -253,13 +238,9 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
panic("Unknown 64bit access, %#x\n", daddr); panic("Unknown 64bit access, %#x\n", daddr);
} }
return NoFault; pkt.result = Success;
}
Tick return pioDelay;
AlphaConsole::cacheAccess(MemReqPtr &req)
{
return curTick + 1000;
} }
void void

View file

@ -70,7 +70,7 @@ class MemoryController;
* primarily used doing boot before the kernel has loaded its device * primarily used doing boot before the kernel has loaded its device
* drivers. * drivers.
*/ */
class AlphaConsole : public PioDevice class AlphaConsole : public BasePioDevice
{ {
protected: protected:
struct Access : public AlphaAccess struct Access : public AlphaAccess
@ -96,23 +96,29 @@ class AlphaConsole : public PioDevice
/** a pointer to the CPU boot cpu */ /** a pointer to the CPU boot cpu */
BaseCPU *cpu; BaseCPU *cpu;
Addr addr; public:
static const Addr size = sizeof(struct AlphaAccess); struct Params : public BasePioDevice::Params
{
SimConsole *cons;
SimpleDisk *disk;
AlphaSystem *sys;
BaseCpu *cpu;
};
protected:
const Params *params() const {return (const Params *)_params; }
public: public:
/** Standard Constructor */ /** Standard Constructor */
AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, AlphaConsole(Params *p);
AlphaSystem *s, BaseCPU *c, Platform *platform,
MemoryController *mmu, Addr addr,
HierParams *hier, Bus *pio_bus);
virtual void startup(); virtual void startup();
/** /**
* memory mapped reads and writes * memory mapped reads and writes
*/ */
virtual Fault read(MemReqPtr &req, uint8_t *data); virtual Tick read(Packet &pkt);
virtual Fault write(MemReqPtr &req, const uint8_t *data); virtual Tick write(Packet &pkt);
/** /**
* standard serialization routines for checkpointing * standard serialization routines for checkpointing

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2005 The Regents of The University of Michigan * Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -72,12 +72,6 @@ PioPort::SendEvent::process()
port->transmitList.push_back(&packet); port->transmitList.push_back(&packet);
} }
PioDevice::PioDevice(const std::string &name, Platform *p)
: SimObject(name), platform(p)
{
pioPort = new PioPort(this, p);
}
bool bool
PioPort::recvTiming(Packet &pkt) PioPort::recvTiming(Packet &pkt)
@ -201,4 +195,13 @@ DmaDevice::~DmaDevice()
delete dmaPort; delete dmaPort;
} }
void
BasePioDevice::addressRanges(AddrRangeList &range_list, bool &owner)
{
assert(pioSize != 0);
owner = true;
range_list.clear();
range_list.push_back(RangeSize(pio_addr, sizeof(struct alphaAccess)));
}

View file

@ -192,20 +192,40 @@ class PioDevice : public SimObject
/** Pure virtual function that the device must implement. Called when a read /** Pure virtual function that the device must implement. Called when a read
* command is recieved by the port. */ * command is recieved by the port. */
virtual bool read(Packet &pkt) = 0; virtual Tick read(Packet &pkt) = 0;
/** Pure virtual function that the device must implement. Called when a /** Pure virtual function that the device must implement. Called when a
* write command is recieved by the port. */ * write command is recieved by the port. */
virtual bool write(Packet &pkt) = 0; virtual Tick write(Packet &pkt) = 0;
public: public:
PioDevice(const std::string &name, Platform *p); /** Params struct which is extended through each device based on the
* parameters it needs. Since we are re-writing everything, we might as well
* start from the bottom this time. */
struct Params
{
std::string name;
Platform *platform;
};
protected:
Params *_params;
public:
const Params *params() const { return _params; }
PioDevice(Params *params)
: SimObject(params()->name), platform(params()->platform)
{}
virtual ~PioDevice(); virtual ~PioDevice();
virtual Port *getPort(const std::string &if_name) virtual Port *getPort(const std::string &if_name)
{ {
if (if_name == "pio") if (if_name == "pio")
if (pioPort != NULL)
panic("pio port already connected to.");
pioPort = new PioPort(this, params()->platform);
return pioPort; return pioPort;
else else
return NULL; return NULL;
@ -214,6 +234,33 @@ class PioDevice : public SimObject
}; };
class BasicPioDevice : public PioDevice
{
public:
struct Params
{
Addr pio_addr;
Tick pio_delay;
};
protected:
/** Address that the device listens to. */
Addr pioAddr;
/** Size that the device's address range. */
Addr pioSize = 0;
/** Delay that the device experinces on an access. */
Tick pioDelay;
public:
BasePioDevice(Params *p)
: PioDevice(p), pioAddr(p->pio_addr), pioDelay(p->pioDelay)
{}
virtual void addressRanges(AddrRangeList &range_list, bool &owner);
};
class DmaDevice : public PioDevice class DmaDevice : public PioDevice
{ {
protected: protected:

View file

@ -97,7 +97,11 @@ struct Packet
/** A pointer to the data being transfered. It can be differnt sizes /** A pointer to the data being transfered. It can be differnt sizes
at each level of the heirarchy so it belongs in the packet, at each level of the heirarchy so it belongs in the packet,
not request*/ not request.
This pointer may be NULL! If it isn't null when received by the producer
of data it refers to memory that has not been dynamically allocated.
Otherwise the producer should simply allocate dynamic memory to use.
*/
PacketDataPtr data; PacketDataPtr data;
/** Indicates the size of the request. */ /** Indicates the size of the request. */