#include "base/statistics.hh"
#include "mem/request.hh"
#include "params/ArmTLB.hh"
-#include "sim/faults.hh"
+#include "sim/fault.hh"
#include "sim/tlb.hh"
class ThreadContext;
namespace ArmISA {
+class TableWalker;
+
class TLB : public BaseTLB
{
public:
enum ArmFlags {
- AlignmentMask = 0x7,
+ AlignmentMask = 0x1f,
AlignByte = 0x0,
AlignHalfWord = 0x1,
AlignWord = 0x3,
AlignDoubleWord = 0x7,
+ AlignQuadWord = 0xf,
+ AlignOctWord = 0x1f,
- AllowUnaligned = 0x8,
+ 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 = 0x10
+ 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 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);
virtual ~TLB();
int getsize() const { return size; }
- void insert(Addr vaddr, ArmISA::PTE &pte);
+ 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 bool validVirtualAddress(Addr vaddr);
+ /**
+ * 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);
- void translateTiming(RequestPtr req, ThreadContext *tc,
+ Fault translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Mode mode);
// Checkpointing