From 6ab53415efe3e06c06589a8a6ef38185ff6f94b7 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 30 Jun 2007 10:16:18 -0700 Subject: Get rid of Packet result field. Error responses are now encoded in cmd field. --HG-- extra : convert_revision : d67819b7e3ee4b9a5bf08541104de0a89485e90b --- src/arch/sparc/tlb.cc | 4 +- src/cpu/o3/fetch_impl.hh | 6 -- src/cpu/o3/lsq_unit.hh | 6 -- src/cpu/o3/lsq_unit_impl.hh | 26 ------- src/cpu/ozone/lw_lsq.hh | 10 --- src/cpu/ozone/lw_lsq_impl.hh | 18 ----- src/cpu/simple/atomic.cc | 76 ++++++------------ src/cpu/simple/atomic.hh | 10 +-- src/cpu/simple/base.hh | 3 - src/cpu/simple/timing.cc | 8 +- src/dev/alpha/console.cc | 11 +-- src/dev/alpha/tsunami_cchip.cc | 5 +- src/dev/alpha/tsunami_io.cc | 6 +- src/dev/alpha/tsunami_pchip.cc | 6 +- src/dev/i8254xGBe.cc | 4 +- src/dev/ide_ctrl.cc | 14 ++-- src/dev/io_device.cc | 4 +- src/dev/isa_fake.cc | 9 +-- src/dev/ns_gige.cc | 8 +- src/dev/pciconfigall.cc | 4 +- src/dev/pcidev.cc | 5 +- src/dev/sparc/dtod.cc | 3 +- src/dev/sparc/iob.cc | 5 +- src/dev/sparc/mm_disk.cc | 6 +- src/dev/uart8250.cc | 6 +- src/mem/bridge.cc | 17 ++--- src/mem/bridge.hh | 2 +- src/mem/bus.cc | 30 ++++---- src/mem/cache/base_cache.cc | 2 +- src/mem/cache/cache_impl.hh | 12 ++- src/mem/packet.cc | 19 ++--- src/mem/packet.hh | 169 ++++++++++++++++++----------------------- src/mem/physical.cc | 2 +- src/mem/port.cc | 3 +- src/mem/tport.cc | 21 +++-- 35 files changed, 199 insertions(+), 341 deletions(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 09266fd6e..68df19618 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -1023,7 +1023,7 @@ doMmuReadError: panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n", (uint32_t)asi, va); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return tc->getCpuPtr()->cycles(1); } @@ -1268,7 +1268,7 @@ doMmuWriteError: panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n", (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return tc->getCpuPtr()->cycles(1); } diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 01e9b5b31..aa0c69ac4 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -628,12 +628,6 @@ DefaultFetch::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid // Now do the timing access to see whether or not the instruction // exists within the cache. if (!icachePort->sendTiming(data_pkt)) { - if (data_pkt->result == Packet::BadAddress) { - fault = TheISA::genMachineCheckFault(); - delete mem_req; - memReq[tid] = NULL; - warn("Bad address!\n"); - } assert(retryPkt == NULL); assert(retryTid == -1); DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid); diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index cc33e025d..d964b9f9f 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -653,8 +653,6 @@ LSQUnit::read(Request *req, T &data, int load_idx) data_pkt->senderState = state; if (!dcachePort->sendTiming(data_pkt)) { - Packet::Result result = data_pkt->result; - // Delete state and data packet because a load retry // initiates a pipeline restart; it does not retry. delete state; @@ -663,10 +661,6 @@ LSQUnit::read(Request *req, T &data, int load_idx) req = NULL; - if (result == Packet::BadAddress) { - return TheISA::genMachineCheckFault(); - } - // If the access didn't succeed, tell the LSQ by setting // the retry thread id. lsq->setRetryTid(lsqID); diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index bde4f8079..91e616589 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -690,9 +690,6 @@ LSQUnit::writebackStores() } if (!dcachePort->sendTiming(data_pkt)) { - if (data_pkt->result == Packet::BadAddress) { - panic("LSQ sent out a bad address for a completed store!"); - } // Need to handle becoming blocked on a store. DPRINTF(IEW, "D-Cache became blocked when writing [sn:%lli], will" "retry later\n", @@ -844,26 +841,6 @@ LSQUnit::storePostSend(PacketPtr pkt) #endif } - if (pkt->result != Packet::Success) { - DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n", - storeWBIdx); - - DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", - storeQueue[storeWBIdx].inst->seqNum); - - //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); - - //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size()); - - // @todo: Increment stat here. - } else { - DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n", - storeWBIdx); - - DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n", - storeQueue[storeWBIdx].inst->seqNum); - } - incrStIdx(storeWBIdx); } @@ -952,9 +929,6 @@ LSQUnit::recvRetry() assert(retryPkt != NULL); if (dcachePort->sendTiming(retryPkt)) { - if (retryPkt->result == Packet::BadAddress) { - panic("LSQ sent out a bad address for a completed store!"); - } storePostSend(retryPkt); retryPkt = NULL; isStoreBlocked = false; diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index 2048ad6bb..d9e0d04ac 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -661,16 +661,6 @@ OzoneLWLSQ::read(RequestPtr req, T &data, int load_idx) cpu->lockFlag = true; } - if (data_pkt->result != Packet::Success) { - DPRINTF(OzoneLSQ, "OzoneLSQ: D-cache miss!\n"); - DPRINTF(Activity, "Activity: ld accessing mem miss [sn:%lli]\n", - inst->seqNum); - } else { - DPRINTF(OzoneLSQ, "OzoneLSQ: D-cache hit!\n"); - DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n", - inst->seqNum); - } - return NoFault; } diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh index f26b06453..eefc0df83 100644 --- a/src/cpu/ozone/lw_lsq_impl.hh +++ b/src/cpu/ozone/lw_lsq_impl.hh @@ -853,24 +853,6 @@ OzoneLWLSQ::storePostSend(PacketPtr pkt, DynInstPtr &inst) } #endif } - - if (pkt->result != Packet::Success) { - DPRINTF(OzoneLSQ,"D-Cache Write Miss!\n"); - - DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", - inst->seqNum); - - //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); - - //DPRINTF(OzoneLWLSQ, "Added MSHR. count = %i\n",mshrSeqNums.size()); - - // @todo: Increment stat here. - } else { - DPRINTF(OzoneLSQ,"D-Cache: Write Hit!\n"); - - DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n", - inst->seqNum); - } } template diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 03ff1282b..bcd6662c8 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -148,23 +148,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p) icachePort.snoopRangeSent = false; dcachePort.snoopRangeSent = false; - ifetch_req = new Request(); - ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT - ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast); - ifetch_pkt->dataStatic(&inst); - - data_read_req = new Request(); - data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too - data_read_pkt = new Packet(data_read_req, MemCmd::ReadReq, - Packet::Broadcast); - data_read_pkt->dataStatic(&dataReg); - - data_write_req = new Request(); - data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too - data_write_pkt = new Packet(data_write_req, MemCmd::WriteReq, - Packet::Broadcast); - data_swap_pkt = new Packet(data_write_req, MemCmd::SwapReq, - Packet::Broadcast); + ifetch_req.setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT + data_read_req.setThreadContext(p->cpu_id, 0); // Add thread ID here too + data_write_req.setThreadContext(p->cpu_id, 0); // Add thread ID here too } @@ -282,9 +268,7 @@ Fault AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) { // use the CPU's statically allocated read request and packet objects - Request *req = data_read_req; - PacketPtr pkt = data_read_pkt; - + Request *req = &data_read_req; req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { @@ -296,19 +280,15 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) // Now do the access. if (fault == NoFault) { - pkt->reinitFromRequest(); + Packet pkt = Packet(req, MemCmd::ReadReq, Packet::Broadcast); + pkt.dataStatic(&data); if (req->isMmapedIpr()) - dcache_latency = TheISA::handleIprRead(thread->getTC(),pkt); + dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt); else - dcache_latency = dcachePort.sendAtomic(pkt); + dcache_latency = dcachePort.sendAtomic(&pkt); dcache_access = true; -#if !defined(NDEBUG) - if (pkt->result != Packet::Success) - panic("Unable to find responder for address pa = %#X va = %#X\n", - pkt->req->getPaddr(), pkt->req->getVaddr()); -#endif - data = pkt->get(); + assert(!pkt.isError()); if (req->isLocked()) { TheISA::handleLockedRead(thread, req); @@ -378,16 +358,9 @@ Fault AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { // use the CPU's statically allocated write request and packet objects - Request *req = data_write_req; - PacketPtr pkt; - + Request *req = &data_write_req; req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); - if (req->isSwap()) - pkt = data_swap_pkt; - else - pkt = data_write_pkt; - if (traceData) { traceData->setAddr(addr); } @@ -397,6 +370,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) // Now do the access. if (fault == NoFault) { + Packet pkt = + Packet(req, req->isSwap() ? MemCmd::SwapReq : MemCmd::WriteReq, + Packet::Broadcast); + pkt.dataStatic(&data); + bool do_access = true; // flag to suppress cache access if (req->isLocked()) { @@ -409,27 +387,19 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) if (do_access) { - pkt->reinitFromRequest(); - pkt->dataStatic(&data); - if (req->isMmapedIpr()) { - dcache_latency = TheISA::handleIprWrite(thread->getTC(), pkt); + dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt); } else { data = htog(data); - dcache_latency = dcachePort.sendAtomic(pkt); + dcache_latency = dcachePort.sendAtomic(&pkt); } dcache_access = true; - -#if !defined(NDEBUG) - if (pkt->result != Packet::Success) - panic("Unable to find responder for address pa = %#X va = %#X\n", - pkt->req->getPaddr(), pkt->req->getVaddr()); -#endif + assert(!pkt.isError()); } if (req->isSwap()) { assert(res); - *res = pkt->get(); + *res = pkt.get(); } else if (res) { *res = req->getExtraData(); } @@ -513,7 +483,7 @@ AtomicSimpleCPU::tick() if (!curStaticInst || !curStaticInst->isDelayedCommit()) checkForInterrupts(); - Fault fault = setupFetchRequest(ifetch_req); + Fault fault = setupFetchRequest(&ifetch_req); if (fault == NoFault) { Tick icache_latency = 0; @@ -524,9 +494,11 @@ AtomicSimpleCPU::tick() //if(predecoder.needMoreBytes()) //{ icache_access = true; - ifetch_pkt->reinitFromRequest(); + Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq, + Packet::Broadcast); + ifetch_pkt.dataStatic(&inst); - icache_latency = icachePort.sendAtomic(ifetch_pkt); + icache_latency = icachePort.sendAtomic(&ifetch_pkt); // ifetch_req is initialized to read the instruction directly // into the CPU object's inst field. //} diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index b127e3791..28e883b24 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -121,13 +121,9 @@ class AtomicSimpleCPU : public BaseSimpleCPU }; DcachePort dcachePort; - Request *ifetch_req; - PacketPtr ifetch_pkt; - Request *data_read_req; - PacketPtr data_read_pkt; - Request *data_write_req; - PacketPtr data_write_pkt; - PacketPtr data_swap_pkt; + Request ifetch_req; + Request data_read_req; + Request data_write_req; bool dcache_access; Tick dcache_latency; diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 243167db0..0550aa036 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -131,9 +131,6 @@ class BaseSimpleCPU : public BaseCPU // The predecoder TheISA::Predecoder predecoder; - // Static data storage - TheISA::LargestRead dataReg; - StaticInstPtr curStaticInst; StaticInstPtr curMacroStaticInst; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 7698a588d..b4e4a4433 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -501,7 +501,7 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt) { // received a response from the icache: execute the received // instruction - assert(pkt->result == Packet::Success); + assert(!pkt->isError()); assert(_status == IcacheWaitResponse); _status = Running; @@ -569,7 +569,7 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt) return true; } - else if (pkt->result == Packet::Nacked) { + else if (pkt->wasNacked()) { assert(cpu->_status == IcacheWaitResponse); pkt->reinitNacked(); if (!sendTiming(pkt)) { @@ -600,7 +600,7 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt) { // received a response from the dcache: complete the load or store // instruction - assert(pkt->result == Packet::Success); + assert(!pkt->isError()); assert(_status == DcacheWaitResponse); _status = Running; @@ -663,7 +663,7 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt) return true; } - else if (pkt->result == Packet::Nacked) { + else if (pkt->wasNacked()) { assert(cpu->_status == DcacheWaitResponse); pkt->reinitNacked(); if (!sendTiming(pkt)) { diff --git a/src/dev/alpha/console.cc b/src/dev/alpha/console.cc index 443f376a5..55549a154 100644 --- a/src/dev/alpha/console.cc +++ b/src/dev/alpha/console.cc @@ -102,7 +102,6 @@ AlphaConsole::read(PacketPtr pkt) * machine dependent address swizzle is required? */ - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; @@ -130,7 +129,7 @@ AlphaConsole::read(PacketPtr pkt) /* Old console code read in everyting as a 32bit int * we now break that for better error checking. */ - pkt->result = Packet::BadAddress; + pkt->setBadAddress(); } DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, pkt->get()); @@ -187,17 +186,15 @@ AlphaConsole::read(PacketPtr pkt) pkt->get()); break; default: - pkt->result = Packet::BadAddress; + pkt->setBadAddress(); } - if (pkt->result == Packet::Unknown) - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } Tick AlphaConsole::write(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; @@ -245,7 +242,7 @@ AlphaConsole::write(PacketPtr pkt) panic("Unknown 64bit access, %#x\n", daddr); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc index 118160adf..a7175d90c 100644 --- a/src/dev/alpha/tsunami_cchip.cc +++ b/src/dev/alpha/tsunami_cchip.cc @@ -78,7 +78,6 @@ TsunamiCChip::read(PacketPtr pkt) { DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr regnum = (pkt->getAddr() - pioAddr) >> 6; @@ -181,7 +180,7 @@ TsunamiCChip::read(PacketPtr pkt) DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", regnum, pkt->getSize(), pkt->get()); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -365,7 +364,7 @@ TsunamiCChip::write(PacketPtr pkt) panic("default in cchip read reached, accessing 0x%x\n"); } // swtich(regnum) } // not BIG_TSUNAMI write - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc index 58933428c..f59a06fba 100644 --- a/src/dev/alpha/tsunami_io.cc +++ b/src/dev/alpha/tsunami_io.cc @@ -461,7 +461,6 @@ TsunamiIO::frequency() const Tick TsunamiIO::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; @@ -520,14 +519,13 @@ TsunamiIO::read(PacketPtr pkt) } else { panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } Tick TsunamiIO::write(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = pkt->getAddr() - pioAddr; @@ -600,7 +598,7 @@ TsunamiIO::write(PacketPtr pkt) panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get()); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc index f30199337..be164e5b9 100644 --- a/src/dev/alpha/tsunami_pchip.cc +++ b/src/dev/alpha/tsunami_pchip.cc @@ -71,7 +71,6 @@ TsunamiPChip::TsunamiPChip(Params *p) Tick TsunamiPChip::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); pkt->allocate(); @@ -145,7 +144,7 @@ TsunamiPChip::read(PacketPtr pkt) default: panic("Default in PChip Read reached reading 0x%x\n", daddr); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -153,7 +152,6 @@ TsunamiPChip::read(PacketPtr pkt) Tick TsunamiPChip::write(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); Addr daddr = (pkt->getAddr() - pioAddr) >> 6; @@ -224,7 +222,7 @@ TsunamiPChip::write(PacketPtr pkt) } // uint64_t - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index baf13c49a..7ea4c704b 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -271,7 +271,7 @@ IGbE::read(PacketPtr pkt) pkt->set(0); }; - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -543,7 +543,7 @@ IGbE::write(PacketPtr pkt) panic("Write request to unknown register number: %#x\n", daddr); }; - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index 921ba1cd0..01243ae73 100644 --- a/src/dev/ide_ctrl.cc +++ b/src/dev/ide_ctrl.cc @@ -295,7 +295,7 @@ IdeController::readConfig(PacketPtr pkt) default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; } @@ -403,7 +403,7 @@ IdeController::writeConfig(PacketPtr pkt) bm_enabled = false; break; } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; } @@ -423,7 +423,7 @@ IdeController::read(PacketPtr pkt) parseAddr(pkt->getAddr(), offset, channel, reg_type); if (!io_enabled) { - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -490,7 +490,7 @@ IdeController::read(PacketPtr pkt) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", offset, pkt->getSize(), pkt->get()); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -506,7 +506,7 @@ IdeController::write(PacketPtr pkt) parseAddr(pkt->getAddr(), offset, channel, reg_type); if (!io_enabled) { - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); DPRINTF(IdeCtrl, "io not enabled\n"); return pioDelay; } @@ -514,7 +514,7 @@ IdeController::write(PacketPtr pkt) switch (reg_type) { case BMI_BLOCK: if (!bm_enabled) { - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -673,7 +673,7 @@ IdeController::write(PacketPtr pkt) offset, pkt->getSize(), pkt->get()); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index ecbb391ef..806d13d07 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -100,9 +100,7 @@ DmaPort::DmaPort(DmaDevice *dev, System *s) bool DmaPort::recvTiming(PacketPtr pkt) { - - - if (pkt->result == Packet::Nacked) { + if (pkt->wasNacked()) { DPRINTF(DMA, "Received nacked Pkt %#x with State: %#x Addr: %#x\n", pkt, pkt->senderState, pkt->getAddr()); diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc index c36ddeb83..5cd0afb36 100644 --- a/src/dev/isa_fake.cc +++ b/src/dev/isa_fake.cc @@ -56,7 +56,6 @@ IsaFake::IsaFake(Params *p) Tick IsaFake::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); if (params()->warnAccess != "") warn("Device %s accessed by read to address %#x size=%d\n", @@ -64,7 +63,7 @@ IsaFake::read(PacketPtr pkt) if (params()->retBadAddr) { DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - pkt->result = Packet::BadAddress; + pkt->setBadAddress(); } else { assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); DPRINTF(Tsunami, "read va=%#x size=%d\n", @@ -85,7 +84,7 @@ IsaFake::read(PacketPtr pkt) default: panic("invalid access size!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); } return pioDelay; } @@ -117,7 +116,7 @@ IsaFake::write(PacketPtr pkt) if (params()->retBadAddr) { DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); - pkt->result = Packet::BadAddress; + pkt->setBadAddress(); } else { DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); @@ -140,7 +139,7 @@ IsaFake::write(PacketPtr pkt) panic("invalid access size!\n"); } } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); } return pioDelay; } diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index e9d9c419d..86f664238 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -487,7 +487,7 @@ NSGigE::writeConfig(PacketPtr pkt) ioEnable = false; break; } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; } @@ -519,7 +519,7 @@ NSGigE::read(PacketPtr pkt) // doesn't actually DEPEND upon their values // MIB are just hardware stats keepers pkt->set(0); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); @@ -715,7 +715,7 @@ NSGigE::read(PacketPtr pkt) DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", daddr, reg, reg); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -1122,7 +1122,7 @@ NSGigE::write(PacketPtr pkt) } else { panic("Invalid Request Size"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc index bd1855847..b07ee1a49 100644 --- a/src/dev/pciconfigall.cc +++ b/src/dev/pciconfigall.cc @@ -54,7 +54,6 @@ PciConfigAll::PciConfigAll(Params *p) Tick PciConfigAll::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); pkt->allocate(); @@ -74,14 +73,13 @@ PciConfigAll::read(PacketPtr pkt) default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return params()->pio_delay; } Tick PciConfigAll::write(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); panic("Attempting to write to config space on non-existant device\n"); M5_DUMMY_RETURN } diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index c2a2bc02d..85337c841 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -68,7 +68,6 @@ PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid, Tick PciDev::PciConfigPort::recvAtomic(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr + PCI_CONFIG_SIZE); return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt); @@ -156,7 +155,7 @@ PciDev::readConfig(PacketPtr pkt) default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; } @@ -283,7 +282,7 @@ PciDev::writeConfig(PacketPtr pkt) default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; } diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc index 42275c60a..22df873b6 100644 --- a/src/dev/sparc/dtod.cc +++ b/src/dev/sparc/dtod.cc @@ -74,7 +74,6 @@ DumbTOD::DumbTOD(Params *p) Tick DumbTOD::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 8); @@ -82,7 +81,7 @@ DumbTOD::read(PacketPtr pkt) pkt->set(todTime); todTime += 1000; - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc index e686e51f7..b27f45eba 100644 --- a/src/dev/sparc/iob.cc +++ b/src/dev/sparc/iob.cc @@ -72,7 +72,6 @@ Iob::Iob(Params *p) Tick Iob::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize) readIob(pkt); @@ -81,7 +80,7 @@ Iob::read(PacketPtr pkt) else panic("Invalid address reached Iob\n"); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -176,7 +175,7 @@ Iob::write(PacketPtr pkt) panic("Invalid address reached Iob\n"); - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc index 81c5c589a..bbb773c48 100644 --- a/src/dev/sparc/mm_disk.cc +++ b/src/dev/sparc/mm_disk.cc @@ -61,7 +61,6 @@ MmDisk::read(PacketPtr pkt) uint32_t d32; uint64_t d64; - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); accessAddr = pkt->getAddr() - pioAddr; @@ -101,7 +100,7 @@ MmDisk::read(PacketPtr pkt) panic("Invalid access size\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -115,7 +114,6 @@ MmDisk::write(PacketPtr pkt) uint32_t d32; uint64_t d64; - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); accessAddr = pkt->getAddr() - pioAddr; @@ -157,7 +155,7 @@ MmDisk::write(PacketPtr pkt) panic("Invalid access size\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 50307aad4..0ad80e077 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -111,7 +111,6 @@ Uart8250::Uart8250(Params *p) Tick Uart8250::read(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 1); @@ -186,7 +185,7 @@ Uart8250::read(PacketPtr pkt) /* uint32_t d32 = *data; DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); */ - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } @@ -194,7 +193,6 @@ Tick Uart8250::write(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 1); @@ -272,7 +270,7 @@ Uart8250::write(PacketPtr pkt) panic("Tried to access a UART port that doesn't exist\n"); break; } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return pioDelay; } diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index fb4574844..77178d518 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -121,14 +121,13 @@ Bridge::BridgePort::recvTiming(PacketPtr pkt) otherPort->sendQueue.size(), otherPort->queuedRequests, otherPort->outstandingResponses); - if (pkt->isRequest() && otherPort->reqQueueFull() && pkt->result != - Packet::Nacked) { + if (pkt->isRequest() && otherPort->reqQueueFull() && !pkt->wasNacked()) { DPRINTF(BusBridge, "Remote queue full, nacking\n"); nackRequest(pkt); return true; } - if (pkt->needsResponse() && pkt->result != Packet::Nacked) + if (pkt->needsResponse() && !pkt->wasNacked()) if (respQueueFull()) { DPRINTF(BusBridge, "Local queue full, no space for response, nacking\n"); DPRINTF(BusBridge, "queue size: %d outreq: %d outstanding resp: %d\n", @@ -149,7 +148,7 @@ void Bridge::BridgePort::nackRequest(PacketPtr pkt) { // Nack the packet - pkt->result = Packet::Nacked; + pkt->setNacked(); pkt->setDest(pkt->getSrc()); //put it on the list to send @@ -194,7 +193,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt) void Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) { - if (pkt->isResponse() || pkt->result == Packet::Nacked) { + if (pkt->isResponse() || pkt->wasNacked()) { // This is a response for a request we forwarded earlier. The // corresponding PacketBuffer should be stored in the packet's // senderState field. @@ -206,7 +205,7 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) // Check if this packet was expecting a response and it's a nacked // packet, in which case we will never being seeing it - if (buf->expectResponse && pkt->result == Packet::Nacked) + if (buf->expectResponse && pkt->wasNacked()) --outstandingResponses; @@ -217,7 +216,7 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) } - if (pkt->isRequest() && pkt->result != Packet::Nacked) { + if (pkt->isRequest() && !pkt->wasNacked()) { ++queuedRequests; } @@ -251,7 +250,7 @@ Bridge::BridgePort::trySend() // Ugly! @todo When multilevel coherence works this will be removed if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && - pkt->result != Packet::Nacked) { + !pkt->wasNacked()) { PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq, Packet::Broadcast); funcPkt->dataStatic(pkt->getPtr()); @@ -264,7 +263,7 @@ Bridge::BridgePort::trySend() buf->origSrc, pkt->getDest(), pkt->getAddr()); bool wasReq = pkt->isRequest(); - bool wasNacked = pkt->result == Packet::Nacked; + bool wasNacked = pkt->wasNacked(); if (sendTiming(pkt)) { // send successful diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 89d626611..7af764437 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -86,7 +86,7 @@ class Bridge : public MemObject expectResponse(_pkt->needsResponse() && !nack) { - if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked) + if (!pkt->isResponse() && !nack && !pkt->wasNacked()) pkt->senderState = this; } diff --git a/src/mem/bus.cc b/src/mem/bus.cc index ffd5e25a7..83ce0f87d 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -173,9 +173,8 @@ bool Bus::recvTiming(PacketPtr pkt) { Port *port; - DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s result %d\n", - pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString(), - pkt->result); + DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n", + pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); BusPort *pktPort; if (pkt->getSrc() == defaultId) @@ -329,6 +328,8 @@ Bus::functionalSnoop(PacketPtr pkt, Port *responder) // id after each int src_id = pkt->getSrc(); + assert(pkt->isRequest()); // hasn't already been satisfied + for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end(); s_iter++) { @@ -336,7 +337,7 @@ Bus::functionalSnoop(PacketPtr pkt, Port *responder) if (p != responder && p->getId() != src_id) { p->sendFunctional(pkt); } - if (pkt->result == Packet::Success) { + if (pkt->isResponse()) { break; } pkt->setSrc(src_id); @@ -369,14 +370,15 @@ Bus::recvAtomic(PacketPtr 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); + assert(pkt->isRequest()); // Variables for recording original command and snoop response (if // any)... if a snooper respondes, we will need to restore // original command so that additional snoops can take place // properly MemCmd orig_cmd = pkt->cmd; - Packet::Result response_result = Packet::Unknown; MemCmd response_cmd = MemCmd::InvalidCmd; + int orig_src = pkt->getSrc(); Port *target_port = findPort(pkt->getAddr(), pkt->getSrc()); @@ -387,20 +389,18 @@ Bus::recvAtomic(PacketPtr pkt) assert(p != target_port); if (p->getId() != pkt->getSrc()) { p->sendAtomic(pkt); - if (pkt->result != Packet::Unknown) { + if (pkt->isResponse()) { // response from snoop agent assert(pkt->cmd != orig_cmd); assert(pkt->memInhibitAsserted()); - assert(pkt->isResponse()); // should only happen once - assert(response_result == Packet::Unknown); assert(response_cmd == MemCmd::InvalidCmd); // save response state - response_result = pkt->result; response_cmd = pkt->cmd; // restore original packet state for remaining snoopers pkt->cmd = orig_cmd; - pkt->result = Packet::Unknown; + pkt->setSrc(orig_src); + pkt->setDest(Packet::Broadcast); } } } @@ -408,13 +408,11 @@ Bus::recvAtomic(PacketPtr pkt) Tick response_time = target_port->sendAtomic(pkt); // if we got a response from a snooper, restore it here - if (response_result != Packet::Unknown) { - assert(response_cmd != MemCmd::InvalidCmd); + if (response_cmd != MemCmd::InvalidCmd) { // no one else should have responded - assert(pkt->result == Packet::Unknown); + assert(!pkt->isResponse()); assert(pkt->cmd == orig_cmd); pkt->cmd = response_cmd; - pkt->result = response_result; } // why do we have this packet field and the return value both??? @@ -434,8 +432,8 @@ Bus::recvFunctional(PacketPtr pkt) Port* port = findPort(pkt->getAddr(), pkt->getSrc()); functionalSnoop(pkt, port ? port : interfaces[pkt->getSrc()]); - // If the snooping found what we were looking for, we're done. - if (pkt->result != Packet::Success && port) { + // If the snooping hasn't found what we were looking for, keep going. + if (!pkt->isResponse() && port) { port->sendFunctional(pkt); } } diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 5062d6e87..870658675 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -82,7 +82,7 @@ void BaseCache::CachePort::checkAndSendFunctional(PacketPtr pkt) { checkFunctional(pkt); - if (pkt->result != Packet::Success) + if (!pkt->isResponse()) sendFunctional(pkt); } diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index b76d7e392..1823ea6b9 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -502,7 +502,6 @@ Cache::atomicAccess(PacketPtr pkt) if (pkt->needsResponse()) { pkt->makeAtomicResponse(); - pkt->result = Packet::Success; } return lat; @@ -648,14 +647,13 @@ Cache::handleResponse(PacketPtr pkt) MSHR *mshr = dynamic_cast(pkt->senderState); assert(mshr); - if (pkt->result == Packet::Nacked) { + if (pkt->wasNacked()) { //pkt->reinitFromRequest(); warn("NACKs from devices not connected to the same bus " "not implemented\n"); return; } - assert(pkt->result != Packet::BadAddress); - assert(pkt->result == Packet::Success); + assert(!pkt->isError()); DPRINTF(Cache, "Handling response to %x\n", pkt->getAddr()); MSHRQueue *mq = mshr->queue; @@ -1142,7 +1140,7 @@ void Cache::CpuSidePort::recvFunctional(PacketPtr pkt) { checkFunctional(pkt); - if (pkt->result != Packet::Success) + if (!pkt->isResponse()) myCache()->functionalAccess(pkt, cache->memSidePort); } @@ -1180,7 +1178,7 @@ Cache::MemSidePort::recvTiming(PacketPtr pkt) // this needs to be fixed so that the cache updates the mshr and sends the // packet back out on the link, but it probably won't happen so until this // gets fixed, just panic when it does - if (pkt->result == Packet::Nacked) + if (pkt->wasNacked()) panic("Need to implement cache resending nacked packets!\n"); if (pkt->isRequest() && blocked) { @@ -1216,7 +1214,7 @@ void Cache::MemSidePort::recvFunctional(PacketPtr pkt) { checkFunctional(pkt); - if (pkt->result != Packet::Success) + if (!pkt->isResponse()) myCache()->functionalAccess(pkt, cache->cpuSidePort); } diff --git a/src/mem/packet.cc b/src/mem/packet.cc index cd0ed8a2e..55fe13f3c 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -115,7 +115,13 @@ MemCmd::commandInfo[] = SwapResp, "SwapReq" }, /* SwapResp -- for Swap ldstub type operations */ { SET5(IsRead, IsWrite, NeedsExclusive, IsResponse, HasData), - InvalidCmd, "SwapResp" } + InvalidCmd, "SwapResp" }, + /* NetworkNackError -- nacked at network layer (not by protocol) */ + { SET2(IsRequest, IsError), InvalidCmd, "NetworkNackError" }, + /* InvalidDestError -- packet dest field invalid */ + { SET2(IsRequest, IsError), InvalidCmd, "InvalidDestError" }, + /* BadAddressError -- memory address invalid */ + { SET2(IsRequest, IsError), InvalidCmd, "BadAddressError" } }; @@ -205,7 +211,7 @@ Packet::checkFunctional(Addr addr, int size, uint8_t *data) if (func_start >= val_start && func_end <= val_end) { allocate(); std::memcpy(getPtr(), data + offset, getSize()); - result = Packet::Success; + makeResponse(); return true; } else { // In this case the timing packet only partially satisfies @@ -245,15 +251,6 @@ operator<<(std::ostream &o, const Packet &p) o << p.getAddr() + p.getSize() - 1 << "] "; o.unsetf(std::ios_base::hex| std::ios_base::showbase); - if (p.result == Packet::Success) - o << "Successful "; - if (p.result == Packet::BadAddress) - o << "BadAddress "; - if (p.result == Packet::Nacked) - o << "Nacked "; - if (p.result == Packet::Unknown) - o << "Inflight "; - if (p.isRead()) o << "Read "; if (p.isWrite()) diff --git a/src/mem/packet.hh b/src/mem/packet.hh index fc1c283ed..10b9f490c 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -84,6 +84,13 @@ class MemCmd StoreCondResp, SwapReq, SwapResp, + // Error responses + // @TODO these should be classified as responses rather than + // requests; coding them as requests initially for backwards + // compatibility + NetworkNackError, // nacked at network layer (not by protocol) + InvalidDestError, // packet dest field invalid + BadAddressError, // memory address invalid NUM_MEM_CMDS }; @@ -103,6 +110,7 @@ class MemCmd IsHWPrefetch, IsLocked, //!< Alpha/MIPS LL or SC access HasData, //!< There is an associated payload + IsError, //!< Error response NUM_COMMAND_ATTRIBUTES }; @@ -135,12 +143,13 @@ class MemCmd bool isWrite() const { return testCmdAttrib(IsWrite); } bool isRequest() const { return testCmdAttrib(IsRequest); } bool isResponse() const { return testCmdAttrib(IsResponse); } - bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); } + bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); } bool needsResponse() const { return testCmdAttrib(NeedsResponse); } bool isInvalidate() const { return testCmdAttrib(IsInvalidate); } bool hasData() const { return testCmdAttrib(HasData); } bool isReadWrite() const { return isRead() && isWrite(); } bool isLocked() const { return testCmdAttrib(IsLocked); } + bool isError() const { return testCmdAttrib(IsError); } const Command responseCommand() const { return commandInfo[cmd].response; @@ -184,6 +193,12 @@ class Packet : public FastAlloc typedef MemCmd::Command Command; + /** The command field of the packet. */ + MemCmd cmd; + + /** A pointer to the original request. */ + RequestPtr req; + private: /** A pointer to the data being transfered. It can be differnt * sizes at each level of the heirarchy so it belongs in the @@ -223,19 +238,28 @@ class Packet : public FastAlloc * (unlike * addr, size, and src). */ short dest; + /** The original value of the command field. Only valid when the + * current command field is an error condition; in that case, the + * previous contents of the command field are copied here. This + * field is *not* set on non-error responses. + */ + MemCmd origCmd; + /** Are the 'addr' and 'size' fields valid? */ bool addrSizeValid; /** Is the 'src' field valid? */ bool srcValid; + bool destValid; - enum SnoopFlag { + enum Flag { + // Snoop flags MemInhibit, Shared, - NUM_SNOOP_FLAGS + NUM_PACKET_FLAGS }; - /** Coherence snoopFlags for snooping */ - std::bitset snoopFlags; + /** Status flags */ + std::bitset flags; public: @@ -252,22 +276,6 @@ class Packet : public FastAlloc * should be routed based on its address. */ static const short Broadcast = -1; - /** 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 FastAlloc { - public: - virtual ~CoherenceState() {} - }; - - /** 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 @@ -284,11 +292,6 @@ class Packet : public FastAlloc * to cast to the state appropriate to the sender. */ SenderState *senderState; - public: - - /** The command field of the packet. */ - MemCmd cmd; - /** Return the string name of the cmd field (for debugging and * tracing). */ const std::string &cmdString() const { return cmd.toString(); } @@ -296,68 +299,59 @@ class Packet : public FastAlloc /** Return the index of this command. */ inline int cmdToIndex() const { return cmd.toInt(); } - public: - bool isRead() const { return cmd.isRead(); } bool isWrite() const { return cmd.isWrite(); } bool isRequest() const { return cmd.isRequest(); } bool isResponse() const { return cmd.isResponse(); } - bool needsExclusive() const { return cmd.needsExclusive(); } + bool needsExclusive() const { return cmd.needsExclusive(); } bool needsResponse() const { return cmd.needsResponse(); } bool isInvalidate() const { return cmd.isInvalidate(); } bool hasData() const { return cmd.hasData(); } bool isReadWrite() const { return cmd.isReadWrite(); } bool isLocked() const { return cmd.isLocked(); } - - void assertMemInhibit() { snoopFlags[MemInhibit] = true; } - void assertShared() { snoopFlags[Shared] = true; } - bool memInhibitAsserted() { return snoopFlags[MemInhibit]; } - bool sharedAsserted() { return snoopFlags[Shared]; } + bool isError() const { return cmd.isError(); } + + // Snoop flags + void assertMemInhibit() { flags[MemInhibit] = true; } + void assertShared() { flags[Shared] = true; } + bool memInhibitAsserted() { return flags[MemInhibit]; } + bool sharedAsserted() { return flags[Shared]; } + + // Network error conditions... encapsulate them as methods since + // their encoding keeps changing (from result field to command + // field, etc.) + void setNacked() { origCmd = cmd; cmd = MemCmd::NetworkNackError; } + void setBadAddress() { origCmd = cmd; cmd = MemCmd::BadAddressError; } + bool wasNacked() { return cmd == MemCmd::NetworkNackError; } + bool hadBadAddress() { return cmd == MemCmd::BadAddressError; } bool nic_pkt() { panic("Unimplemented"); M5_DUMMY_RETURN } - /** Possible results of a packet's request. */ - enum Result - { - Success, - BadAddress, - Nacked, - Unknown - }; - - /** The result of this packet's request. */ - Result result; - /** Accessor function that returns the source index of the packet. */ - short getSrc() const { assert(srcValid); return src; } + short getSrc() const { assert(srcValid); return src; } void setSrc(short _src) { src = _src; srcValid = true; } /** Reset source field, e.g. to retransmit packet on different bus. */ void clearSrc() { srcValid = false; } /** Accessor function that returns the destination index of the packet. */ - short getDest() const { return dest; } - void setDest(short _dest) { dest = _dest; } + short getDest() const { assert(destValid); return dest; } + void setDest(short _dest) { dest = _dest; destValid = true; } Addr getAddr() const { assert(addrSizeValid); return addr; } - int getSize() const { assert(addrSizeValid); return size; } + int getSize() const { assert(addrSizeValid); return size; } Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); } - void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; } - void cmdOverride(MemCmd newCmd) { cmd = newCmd; } - /** 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, MemCmd _cmd, short _dest) - : data(NULL), staticData(false), dynamicData(false), arrayData(false), + : cmd(_cmd), req(_req), + data(NULL), staticData(false), dynamicData(false), arrayData(false), addr(_req->paddr), size(_req->size), dest(_dest), - addrSizeValid(_req->validPaddr), srcValid(false), - snoopFlags(0), - time(curTick), - req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), - result(Unknown) + addrSizeValid(_req->validPaddr), srcValid(false), destValid(true), + flags(0), time(curTick), senderState(NULL) { } @@ -365,13 +359,11 @@ class Packet : public FastAlloc * a request that is for a whole block, not the address from the req. * this allows for overriding the size/addr of the req.*/ Packet(Request *_req, MemCmd _cmd, short _dest, int _blkSize) - : data(NULL), staticData(false), dynamicData(false), arrayData(false), + : cmd(_cmd), req(_req), + data(NULL), staticData(false), dynamicData(false), arrayData(false), addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize), dest(_dest), - addrSizeValid(_req->validPaddr), srcValid(false), - snoopFlags(0), - time(curTick), - req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), - result(Unknown) + addrSizeValid(_req->validPaddr), srcValid(false), destValid(true), + flags(0), time(curTick), senderState(NULL) { } @@ -382,15 +374,14 @@ class Packet : public FastAlloc * dynamic data, user must guarantee that the new packet's * lifetime is less than that of the original packet. */ Packet(Packet *origPkt) - : data(NULL), staticData(false), dynamicData(false), arrayData(false), + : cmd(origPkt->cmd), req(origPkt->req), + data(NULL), staticData(false), dynamicData(false), arrayData(false), addr(origPkt->addr), size(origPkt->size), src(origPkt->src), dest(origPkt->dest), - addrSizeValid(origPkt->addrSizeValid), srcValid(origPkt->srcValid), - snoopFlags(origPkt->snoopFlags), - time(curTick), - req(origPkt->req), coherence(origPkt->coherence), - senderState(origPkt->senderState), cmd(origPkt->cmd), - result(origPkt->result) + addrSizeValid(origPkt->addrSizeValid), + srcValid(origPkt->srcValid), destValid(origPkt->destValid), + flags(origPkt->flags), + time(curTick), senderState(origPkt->senderState) { } @@ -405,12 +396,11 @@ class Packet : public FastAlloc * multiple transactions. */ void reinitFromRequest() { assert(req->validPaddr); - snoopFlags = 0; + flags = 0; addr = req->paddr; size = req->size; time = req->time; addrSizeValid = true; - result = Unknown; if (dynamicData) { deleteData(); dynamicData = false; @@ -424,34 +414,24 @@ class Packet : public FastAlloc * destination fields are *not* modified, as is appropriate for * atomic accesses. */ - void makeAtomicResponse() + void makeResponse() { assert(needsResponse()); assert(isRequest()); - assert(result == Unknown); cmd = cmd.responseCommand(); - result = Success; + dest = src; + destValid = srcValid; + srcValid = false; } - /** - * Perform the additional work required for timing responses above - * and beyond atomic responses; i.e., change the destination to - * point back to the requester and clear the source field. - */ - void convertAtomicToTimingResponse() + void makeAtomicResponse() { - dest = getSrc(); - srcValid = false; + makeResponse(); } - /** - * Take a request packet and modify it in place to be suitable for - * returning as a response to a timing request. - */ void makeTimingResponse() { - makeAtomicResponse(); - convertAtomicToTimingResponse(); + makeResponse(); } /** @@ -462,9 +442,10 @@ class Packet : public FastAlloc void reinitNacked() { - assert(needsResponse() && result == Nacked); - dest = Broadcast; - result = Unknown; + assert(wasNacked()); + cmd = origCmd; + assert(needsResponse()); + setDest(Broadcast); } diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 93cba96c4..2742eca51 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -322,7 +322,7 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt) pkt->cmdString()); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); } diff --git a/src/mem/port.cc b/src/mem/port.cc index e6ea773f2..ba4f23668 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -58,12 +58,11 @@ void Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) { Request req; - Packet pkt(&req, cmd, Packet::Broadcast); for (ChunkGenerator gen(addr, size, peerBlockSize()); !gen.done(); gen.next()) { req.setPhys(gen.addr(), gen.size(), 0); - pkt.reinitFromRequest(); + Packet pkt(&req, cmd, Packet::Broadcast); pkt.dataStatic(p); sendFunctional(&pkt); p += gen.size(); diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 6c8c12ce2..d6ff64608 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -55,7 +55,7 @@ SimpleTimingPort::recvFunctional(PacketPtr pkt) checkFunctional(pkt); // Just do an atomic access and throw away the returned latency - if (pkt->result != Packet::Success) + if (!pkt->isResponse()) recvAtomic(pkt); } @@ -68,7 +68,6 @@ SimpleTimingPort::recvTiming(PacketPtr pkt) // correctly with the drain code, so that would need to be fixed // if we ever added it back. assert(pkt->isRequest()); - assert(pkt->result == Packet::Unknown); if (pkt->memInhibitAsserted()) { // snooper will supply based on copy of packet @@ -85,7 +84,6 @@ SimpleTimingPort::recvTiming(PacketPtr pkt) // recvAtomic() should already have turned packet into // atomic response assert(pkt->isResponse()); - pkt->convertAtomicToTimingResponse(); schedSendTiming(pkt, curTick + latency); } else { delete pkt->req; @@ -138,12 +136,15 @@ void SimpleTimingPort::sendDeferredPacket() { assert(deferredPacketReady()); - bool success = sendTiming(transmitList.front().pkt); + // take packet off list here; if recvTiming() on the other side + // calls sendTiming() back on us (like SimpleTimingCpu does), then + // we get confused by having a non-active packet on transmitList + DeferredPacket dp = transmitList.front(); + transmitList.pop_front(); + bool success = sendTiming(dp.pkt); if (success) { - //send successful, remove packet - transmitList.pop_front(); - if (!transmitList.empty()) { + if (!transmitList.empty() && !sendEvent->scheduled()) { Tick time = transmitList.front().tick; sendEvent->schedule(time <= curTick ? curTick+1 : time); } @@ -152,6 +153,12 @@ SimpleTimingPort::sendDeferredPacket() drainEvent->process(); drainEvent = NULL; } + } else { + // Unsuccessful, need to put back on transmitList. Callee + // should not have messed with it (since it didn't accept that + // packet), so we can just push it back on the front. + assert(!sendEvent->scheduled()); + transmitList.push_front(dp); } waitingOnRetry = !success; -- cgit v1.2.3