summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2006-05-26 14:17:33 -0400
committerSteve Reinhardt <stever@eecs.umich.edu>2006-05-26 14:17:33 -0400
commite533fad711fce66bf2e4a6669baeb8eaf02799e1 (patch)
tree0fdb6011df3204031dd1dec784649aa3cdac5613 /src/mem
parentda6a7b1263cf624790f06a5f944366fb113dffc8 (diff)
downloadgem5-e533fad711fce66bf2e4a6669baeb8eaf02799e1.tar.xz
Significant rework of Packet class interface:
- new constructor guarantees initialization of most fields - flags track status of non-guaranteed fields (addr, size, src) - accessor functions (getAddr() etc.) check status on access - Command & Result classes are nested in Packet class scope - Command now built from vector of behavior bits - string version of Command for tracing - reinitFromRequest() and makeTimingResponse() encapsulate common manipulations of existing packets src/cpu/simple/atomic.cc: src/cpu/simple/base.cc: src/cpu/simple/timing.cc: src/dev/alpha_console.cc: src/dev/ide_ctrl.cc: src/dev/io_device.cc: src/dev/io_device.hh: src/dev/isa_fake.cc: src/dev/ns_gige.cc: src/dev/pciconfigall.cc: src/dev/sinic.cc: src/dev/tsunami_cchip.cc: src/dev/tsunami_io.cc: src/dev/tsunami_pchip.cc: src/dev/uart8250.cc: src/mem/bus.cc: src/mem/bus.hh: src/mem/physical.cc: src/mem/port.cc: src/mem/port.hh: src/mem/request.hh: Update for new Packet interface. --HG-- extra : convert_revision : 9973d09ea4fa61795f23772a7d3995fa4df5c269
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/bus.cc51
-rw-r--r--src/mem/bus.hh6
-rw-r--r--src/mem/packet.cc50
-rw-r--r--src/mem/packet.hh138
-rw-r--r--src/mem/physical.cc20
-rw-r--r--src/mem/port.cc18
-rw-r--r--src/mem/port.hh2
-rw-r--r--src/mem/request.hh1
8 files changed, 190 insertions, 96 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 4139bf643..a2ce00139 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -55,18 +55,22 @@ Bus::init()
}
-/** Function called by the port when the bus is recieving a Timing
+/** Function called by the port when the bus is receiving a Timing
* transaction.*/
bool
Bus::recvTiming(Packet *pkt)
{
Port *port;
- if (pkt->dest == Packet::Broadcast) {
- port = findPort(pkt->addr, pkt->src);
+ DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
+ pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
+
+ short dest = pkt->getDest();
+ if (dest == Packet::Broadcast) {
+ port = findPort(pkt->getAddr(), pkt->getSrc());
} else {
- assert(pkt->dest >= 0 && pkt->dest < interfaces.size());
- assert(pkt->dest != pkt->src); // catch infinite loops
- port = interfaces[pkt->dest];
+ assert(dest >= 0 && dest < interfaces.size());
+ assert(dest != pkt->getSrc()); // catch infinite loops
+ port = interfaces[dest];
}
return port->sendTiming(pkt);
}
@@ -84,7 +88,7 @@ Bus::findPort(Addr addr, int id)
if (portList[i].range == addr) {
dest_id = portList[i].portId;
found = true;
- DPRINTF(Bus, "Found Addr: %llx on device %d\n", addr, dest_id);
+ DPRINTF(Bus, " found addr 0x%llx on device %d\n", addr, dest_id);
}
i++;
}
@@ -97,33 +101,37 @@ Bus::findPort(Addr addr, int id)
return interfaces[dest_id];
}
-/** Function called by the port when the bus is recieving a Atomic
+/** Function called by the port when the bus is receiving a Atomic
* transaction.*/
Tick
Bus::recvAtomic(Packet *pkt)
{
- assert(pkt->dest == Packet::Broadcast);
- return findPort(pkt->addr, pkt->src)->sendAtomic(pkt);
+ DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n",
+ pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
+ assert(pkt->getDest() == Packet::Broadcast);
+ return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt);
}
-/** Function called by the port when the bus is recieving a Functional
+/** Function called by the port when the bus is receiving a Functional
* transaction.*/
void
Bus::recvFunctional(Packet *pkt)
{
- assert(pkt->dest == Packet::Broadcast);
- findPort(pkt->addr, pkt->src)->sendFunctional(pkt);
+ DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n",
+ pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
+ assert(pkt->getDest() == Packet::Broadcast);
+ findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt);
}
-/** Function called by the port when the bus is recieving a status change.*/
+/** Function called by the port when the bus is receiving a status change.*/
void
Bus::recvStatusChange(Port::Status status, int id)
{
- DPRINTF(Bus, "Bus %d recieved status change from device id %d\n",
- busId, id);
assert(status == Port::RangeChange &&
"The other statuses need to be implemented.");
+ DPRINTF(Bus, "received RangeChange from device id %d\n", id);
+
assert(id < interfaces.size() && id >= 0);
int x;
Port *port = interfaces[id];
@@ -149,8 +157,8 @@ Bus::recvStatusChange(Port::Status status, int id)
dm.portId = id;
dm.range = *iter;
- DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start,
- dm.range.end, id);
+ DPRINTF(Bus, "Adding range %llx - %llx for id %d\n",
+ dm.range.start, dm.range.end, id);
portList.push_back(dm);
}
DPRINTF(MMU, "port list has %d entries\n", portList.size());
@@ -170,13 +178,12 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
resp.clear();
snoop.clear();
- DPRINTF(Bus, "Bus id %d recieved address range request returning\n",
- busId);
+ DPRINTF(Bus, "received address range request, returning:\n");
for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
if (portIter->portId != id) {
resp.push_back(portIter->range);
- DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start,
- portIter->range.end);
+ DPRINTF(Bus, " -- %#llX : %#llX\n",
+ portIter->range.start, portIter->range.end);
}
}
}
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 1d3a7e528..5eeb07904 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -109,17 +109,17 @@ class Bus : public MemObject
/** When reciving a timing request from the peer port (at id),
pass it to the bus. */
virtual bool recvTiming(Packet *pkt)
- { pkt->src = id; return bus->recvTiming(pkt); }
+ { pkt->setSrc(id); return bus->recvTiming(pkt); }
/** When reciving a Atomic requestfrom the peer port (at id),
pass it to the bus. */
virtual Tick recvAtomic(Packet *pkt)
- { pkt->src = id; return bus->recvAtomic(pkt); }
+ { pkt->setSrc(id); return bus->recvAtomic(pkt); }
/** When reciving a Functional requestfrom the peer port (at id),
pass it to the bus. */
virtual void recvFunctional(Packet *pkt)
- { pkt->src = id; bus->recvFunctional(pkt); }
+ { pkt->setSrc(id); bus->recvFunctional(pkt); }
/** When reciving a status changefrom the peer port (at id),
pass it to the bus. */
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index a9be7ac51..3b415d77f 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -34,11 +34,31 @@
#include "base/misc.hh"
#include "mem/packet.hh"
+static const std::string ReadReqString("ReadReq");
+static const std::string WriteReqString("WriteReq");
+static const std::string WriteReqNoAckString("WriteReqNoAck");
+static const std::string ReadRespString("ReadResp");
+static const std::string WriteRespString("WriteResp");
+static const std::string OtherCmdString("<other>");
+
+const std::string &
+Packet::cmdString() const
+{
+ switch (cmd) {
+ case ReadReq: return ReadReqString;
+ case WriteReq: return WriteReqString;
+ case WriteReqNoAck: return WriteReqNoAckString;
+ case ReadResp: return ReadRespString;
+ case WriteResp: return WriteRespString;
+ default: return OtherCmdString;
+ }
+}
/** delete the data pointed to in the data pointer. Ok to call to matter how
* data was allocted. */
void
-Packet::deleteData() {
+Packet::deleteData()
+{
assert(staticData || dynamicData);
if (staticData)
return;
@@ -51,22 +71,24 @@ Packet::deleteData() {
/** If there isn't data in the packet, allocate some. */
void
-Packet::allocate() {
+Packet::allocate()
+{
if (data)
return;
assert(!staticData);
dynamicData = true;
arrayData = true;
- data = new uint8_t[size];
+ data = new uint8_t[getSize()];
}
/** Do the packet modify the same addresses. */
bool
-Packet::intersect(Packet *p) {
- Addr s1 = addr;
- Addr e1 = addr + size;
- Addr s2 = p->addr;
- Addr e2 = p->addr + p->size;
+Packet::intersect(Packet *p)
+{
+ Addr s1 = getAddr();
+ Addr e1 = getAddr() + getSize();
+ Addr s2 = p->getAddr();
+ Addr e2 = p->getAddr() + p->getSize();
if (s1 >= s2 && s1 < e2)
return true;
@@ -77,7 +99,8 @@ Packet::intersect(Packet *p) {
/** Minimally reset a packet so something like simple cpu can reuse it. */
void
-Packet::reset() {
+Packet::reset()
+{
result = Unknown;
if (dynamicData) {
deleteData();
@@ -88,7 +111,8 @@ Packet::reset() {
}
-
-
-bool fixPacket(Packet *func, Packet *timing)
-{ panic("Need to implement!"); }
+bool
+fixPacket(Packet *func, Packet *timing)
+{
+ panic("Need to implement!");
+}
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index e8a7b0c73..83f52ede5 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -43,24 +43,6 @@ struct Packet;
typedef Packet* PacketPtr;
typedef uint8_t* PacketDataPtr;
-/** List of all commands associated with a packet. */
-enum Command
-{
- Read,
- Write
-};
-
-/** The result of a particular pakets request. */
-enum PacketResult
-{
- Success,
- BadAddress,
- Unknown
-};
-
-class SenderState{};
-class Coherence{};
-
/**
* A Packet is the structure to handle requests between two levels
* of the memory system. The Request is a global object that trancends
@@ -74,7 +56,7 @@ class Coherence{};
* Packets are assumed to be returned in the case of a single response. If
* the transaction has no response, then the consumer will delete the packet.
*/
-struct Packet
+class Packet
{
private:
/** A pointer to the data being transfered. It can be differnt sizes
@@ -95,57 +77,132 @@ struct Packet
bool arrayData;
- public:
/** The address of the request, could be virtual or physical (depending on
cache configurations). */
Addr addr;
- /** Flag structure to hold flags for this particular packet */
- uint64_t flags;
+ /** Indicates the size of the request. */
+ int size;
+
+ /** A index of the source of the transaction. */
+ short src;
+
+ /** A index to the destination of the transaction. */
+ short dest;
+
+ bool addrValid;
+ bool sizeValid;
+ bool srcValid;
+
+ public:
+
+ static const short Broadcast = -1;
/** A pointer to the overall request. */
RequestPtr req;
+ class CoherenceState {
+ public:
+ virtual ~CoherenceState() {}
+ };
+
/** A virtual base opaque structure used to hold
coherence status messages. */
- Coherence *coherence; // virtual base opaque,
+ CoherenceState *coherence; // virtual base opaque,
// assert(dynamic_cast<Foo>) etc.
- /** A virtual base opaque structure used to hold the senders state. */
- void *senderState; // virtual base opaque,
- // assert(dynamic_cast<Foo>) etc.
-
- /** Indicates the size of the request. */
- int size;
+ class SenderState {
+ public:
+ virtual ~SenderState() {}
+ };
- /** A index of the source of the transaction. */
- short src;
+ /** A virtual base opaque structure used to hold the senders state. */
+ SenderState *senderState; // virtual base opaque,
+ // assert(dynamic_cast<Foo>) etc.
- static const short Broadcast = -1;
+ private:
+ /** List of command attributes. */
+ enum CommandAttribute
+ {
+ IsRead = 1 << 0,
+ IsWrite = 1 << 1,
+ IsPrefetch = 1 << 2,
+ IsInvalidate = 1 << 3,
+ IsRequest = 1 << 4,
+ IsResponse = 1 << 5,
+ NeedsResponse = 1 << 6,
+ };
- /** A index to the destination of the transaction. */
- short dest;
+ public:
+ /** List of all commands associated with a packet. */
+ enum Command
+ {
+ ReadReq = IsRead | IsRequest | NeedsResponse,
+ WriteReq = IsWrite | IsRequest | NeedsResponse,
+ WriteReqNoAck = IsWrite | IsRequest,
+ ReadResp = IsRead | IsResponse,
+ WriteResp = IsWrite | IsResponse
+ };
+
+ const std::string &cmdString() const;
/** The command of the transaction. */
Command cmd;
+ bool isRead() { return (cmd & IsRead) != 0; }
+ bool isRequest() { return (cmd & IsRequest) != 0; }
+ bool isResponse() { return (cmd & IsResponse) != 0; }
+ bool needsResponse() { return (cmd & NeedsResponse) != 0; }
+
+ void makeTimingResponse() {
+ assert(needsResponse());
+ int icmd = (int)cmd;
+ icmd &= ~(IsRequest | NeedsResponse);
+ icmd |= IsResponse;
+ cmd = (Command)icmd;
+ dest = src;
+ srcValid = false;
+ }
+
/** The time this request was responded to. Used to calculate latencies. */
Tick time;
+ /** The result of a particular packets request. */
+ enum Result
+ {
+ Success,
+ BadAddress,
+ Unknown
+ };
+
/** The result of the packet transaction. */
- PacketResult result;
+ Result result;
/** Accessor function that returns the source index of the packet. */
- short getSrc() const { return src; }
+ short getSrc() const { assert(srcValid); return src; }
+ void setSrc(short _src) { src = _src; srcValid = true; }
/** Accessor function that returns the destination index of
the packet. */
short getDest() const { return dest; }
+ void setDest(short _dest) { dest = _dest; }
+
+ Addr getAddr() const { assert(addrValid); return addr; }
+ void setAddr(Addr _addr) { addr = _addr; addrValid = true; }
+
+ int getSize() const { assert(sizeValid); return size; }
+ void setSize(int _size) { size = _size; sizeValid = true; }
- Packet()
+
+ Packet(Request *_req, Command _cmd, short _dest)
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
+ addr(_req->paddr), size(_req->size), dest(_dest),
+ addrValid(_req->validPaddr), sizeValid(_req->validSize),
+ srcValid(false),
+ req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
time(curTick), result(Unknown)
- {}
+ {
+ }
~Packet()
{ deleteData(); }
@@ -154,6 +211,11 @@ struct Packet
/** Minimally reset a packet so something like simple cpu can reuse it. */
void reset();
+ void reinitFromRequest() {
+ if (req->validPaddr) setAddr(req->paddr);
+ if (req->validSize) setSize(req->size);
+ }
+
/** Set the data pointer to the following value that should not be freed. */
template <typename T>
void dataStatic(T *p);
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index ae27d762f..26dbef0cd 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -128,7 +128,7 @@ PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort)
doFunctionalAccess(pkt);
// turn packet around to go back to requester
- pkt->dest = pkt->src;
+ pkt->makeTimingResponse();
MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort);
response->schedule(curTick + lat);
@@ -146,16 +146,18 @@ PhysicalMemory::doAtomicAccess(Packet *pkt)
void
PhysicalMemory::doFunctionalAccess(Packet *pkt)
{
- assert(pkt->addr + pkt->size < pmem_size);
+ assert(pkt->getAddr() + pkt->getSize() < pmem_size);
switch (pkt->cmd) {
- case Read:
- memcpy(pkt->getPtr<uint8_t>(), pmem_addr + pkt->addr - base_addr,
- pkt->size);
+ case Packet::ReadReq:
+ memcpy(pkt->getPtr<uint8_t>(),
+ pmem_addr + pkt->getAddr() - base_addr,
+ pkt->getSize());
break;
- case Write:
- memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(),
- pkt->size);
+ case Packet::WriteReq:
+ memcpy(pmem_addr + pkt->getAddr() - base_addr,
+ pkt->getPtr<uint8_t>(),
+ pkt->getSize());
// temporary hack: will need to add real LL/SC implementation
// for cacheless systems later.
if (pkt->req->getFlags() & LOCKED) {
@@ -166,7 +168,7 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
panic("unimplemented");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
}
Port *
diff --git a/src/mem/port.cc b/src/mem/port.cc
index fb3103ed1..ee224d92b 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -35,18 +35,16 @@
#include "mem/port.hh"
void
-Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
+Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
{
Request req(false);
- Packet pkt;
- pkt.req = &req;
- pkt.cmd = cmd;
- pkt.dest = Packet::Broadcast;
+ Packet pkt(&req, cmd, Packet::Broadcast);
for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) {
- req.setPaddr(pkt.addr = gen.addr());
- req.setSize(pkt.size = gen.size());
+ req.setPaddr(gen.addr());
+ req.setSize(gen.size());
+ pkt.reinitFromRequest();
pkt.dataStatic(p);
sendFunctional(&pkt);
p += gen.size();
@@ -56,13 +54,13 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
void
Port::writeBlob(Addr addr, uint8_t *p, int size)
{
- blobHelper(addr, p, size, Write);
+ blobHelper(addr, p, size, Packet::WriteReq);
}
void
Port::readBlob(Addr addr, uint8_t *p, int size)
{
- blobHelper(addr, p, size, Read);
+ blobHelper(addr, p, size, Packet::ReadReq);
}
void
@@ -72,7 +70,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
uint8_t *buf = new uint8_t[size];
memset(buf, val, size);
- blobHelper(addr, buf, size, Write);
+ blobHelper(addr, buf, size, Packet::WriteReq);
delete [] buf;
}
diff --git a/src/mem/port.hh b/src/mem/port.hh
index e8a20235a..85209964e 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -232,7 +232,7 @@ class Port
/** Internal helper function for read/writeBlob().
*/
- void blobHelper(Addr addr, uint8_t *p, int size, Command cmd);
+ void blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd);
};
/** A simple functional port that is only meant for one way communication to
diff --git a/src/mem/request.hh b/src/mem/request.hh
index 2db7b7779..10550e859 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -195,6 +195,7 @@ class Request
/** Accesor function for pc.*/
void setPC(Addr _pc);
+ friend class Packet;
};
#endif // __MEM_REQUEST_HH__