/*
+ * Copyright (c) 2010 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) 2001-2005 The Regents of The University of Michigan
- * Copyright (c) 2007 MIPS Technologies, Inc.
- * Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Nathan Binkert
- * Steve Reinhardt
- * Stephen Hines
+ * Authors: Ali Saidi
*/
#ifndef __ARCH_ARM_TLB_HH__
#include "arch/arm/pagetable.hh"
#include "base/statistics.hh"
#include "mem/request.hh"
-#include "params/ArmDTB.hh"
-#include "params/ArmITB.hh"
-#include "sim/faults.hh"
+#include "params/ArmTLB.hh"
+#include "sim/fault.hh"
#include "sim/tlb.hh"
class ThreadContext;
-/* ARM does not distinguish between a DTLB and an ITLB -> unified TLB
- However, to maintain compatibility with other architectures, we'll
- simply create an ITLB and DTLB that will point to the real TLB */
namespace ArmISA {
-// WARN: This particular TLB entry is not necessarily conformed to ARM ISA
-struct TlbEntry
-{
- Addr _pageStart;
- TlbEntry() {}
- TlbEntry(Addr asn, Addr vaddr, Addr paddr) : _pageStart(paddr) {}
-
- void
- updateVaddr(Addr new_vaddr)
- {
- panic("unimplemented");
- }
-
- Addr pageStart()
- {
- return _pageStart;
- }
-
- void serialize(std::ostream &os)
- {
- SERIALIZE_SCALAR(_pageStart);
- }
-
- void unserialize(Checkpoint *cp, const std::string §ion)
- {
- UNSERIALIZE_SCALAR(_pageStart);
- }
-
-};
+class TableWalker;
class TLB : public BaseTLB
{
+ public:
+ enum ArmFlags {
+ AlignmentMask = 0x1f,
+
+ AlignByte = 0x0,
+ AlignHalfWord = 0x1,
+ AlignWord = 0x3,
+ AlignDoubleWord = 0x7,
+ AlignQuadWord = 0xf,
+ AlignOctWord = 0x1f,
+
+ AllowUnaligned = 0x20,
+ // Priv code operating as if it wasn't
+ UserMode = 0x40,
+ // Because zero otherwise looks like a valid setting and may be used
+ // accidentally, this bit must be non-zero to show it was used on
+ // purpose.
+ MustBeOne = 0x80
+ };
protected:
typedef std::multimap<Addr, int> PageTable;
PageTable lookupTable; // Quick lookup into page table
- ArmISA::PTE *table; // the Page Table
+ TlbEntry *table; // the Page Table
int size; // TLB Size
- int nlu; // not last used entry (for replacement)
- void nextnlu() { if (++nlu >= size) nlu = 0; }
- ArmISA::PTE *lookup(Addr vpn, uint8_t asn) const;
+ uint32_t _attr; // Memory attributes for last accessed TLB entry
+
+#if FULL_SYSTEM
+ TableWalker *tableWalker;
+#endif
+
+ /** Lookup an entry in the TLB
+ * @param vpn virtual address
+ * @param asn context id/address space id to use
+ * @param functional if the lookup should modify state
+ * @return pointer to TLB entrry if it exists
+ */
+ TlbEntry *lookup(Addr vpn, uint8_t asn, bool functional = false);
+ // Access Stats
mutable Stats::Scalar read_hits;
mutable Stats::Scalar read_misses;
mutable Stats::Scalar read_acv;
mutable Stats::Scalar write_accesses;
Stats::Formula hits;
Stats::Formula misses;
- Stats::Formula invalids;
Stats::Formula accesses;
+ int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU
+
public:
typedef ArmTLBParams Params;
TLB(const Params *p);
- int probeEntry(Addr vpn,uint8_t) const;
- ArmISA::PTE *getEntry(unsigned) const;
virtual ~TLB();
- int smallPages;
int getsize() const { return size; }
- ArmISA::PTE &index(bool advance = true);
- void insert(Addr vaddr, ArmISA::PTE &pte);
- void insertAt(ArmISA::PTE &pte, unsigned Index, int _smallPages);
+ void insert(Addr vaddr, TlbEntry &pte);
+
+ /** Reset the entire TLB */
void flushAll();
+
+ /** Remove any entries that match both a va and asn
+ * @param mva virtual address to flush
+ * @param asn contextid/asn to flush on match
+ */
+ void flushMvaAsid(Addr mva, uint64_t asn);
+
+ /** Remove any entries that match the asn
+ * @param asn contextid/asn to flush on match
+ */
+ void flushAsid(uint64_t asn);
+
+ /** Remove all entries that match the va regardless of asn
+ * @param mva address to flush from cache
+ */
+ void flushMva(Addr mva);
+
+ Fault trickBoxCheck(RequestPtr req, Mode mode, uint8_t domain, bool sNp);
+ Fault walkTrickBoxCheck(Addr pa, Addr va, Addr sz, bool is_exec,
+ bool is_write, uint8_t domain, bool sNp);
+
+ void printTlb();
+
void demapPage(Addr vaddr, uint64_t asn)
{
- panic("demapPage unimplemented.\n");
+ flushMvaAsid(vaddr, asn);
}
- // static helper functions... really
static bool validVirtualAddress(Addr vaddr);
- static Fault checkCacheability(RequestPtr &req);
+ /**
+ * Do a functional lookup on the TLB (for debugging)
+ * and don't modify any internal state
+ * @param tc thread context to get the context id from
+ * @param vaddr virtual address to translate
+ * @param pa returned physical address
+ * @return if the translation was successful
+ */
+ bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr);
+
+ /** Accessor functions for memory attributes for last accessed TLB entry
+ */
+ void
+ setAttr(uint32_t attr)
+ {
+ _attr = attr;
+ }
+ uint32_t
+ getAttr() const
+ {
+ return _attr;
+ }
+
+#if FULL_SYSTEM
+ Fault translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
+ Translation *translation, bool &delay, bool timing);
+#else
+ Fault translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
+ Translation *translation, bool &delay, bool timing);
+#endif
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
+ Fault translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, Mode mode);
// Checkpointing
void serialize(std::ostream &os);
void regStats();
};
-class ITB : public TLB
-{
- public:
- typedef ArmTLBParams Params;
- ITB(const Params *p);
-
- Fault translateAtomic(RequestPtr req, ThreadContext *tc);
- void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation);
-};
-
-class DTB : public TLB
-{
- public:
- typedef ArmTLBParams Params;
- DTB(const Params *p);
-
- Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write);
- void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write);
-};
-
-class UTB : public ITB, public DTB
-{
- public:
- typedef ArmTLBParams Params;
- UTB(const Params *p);
-
-};
-
-}
+/* namespace ArmISA */ }
#endif // __ARCH_ARM_TLB_HH__