From f89b56b61ad9cb4605d0c3297b5d563672812ce9 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 13:59:03 -0400 Subject: Check the response queue on functional accesses. The response queue is not tying up an MSHR, should we change that or assume infinite storage for responses? src/mem/cache/base_cache.cc: src/mem/tport.cc: Add in functional check of retry queued packets. --HG-- extra : convert_revision : 0cb40b3a96d37a5e9eec95312d660ec6a9ce526a --- src/mem/cache/base_cache.cc | 36 ++++++++++++++++++++++++++++++++++++ src/mem/tport.cc | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) (limited to 'src/mem') diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 71ea58416..4a4a81f73 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -107,6 +107,42 @@ BaseCache::CachePort::recvAtomic(Packet *pkt) void BaseCache::CachePort::recvFunctional(Packet *pkt) { + //Check storage here first + list::iterator i = drainList.begin(); + list::iterator end = drainList.end(); + for (; i != end; ++i) { + Packet * target = *i; + // If the target contains data, and it overlaps the + // probed request, need to update data + if (target->intersect(pkt)) { + uint8_t* pkt_data; + uint8_t* write_data; + int data_size; + if (target->getAddr() < pkt->getAddr()) { + int offset = pkt->getAddr() - target->getAddr(); + pkt_data = pkt->getPtr(); + write_data = target->getPtr() + offset; + data_size = target->getSize() - offset; + assert(data_size > 0); + if (data_size > pkt->getSize()) + data_size = pkt->getSize(); + } else { + int offset = target->getAddr() - pkt->getAddr(); + pkt_data = pkt->getPtr() + offset; + write_data = target->getPtr(); + data_size = pkt->getSize() - offset; + assert(data_size > pkt->getSize()); + if (data_size > target->getSize()) + data_size = target->getSize(); + } + + if (pkt->isWrite()) { + memcpy(pkt_data, write_data, data_size); + } else { + memcpy(write_data, pkt_data, data_size); + } + } + } cache->doFunctionalAccess(pkt, isCpuSide); } diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 456878d0a..50aab31c4 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -33,7 +33,43 @@ void SimpleTimingPort::recvFunctional(Packet *pkt) { - // just do an atomic access and throw away the returned latency + //First check queued events + std::list::iterator i = transmitList.begin(); + std::list::iterator end = transmitList.end(); + for (; i != end; ++i) { + Packet * target = *i; + // If the target contains data, and it overlaps the + // probed request, need to update data + if (target->intersect(pkt)) { + uint8_t* pkt_data; + uint8_t* write_data; + int data_size; + if (target->getAddr() < pkt->getAddr()) { + int offset = pkt->getAddr() - target->getAddr(); + pkt_data = pkt->getPtr(); + write_data = target->getPtr() + offset; + data_size = target->getSize() - offset; + assert(data_size > 0); + if (data_size > pkt->getSize()) + data_size = pkt->getSize(); + } else { + int offset = target->getAddr() - pkt->getAddr(); + pkt_data = pkt->getPtr() + offset; + write_data = target->getPtr(); + data_size = pkt->getSize() - offset; + assert(data_size > pkt->getSize()); + if (data_size > target->getSize()) + data_size = target->getSize(); + } + + if (pkt->isWrite()) { + memcpy(pkt_data, write_data, data_size); + } else { + memcpy(write_data, pkt_data, data_size); + } + } + } + //Then just do an atomic access and throw away the returned latency recvAtomic(pkt); } -- cgit v1.2.3