summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorGiacomo Gabrielli <Giacomo.Gabrielli@arm.com>2014-01-24 15:29:30 -0600
committerGiacomo Gabrielli <Giacomo.Gabrielli@arm.com>2014-01-24 15:29:30 -0600
commitaefe9cc624902fe26535028f86ba3a45f555bcf0 (patch)
tree4d775f34b34eeafc0c596b95aa071cc52fb94283 /src/mem
parent7f835a59f1c342eb1c170973ad53c493cc38e978 (diff)
downloadgem5-aefe9cc624902fe26535028f86ba3a45f555bcf0.tar.xz
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.
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/cache/base.hh6
-rw-r--r--src/mem/cache/blk.cc17
-rw-r--r--src/mem/cache/blk.hh15
-rw-r--r--src/mem/cache/cache.hh23
-rw-r--r--src/mem/cache/cache_impl.hh134
-rw-r--r--src/mem/cache/mshr.cc16
-rw-r--r--src/mem/cache/mshr.hh3
-rw-r--r--src/mem/cache/mshr_queue.cc24
-rw-r--r--src/mem/cache/mshr_queue.hh10
-rw-r--r--src/mem/cache/prefetch/base.cc33
-rw-r--r--src/mem/cache/prefetch/base.hh6
-rw-r--r--src/mem/cache/prefetch/ghb.cc24
-rw-r--r--src/mem/cache/prefetch/ghb.hh14
-rw-r--r--src/mem/cache/prefetch/stride.cc33
-rw-r--r--src/mem/cache/prefetch/stride.hh15
-rw-r--r--src/mem/cache/tags/cacheset.hh14
-rw-r--r--src/mem/cache/tags/fa_lru.cc5
-rw-r--r--src/mem/cache/tags/fa_lru.hh7
-rw-r--r--src/mem/cache/tags/lru.cc15
-rw-r--r--src/mem/cache/tags/lru.hh7
-rw-r--r--src/mem/packet.cc8
-rw-r--r--src/mem/packet.hh22
-rw-r--r--src/mem/request.hh4
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
};
/**
@@ -263,6 +265,15 @@ class CacheBlk
}
/**
+ * 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
* redundant records on the list, but that's OK, as they'll all
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<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;
}
}
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<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;
}
}
}
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<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);
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<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;
}
}
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<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?
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<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)) {
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<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);
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<StrideEntry*> 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 <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>
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<uint8_t>() : 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__