diff options
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/bus.cc | 51 | ||||
-rw-r--r-- | src/mem/bus.hh | 6 | ||||
-rw-r--r-- | src/mem/packet.cc | 50 | ||||
-rw-r--r-- | src/mem/packet.hh | 138 | ||||
-rw-r--r-- | src/mem/physical.cc | 20 | ||||
-rw-r--r-- | src/mem/port.cc | 18 | ||||
-rw-r--r-- | src/mem/port.hh | 2 | ||||
-rw-r--r-- | src/mem/request.hh | 1 |
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__ |