mem: Add support for a security bit in the memory system
authorGiacomo Gabrielli <Giacomo.Gabrielli@arm.com>
Fri, 24 Jan 2014 21:29:30 +0000 (15:29 -0600)
committerGiacomo Gabrielli <Giacomo.Gabrielli@arm.com>
Fri, 24 Jan 2014 21:29:30 +0000 (15:29 -0600)
This patch adds the basic building blocks required to support e.g. ARM
TrustZone by discerning secure and non-secure memory accesses.

23 files changed:
src/mem/cache/base.hh
src/mem/cache/blk.cc
src/mem/cache/blk.hh
src/mem/cache/cache.hh
src/mem/cache/cache_impl.hh
src/mem/cache/mshr.cc
src/mem/cache/mshr.hh
src/mem/cache/mshr_queue.cc
src/mem/cache/mshr_queue.hh
src/mem/cache/prefetch/base.cc
src/mem/cache/prefetch/base.hh
src/mem/cache/prefetch/ghb.cc
src/mem/cache/prefetch/ghb.hh
src/mem/cache/prefetch/stride.cc
src/mem/cache/prefetch/stride.hh
src/mem/cache/tags/cacheset.hh
src/mem/cache/tags/fa_lru.cc
src/mem/cache/tags/fa_lru.hh
src/mem/cache/tags/lru.cc
src/mem/cache/tags/lru.hh
src/mem/packet.cc
src/mem/packet.hh
src/mem/request.hh

index 50ba396b27c7e9506b6869742cad277501bd6cca..c1c77cde9fb9a343d93774ea21762e40cd16b38c 100644 (file)
@@ -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)
     {
index 4952ed758c7e3b68bd049aa9718b729d50a39f10..210304dbf00b158db26cfafb4dbf5674a79be38c 100644 (file)
@@ -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' : '-');
 }
 
index 47cd305c068a9a254638f2f0988aca86546131c5..c65498f075743b79d86e7445f9ca0dd242debeaa 100644 (file)
@@ -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
index ab884372c47eea6471170804e5d85cb051be9b80..60f3650e7222260720fe01e747e932413aaf91ca 100644 (file)
@@ -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);
     }
 
     /**
index e86b3d704951adb0515dc40032e581ac196f39df..acd3ef64fe920a4d8f32465d477da7844b353f6d 100644 (file)
@@ -301,11 +301,12 @@ Cache<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::uncacheableFlush(PacketPtr pkt)
 
 template<class TagStore>
 typename Cache<TagStore>::BlkType*
-Cache<TagStore>::allocateBlock(Addr addr, PacketList &writebacks)
+Cache<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::recvTimingSnoopReq(PacketPtr pkt)
 
     //We also need to check the writeback buffers and handle those
     std::vector<MSHR *> 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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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<TagStore>::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;
             }
         }
index f96c5c1a7b0c4031562167c939e94bd9cddb9a72..df3045a2fbfc3d033cb3e1f482d63f13d2ac44ec 100644 (file)
@@ -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" : "",
index c9c30b3e6d24aee764e29212291be34225a75299..65357b9e6debf2e668155ec31210db11240e9092 100644 (file)
@@ -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;
 
index d8cc5f40a680f50e7b2b3f0402a9e2ff56edec99..3150b4f5d4e4cf7e0c167b0db8d7d12ebcd6aefb 100644 (file)
@@ -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<MSHR*>& matches) const
+MSHRQueue::findMatches(Addr addr, bool is_secure, vector<MSHR*>& matches) const
 {
     // Need an empty vector
     assert(matches.empty());
@@ -85,7 +85,7 @@ MSHRQueue::findMatches(Addr addr, vector<MSHR*>& 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;
             }
         }
     }
index 726aa6b8e4a8108f74090f7674e58fcc7aeca59e..9177433af45ff987c496848479b06de19deec5ff 100644 (file)
@@ -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<MSHR*>& matches) const;
+    bool findMatches(Addr 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 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);
 
index ed7b63f82589a5f5fcb1a1881bc481a63c85fe0a..c440978e60cee5c10cac8d1fa3a63c1e4bba964b 100644 (file)
@@ -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<DeferredPacket>::iterator iter = inPrefetch(blk_addr);
+        std::list<DeferredPacket>::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<BasePrefetcher::DeferredPacket>::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<DeferredPacket>::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;
         }
     }
index 07ca3dd6ff074d77f00981271933ce93b2763a6b..953852c38570b0b886bf070db2a48a75631e242a 100644 (file)
@@ -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<Addr> &addresses,
                                    std::list<Cycles> &delays) = 0;
 
-    std::list<DeferredPacket>::iterator inPrefetch(Addr address);
+    std::list<DeferredPacket>::iterator inPrefetch(Addr address, bool is_secure);
 
     /**
      * Utility function: are addresses a and b on the same VM page?
index 9ceb051a7ca600b8e0464f4969246351b57c6222..e153c777d64477ad8d57ef1cb2b4f5896a7942f8 100644 (file)
@@ -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<Addr> &addresses,
                                  std::list<Cycles> &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)) {
index 3e4123de02ecf556a55c6563df405bf8c6efd608..9ddff11605fc42f354d21125fd40868660929ab4 100644 (file)
@@ -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)
index cb67f50f84545b1c61a06753e32d3b88b57d9810..fd8b20fcced29ef92270a676968dd11b4cd6f3e2 100644 (file)
@@ -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<Addr> &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<Addr> &addresses,
     /* Scan Table for instAddr Match */
     std::list<StrideEntry*>::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<Addr> &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<Addr> &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<Addr> &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<StrideEntry*>::iterator min_pos = tab.begin();
@@ -112,7 +129,8 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list<Addr> &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<Addr> &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);
index 89ac7acad04678a9594c9f0cc1c945cba806e26a..b02d97d56947194b6008c55d63f2e326c1cfd7e2 100644 (file)
@@ -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<StrideEntry*> table[Max_Contexts];
 
   public:
index 31eb28bf0fa85038749a46ab14447e03d58eff87..88e661cad74e80a88740c9cfbcd54144fe097587 100644 (file)
@@ -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 <class Blktype>
 Blktype*
-CacheSet<Blktype>::findBlk(Addr tag, int& way_id) const
+CacheSet<Blktype>::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<Blktype>::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<Blktype>::findBlk(Addr tag, int& way_id) const
 
 template <class Blktype>
 Blktype*
-CacheSet<Blktype>::findBlk(Addr tag) const
+CacheSet<Blktype>::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 <class Blktype>
index ddaa093d8fe7189b46b8d75b03cd720f6cd662c1..c3e2b66e41ed7a39c4d03b7264e3e69334b27327 100644 (file)
@@ -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);
index 3fbb8f0f49d39c1833c4042e67b8d767e5bcf0b8..1465bd8619ec49b52f162bb23bc242f5630cfee2 100644 (file)
@@ -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.
index 58f3f097706a1e43dc19ddf743f1ef1f82786f95..ff0596987a5e9cd40afc0bf890d20d18fbac48c1 100644 (file)
@@ -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());
index b9f8fc25c7271d192abff98a935f39cb962a6352..9d438497abccdbaf1871d6a7a5d6525233a4c14f 100644 (file)
@@ -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.
index a4ee1e56af981db0b006e601ffd46d3821e458c0..faa9d9a53e2f95aa03d76d3536ce8ba40ad14329 100644 (file)
@@ -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;
     }
index 04ad0ee2849cda4f205e17915fc003cdb42ee9c1..4bdcc9a93e16577027afe1718fe2abc416f06fb2 100644 (file)
@@ -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<uint8_t>() : NULL;
-        return checkFunctional(other, other->getAddr(), other->getSize(),
-                               data);
+        return checkFunctional(other, other->getAddr(), other->isSecure(),
+                               other->getSize(), data);
     }
 
     /**
index fb21e3ff3886ca7bf47a615bed37196b6717034d..ade7a75dfab0352f68f53670b81ec6826c8420d9 100644 (file)
@@ -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__