From aefe9cc624902fe26535028f86ba3a45f555bcf0 Mon Sep 17 00:00:00 2001 From: Giacomo Gabrielli Date: Fri, 24 Jan 2014 15:29:30 -0600 Subject: mem: Add support for a security bit in the memory system This patch adds the basic building blocks required to support e.g. ARM TrustZone by discerning secure and non-secure memory accesses. --- src/mem/cache/base.hh | 6 +- src/mem/cache/blk.cc | 17 ++++- src/mem/cache/blk.hh | 15 ++++- src/mem/cache/cache.hh | 23 +++---- src/mem/cache/cache_impl.hh | 134 +++++++++++++++++++++++---------------- src/mem/cache/mshr.cc | 16 +++-- src/mem/cache/mshr.hh | 3 + src/mem/cache/mshr_queue.cc | 24 +++---- src/mem/cache/mshr_queue.hh | 10 ++- src/mem/cache/prefetch/base.cc | 33 ++++++---- src/mem/cache/prefetch/base.hh | 6 +- src/mem/cache/prefetch/ghb.cc | 24 ++++++- src/mem/cache/prefetch/ghb.hh | 14 ++++ src/mem/cache/prefetch/stride.cc | 33 ++++++++-- src/mem/cache/prefetch/stride.hh | 15 ++++- src/mem/cache/tags/cacheset.hh | 14 ++-- src/mem/cache/tags/fa_lru.cc | 5 +- src/mem/cache/tags/fa_lru.hh | 7 +- src/mem/cache/tags/lru.cc | 15 +++-- src/mem/cache/tags/lru.hh | 7 +- src/mem/packet.cc | 8 ++- src/mem/packet.hh | 22 +++++-- src/mem/request.hh | 4 ++ 23 files changed, 311 insertions(+), 144 deletions(-) diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 50ba396b2..c1c77cde9 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012-2013 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -560,9 +560,9 @@ class BaseCache : public MemObject virtual unsigned int drain(DrainManager *dm); - virtual bool inCache(Addr addr) const = 0; + virtual bool inCache(Addr addr, bool is_secure) const = 0; - virtual bool inMissQueue(Addr addr) const = 0; + virtual bool inMissQueue(Addr addr, bool is_secure) const = 0; void incMissCount(PacketPtr pkt) { diff --git a/src/mem/cache/blk.cc b/src/mem/cache/blk.cc index 4952ed758..210304dbf 100644 --- a/src/mem/cache/blk.cc +++ b/src/mem/cache/blk.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012-2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2007 The Regents of The University of Michigan * All rights reserved. * @@ -33,9 +45,10 @@ void CacheBlkPrintWrapper::print(std::ostream &os, int verbosity, const std::string &prefix) const { - ccprintf(os, "%sblk %c%c%c\n", prefix, + ccprintf(os, "%sblk %c%c%c%c\n", prefix, blk->isValid() ? 'V' : '-', blk->isWritable() ? 'E' : '-', - blk->isDirty() ? 'M' : '-'); + blk->isDirty() ? 'M' : '-', + blk->isSecure() ? 'S' : '-'); } diff --git a/src/mem/cache/blk.hh b/src/mem/cache/blk.hh index 47cd305c0..c65498f07 100644 --- a/src/mem/cache/blk.hh +++ b/src/mem/cache/blk.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012-2013 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -70,7 +70,9 @@ enum CacheBlkStatusBits { /** block was referenced */ BlkReferenced = 0x10, /** block was a hardware prefetch yet unaccessed*/ - BlkHWPrefetched = 0x20 + BlkHWPrefetched = 0x20, + /** block holds data from the secure memory space */ + BlkSecure = 0x40 }; /** @@ -262,6 +264,15 @@ class CacheBlk return (status & BlkHWPrefetched) != 0; } + /** + * Check if this block holds data from the secure memory space. + * @return True if the block holds data from the secure memory space. + */ + bool isSecure() const + { + return (status & BlkSecure) != 0; + } + /** * Track the fact that a local locked was issued to the block. If * multiple LLs get issued from the same context we could have diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index ab884372c..60f3650e7 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -209,12 +209,13 @@ class Cache : public BaseCache void cmpAndSwap(BlkType *blk, PacketPtr pkt); /** - * Find a block frame for new block at address addr, assuming that - * the block is not currently in the cache. Append writebacks if - * any to provided packet list. Return free block frame. May - * return NULL if there are no replaceable blocks at the moment. + * Find a block frame for new block at address addr targeting the + * given security space, assuming that the block is not currently + * in the cache. Append writebacks if any to provided packet + * list. Return free block frame. May return NULL if there are + * no replaceable blocks at the moment. */ - BlkType *allocateBlock(Addr addr, PacketList &writebacks); + BlkType *allocateBlock(Addr addr, bool is_secure, PacketList &writebacks); /** * Populates a cache block and handles all outstanding requests for the @@ -384,16 +385,16 @@ class Cache : public BaseCache return mshrQueue.allocated != 0; } - CacheBlk *findBlock(Addr addr) const { - return tags->findBlock(addr); + CacheBlk *findBlock(Addr addr, bool is_secure) const { + return tags->findBlock(addr, is_secure); } - bool inCache(Addr addr) const { - return (tags->findBlock(addr) != 0); + bool inCache(Addr addr, bool is_secure) const { + return (tags->findBlock(addr, is_secure) != 0); } - bool inMissQueue(Addr addr) const { - return (mshrQueue.findMatch(addr) != 0); + bool inMissQueue(Addr addr, bool is_secure) const { + return (mshrQueue.findMatch(addr, is_secure) != 0); } /** diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index e86b3d704..acd3ef64f 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -301,11 +301,12 @@ Cache::access(PacketPtr pkt, BlkType *&blk, } int id = pkt->req->hasContextId() ? pkt->req->contextId() : -1; - blk = tags->accessBlock(pkt->getAddr(), lat, id); + blk = tags->accessBlock(pkt->getAddr(), pkt->isSecure(), lat, id); - DPRINTF(Cache, "%s%s %x %s %s\n", pkt->cmdString(), + DPRINTF(Cache, "%s%s %x (%s) %s %s\n", pkt->cmdString(), pkt->req->isInstFetch() ? " (ifetch)" : "", - pkt->getAddr(), blk ? "hit" : "miss", blk ? blk->print() : ""); + pkt->getAddr(), pkt->isSecure() ? "s" : "ns", + blk ? "hit" : "miss", blk ? blk->print() : ""); if (blk != NULL) { @@ -327,7 +328,7 @@ Cache::access(PacketPtr pkt, BlkType *&blk, assert(blkSize == pkt->getSize()); if (blk == NULL) { // need to do a replacement - blk = allocateBlock(pkt->getAddr(), writebacks); + blk = allocateBlock(pkt->getAddr(), pkt->isSecure(), writebacks); if (blk == NULL) { // no replaceable block available, give up. // writeback will be forwarded to next level. @@ -390,8 +391,8 @@ Cache::recvTimingSnoopResp(PacketPtr pkt) assert(pkt->cmd == MemCmd::HardPFResp); // Check if it's a prefetch response and handle it. We shouldn't // get any other kinds of responses without FRRs. - DPRINTF(Cache, "Got prefetch response from above for addr %#x\n", - pkt->getAddr()); + DPRINTF(Cache, "Got prefetch response from above for addr %#x (%s)\n", + pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); recvTimingResp(pkt); return; } @@ -431,8 +432,8 @@ Cache::recvTimingReq(PacketPtr pkt) } if (pkt->memInhibitAsserted()) { - DPRINTF(Cache, "mem inhibited on 0x%x: not responding\n", - pkt->getAddr()); + DPRINTF(Cache, "mem inhibited on 0x%x (%s): not responding\n", + pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); assert(!pkt->req->isUncacheable()); // Special tweak for multilevel coherence: snoop downward here // on invalidates since there may be other caches below here @@ -489,7 +490,8 @@ Cache::recvTimingReq(PacketPtr pkt) (pkt->cmd == MemCmd::WriteReq || pkt->cmd == MemCmd::WriteInvalidateReq) ) { // not outstanding misses, can do this - MSHR *outstanding_miss = mshrQueue.findMatch(pkt->getAddr()); + MSHR *outstanding_miss = mshrQueue.findMatch(pkt->getAddr(), + pkt->isSecure()); if (pkt->cmd == MemCmd::WriteInvalidateReq || !outstanding_miss) { if (outstanding_miss) { warn("WriteInv doing a fastallocate" @@ -532,7 +534,7 @@ Cache::recvTimingReq(PacketPtr pkt) pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; Addr blk_addr = blockAlign(pkt->getAddr()); - MSHR *mshr = mshrQueue.findMatch(blk_addr); + MSHR *mshr = mshrQueue.findMatch(blk_addr, pkt->isSecure()); if (mshr) { /// MSHR hit @@ -672,16 +674,19 @@ Cache::recvAtomic(PacketPtr pkt) // have to invalidate ourselves and any lower caches even if // upper cache will be responding if (pkt->isInvalidate()) { - BlkType *blk = tags->findBlock(pkt->getAddr()); + BlkType *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); if (blk && blk->isValid()) { tags->invalidate(blk); blk->invalidate(); - DPRINTF(Cache, "rcvd mem-inhibited %s on 0x%x: invalidating\n", - pkt->cmdString(), pkt->getAddr()); + DPRINTF(Cache, "rcvd mem-inhibited %s on 0x%x (%s):" + " invalidating\n", + pkt->cmdString(), pkt->getAddr(), + pkt->isSecure() ? "s" : "ns"); } if (!last_level_cache) { - DPRINTF(Cache, "forwarding mem-inhibited %s on 0x%x\n", - pkt->cmdString(), pkt->getAddr()); + DPRINTF(Cache, "forwarding mem-inhibited %s on 0x%x (%s)\n", + pkt->cmdString(), pkt->getAddr(), + pkt->isSecure() ? "s" : "ns"); lat += ticksToCycles(memSidePort->sendAtomic(pkt)); } } else { @@ -711,8 +716,9 @@ Cache::recvAtomic(PacketPtr pkt) bus_pkt = pkt; } - DPRINTF(Cache, "Sending an atomic %s for %x\n", - bus_pkt->cmdString(), bus_pkt->getAddr()); + DPRINTF(Cache, "Sending an atomic %s for %x (%s)\n", + bus_pkt->cmdString(), bus_pkt->getAddr(), + bus_pkt->isSecure() ? "s" : "ns"); #if TRACING_ON CacheBlk::State old_state = blk ? blk->status : 0; @@ -720,8 +726,10 @@ Cache::recvAtomic(PacketPtr pkt) lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt)); - DPRINTF(Cache, "Receive response: %s for addr %x in state %i\n", - bus_pkt->cmdString(), bus_pkt->getAddr(), old_state); + DPRINTF(Cache, "Receive response: %s for addr %x (%s) in state %i\n", + bus_pkt->cmdString(), bus_pkt->getAddr(), + bus_pkt->isSecure() ? "s" : "ns", + old_state); // If packet was a forward, the response (if any) is already // in place in the bus_pkt == pkt structure, so we don't need @@ -794,8 +802,9 @@ Cache::functionalAccess(PacketPtr pkt, bool fromCpuSide) } Addr blk_addr = blockAlign(pkt->getAddr()); - BlkType *blk = tags->findBlock(pkt->getAddr()); - MSHR *mshr = mshrQueue.findMatch(blk_addr); + bool is_secure = pkt->isSecure(); + BlkType *blk = tags->findBlock(pkt->getAddr(), is_secure); + MSHR *mshr = mshrQueue.findMatch(blk_addr, is_secure); pkt->pushLabel(name()); @@ -808,7 +817,8 @@ Cache::functionalAccess(PacketPtr pkt, bool fromCpuSide) // see if we have data at all (owned or otherwise) bool have_data = blk && blk->isValid() - && pkt->checkFunctional(&cbpw, blk_addr, blkSize, blk->data); + && pkt->checkFunctional(&cbpw, blk_addr, is_secure, blkSize, + blk->data); // data we have is dirty if marked as such or if valid & ownership // pending due to outstanding UpgradeReq @@ -822,8 +832,8 @@ Cache::functionalAccess(PacketPtr pkt, bool fromCpuSide) || writeBuffer.checkFunctional(pkt, blk_addr) || memSidePort->checkFunctional(pkt); - DPRINTF(Cache, "functional %s %x %s%s%s\n", - pkt->cmdString(), pkt->getAddr(), + DPRINTF(Cache, "functional %s %x (%s) %s%s%s\n", + pkt->cmdString(), pkt->getAddr(), is_secure ? "s" : "ns", (blk && blk->isValid()) ? "valid " : "", have_data ? "data " : "", done ? "done " : ""); @@ -866,12 +876,13 @@ Cache::recvTimingResp(PacketPtr pkt) assert(mshr); if (is_error) { - DPRINTF(Cache, "Cache received packet with error for address %x, " - "cmd: %s\n", pkt->getAddr(), pkt->cmdString()); + DPRINTF(Cache, "Cache received packet with error for address %x (%s), " + "cmd: %s\n", pkt->getAddr(), pkt->isSecure() ? "s" : "ns", + pkt->cmdString()); } - DPRINTF(Cache, "Handling response to %s for address %x\n", - pkt->cmdString(), pkt->getAddr()); + DPRINTF(Cache, "Handling response to %s for address %x (%s)\n", + pkt->cmdString(), pkt->getAddr(), pkt->isSecure() ? "s" : "ns"); MSHRQueue *mq = mshr->queue; bool wasFull = mq->isFull(); @@ -884,7 +895,7 @@ Cache::recvTimingResp(PacketPtr pkt) // Initial target is used just for stats MSHR::Target *initial_tgt = mshr->getTarget(); - BlkType *blk = tags->findBlock(pkt->getAddr()); + BlkType *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); int stats_cmd_idx = initial_tgt->pkt->cmdToIndex(); Tick miss_latency = curTick() - initial_tgt->recvTime; PacketList writebacks; @@ -1074,6 +1085,8 @@ Cache::writebackBlk(BlkType *blk) Request *writebackReq = new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0, Request::wbMasterId); + if (blk->isSecure()) + writebackReq->setFlags(Request::SECURE); writebackReq->taskId(blk->task_id); blk->task_id= ContextSwitchTaskId::Unknown; @@ -1166,7 +1179,7 @@ Cache::uncacheableFlush(PacketPtr pkt) if (pkt->req->isClearLL()) tags->clearLocks(); - BlkType *blk(tags->findBlock(pkt->getAddr())); + BlkType *blk(tags->findBlock(pkt->getAddr(), pkt->isSecure())); if (blk) { writebackVisitor(*blk); invalidateVisitor(*blk); @@ -1176,13 +1189,14 @@ Cache::uncacheableFlush(PacketPtr pkt) template typename Cache::BlkType* -Cache::allocateBlock(Addr addr, PacketList &writebacks) +Cache::allocateBlock(Addr addr, bool is_secure, + PacketList &writebacks) { BlkType *blk = tags->findVictim(addr, writebacks); if (blk->isValid()) { Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set); - MSHR *repl_mshr = mshrQueue.findMatch(repl_addr); + MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure()); if (repl_mshr) { // must be an outstanding upgrade request on block // we're about to replace... @@ -1192,8 +1206,9 @@ Cache::allocateBlock(Addr addr, PacketList &writebacks) // allocation failed, block not inserted return NULL; } else { - DPRINTF(Cache, "replacement: replacing %x with %x: %s\n", - repl_addr, addr, + DPRINTF(Cache, "replacement: replacing %x (%s) with %x (%s): %s\n", + repl_addr, blk->isSecure() ? "s" : "ns", + addr, is_secure ? "s" : "ns", blk->isDirty() ? "writeback" : "clean"); if (blk->isDirty()) { @@ -1218,6 +1233,7 @@ Cache::handleFill(PacketPtr pkt, BlkType *blk, PacketList &writebacks) { Addr addr = pkt->getAddr(); + bool is_secure = pkt->isSecure(); #if TRACING_ON CacheBlk::State old_state = blk ? blk->status : 0; #endif @@ -1226,7 +1242,7 @@ Cache::handleFill(PacketPtr pkt, BlkType *blk, // better have read new data... assert(pkt->hasData()); // need to do a replacement - blk = allocateBlock(addr, writebacks); + blk = allocateBlock(addr, is_secure, writebacks); if (blk == NULL) { // No replaceable block... just use temporary storage to // complete the current request and then get rid of it @@ -1234,7 +1250,9 @@ Cache::handleFill(PacketPtr pkt, BlkType *blk, blk = tempBlock; tempBlock->set = tags->extractSet(addr); tempBlock->tag = tags->extractTag(addr); - DPRINTF(Cache, "using temp block for %x\n", addr); + // @todo: set security state as well... + DPRINTF(Cache, "using temp block for %x (%s)\n", addr, + is_secure ? "s" : "ns"); } else { tags->insertBlock(pkt, blk); } @@ -1250,6 +1268,8 @@ Cache::handleFill(PacketPtr pkt, BlkType *blk, // don't want to lose that } + if (is_secure) + blk->status |= BlkSecure; blk->status |= BlkValid | BlkReadable; if (!pkt->sharedAsserted()) { @@ -1265,8 +1285,8 @@ Cache::handleFill(PacketPtr pkt, BlkType *blk, blk->status |= BlkDirty; } - DPRINTF(Cache, "Block addr %x moving from state %x to %s\n", - addr, old_state, blk->print()); + DPRINTF(Cache, "Block addr %x (%s) moving from state %x to %s\n", + addr, is_secure ? "s" : "ns", old_state, blk->print()); // if we got new data, copy it in if (pkt->isRead()) { @@ -1453,16 +1473,18 @@ Cache::recvTimingSnoopReq(PacketPtr pkt) return; } - BlkType *blk = tags->findBlock(pkt->getAddr()); + bool is_secure = pkt->isSecure(); + BlkType *blk = tags->findBlock(pkt->getAddr(), is_secure); Addr blk_addr = blockAlign(pkt->getAddr()); - MSHR *mshr = mshrQueue.findMatch(blk_addr); + MSHR *mshr = mshrQueue.findMatch(blk_addr, is_secure); // Let the MSHR itself track the snoop and decide whether we want // to go ahead and do the regular cache snoop if (mshr && mshr->handleSnoop(pkt, order++)) { - DPRINTF(Cache, "Deferring snoop on in-service MSHR to blk %x." - "mshrs: %s\n", blk_addr, mshr->print()); + DPRINTF(Cache, "Deferring snoop on in-service MSHR to blk %x (%s)." + "mshrs: %s\n", blk_addr, is_secure ? "s" : "ns", + mshr->print()); if (mshr->getNumTargets() > numTarget) warn("allocating bonus target for snoop"); //handle later @@ -1471,9 +1493,9 @@ Cache::recvTimingSnoopReq(PacketPtr pkt) //We also need to check the writeback buffers and handle those std::vector writebacks; - if (writeBuffer.findMatches(blk_addr, writebacks)) { - DPRINTF(Cache, "Snoop hit in writeback to addr: %x\n", - pkt->getAddr()); + if (writeBuffer.findMatches(blk_addr, is_secure, writebacks)) { + DPRINTF(Cache, "Snoop hit in writeback to addr: %x (%s)\n", + pkt->getAddr(), is_secure ? "s" : "ns"); //Look through writebacks for any non-uncachable writes, use that if (writebacks.size()) { @@ -1538,7 +1560,7 @@ Cache::recvAtomicSnoop(PacketPtr pkt) return 0; } - BlkType *blk = tags->findBlock(pkt->getAddr()); + BlkType *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); handleSnoop(pkt, blk, false, false, false); return hitLatency * clockPeriod(); } @@ -1567,7 +1589,8 @@ Cache::getNextMSHR() // Write buffer is full, so we'd like to issue a write; // need to search MSHR queue for conflicting earlier miss. MSHR *conflict_mshr = - mshrQueue.findPending(write_mshr->addr, write_mshr->size); + mshrQueue.findPending(write_mshr->addr, write_mshr->size, + write_mshr->isSecure); if (conflict_mshr && conflict_mshr->order < write_mshr->order) { // Service misses in order until conflict is cleared. @@ -1581,7 +1604,8 @@ Cache::getNextMSHR() // Write buffer isn't full, but need to check it for // conflicting earlier writeback MSHR *conflict_mshr = - writeBuffer.findPending(miss_mshr->addr, miss_mshr->size); + writeBuffer.findPending(miss_mshr->addr, miss_mshr->size, + miss_mshr->isSecure); if (conflict_mshr) { // not sure why we don't check order here... it was in the // original code but commented out. @@ -1609,8 +1633,9 @@ Cache::getNextMSHR() PacketPtr pkt = prefetcher->getPacket(); if (pkt) { Addr pf_addr = blockAlign(pkt->getAddr()); - if (!tags->findBlock(pf_addr) && !mshrQueue.findMatch(pf_addr) && - !writeBuffer.findMatch(pf_addr)) { + if (!tags->findBlock(pf_addr, pkt->isSecure()) && + !mshrQueue.findMatch(pf_addr, pkt->isSecure()) && + !writeBuffer.findMatch(pf_addr, pkt->isSecure())) { // Update statistic on number of prefetches issued // (hwpf_mshr_misses) assert(pkt->req->masterId() < system->maxMasters()); @@ -1659,10 +1684,10 @@ Cache::getTimingPacket() return NULL; } else if (mshr->isForwardNoResponse()) { // no response expected, just forward packet as it is - assert(tags->findBlock(mshr->addr) == NULL); + assert(tags->findBlock(mshr->addr, mshr->isSecure) == NULL); pkt = tgt_pkt; } else { - BlkType *blk = tags->findBlock(mshr->addr); + BlkType *blk = tags->findBlock(mshr->addr, mshr->isSecure); if (tgt_pkt->cmd == MemCmd::HardPFReq) { // It might be possible for a writeback to arrive between @@ -1683,8 +1708,9 @@ Cache::getTimingPacket() if (snoop_pkt.memInhibitAsserted()) { markInService(mshr, &snoop_pkt); - DPRINTF(Cache, "Upward snoop of prefetch for addr %#x hit\n", - tgt_pkt->getAddr()); + DPRINTF(Cache, "Upward snoop of prefetch for addr" + " %#x (%s) hit\n", + tgt_pkt->getAddr(), tgt_pkt->isSecure()? "s": "ns"); return NULL; } } diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index f96c5c1a7..df3045a2f 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012-2013 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -64,8 +64,8 @@ using namespace std; MSHR::MSHR() : readyTime(0), _isUncacheable(false), downstreamPending(false), pendingDirty(false), postInvalidate(false), postDowngrade(false), queue(NULL), order(0), addr(0), size(0), - inService(false), isForward(false), threadNum(InvalidThreadID), - data(NULL) + isSecure(false), inService(false), isForward(false), + threadNum(InvalidThreadID), data(NULL) { } @@ -201,11 +201,12 @@ print(std::ostream &os, int verbosity, const std::string &prefix) const void -MSHR::allocate(Addr _addr, int _size, PacketPtr target, - Tick whenReady, Counter _order) +MSHR::allocate(Addr _addr, int _size, PacketPtr target, Tick whenReady, + Counter _order) { addr = _addr; size = _size; + isSecure = target->isSecure(); readyTime = whenReady; order = _order; assert(target); @@ -440,7 +441,7 @@ MSHR::checkFunctional(PacketPtr pkt) // For other requests, we iterate over the individual targets // since that's where the actual data lies. if (pkt->isPrint()) { - pkt->checkFunctional(this, addr, size, NULL); + pkt->checkFunctional(this, addr, isSecure, size, NULL); return false; } else { return (targets.checkFunctional(pkt) || @@ -452,8 +453,9 @@ MSHR::checkFunctional(PacketPtr pkt) void MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const { - ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s %s\n", + ccprintf(os, "%s[%x:%x](%s) %s %s %s state: %s %s %s %s %s\n", prefix, addr, addr+size-1, + isSecure ? "s" : "ns", isForward ? "Forward" : "", isForwardNoResponse() ? "ForwNoResp" : "", needsExclusive() ? "Excl" : "", diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh index c9c30b3e6..65357b9e6 100644 --- a/src/mem/cache/mshr.hh +++ b/src/mem/cache/mshr.hh @@ -155,6 +155,9 @@ class MSHR : public Packet::SenderState, public Printable /** Size of the request. */ int size; + /** True if the request targets the secure memory space. */ + bool isSecure; + /** True if the request has been sent to the bus. */ bool inService; diff --git a/src/mem/cache/mshr_queue.cc b/src/mem/cache/mshr_queue.cc index d8cc5f40a..3150b4f5d 100644 --- a/src/mem/cache/mshr_queue.cc +++ b/src/mem/cache/mshr_queue.cc @@ -62,13 +62,13 @@ MSHRQueue::MSHRQueue(const std::string &_label, } MSHR * -MSHRQueue::findMatch(Addr addr) const +MSHRQueue::findMatch(Addr 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) { + if (mshr->addr == addr && mshr->isSecure == is_secure) { return mshr; } } @@ -76,7 +76,7 @@ MSHRQueue::findMatch(Addr addr) const } bool -MSHRQueue::findMatches(Addr addr, vector& matches) const +MSHRQueue::findMatches(Addr addr, bool is_secure, vector& matches) const { // Need an empty vector assert(matches.empty()); @@ -85,7 +85,7 @@ MSHRQueue::findMatches(Addr addr, vector& matches) const MSHR::ConstIterator end = allocatedList.end(); for (; i != end; ++i) { MSHR *mshr = *i; - if (mshr->addr == addr) { + if (mshr->addr == addr && mshr->isSecure == is_secure) { retval = true; matches.push_back(mshr); } @@ -113,19 +113,19 @@ MSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) MSHR * -MSHRQueue::findPending(Addr addr, int size) const +MSHRQueue::findPending(Addr addr, int size, bool is_secure) const { MSHR::ConstIterator i = readyList.begin(); MSHR::ConstIterator end = readyList.end(); for (; i != end; ++i) { MSHR *mshr = *i; - if (mshr->addr < addr) { - if (mshr->addr + mshr->size > addr) { - return mshr; - } - } else { - if (addr + size > mshr->addr) { - return mshr; + 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; } } } diff --git a/src/mem/cache/mshr_queue.hh b/src/mem/cache/mshr_queue.hh index 726aa6b8e..9177433af 100644 --- a/src/mem/cache/mshr_queue.hh +++ b/src/mem/cache/mshr_queue.hh @@ -113,25 +113,29 @@ class MSHRQueue : public Drainable /** * Find the first MSHR that matches the provided address. * @param addr The 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) const; + MSHR *findMatch(Addr addr, bool is_secure) const; /** * Find and return all the matching entries in the provided vector. * @param addr The 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, std::vector& matches) const; + bool findMatches(Addr addr, bool is_secure, + std::vector& matches) const; /** * Find any pending requests that overlap the given request. * @param pkt The request to find. + * @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) const; + MSHR *findPending(Addr addr, int size, bool is_secure) const; bool checkFunctional(PacketPtr pkt, Addr blk_addr); diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index ed7b63f82..c440978e6 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -122,9 +122,9 @@ BasePrefetcher::regStats() } inline bool -BasePrefetcher::inCache(Addr addr) +BasePrefetcher::inCache(Addr addr, bool is_secure) { - if (cache->inCache(addr)) { + if (cache->inCache(addr, is_secure)) { pfCacheHit++; return true; } @@ -132,9 +132,9 @@ BasePrefetcher::inCache(Addr addr) } inline bool -BasePrefetcher::inMissQueue(Addr addr) +BasePrefetcher::inMissQueue(Addr addr, bool is_secure) { - if (cache->inMissQueue(addr)) { + if (cache->inMissQueue(addr, is_secure)) { pfMSHRHit++; return true; } @@ -157,12 +157,14 @@ BasePrefetcher::getPacket() pf.pop_front(); Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); + bool is_secure = pkt->isSecure(); - if (!inCache(blk_addr) && !inMissQueue(blk_addr)) + if (!inCache(blk_addr, is_secure) && !inMissQueue(blk_addr, is_secure)) // we found a prefetch, return it break; - DPRINTF(HWPrefetch, "addr 0x%x in cache, skipping\n", pkt->getAddr()); + DPRINTF(HWPrefetch, "addr 0x%x (%s) in cache, skipping\n", + pkt->getAddr(), is_secure ? "s" : "ns"); delete pkt->req; delete pkt; @@ -174,7 +176,8 @@ BasePrefetcher::getPacket() pfIssued++; assert(pkt != NULL); - DPRINTF(HWPrefetch, "returning 0x%x\n", pkt->getAddr()); + DPRINTF(HWPrefetch, "returning 0x%x (%s)\n", pkt->getAddr(), + pkt->isSecure() ? "s" : "ns"); return pkt; } @@ -185,12 +188,15 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick tick) if (!pkt->req->isUncacheable() && !(pkt->req->isInstFetch() && onlyData)) { // Calculate the blk address Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); + bool is_secure = pkt->isSecure(); // Check if miss is in pfq, if so remove it - std::list::iterator iter = inPrefetch(blk_addr); + std::list::iterator iter = inPrefetch(blk_addr, + is_secure); if (iter != pf.end()) { DPRINTF(HWPrefetch, "Saw a miss to a queued prefetch addr: " - "0x%x, removing it\n", blk_addr); + "0x%x (%s), removing it\n", blk_addr, + is_secure ? "s" : "ns"); pfRemovedMSHR++; delete iter->pkt->req; delete iter->pkt; @@ -239,7 +245,7 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick tick) addr, *delayIter, time); // Check if it is already in the pf buffer - if (inPrefetch(addr) != pf.end()) { + if (inPrefetch(addr, is_secure) != pf.end()) { pfBufferHit++; DPRINTF(HWPrefetch, "Prefetch addr already in pf buffer\n"); continue; @@ -247,6 +253,8 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick tick) // create a prefetch memreq Request *prefetchReq = new Request(*addrIter, blkSize, 0, masterId); + if (is_secure) + prefetchReq->setFlags(Request::SECURE); prefetchReq->taskId(ContextSwitchTaskId::Prefetcher); PacketPtr prefetch = new Packet(prefetchReq, MemCmd::HardPFReq); @@ -274,12 +282,13 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick tick) } std::list::iterator -BasePrefetcher::inPrefetch(Addr address) +BasePrefetcher::inPrefetch(Addr address, bool is_secure) { // Guaranteed to only be one match, we always check before inserting std::list::iterator iter; for (iter = pf.begin(); iter != pf.end(); iter++) { - if ((iter->pkt->getAddr() & ~(Addr)(blkSize-1)) == address) { + if (((*iter).pkt->getAddr() & ~(Addr)(blkSize-1)) == address && + (*iter).pkt->isSecure() == is_secure) { return iter; } } diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index 07ca3dd6f..953852c38 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -137,9 +137,9 @@ class BasePrefetcher : public ClockedObject */ Tick notify(PacketPtr &pkt, Tick tick); - bool inCache(Addr addr); + bool inCache(Addr addr, bool is_secure); - bool inMissQueue(Addr addr); + bool inMissQueue(Addr addr, bool is_secure); PacketPtr getPacket(); @@ -157,7 +157,7 @@ class BasePrefetcher : public ClockedObject std::list &addresses, std::list &delays) = 0; - std::list::iterator inPrefetch(Addr address); + std::list::iterator inPrefetch(Addr address, bool is_secure); /** * Utility function: are addresses a and b on the same VM page? diff --git a/src/mem/cache/prefetch/ghb.cc b/src/mem/cache/prefetch/ghb.cc index 9ceb051a7..e153c777d 100644 --- a/src/mem/cache/prefetch/ghb.cc +++ b/src/mem/cache/prefetch/ghb.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012-2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2005 The Regents of The University of Michigan * All rights reserved. * @@ -43,16 +55,26 @@ GHBPrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, std::list &delays) { Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); + bool is_secure = pkt->isSecure(); int master_id = useMasterId ? pkt->req->masterId() : 0; assert(master_id < Max_Masters); + bool same_sec_state = true; + // Avoid activating prefetch if the security state is not + // consistent across requests + if (is_secure != lastMissIsSecure[master_id] || + is_secure != secondLastMissIsSecure[master_id]) + same_sec_state = false; + int new_stride = blk_addr - lastMissAddr[master_id]; int old_stride = lastMissAddr[master_id] - secondLastMissAddr[master_id]; secondLastMissAddr[master_id] = lastMissAddr[master_id]; + secondLastMissIsSecure[master_id] = lastMissIsSecure[master_id]; lastMissAddr[master_id] = blk_addr; + lastMissIsSecure[master_id] = is_secure; - if (new_stride == old_stride) { + if (same_sec_state && new_stride == old_stride) { for (int d = 1; d <= degree; d++) { Addr new_addr = blk_addr + d * new_stride; if (pageStop && !samePage(blk_addr, new_addr)) { diff --git a/src/mem/cache/prefetch/ghb.hh b/src/mem/cache/prefetch/ghb.hh index 3e4123de0..9ddff1160 100644 --- a/src/mem/cache/prefetch/ghb.hh +++ b/src/mem/cache/prefetch/ghb.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012-2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2005 The Regents of The University of Michigan * All rights reserved. * @@ -46,7 +58,9 @@ class GHBPrefetcher : public BasePrefetcher static const int Max_Masters = 64; Addr secondLastMissAddr[Max_Masters]; + bool secondLastMissIsSecure[Max_Masters]; Addr lastMissAddr[Max_Masters]; + bool lastMissIsSecure[Max_Masters]; public: GHBPrefetcher(const Params *p) diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc index cb67f50f8..fd8b20fcc 100644 --- a/src/mem/cache/prefetch/stride.cc +++ b/src/mem/cache/prefetch/stride.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012-2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2005 The Regents of The University of Michigan * All rights reserved. * @@ -48,6 +60,7 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, } Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); + bool is_secure = pkt->isSecure(); MasterID master_id = useMasterId ? pkt->req->masterId() : 0; Addr pc = pkt->req->getPC(); assert(master_id < Max_Contexts); @@ -56,7 +69,8 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, /* Scan Table for instAddr Match */ std::list::iterator iter; for (iter = tab.begin(); iter != tab.end(); iter++) { - if ((*iter)->instAddr == pc) + // Entries have to match on the security state as well + if ((*iter)->instAddr == pc && (*iter)->isSecure == is_secure) break; } @@ -75,11 +89,13 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, (*iter)->confidence = 0; } - DPRINTF(HWPrefetch, "hit: PC %x blk_addr %x stride %d (%s), conf %d\n", - pc, blk_addr, new_stride, stride_match ? "match" : "change", + DPRINTF(HWPrefetch, "hit: PC %x blk_addr %x (%s) stride %d (%s), " + "conf %d\n", pc, blk_addr, is_secure ? "s" : "ns", new_stride, + stride_match ? "match" : "change", (*iter)->confidence); (*iter)->missAddr = blk_addr; + (*iter)->isSecure = is_secure; if ((*iter)->confidence <= 0) return; @@ -91,8 +107,8 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, pfSpanPage += degree - d + 1; return; } else { - DPRINTF(HWPrefetch, " queuing prefetch to %x @ %d\n", - new_addr, latency); + DPRINTF(HWPrefetch, " queuing prefetch to %x (%s) @ %d\n", + new_addr, is_secure ? "s" : "ns", latency); addresses.push_back(new_addr); delays.push_back(latency); } @@ -101,7 +117,8 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, // Miss in table // Find lowest confidence and replace - DPRINTF(HWPrefetch, "miss: PC %x blk_addr %x\n", pc, blk_addr); + DPRINTF(HWPrefetch, "miss: PC %x blk_addr %x (%s)\n", pc, blk_addr, + is_secure ? "s" : "ns"); if (tab.size() >= 256) { //set default table size is 256 std::list::iterator min_pos = tab.begin(); @@ -112,7 +129,8 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, min_conf = (*iter)->confidence; } } - DPRINTF(HWPrefetch, " replacing PC %x\n", (*min_pos)->instAddr); + DPRINTF(HWPrefetch, " replacing PC %x (%s)\n", + (*min_pos)->instAddr, (*min_pos)->isSecure ? "s" : "ns"); // free entry and delete it delete *min_pos; @@ -122,6 +140,7 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list &addresses, StrideEntry *new_entry = new StrideEntry; new_entry->instAddr = pc; new_entry->missAddr = blk_addr; + new_entry->isSecure = is_secure; new_entry->stride = 0; new_entry->confidence = 0; tab.push_back(new_entry); diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index 89ac7acad..b02d97d56 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012-2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2005 The Regents of The University of Michigan * All rights reserved. * @@ -57,12 +69,11 @@ class StridePrefetcher : public BasePrefetcher public: Addr instAddr; Addr missAddr; + bool isSecure; int stride; int confidence; }; - Addr *lastMissAddr[Max_Contexts]; - std::list table[Max_Contexts]; public: diff --git a/src/mem/cache/tags/cacheset.hh b/src/mem/cache/tags/cacheset.hh index 31eb28bf0..88e661cad 100644 --- a/src/mem/cache/tags/cacheset.hh +++ b/src/mem/cache/tags/cacheset.hh @@ -69,10 +69,11 @@ class CacheSet * Find a block matching the tag in this set. * @param way_id The id of the way that matches the tag. * @param tag The Tag to find. + * @param is_secure True if the target memory space is secure. * @return Pointer to the block if found. Set way_id to assoc if none found */ - Blktype* findBlk(Addr tag, int& way_id) const ; - Blktype* findBlk(Addr tag) const ; + Blktype* findBlk(Addr tag, bool is_secure, int& way_id) const ; + Blktype* findBlk(Addr tag, bool is_secure) const ; /** * Move the given block to the head of the list. @@ -90,7 +91,7 @@ class CacheSet template Blktype* -CacheSet::findBlk(Addr tag, int& way_id) const +CacheSet::findBlk(Addr tag, bool is_secure, int& way_id) const { /** * Way_id returns the id of the way that matches the block @@ -98,7 +99,8 @@ CacheSet::findBlk(Addr tag, int& way_id) const */ way_id = assoc; for (int i = 0; i < assoc; ++i) { - if (blks[i]->tag == tag && blks[i]->isValid()) { + if (blks[i]->tag == tag && blks[i]->isValid() && + blks[i]->isSecure() == is_secure) { way_id = i; return blks[i]; } @@ -108,10 +110,10 @@ CacheSet::findBlk(Addr tag, int& way_id) const template Blktype* -CacheSet::findBlk(Addr tag) const +CacheSet::findBlk(Addr tag, bool is_secure) const { int ignored_way_id; - return findBlk(tag, ignored_way_id); + return findBlk(tag, is_secure, ignored_way_id); } template diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index ddaa093d8..c3e2b66e4 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -171,7 +171,8 @@ FALRU::invalidate(FALRU::BlkType *blk) } FALRUBlk* -FALRU::accessBlock(Addr addr, Cycles &lat, int context_src, int *inCache) +FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int context_src, + int *inCache) { accesses++; int tmp_in_cache = 0; @@ -209,7 +210,7 @@ FALRU::accessBlock(Addr addr, Cycles &lat, int context_src, int *inCache) FALRUBlk* -FALRU::findBlock(Addr addr) const +FALRU::findBlock(Addr addr, bool is_secure) const { Addr blkAddr = blkAlign(addr); FALRUBlk* blk = hashLookup(blkAddr); diff --git a/src/mem/cache/tags/fa_lru.hh b/src/mem/cache/tags/fa_lru.hh index 3fbb8f0f4..1465bd861 100644 --- a/src/mem/cache/tags/fa_lru.hh +++ b/src/mem/cache/tags/fa_lru.hh @@ -182,20 +182,23 @@ public: * access and should only be used as such. * Returns the access latency and inCache flags as a side effect. * @param addr The address to look for. + * @param is_secure True if the target memory space is secure. * @param asid The address space ID. * @param lat The latency of the access. * @param inCache The FALRUBlk::inCache flags. * @return Pointer to the cache block. */ - FALRUBlk* accessBlock(Addr addr, Cycles &lat, int context_src, int *inCache = 0); + FALRUBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat, + int context_src, int *inCache = 0); /** * Find the block in the cache, do not update the replacement data. * @param addr The address to look for. + * @param is_secure True if the target memory space is secure. * @param asid The address space ID. * @return Pointer to the cache block. */ - FALRUBlk* findBlock(Addr addr) const; + FALRUBlk* findBlock(Addr addr, bool is_secure) const; /** * Find a replacement block for the address provided. diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc index 58f3f0977..ff0596987 100644 --- a/src/mem/cache/tags/lru.cc +++ b/src/mem/cache/tags/lru.cc @@ -127,11 +127,11 @@ LRU::~LRU() } LRU::BlkType* -LRU::accessBlock(Addr addr, Cycles &lat, int master_id) +LRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int master_id) { Addr tag = extractTag(addr); unsigned set = extractSet(addr); - BlkType *blk = sets[set].findBlk(tag); + BlkType *blk = sets[set].findBlk(tag, is_secure); lat = hitLatency; // Access all tags in parallel, hence one in each way. The data side @@ -149,8 +149,8 @@ LRU::accessBlock(Addr addr, Cycles &lat, int master_id) if (blk != NULL) { // move this block to head of the MRU list sets[set].moveToHead(blk); - DPRINTF(CacheRepl, "set %x: moving blk %x to MRU\n", - set, regenerateBlkAddr(tag, set)); + DPRINTF(CacheRepl, "set %x: moving blk %x (%s) to MRU\n", + set, regenerateBlkAddr(tag, set), is_secure ? "s" : "ns"); if (blk->whenReady > curTick() && cache->ticksToCycles(blk->whenReady - curTick()) > hitLatency) { lat = cache->ticksToCycles(blk->whenReady - curTick()); @@ -163,11 +163,11 @@ LRU::accessBlock(Addr addr, Cycles &lat, int master_id) LRU::BlkType* -LRU::findBlock(Addr addr) const +LRU::findBlock(Addr addr, bool is_secure) const { Addr tag = extractTag(addr); unsigned set = extractSet(addr); - BlkType *blk = sets[set].findBlk(tag); + BlkType *blk = sets[set].findBlk(tag, is_secure); return blk; } @@ -191,6 +191,7 @@ LRU::insertBlock(PacketPtr pkt, BlkType *blk) Addr addr = pkt->getAddr(); MasterID master_id = pkt->req->masterId(); uint32_t task_id = pkt->req->taskId(); + bool is_secure = pkt->isSecure(); if (!blk->isTouched) { tagsInUse++; blk->isTouched = true; @@ -220,6 +221,8 @@ LRU::insertBlock(PacketPtr pkt, BlkType *blk) blk->isTouched = true; // Set tag for new block. Caller is responsible for setting status. blk->tag = extractTag(addr); + if (is_secure) + blk->status |= BlkSecure; // deal with what we are bringing in assert(master_id < cache->system->maxMasters()); diff --git a/src/mem/cache/tags/lru.hh b/src/mem/cache/tags/lru.hh index b9f8fc25c..9d438497a 100644 --- a/src/mem/cache/tags/lru.hh +++ b/src/mem/cache/tags/lru.hh @@ -148,20 +148,23 @@ public: * NULL pointer is returned. This has all the implications of a cache * access and should only be used as such. Returns the access latency as a side effect. * @param addr The address to find. + * @param is_secure True if the target memory space is secure. * @param asid The address space ID. * @param lat The access latency. * @return Pointer to the cache block if found. */ - BlkType* accessBlock(Addr addr, Cycles &lat, int context_src); + BlkType* accessBlock(Addr addr, bool is_secure, Cycles &lat, + int context_src); /** * Finds the given address in the cache, do not update replacement data. * i.e. This is a no-side-effect find of a block. * @param addr The address to find. + * @param is_secure True if the target memory space is secure. * @param asid The address space ID. * @return Pointer to the cache block if found. */ - BlkType* findBlock(Addr addr) const; + BlkType* findBlock(Addr addr, bool is_secure) const; /** * Find a block to evict for the address provided. diff --git a/src/mem/packet.cc b/src/mem/packet.cc index a4ee1e56a..faa9d9a53 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -172,14 +172,16 @@ MemCmd::commandInfo[] = }; bool -Packet::checkFunctional(Printable *obj, Addr addr, int size, uint8_t *data) +Packet::checkFunctional(Printable *obj, Addr addr, bool is_secure, int size, + uint8_t *data) { Addr func_start = getAddr(); Addr func_end = getAddr() + getSize() - 1; Addr val_start = addr; Addr val_end = val_start + size - 1; - if (func_start > val_end || val_start > func_end) { + if (is_secure != _isSecure || func_start > val_end || + val_start > func_end) { // no intersection return false; } diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 04ad0ee28..4bdcc9a93 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -286,6 +286,9 @@ class Packet : public Printable /// physical, depending on the system configuration. Addr addr; + /// True if the request targets the secure memory space. + bool _isSecure; + /// The size of the request or transfer. unsigned size; @@ -562,6 +565,12 @@ class Packet : public Printable unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; } Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize - 1); } + bool isSecure() const + { + assert(flags.isSet(VALID_ADDR)); + return _isSecure; + } + /** * It has been determined that the SC packet should successfully update * memory. Therefore, convert this SC packet to a normal write. @@ -601,6 +610,7 @@ class Packet : public Printable if (req->hasPaddr()) { addr = req->getPaddr(); flags.set(VALID_ADDR); + _isSecure = req->isSecure(); } if (req->hasSize()) { size = req->getSize(); @@ -623,6 +633,7 @@ class Packet : public Printable if (req->hasPaddr()) { addr = req->getPaddr() & ~(_blkSize - 1); flags.set(VALID_ADDR); + _isSecure = req->isSecure(); } size = _blkSize; flags.set(VALID_SIZE); @@ -638,7 +649,8 @@ class Packet : public Printable Packet(Packet *pkt, bool clearFlags = false) : cmd(pkt->cmd), req(pkt->req), data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL), - addr(pkt->addr), size(pkt->size), src(pkt->src), dest(pkt->dest), + addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size), + src(pkt->src), dest(pkt->dest), bytesValidStart(pkt->bytesValidStart), bytesValidEnd(pkt->bytesValidEnd), busFirstWordDelay(pkt->busFirstWordDelay), @@ -679,6 +691,7 @@ class Packet : public Printable assert(req->hasPaddr()); flags = 0; addr = req->getPaddr(); + _isSecure = req->isSecure(); size = req->getSize(); src = InvalidPortID; @@ -887,7 +900,8 @@ class Packet : public Printable * value. If the functional request is a write, it may update the * memory value. */ - bool checkFunctional(Printable *obj, Addr base, int size, uint8_t *data); + bool checkFunctional(Printable *obj, Addr base, bool is_secure, int size, + uint8_t *data); /** * Check a functional request against a memory value stored in @@ -897,8 +911,8 @@ class Packet : public Printable checkFunctional(PacketPtr other) { uint8_t *data = other->hasData() ? other->getPtr() : NULL; - return checkFunctional(other, other->getAddr(), other->getSize(), - data); + return checkFunctional(other, other->getAddr(), other->isSecure(), + other->getSize(), data); } /** diff --git a/src/mem/request.hh b/src/mem/request.hh index fb21e3ff3..ade7a75df 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -140,6 +140,9 @@ class Request * valid together with MMAPPED_IPR) */ static const FlagsType GENERIC_IPR = 0x08000000; + /** The request targets the secure memory space. */ + static const FlagsType SECURE = 0x10000000; + /** These flags are *not* cleared when a Request object is reused (assigned a new address). */ static const FlagsType STICKY_FLAGS = INST_FETCH; @@ -612,6 +615,7 @@ class Request bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); } bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); } bool isClearLL() const { return _flags.isSet(CLEAR_LL); } + bool isSecure() const { return _flags.isSet(SECURE); } }; #endif // __MEM_REQUEST_HH__ -- cgit v1.2.3