MSHR *allocateBufferInternal(MSHRQueue *mq, Addr addr, int size,
PacketPtr pkt, Tick time, bool requestBus)
{
+ // check that the address is block aligned since we rely on
+ // this in a number of places when checking for matches and
+ // overlap
+ assert(addr == blockAlign(addr));
+
MSHR *mshr = mq->allocate(addr, size, pkt, time, order++);
if (mq->isFull()) {
{
assert(pkt->isWrite() && !pkt->isRead());
return allocateBufferInternal(&writeBuffer,
- pkt->getAddr(), pkt->getSize(),
+ blockAlign(pkt->getAddr()), blkSize,
pkt, time, requestBus);
}
assert(pkt->req->isUncacheable());
assert(pkt->isRead());
return allocateBufferInternal(&mshrQueue,
- pkt->getAddr(), pkt->getSize(),
+ blockAlign(pkt->getAddr()), blkSize,
pkt, time, requestBus);
}
}
PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize);
+ // the packet should be block aligned
+ assert(pkt->getAddr() == blockAlign(pkt->getAddr()));
+
pkt->allocate();
DPRINTF(Cache, "%s created %s addr %#llx size %d\n",
__func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
completion_time += clockEdge(responseLatency) +
pkt->payloadDelay;
if (pkt->isRead() && !is_error) {
+ // sanity check
+ assert(pkt->getAddr() == tgt_pkt->getAddr());
+ assert(pkt->getSize() >= tgt_pkt->getSize());
+
tgt_pkt->setData(pkt->getConstPtr<uint8_t>());
}
}
// if we got new data, copy it in (checking for a read response
// and a response that has data is the same in the end)
if (pkt->isRead()) {
+ // sanity checks
assert(pkt->hasData());
+ assert(pkt->getSize() == blkSize);
+
std::memcpy(blk->data, pkt->getConstPtr<uint8_t>(), blkSize);
}
// We pay for fillLatency here.
!miss_mshr)) {
// need to search MSHR queue for conflicting earlier miss.
MSHR *conflict_mshr =
- mshrQueue.findPending(write_mshr->addr, write_mshr->size,
+ mshrQueue.findPending(write_mshr->blkAddr,
write_mshr->isSecure);
if (conflict_mshr && conflict_mshr->order < write_mshr->order) {
} else if (miss_mshr) {
// need to check for conflicting earlier writeback
MSHR *conflict_mshr =
- writeBuffer.findPending(miss_mshr->addr, miss_mshr->size,
+ writeBuffer.findPending(miss_mshr->blkAddr,
miss_mshr->isSecure);
if (conflict_mshr) {
// not sure why we don't check order here... it was in the
if (mshr->isForwardNoResponse()) {
// no response expected, just forward packet as it is
- assert(tags->findBlock(mshr->addr, mshr->isSecure) == NULL);
+ assert(tags->findBlock(mshr->blkAddr, mshr->isSecure) == NULL);
pkt = tgt_pkt;
} else {
- BlkType *blk = tags->findBlock(mshr->addr, mshr->isSecure);
+ BlkType *blk = tags->findBlock(mshr->blkAddr, mshr->isSecure);
if (tgt_pkt->cmd == MemCmd::HardPFReq) {
// We need to check the caches above us to verify that
if (snoop_pkt.isBlockCached() || blk != NULL) {
DPRINTF(Cache, "Block present, prefetch squashed by cache. "
- "Deallocating mshr target %#x.\n", mshr->addr);
+ "Deallocating mshr target %#x.\n",
+ mshr->blkAddr);
// Deallocate the mshr target
if (mshr->queue->forceDeallocateTarget(mshr)) {
/*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
MSHR::MSHR() : readyTime(0), _isUncacheable(false), downstreamPending(false),
pendingDirty(false),
postInvalidate(false), postDowngrade(false),
- queue(NULL), order(0), addr(0),
- size(0), isSecure(false), inService(false),
+ queue(NULL), order(0), blkAddr(0),
+ blkSize(0), isSecure(false), inService(false),
isForward(false), threadNum(InvalidThreadID), data(NULL)
{
}
void
-MSHR::allocate(Addr _addr, int _size, PacketPtr target, Tick whenReady,
- Counter _order)
+MSHR::allocate(Addr blk_addr, unsigned blk_size, PacketPtr target,
+ Tick when_ready, Counter _order)
{
- addr = _addr;
- size = _size;
+ blkAddr = blk_addr;
+ blkSize = blk_size;
isSecure = target->isSecure();
- readyTime = whenReady;
+ readyTime = when_ready;
order = _order;
assert(target);
isForward = false;
// snoop (mem-side request), so set source according to request here
Target::Source source = (target->cmd == MemCmd::HardPFReq) ?
Target::FromPrefetcher : Target::FromCPU;
- targets.add(target, whenReady, _order, source, true);
+ targets.add(target, when_ready, _order, source, true);
assert(deferredTargets.isReset());
data = NULL;
}
// For other requests, we iterate over the individual targets
// since that's where the actual data lies.
if (pkt->isPrint()) {
- pkt->checkFunctional(this, addr, isSecure, size, NULL);
+ pkt->checkFunctional(this, blkAddr, isSecure, blkSize, NULL);
return false;
} else {
return (targets.checkFunctional(pkt) ||
MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
{
ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s\n",
- prefix, addr, addr+size-1,
+ prefix, blkAddr, blkAddr + blkSize - 1,
isSecure ? "s" : "ns",
isForward ? "Forward" : "",
isForwardNoResponse() ? "ForwNoResp" : "",
/*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* Miss Status and Handling Register (MSHR) declaration.
*/
-#ifndef __MSHR_HH__
-#define __MSHR_HH__
+#ifndef __MEM_CACHE_MSHR_HH__
+#define __MEM_CACHE_MSHR_HH__
#include <list>
/** Order number assigned by the miss queue. */
Counter order;
- /** Address of the request. */
- Addr addr;
+ /** Block aligned address of the MSHR. */
+ Addr blkAddr;
- /** Size of the request. */
- int size;
+ /** Block size of the cache. */
+ unsigned blkSize;
/** True if the request targets the secure memory space. */
bool isSecure;
/**
* Allocate a miss to this MSHR.
- * @param cmd The requesting command.
- * @param addr The address of the miss.
- * @param asid The address space id of the miss.
- * @param size The number of bytes to request.
- * @param pkt The original miss.
+ * @param blk_addr The address of the block.
+ * @param blk_size The number of bytes to request.
+ * @param pkt The original miss.
+ * @param when_ready When should the MSHR be ready to act upon.
+ * @param _order The logical order of this MSHR
*/
- void allocate(Addr addr, int size, PacketPtr pkt,
- Tick when, Counter _order);
+ void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
+ Tick when_ready, Counter _order);
bool markInService(bool pending_dirty_resp);
std::string print() const;
};
-#endif //__MSHR_HH__
+#endif // __MEM_CACHE_MSHR_HH__
/*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
}
MSHR *
-MSHRQueue::findMatch(Addr addr, bool is_secure) const
+MSHRQueue::findMatch(Addr blk_addr, bool is_secure) const
{
MSHR::ConstIterator i = allocatedList.begin();
MSHR::ConstIterator end = allocatedList.end();
for (; i != end; ++i) {
MSHR *mshr = *i;
- if (mshr->addr == addr && mshr->isSecure == is_secure) {
+ if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
return mshr;
}
}
}
bool
-MSHRQueue::findMatches(Addr addr, bool is_secure, vector<MSHR*>& matches) const
+MSHRQueue::findMatches(Addr blk_addr, bool is_secure,
+ vector<MSHR*>& matches) const
{
// Need an empty vector
assert(matches.empty());
MSHR::ConstIterator end = allocatedList.end();
for (; i != end; ++i) {
MSHR *mshr = *i;
- if (mshr->addr == addr && mshr->isSecure == is_secure) {
+ if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
retval = true;
matches.push_back(mshr);
}
MSHR::ConstIterator end = allocatedList.end();
for (; i != end; ++i) {
MSHR *mshr = *i;
- if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
+ if (mshr->blkAddr == blk_addr && mshr->checkFunctional(pkt)) {
pkt->popLabel();
return true;
}
MSHR *
-MSHRQueue::findPending(Addr addr, int size, bool is_secure) const
+MSHRQueue::findPending(Addr blk_addr, bool is_secure) const
{
MSHR::ConstIterator i = readyList.begin();
MSHR::ConstIterator end = readyList.end();
for (; i != end; ++i) {
MSHR *mshr = *i;
- if (mshr->isSecure == is_secure) {
- if (mshr->addr < addr) {
- if (mshr->addr + mshr->size > addr)
- return mshr;
- } else {
- if (addr + size > mshr->addr)
- return mshr;
- }
+ if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
+ return mshr;
}
}
return NULL;
MSHR *
-MSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
- Tick when, Counter order)
+MSHRQueue::allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
+ Tick when_ready, Counter order)
{
assert(!freeList.empty());
MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0);
freeList.pop_front();
- mshr->allocate(addr, size, pkt, when, order);
+ mshr->allocate(blk_addr, blk_size, pkt, when_ready, order);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
mshr->readyIter = addToReadyList(mshr);
/*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* Declaration of a structure to manage MSHRs.
*/
-#ifndef __MEM__CACHE__MISS__MSHR_QUEUE_HH__
-#define __MEM__CACHE__MISS__MSHR_QUEUE_HH__
+#ifndef __MEM_CACHE_MSHR_QUEUE_HH__
+#define __MEM_CACHE_MSHR_QUEUE_HH__
#include <vector>
/**
* Find the first MSHR that matches the provided address.
- * @param addr The address to find.
+ * @param blk_addr The block address to find.
* @param is_secure True if the target memory space is secure.
* @return Pointer to the matching MSHR, null if not found.
*/
- MSHR *findMatch(Addr addr, bool is_secure) const;
+ MSHR *findMatch(Addr blk_addr, bool is_secure) const;
/**
* Find and return all the matching entries in the provided vector.
- * @param addr The address to find.
+ * @param blk_addr The block address to find.
* @param is_secure True if the target memory space is secure.
* @param matches The vector to return pointers to the matching entries.
* @return True if any matches are found, false otherwise.
- * @todo Typedef the vector??
*/
- bool findMatches(Addr addr, bool is_secure,
+ bool findMatches(Addr blk_addr, bool is_secure,
std::vector<MSHR*>& matches) const;
/**
* Find any pending requests that overlap the given request.
- * @param pkt The request to find.
+ * @param blk_addr Block address.
* @param is_secure True if the target memory space is secure.
* @return A pointer to the earliest matching MSHR.
*/
- MSHR *findPending(Addr addr, int size, bool is_secure) const;
+ MSHR *findPending(Addr blk_addr, bool is_secure) const;
bool checkFunctional(PacketPtr pkt, Addr blk_addr);
/**
* Allocates a new MSHR for the request and size. This places the request
* as the first target in the MSHR.
- * @param pkt The request to handle.
- * @param size The number in bytes to fetch from memory.
+ *
+ * @param blk_addr The address of the block.
+ * @param blk_size The number of bytes to request.
+ * @param pkt The original miss.
+ * @param when_ready When should the MSHR be ready to act upon.
+ * @param order The logical order of this MSHR
+ *
* @return The a pointer to the MSHR allocated.
*
* @pre There are free entries.
*/
- MSHR *allocate(Addr addr, int size, PacketPtr &pkt,
- Tick when, Counter order);
+ MSHR *allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
+ Tick when_ready, Counter order);
/**
* Removes the given MSHR from the queue. This places the MSHR on the
unsigned int drain(DrainManager *dm);
};
-#endif //__MEM__CACHE__MISS__MSHR_QUEUE_HH__
+#endif //__MEM_CACHE_MSHR_QUEUE_HH__