From 91e3aa629550fcdaa03173f94674a74ac906ae4c Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 30 May 2006 22:30:42 -0400 Subject: [PATCH] Minor further cleanup & commenting of Packet class. src/cpu/simple/atomic.cc: Make common ifetch setup based on Request rather than Packet. Packet::reset() no longer a separate function. sendAtomic() returns latency, not absolute tick. src/cpu/simple/atomic.hh: sendAtomic returns latency, not absolute tick. src/cpu/simple/base.cc: src/cpu/simple/base.hh: src/cpu/simple/timing.cc: Make common ifetch setup based on Request rather than Packet. src/dev/alpha_console.cc: src/dev/ide_ctrl.cc: src/dev/io_device.cc: 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/physical.cc: Get rid of redundant Packet time field. src/mem/packet.cc: Eliminate reset() method. src/mem/packet.hh: Fold reset() function into reinitFromRequest()... it was only ever called together with that function. Get rid of redundant time field. Cleanup/add comments. src/mem/port.hh: Document in comment that sendAtomic returns latency, not absolute tick. --HG-- extra : convert_revision : 0252f1a294043ca3ed58f437232ad24fc0733e0c --- src/cpu/simple/atomic.cc | 19 +++-- src/cpu/simple/atomic.hh | 2 +- src/cpu/simple/base.cc | 20 ++--- src/cpu/simple/base.hh | 2 +- src/cpu/simple/timing.cc | 2 +- src/dev/alpha_console.cc | 3 - src/dev/ide_ctrl.cc | 3 - src/dev/io_device.cc | 4 +- src/dev/isa_fake.cc | 3 - src/dev/ns_gige.cc | 3 - src/dev/pciconfigall.cc | 3 - src/dev/sinic.cc | 3 - src/dev/tsunami_cchip.cc | 4 - src/dev/tsunami_io.cc | 3 - src/dev/tsunami_pchip.cc | 4 - src/dev/uart8250.cc | 2 - src/mem/packet.cc | 14 ---- src/mem/packet.hh | 154 ++++++++++++++++++++++++--------------- src/mem/physical.cc | 3 +- src/mem/port.hh | 9 ++- 20 files changed, 120 insertions(+), 140 deletions(-) diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index a0d26a8ab..c2e6f6185 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -250,10 +250,9 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) // Now do the access. if (fault == NoFault) { - data_read_pkt->reset(); data_read_pkt->reinitFromRequest(); - dcache_complete = dcachePort.sendAtomic(data_read_pkt); + dcache_latency = dcachePort.sendAtomic(data_read_pkt); dcache_access = true; assert(data_read_pkt->result == Packet::Success); @@ -329,12 +328,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) // Now do the access. if (fault == NoFault) { - data_write_pkt->reset(); data = htog(data); - data_write_pkt->dataStatic(&data); data_write_pkt->reinitFromRequest(); + data_write_pkt->dataStatic(&data); - dcache_complete = dcachePort.sendAtomic(data_write_pkt); + dcache_latency = dcachePort.sendAtomic(data_write_pkt); dcache_access = true; assert(data_write_pkt->result == Packet::Success); @@ -411,11 +409,12 @@ AtomicSimpleCPU::tick() checkForInterrupts(); ifetch_req->resetMin(); - ifetch_pkt->reset(); - Fault fault = setupFetchPacket(ifetch_pkt); + Fault fault = setupFetchRequest(ifetch_req); if (fault == NoFault) { - Tick icache_complete = icachePort.sendAtomic(ifetch_pkt); + ifetch_pkt->reinitFromRequest(); + + Tick icache_latency = icachePort.sendAtomic(ifetch_pkt); // ifetch_req is initialized to read the instruction directly // into the CPU object's inst field. @@ -430,9 +429,9 @@ AtomicSimpleCPU::tick() // cycle time. If not, the next tick event may get // scheduled at a non-integer multiple of the CPU // cycle time. - Tick icache_stall = icache_complete - curTick - cycles(1); + Tick icache_stall = icache_latency - cycles(1); Tick dcache_stall = - dcache_access ? dcache_complete - curTick - cycles(1) : 0; + dcache_access ? dcache_latency - cycles(1) : 0; latency += icache_stall + dcache_stall; } diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 65269bd6d..8c76fbdc8 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -116,7 +116,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU Packet *data_write_pkt; bool dcache_access; - Tick dcache_complete; + Tick dcache_latency; public: diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 18f170449..2e9b4b81f 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -351,29 +351,21 @@ BaseSimpleCPU::checkForInterrupts() Fault -BaseSimpleCPU::setupFetchPacket(Packet *ifetch_pkt) +BaseSimpleCPU::setupFetchRequest(Request *req) { - // Try to fetch an instruction - // set up memory request for instruction fetch - DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), cpuXC->readNextPC(),cpuXC->readNextNPC()); - Request *ifetch_req = ifetch_pkt->req; - ifetch_req->setVaddr(cpuXC->readPC() & ~3); - ifetch_req->setTime(curTick); + req->setVaddr(cpuXC->readPC() & ~3); + req->setTime(curTick); #if FULL_SYSTEM - ifetch_req->setFlags((cpuXC->readPC() & 1) ? PHYSICAL : 0); + req->setFlags((cpuXC->readPC() & 1) ? PHYSICAL : 0); #else - ifetch_req->setFlags(0); + req->setFlags(0); #endif - Fault fault = cpuXC->translateInstReq(ifetch_req); - - if (fault == NoFault) { - ifetch_pkt->reinitFromRequest(); - } + Fault fault = cpuXC->translateInstReq(req); return fault; } diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 4c0e6f3c7..dbeb6afce 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -129,7 +129,7 @@ class BaseSimpleCPU : public BaseCPU StaticInstPtr curStaticInst; void checkForInterrupts(); - Fault setupFetchPacket(Packet *ifetch_pkt); + Fault setupFetchRequest(Request *req); void preExecute(); void postExecute(); void advancePC(Fault fault); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 5f094d033..ed0c2da94 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -342,11 +342,11 @@ TimingSimpleCPU::fetch() Request *ifetch_req = new Request(true); ifetch_req->setSize(sizeof(MachInst)); + Fault fault = setupFetchRequest(ifetch_req); ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); ifetch_pkt->dataStatic(&inst); - Fault fault = setupFetchPacket(ifetch_pkt); if (fault == NoFault) { if (!icachePort.sendTiming(ifetch_pkt)) { // Need to wait for retry diff --git a/src/dev/alpha_console.cc b/src/dev/alpha_console.cc index 0b4bb048c..c5b105fc7 100644 --- a/src/dev/alpha_console.cc +++ b/src/dev/alpha_console.cc @@ -98,7 +98,6 @@ AlphaConsole::read(Packet *pkt) assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - pkt->time += pioDelay; Addr daddr = pkt->getAddr() - pioAddr; pkt->allocate(); @@ -191,8 +190,6 @@ AlphaConsole::read(Packet *pkt) Tick AlphaConsole::write(Packet *pkt) { - pkt->time += pioDelay; - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index eb03d5db8..d8dff0870 100644 --- a/src/dev/ide_ctrl.cc +++ b/src/dev/ide_ctrl.cc @@ -430,7 +430,6 @@ IdeController::read(Packet *pkt) IdeRegType reg_type; int disk; - pkt->time += pioDelay; pkt->allocate(); if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4) panic("Bad IDE read size: %d\n", pkt->getSize()); @@ -518,8 +517,6 @@ IdeController::write(Packet *pkt) int disk; uint8_t oldVal, newVal; - pkt->time += pioDelay; - parseAddr(pkt->getAddr(), offset, channel, reg_type); if (!io_enabled) { diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 563fdb759..0a8379095 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -80,10 +80,10 @@ PioPort::SendEvent::process() bool PioPort::recvTiming(Packet *pkt) { - device->recvAtomic(pkt); + Tick latency = device->recvAtomic(pkt); // turn packet around to go back to requester pkt->makeTimingResponse(); - sendTiming(pkt, pkt->time - pkt->req->getTime()); + sendTiming(pkt, latency); return true; } diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc index c303ffc30..c00ee0adb 100644 --- a/src/dev/isa_fake.cc +++ b/src/dev/isa_fake.cc @@ -54,8 +54,6 @@ IsaFake::read(Packet *pkt) assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - pkt->time += pioDelay; - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); switch (pkt->getSize()) { @@ -80,7 +78,6 @@ IsaFake::read(Packet *pkt) Tick IsaFake::write(Packet *pkt) { - pkt->time += pioDelay; DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); pkt->result = Packet::Success; return pioDelay; diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index 963675847..719747b26 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -492,7 +492,6 @@ NSGigE::read(Packet *pkt) { assert(ioEnable); - pkt->time += pioDelay; pkt->allocate(); //The mask is to give you only the offset into the device register file @@ -728,8 +727,6 @@ NSGigE::write(Packet *pkt) DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", daddr, pkt->getAddr(), pkt->getSize()); - pkt->time += pioDelay; - if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc index 14a28e86d..9b679ed95 100644 --- a/src/dev/pciconfigall.cc +++ b/src/dev/pciconfigall.cc @@ -99,7 +99,6 @@ PciConfigAll::read(Packet *pkt) int func = (daddr >> 8) & 0x7; int reg = daddr & 0xFF; - pkt->time += pioDelay; pkt->allocate(); DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr, @@ -134,8 +133,6 @@ PciConfigAll::read(Packet *pkt) Tick PciConfigAll::write(Packet *pkt) { - pkt->time += pioDelay; - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) || diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index 31fbc49aa..529024a90 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -322,7 +322,6 @@ Device::read(Packet *pkt) Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; - pkt->time += pioDelay; pkt->allocate(); if (!regValid(raddr)) @@ -410,8 +409,6 @@ Device::write(Packet *pkt) Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; - pkt->time += pioDelay; - if (!regValid(raddr)) panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", cpu, daddr, pkt->getAddr(), pkt->getSize()); diff --git a/src/dev/tsunami_cchip.cc b/src/dev/tsunami_cchip.cc index 146321b9f..e5ef18448 100644 --- a/src/dev/tsunami_cchip.cc +++ b/src/dev/tsunami_cchip.cc @@ -76,7 +76,6 @@ TsunamiCChip::read(Packet *pkt) assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - pkt->time += pioDelay; Addr regnum = (pkt->getAddr() - pioAddr) >> 6; Addr daddr = (pkt->getAddr() - pioAddr); @@ -182,9 +181,6 @@ TsunamiCChip::read(Packet *pkt) Tick TsunamiCChip::write(Packet *pkt) { - pkt->time += pioDelay; - - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ; diff --git a/src/dev/tsunami_io.cc b/src/dev/tsunami_io.cc index 729a61cf7..8eaf7679f 100644 --- a/src/dev/tsunami_io.cc +++ b/src/dev/tsunami_io.cc @@ -447,7 +447,6 @@ TsunamiIO::read(Packet *pkt) assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - pkt->time += pioDelay; Addr daddr = pkt->getAddr() - pioAddr; DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), @@ -511,8 +510,6 @@ TsunamiIO::read(Packet *pkt) Tick TsunamiIO::write(Packet *pkt) { - pkt->time += pioDelay; - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; diff --git a/src/dev/tsunami_pchip.cc b/src/dev/tsunami_pchip.cc index c430ca0a0..5252ccea6 100644 --- a/src/dev/tsunami_pchip.cc +++ b/src/dev/tsunami_pchip.cc @@ -70,8 +70,6 @@ TsunamiPChip::read(Packet *pkt) assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - pkt->time += pioDelay; pkt->allocate(); Addr daddr = (pkt->getAddr() - pioAddr) >> 6;; assert(pkt->getSize() == sizeof(uint64_t)); @@ -151,8 +149,6 @@ TsunamiPChip::read(Packet *pkt) Tick TsunamiPChip::write(Packet *pkt) { - pkt->time += pioDelay; - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = (pkt->getAddr() - pioAddr) >> 6; diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 8a5a1f1cd..9aae6a75b 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -114,7 +114,6 @@ Uart8250::read(Packet *pkt) assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 1); - pkt->time += pioDelay; Addr daddr = pkt->getAddr() - pioAddr; pkt->allocate(); @@ -198,7 +197,6 @@ Uart8250::write(Packet *pkt) assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 1); - pkt->time += pioDelay; Addr daddr = pkt->getAddr() - pioAddr; DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get()); diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 3b415d77f..4cda657f5 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -97,20 +97,6 @@ Packet::intersect(Packet *p) return false; } -/** Minimally reset a packet so something like simple cpu can reuse it. */ -void -Packet::reset() -{ - result = Unknown; - if (dynamicData) { - deleteData(); - dynamicData = false; - arrayData = false; - time = curTick; - } -} - - bool fixPacket(Packet *func, Packet *timing) { diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 83f52ede5..e09ef4b85 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -28,8 +28,7 @@ /** * @file - * Declaration of the Packet Class, a packet is a transaction occuring - * between a single level of the memory heirarchy (ie L1->L2). + * Declaration of the Packet class. */ #ifndef __MEM_PACKET_HH__ @@ -44,81 +43,98 @@ typedef Packet* PacketPtr; typedef uint8_t* PacketDataPtr; /** - * A Packet is the structure to handle requests between two levels - * of the memory system. The Request is a global object that trancends - * all of the memory heirarchy, but at each levels interface a packet - * is created to transfer data/requests. For example, a request would - * be used to initiate a request to go to memory/IOdevices, as the request - * passes through the memory system several packets will be created. One - * will be created to go between the L1 and L2 caches and another to go to - * the next level and so forth. - * - * 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. + * A Packet is used to encapsulate a transfer between two objects in + * the memory system (e.g., the L1 and L2 cache). (In contrast, a + * single Request travels all the way from the requester to the + * ultimate destination and back, possibly being conveyed by several + * different Packets along the way.) */ class Packet { private: - /** 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. This may or may not be populated when a responder recieves - the packet. If not populated it memory should be allocated. + /** 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. This may or may not be populated when a + * responder recieves the packet. If not populated it memory + * should be allocated. */ PacketDataPtr data; - /** Is the data pointer set to a value that shouldn't be freed when the - * packet is destroyed? */ + /** Is the data pointer set to a value that shouldn't be freed + * when the packet is destroyed? */ bool staticData; - /** The data pointer points to a value that should be freed when the packet - * is destroyed. */ + /** The data pointer points to a value that should be freed when + * the packet is destroyed. */ bool dynamicData; - /** the data pointer points to an array (thus delete [] ) needs to be called - * on it rather than simply delete.*/ + /** the data pointer points to an array (thus delete [] ) needs to + * be called on it rather than simply delete.*/ bool arrayData; - /** The address of the request, could be virtual or physical (depending on - cache configurations). */ + /** The address of the request. This address could be virtual or + * physical, depending on the system configuration. */ Addr addr; - /** Indicates the size of the request. */ + /** The size of the request or transfer. */ int size; - /** A index of the source of the transaction. */ + /** Device address (e.g., bus ID) of the source of the + * transaction. The source is not responsible for setting this + * field; it is set implicitly by the interconnect when the + * packet * is first sent. */ short src; - /** A index to the destination of the transaction. */ + /** Device address (e.g., bus ID) of the destination of the + * transaction. The special value Broadcast indicates that the + * packet should be routed based on its address. This field is + * initialized in the constructor and is thus always valid + * (unlike * addr, size, and src). */ short dest; + /** Is the 'addr' field valid? */ bool addrValid; + /** Is the 'size' field valid? */ bool sizeValid; + /** Is the 'src' field valid? */ bool srcValid; public: + /** The special destination address indicating that the packet + * should be routed based on its address. */ static const short Broadcast = -1; - /** A pointer to the overall request. */ + /** A pointer to the original request. */ RequestPtr req; + /** A virtual base opaque structure used to hold coherence-related + * state. A specific subclass would be derived from this to + * carry state specific to a particular coherence protocol. */ class CoherenceState { public: virtual ~CoherenceState() {} }; - /** A virtual base opaque structure used to hold - coherence status messages. */ - CoherenceState *coherence; // virtual base opaque, - // assert(dynamic_cast) etc. + /** This packet's coherence state. Caches should use + * dynamic_cast<> to cast to the state appropriate for the + * system's coherence protocol. */ + CoherenceState *coherence; + /** A virtual base opaque structure used to hold state associated + * with the packet but specific to the sending device (e.g., an + * MSHR). A pointer to this state is returned in the packet's + * response so that the sender can quickly look up the state + * needed to process it. A specific subclass would be derived + * from this to carry state specific to a particular sending + * device. */ class SenderState { public: virtual ~SenderState() {} }; - /** A virtual base opaque structure used to hold the senders state. */ - SenderState *senderState; // virtual base opaque, - // assert(dynamic_cast) etc. + /** This packet's sender state. Devices should use dynamic_cast<> + * to cast to the state appropriate to the sender. */ + SenderState *senderState; private: /** List of command attributes. */ @@ -144,9 +160,11 @@ class Packet WriteResp = IsWrite | IsResponse }; + /** Return the string name of the cmd field (for debugging and + * tracing). */ const std::string &cmdString() const; - /** The command of the transaction. */ + /** The command field of the packet. */ Command cmd; bool isRead() { return (cmd & IsRead) != 0; } @@ -154,20 +172,7 @@ class Packet 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. */ + /** Possible results of a packet's request. */ enum Result { Success, @@ -175,7 +180,7 @@ class Packet Unknown }; - /** The result of the packet transaction. */ + /** The result of this packet's request. */ Result result; /** Accessor function that returns the source index of the packet. */ @@ -193,27 +198,56 @@ class Packet int getSize() const { assert(sizeValid); return size; } void setSize(int _size) { size = _size; sizeValid = true; } - + /** Constructor. Note that a Request object must be constructed + * first, but the Requests's physical address and size fields + * need not be valid. The command and destination addresses + * must be supplied. */ 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) + result(Unknown) { } + /** Destructor. */ ~Packet() { deleteData(); } - - /** Minimally reset a packet so something like simple cpu can reuse it. */ - void reset(); - + /** Reinitialize packet address and size from the associated + * Request object, and reset other fields that may have been + * modified by a previous transaction. Typically called when a + * statically allocated Request/Packet pair is reused for + * multiple transactions. */ void reinitFromRequest() { - if (req->validPaddr) setAddr(req->paddr); - if (req->validSize) setSize(req->size); + assert(req->validPaddr); + setAddr(req->paddr); + assert(req->validSize); + setSize(req->size); + result = Unknown; + if (dynamicData) { + deleteData(); + dynamicData = false; + arrayData = false; + } + } + + /** Take a request packet and modify it in place to be suitable + * for returning as a response to that request. Used for timing + * accesses only. For atomic and functional accesses, the + * request packet is always implicitly passed back *without* + * modifying the command or destination fields, so this function + * should not be called. */ + void makeTimingResponse() { + assert(needsResponse()); + int icmd = (int)cmd; + icmd &= ~(IsRequest | NeedsResponse); + icmd |= IsResponse; + cmd = (Command)icmd; + dest = src; + srcValid = false; } /** Set the data pointer to the following value that should not be freed. */ diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 26dbef0cd..fa7eb803e 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -139,8 +139,7 @@ Tick PhysicalMemory::doAtomicAccess(Packet *pkt) { doFunctionalAccess(pkt); - pkt->time = curTick + lat; - return curTick + lat; + return lat; } void diff --git a/src/mem/port.hh b/src/mem/port.hh index d0fa5ae8d..80ae035b1 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -165,10 +165,11 @@ class Port */ bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); } - /** Function called by the associated device to send an atomic access, - an access in which the data is moved and the state is updated in one - cycle, without interleaving with other memory accesses. - */ + /** Function called by the associated device to send an atomic + * access, an access in which the data is moved and the state is + * updated in one cycle, without interleaving with other memory + * accesses. Returns estimated latency of access. + */ Tick sendAtomic(Packet *pkt) { return peer->recvAtomic(pkt); }