move stuff around so PageShift is defined before it is needed

don't ever include a file while in a namespace
start of making alpha console new memsystem happy
Make a BasePioDevice which is what all the simple Pio devices will inherit from
add a description of when the data pointer will have memory

arch/alpha/isa_traits.hh:
    don't ever include a file while in a namespace
dev/alpha_console.cc:
dev/alpha_console.hh:
    start of making alpha console new memsystem happy
dev/io_device.cc:
dev/io_device.hh:
    Make a BasePioDevice which is what all the simple Pio devices will inherit from
mem/packet.hh:
    add a description of when the data pointer will have memory

--HG--
extra : convert_revision : 495c0915541f9cad3eb42891e60b4ecbee7952bf
This commit is contained in:
Ali Saidi 2006-03-29 17:37:25 -05:00
parent c27c122afc
commit 62f5d7dd3f
6 changed files with 140 additions and 100 deletions

View file

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

View file

@ -34,7 +34,6 @@
#include <cstdio>
#include <string>
#include "arch/alpha/ev5.hh"
#include "arch/alpha/system.hh"
#include "base/inifile.hh"
#include "base/str.hh"
@ -45,30 +44,17 @@
#include "dev/simconsole.hh"
#include "dev/simple_disk.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/sim_object.hh"
using namespace std;
using namespace AlphaISA;
AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
AlphaSystem *s, BaseCPU *c, Platform *p,
MemoryController *mmu, Addr a,
HierParams *hier, Bus *pio_bus)
: PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a)
AlphaConsole::AlphaConsole(Params *p)
: PioDevice(p->name, p->platform), disk(p->disk),
console(params()->cons), system(params()->sys), cpu(params()->cpu),
pioSize(sizeof(struct alphaAccess))
{
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->last_offset = size - 1;
@ -99,115 +85,117 @@ AlphaConsole::startup()
alphaAccess->intrClockFrequency = platform->intrFrequency();
}
Fault
AlphaConsole::read(MemReqPtr &req, uint8_t *data)
Tick
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):
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
*(uint32_t*)data);
if (!pkt.data) pkt.pkt.data = new uint32_t;
switch (daddr)
{
case offsetof(AlphaAccess, last_offset):
*(uint32_t*)data = alphaAccess->last_offset;
*(uint32_t*)pkt.data = alphaAccess->last_offset;
break;
case offsetof(AlphaAccess, version):
*(uint32_t*)data = alphaAccess->version;
*(uint32_t*)pkt.data = alphaAccess->version;
break;
case offsetof(AlphaAccess, numCPUs):
*(uint32_t*)data = alphaAccess->numCPUs;
*(uint32_t*)pkt.data = alphaAccess->numCPUs;
break;
case offsetof(AlphaAccess, intrClockFrequency):
*(uint32_t*)data = alphaAccess->intrClockFrequency;
*(uint32_t*)pkt.data = alphaAccess->intrClockFrequency;
break;
default:
// Old console code read in everyting as a 32bit int
*(uint32_t*)data = *(uint32_t*)(consoleData + daddr);
/* Old console code read in everyting as a 32bit int
* 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;
case sizeof(uint64_t):
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
*(uint64_t*)data);
if (!pkt.data) pkt.pkt.data = new uint64_t;
switch (daddr)
{
case offsetof(AlphaAccess, inputChar):
*(uint64_t*)data = console->console_in();
*(uint64_t*)pkt.data = console->console_in();
break;
case offsetof(AlphaAccess, cpuClock):
*(uint64_t*)data = alphaAccess->cpuClock;
*(uint64_t*)pkt.data = alphaAccess->cpuClock;
break;
case offsetof(AlphaAccess, mem_size):
*(uint64_t*)data = alphaAccess->mem_size;
*(uint64_t*)pkt.data = alphaAccess->mem_size;
break;
case offsetof(AlphaAccess, kernStart):
*(uint64_t*)data = alphaAccess->kernStart;
*(uint64_t*)pkt.data = alphaAccess->kernStart;
break;
case offsetof(AlphaAccess, kernEnd):
*(uint64_t*)data = alphaAccess->kernEnd;
*(uint64_t*)pkt.data = alphaAccess->kernEnd;
break;
case offsetof(AlphaAccess, entryPoint):
*(uint64_t*)data = alphaAccess->entryPoint;
*(uint64_t*)pkt.data = alphaAccess->entryPoint;
break;
case offsetof(AlphaAccess, diskUnit):
*(uint64_t*)data = alphaAccess->diskUnit;
*(uint64_t*)pkt.data = alphaAccess->diskUnit;
break;
case offsetof(AlphaAccess, diskCount):
*(uint64_t*)data = alphaAccess->diskCount;
*(uint64_t*)pkt.data = alphaAccess->diskCount;
break;
case offsetof(AlphaAccess, diskPAddr):
*(uint64_t*)data = alphaAccess->diskPAddr;
*(uint64_t*)pkt.data = alphaAccess->diskPAddr;
break;
case offsetof(AlphaAccess, diskBlock):
*(uint64_t*)data = alphaAccess->diskBlock;
*(uint64_t*)pkt.data = alphaAccess->diskBlock;
break;
case offsetof(AlphaAccess, diskOperation):
*(uint64_t*)data = alphaAccess->diskOperation;
*(uint64_t*)pkt.data = alphaAccess->diskOperation;
break;
case offsetof(AlphaAccess, outputChar):
*(uint64_t*)data = alphaAccess->outputChar;
*(uint64_t*)pkt.data = alphaAccess->outputChar;
break;
default:
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
sizeof(alphaAccess->cpuStack[0]);
if (cpunum >= 0 && cpunum < 64)
*(uint64_t*)data = alphaAccess->cpuStack[cpunum];
*(uint64_t*)pkt.data = alphaAccess->cpuStack[cpunum];
else
panic("Unknown 64bit access, %#x\n", daddr);
}
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
*(uint64_t*)data);
break;
default:
return genMachineCheckFault();
pkt.result = BadAddress;
}
return NoFault;
if (pkt.result == Unknown) pkt.result = Success;
return pioDelay;
}
Fault
Tick
AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
{
uint64_t val;
pkt.time = curTick + pioDelay;
switch (req->size) {
case sizeof(uint32_t):
val = *(uint32_t *)data;
break;
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
Addr daddr = req.addr - pioAddr;
case sizeof(uint64_t):
val = *(uint64_t *)data;
break;
default:
return genMachineCheckFault();
}
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
ExecContext *other_xc;
uint64_t val = *(uint64_t *)data;
assert(pkt.size == sizeof(uint64_t));
switch (daddr) {
case offsetof(AlphaAccess, diskUnit):
@ -239,9 +227,6 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
console->out((char)(val & 0xff));
break;
other_xc->activate(); //Start the cpu
break;
default:
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
sizeof(alphaAccess->cpuStack[0]);
@ -253,13 +238,9 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
panic("Unknown 64bit access, %#x\n", daddr);
}
return NoFault;
}
pkt.result = Success;
Tick
AlphaConsole::cacheAccess(MemReqPtr &req)
{
return curTick + 1000;
return pioDelay;
}
void

View file

@ -70,7 +70,7 @@ class MemoryController;
* primarily used doing boot before the kernel has loaded its device
* drivers.
*/
class AlphaConsole : public PioDevice
class AlphaConsole : public BasePioDevice
{
protected:
struct Access : public AlphaAccess
@ -96,23 +96,29 @@ class AlphaConsole : public PioDevice
/** a pointer to the CPU boot cpu */
BaseCPU *cpu;
Addr addr;
static const Addr size = sizeof(struct AlphaAccess);
public:
struct Params : public BasePioDevice::Params
{
SimConsole *cons;
SimpleDisk *disk;
AlphaSystem *sys;
BaseCpu *cpu;
};
protected:
const Params *params() const {return (const Params *)_params; }
public:
/** Standard Constructor */
AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d,
AlphaSystem *s, BaseCPU *c, Platform *platform,
MemoryController *mmu, Addr addr,
HierParams *hier, Bus *pio_bus);
AlphaConsole(Params *p);
virtual void startup();
/**
* memory mapped reads and writes
*/
virtual Fault read(MemReqPtr &req, uint8_t *data);
virtual Fault write(MemReqPtr &req, const uint8_t *data);
virtual Tick read(Packet &pkt);
virtual Tick write(Packet &pkt);
/**
* 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.
*
* Redistribution and use in source and binary forms, with or without
@ -72,12 +72,6 @@ PioPort::SendEvent::process()
port->transmitList.push_back(&packet);
}
PioDevice::PioDevice(const std::string &name, Platform *p)
: SimObject(name), platform(p)
{
pioPort = new PioPort(this, p);
}
bool
PioPort::recvTiming(Packet &pkt)
@ -201,4 +195,13 @@ DmaDevice::~DmaDevice()
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
* 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
* write command is recieved by the port. */
virtual bool write(Packet &pkt) = 0;
virtual Tick write(Packet &pkt) = 0;
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 Port *getPort(const std::string &if_name)
{
if (if_name == "pio")
if (pioPort != NULL)
panic("pio port already connected to.");
pioPort = new PioPort(this, params()->platform);
return pioPort;
else
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
{
protected:

View file

@ -97,7 +97,11 @@ struct Packet
/** A pointer to the data being transfered. It can be differnt sizes
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;
/** Indicates the size of the request. */