2c2
< * Copyright (c) 2010 ARM Limited
---
> * Copyright (c) 2010, 2012-2013 ARM Limited
45a46,47
> #include <cstdint>
>
73a76,84
> // Lookup level
> enum LookupLevel {
> L0 = 0, // AArch64 only
> L1,
> L2,
> L3,
> MAX_LOOKUP_LEVELS
> };
>
78c89
< enum MemoryType {
---
> enum class MemoryType : std::uint8_t {
83,87c94,99
< enum DomainType {
< DomainNoAccess = 0,
< DomainClient,
< DomainReserved,
< DomainManager
---
>
> enum class DomainType : std::uint8_t {
> NoAccess = 0,
> Client,
> Reserved,
> Manager
94c106,114
< uint32_t asid; // Address Space Identifier
---
> uint64_t attributes; // Memory attributes formatted for PAR
>
> LookupLevel lookupLevel; // Lookup level where the descriptor was fetched
> // from. Used to set the FSR for faults
> // occurring while the long desc. format is in
> // use (AArch32 w/ LPAE and AArch64)
>
> uint16_t asid; // Address Space Identifier
> uint8_t vmid; // Virtual machine Identifier
95a116,127
> uint8_t innerAttrs;
> uint8_t outerAttrs;
> uint8_t ap; // Access permissions bits
> uint8_t hap; // Hyp access permissions bits
> DomainType domain; // Access Domain
>
> MemoryType mtype;
>
> // True if the long descriptor format is used for this entry (LPAE only)
> bool longDescFormat; // @todo use this in the update attribute bethod
>
> bool isHyp;
98a131,137
> // True if the entry targets the non-secure physical address space
> bool ns;
> // True if the entry was brought in from a non-secure page table
> bool nstid;
> // Exception level on insert, AARCH64 EL0&1, AARCH32 -> el=1
> uint8_t el;
>
101d139
< bool sNp; // Section descriptor
104,106d141
< MemoryType mtype;
< uint8_t innerAttrs;
< uint8_t outerAttrs;
108c143
< uint32_t attributes; // Memory attributes formatted for PAR
---
> bool outerShareable;
110d144
<
113,114c147
< uint8_t ap; // Access permissions bits
< uint8_t domain; // Access Domain
---
> bool pxn; // Privileged Execute Never (LPAE only)
117c150,157
< TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
---
> TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) :
> pfn(_paddr >> PageShift), size(PageBytes - 1), vpn(_vaddr >> PageShift),
> attributes(0), lookupLevel(L1), asid(_asn), vmid(0), N(0),
> innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
> domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
> longDescFormat(false), isHyp(false), global(false), valid(true),
> ns(true), nstid(true), el(0), nonCacheable(false), shareable(false),
> outerShareable(false), xn(0), pxn(0)
119,123c159
< pfn = _paddr >> PageShift;
< size = PageBytes - 1;
< asid = _asn;
< global = false;
< valid = true;
---
> // no restrictions by default, hap = 0x3
125c161,162
< vpn = _vaddr >> PageShift;
---
> // @todo Check the memory type
> }
127c164,172
< nonCacheable = sNp = false;
---
> TlbEntry() :
> pfn(0), size(0), vpn(0), attributes(0), lookupLevel(L1), asid(0),
> vmid(0), N(0), innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
> domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
> longDescFormat(false), isHyp(false), global(false), valid(true),
> ns(true), nstid(true), el(0), nonCacheable(false),
> shareable(false), outerShareable(false), xn(0), pxn(0)
> {
> // no restrictions by default, hap = 0x3
129,131c174
< xn = 0;
< ap = 0; // ???
< domain = DomainClient; //???
---
> // @todo Check the memory type
134,136d176
< TlbEntry()
< {}
<
144c184
< pageStart()
---
> pageStart() const
150c190,191
< match(Addr va, uint8_t cid)
---
> match(Addr va, uint8_t _vmid, bool hypLookUp, bool secure_lookup,
> uint8_t target_el) const
151a193,200
> return match(va, 0, _vmid, hypLookUp, secure_lookup, true, target_el);
> }
>
> bool
> match(Addr va, uint16_t asn, uint8_t _vmid, bool hypLookUp,
> bool secure_lookup, bool ignore_asn, uint8_t target_el) const
> {
> bool match = false;
153,155c202,217
< if (valid && va >= v && va <= v + size && (global || cid == asid))
< return true;
< return false;
---
>
> if (valid && va >= v && va <= v + size && (secure_lookup == !nstid) &&
> (hypLookUp == isHyp))
> {
> if (target_el == 2 || target_el == 3)
> match = (el == target_el);
> else
> match = (el == 0) || (el == 1);
> if (match && !ignore_asn) {
> match = global || (asn == asid);
> }
> if (match && nstid) {
> match = isHyp || (_vmid == vmid);
> }
> }
> return match;
159c221
< pAddr(Addr va)
---
> pAddr(Addr va) const
164a227,283
> updateAttributes()
> {
> uint64_t mask;
> uint64_t newBits;
>
> // chec bit 11 to determine if its currently LPAE or VMSA format.
> if ( attributes & (1 << 11) ) {
> newBits = ((outerShareable ? 0x2 :
> shareable ? 0x3 : 0) << 7);
> mask = 0x180;
> } else {
> /** Formatting for Physical Address Register (PAR)
> * Only including lower bits (TLB info here)
> * PAR (32-bit format):
> * PA [31:12]
> * LPAE [11] (Large Physical Address Extension)
> * TLB info [10:1]
> * NOS [10] (Not Outer Sharable)
> * NS [9] (Non-Secure)
> * -- [8] (Implementation Defined)
> * SH [7] (Sharable)
> * Inner[6:4](Inner memory attributes)
> * Outer[3:2](Outer memory attributes)
> * SS [1] (SuperSection)
> * F [0] (Fault, Fault Status in [6:1] if faulted)
> */
> newBits = ((outerShareable ? 0:1) << 10) |
> ((shareable ? 1:0) << 7) |
> (innerAttrs << 4) |
> (outerAttrs << 2);
> // TODO: Supersection bit
> mask = 0x4FC;
> }
> // common bits
> newBits |= ns << 9; // NS bit
> mask |= 1 << 9;
> // add in the new bits
> attributes &= ~mask;
> attributes |= newBits;
> }
>
> void
> setAttributes(bool lpae)
> {
> attributes = lpae ? (1 << 11) : 0;
> updateAttributes();
> }
>
> std::string
> print() const
> {
> return csprintf("%#x, asn %d vmn %d hyp %d ppn %#x size: %#x ap:%d "
> "ns:%d nstid:%d g:%d el:%d", vpn << N, asid, vmid,
> isHyp, pfn << N, size, ap, ns, nstid, global, el);
> }
>
> void
166a286
> SERIALIZE_SCALAR(longDescFormat);
170a291,292
> SERIALIZE_SCALAR(vmid);
> SERIALIZE_SCALAR(isHyp);
173a296,297
> SERIALIZE_SCALAR(ns);
> SERIALIZE_SCALAR(nstid);
175c299
< SERIALIZE_SCALAR(sNp);
---
> SERIALIZE_ENUM(lookupLevel);
179a304
> SERIALIZE_SCALAR(outerShareable);
181a307
> SERIALIZE_SCALAR(pxn);
183c309,311
< SERIALIZE_SCALAR(domain);
---
> SERIALIZE_SCALAR(hap);
> uint8_t domain_ = static_cast<uint8_t>(domain);
> paramOut(os, "domain", domain_);
187a316
> UNSERIALIZE_SCALAR(longDescFormat);
191a321,322
> UNSERIALIZE_SCALAR(vmid);
> UNSERIALIZE_SCALAR(isHyp);
194a326,327
> UNSERIALIZE_SCALAR(ns);
> UNSERIALIZE_SCALAR(nstid);
196c329
< UNSERIALIZE_SCALAR(sNp);
---
> UNSERIALIZE_ENUM(lookupLevel);
200a334
> UNSERIALIZE_SCALAR(outerShareable);
202a337
> UNSERIALIZE_SCALAR(pxn);
204c339,342
< UNSERIALIZE_SCALAR(domain);
---
> UNSERIALIZE_SCALAR(hap);
> uint8_t domain_;
> paramIn(cp, section, "domain", domain_);
> domain = static_cast<DomainType>(domain_);