1/* 2 * Copyright (c) 2010, 2012-2013 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Ali Saidi 41 */ 42 43#ifndef __ARCH_ARM_PAGETABLE_H__ 44#define __ARCH_ARM_PAGETABLE_H__ 45 46#include <cstdint> 47 48#include "arch/arm/isa_traits.hh" 49#include "arch/arm/utility.hh" 50#include "arch/arm/vtophys.hh" 51#include "sim/serialize.hh" 52 53namespace ArmISA { 54 55struct VAddr 56{ 57 VAddr(Addr a) { panic("not implemented yet."); } 58}; 59 60 61// ITB/DTB page table entry 62struct PTE 63{ 64 void serialize(CheckpointOut &cp) const 65 { 66 panic("Need to implement PTE serialization\n"); 67 } 68 69 void unserialize(CheckpointIn &cp) 70 { 71 panic("Need to implement PTE serialization\n"); 72 } 73 74}; 75 76// Lookup level 77enum LookupLevel { 78 L0 = 0, // AArch64 only 79 L1, 80 L2, 81 L3, 82 MAX_LOOKUP_LEVELS 83}; 84 85// ITB/DTB table entry 86struct TlbEntry : public Serializable 87{ 88 public: 89 enum class MemoryType : std::uint8_t { 90 StronglyOrdered, 91 Device, 92 Normal 93 }; 94 95 enum class DomainType : std::uint8_t { 96 NoAccess = 0, 97 Client, 98 Reserved, 99 Manager 100 }; 101 102 // Matching variables 103 Addr pfn; 104 Addr size; // Size of this entry, == Type of TLB Rec 105 Addr vpn; // Virtual Page Number 106 uint64_t attributes; // Memory attributes formatted for PAR 107 108 LookupLevel lookupLevel; // Lookup level where the descriptor was fetched 109 // from. Used to set the FSR for faults 110 // occurring while the long desc. format is in 111 // use (AArch32 w/ LPAE and AArch64) 112 113 uint16_t asid; // Address Space Identifier 114 uint8_t vmid; // Virtual machine Identifier 115 uint8_t N; // Number of bits in pagesize 116 uint8_t innerAttrs; 117 uint8_t outerAttrs; 118 uint8_t ap; // Access permissions bits 119 uint8_t hap; // Hyp access permissions bits 120 DomainType domain; // Access Domain 121 122 MemoryType mtype; 123 124 // True if the long descriptor format is used for this entry (LPAE only) 125 bool longDescFormat; // @todo use this in the update attribute bethod 126 127 bool isHyp; 128 bool global; 129 bool valid; 130 131 // True if the entry targets the non-secure physical address space 132 bool ns; 133 // True if the entry was brought in from a non-secure page table 134 bool nstid; 135 // Exception level on insert, AARCH64 EL0&1, AARCH32 -> el=1 136 ExceptionLevel el; 137 138 // Type of memory 139 bool nonCacheable; // Can we wrap this in mtype? 140 141 // Memory Attributes 142 bool shareable; 143 bool outerShareable; 144 145 // Access permissions 146 bool xn; // Execute Never 147 bool pxn; // Privileged Execute Never (LPAE only) 148 149 //Construct an entry that maps to physical address addr for SE mode 150 TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr, 151 bool uncacheable, bool read_only) : 152 pfn(_paddr >> PageShift), size(PageBytes - 1), vpn(_vaddr >> PageShift), 153 attributes(0), lookupLevel(L1), asid(_asn), vmid(0), N(0), 154 innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3), 155 domain(DomainType::Client), mtype(MemoryType::StronglyOrdered), 156 longDescFormat(false), isHyp(false), global(false), valid(true), 157 ns(true), nstid(true), el(EL0), nonCacheable(uncacheable), 158 shareable(false), outerShareable(false), xn(0), pxn(0) 159 { 160 // no restrictions by default, hap = 0x3 161 162 // @todo Check the memory type 163 if (read_only) 164 warn("ARM TlbEntry does not support read-only mappings\n"); 165 } 166 167 TlbEntry() : 168 pfn(0), size(0), vpn(0), attributes(0), lookupLevel(L1), asid(0), 169 vmid(0), N(0), innerAttrs(0), outerAttrs(0), ap(0), hap(0x3), 170 domain(DomainType::Client), mtype(MemoryType::StronglyOrdered), 171 longDescFormat(false), isHyp(false), global(false), valid(false), 172 ns(true), nstid(true), el(EL0), nonCacheable(false), 173 shareable(false), outerShareable(false), xn(0), pxn(0) 174 { 175 // no restrictions by default, hap = 0x3 176 177 // @todo Check the memory type 178 } 179 180 void 181 updateVaddr(Addr new_vaddr) 182 { 183 vpn = new_vaddr >> PageShift; 184 } 185 186 Addr 187 pageStart() const 188 { 189 return pfn << PageShift; 190 } 191 192 bool 193 match(Addr va, uint8_t _vmid, bool hypLookUp, bool secure_lookup, 194 ExceptionLevel target_el) const 195 { 196 return match(va, 0, _vmid, hypLookUp, secure_lookup, true, target_el); 197 } 198 199 bool 200 match(Addr va, uint16_t asn, uint8_t _vmid, bool hypLookUp, 201 bool secure_lookup, bool ignore_asn, ExceptionLevel target_el) const 202 { 203 bool match = false; 204 Addr v = vpn << N; 205 206 if (valid && va >= v && va <= v + size && (secure_lookup == !nstid) && 207 (hypLookUp == isHyp)) 208 { 209 match = checkELMatch(target_el); 210 211 if (match && !ignore_asn) { 212 match = global || (asn == asid); 213 } 214 if (match && nstid) { 215 match = isHyp || (_vmid == vmid); 216 } 217 } 218 return match; 219 } 220 221 bool 222 checkELMatch(ExceptionLevel target_el) const 223 { 224 if (target_el == EL2 || target_el == EL3) { 225 return (el == target_el); 226 } else { 227 return (el == EL0) || (el == EL1); 228 } 229 } 230 231 Addr 232 pAddr(Addr va) const 233 { 234 return (pfn << N) | (va & size); 235 } 236 237 void 238 updateAttributes() 239 { 240 uint64_t mask; 241 uint64_t newBits; 242 243 // chec bit 11 to determine if its currently LPAE or VMSA format. 244 if ( attributes & (1 << 11) ) { 245 newBits = ((outerShareable ? 0x2 : 246 shareable ? 0x3 : 0) << 7); 247 mask = 0x180; 248 } else { 249 /** Formatting for Physical Address Register (PAR) 250 * Only including lower bits (TLB info here) 251 * PAR (32-bit format): 252 * PA [31:12] 253 * LPAE [11] (Large Physical Address Extension) 254 * TLB info [10:1] 255 * NOS [10] (Not Outer Sharable) 256 * NS [9] (Non-Secure) 257 * -- [8] (Implementation Defined) 258 * SH [7] (Sharable) 259 * Inner[6:4](Inner memory attributes) 260 * Outer[3:2](Outer memory attributes) 261 * SS [1] (SuperSection) 262 * F [0] (Fault, Fault Status in [6:1] if faulted) 263 */ 264 newBits = ((outerShareable ? 0:1) << 10) | 265 ((shareable ? 1:0) << 7) | 266 (innerAttrs << 4) | 267 (outerAttrs << 2); 268 // TODO: Supersection bit 269 mask = 0x4FC; 270 } 271 // common bits 272 newBits |= ns << 9; // NS bit 273 mask |= 1 << 9; 274 // add in the new bits 275 attributes &= ~mask; 276 attributes |= newBits; 277 } 278 279 void 280 setAttributes(bool lpae) 281 { 282 attributes = lpae ? (1 << 11) : 0; 283 updateAttributes(); 284 } 285 286 std::string 287 print() const 288 { 289 return csprintf("%#x, asn %d vmn %d hyp %d ppn %#x size: %#x ap:%d " 290 "ns:%d nstid:%d g:%d el:%d", vpn << N, asid, vmid, 291 isHyp, pfn << N, size, ap, ns, nstid, global, el); 292 } 293 294 void 295 serialize(CheckpointOut &cp) const override 296 { 297 SERIALIZE_SCALAR(longDescFormat); 298 SERIALIZE_SCALAR(pfn); 299 SERIALIZE_SCALAR(size); 300 SERIALIZE_SCALAR(vpn); 301 SERIALIZE_SCALAR(asid); 302 SERIALIZE_SCALAR(vmid); 303 SERIALIZE_SCALAR(isHyp); 304 SERIALIZE_SCALAR(N); 305 SERIALIZE_SCALAR(global); 306 SERIALIZE_SCALAR(valid); 307 SERIALIZE_SCALAR(ns); 308 SERIALIZE_SCALAR(nstid); 309 SERIALIZE_SCALAR(nonCacheable); 310 SERIALIZE_ENUM(lookupLevel); 311 SERIALIZE_ENUM(mtype); 312 SERIALIZE_SCALAR(innerAttrs); 313 SERIALIZE_SCALAR(outerAttrs); 314 SERIALIZE_SCALAR(shareable); 315 SERIALIZE_SCALAR(outerShareable); 316 SERIALIZE_SCALAR(attributes); 317 SERIALIZE_SCALAR(xn); 318 SERIALIZE_SCALAR(pxn); 319 SERIALIZE_SCALAR(ap); 320 SERIALIZE_SCALAR(hap); 321 uint8_t domain_ = static_cast<uint8_t>(domain); 322 paramOut(cp, "domain", domain_); 323 } 324 void 325 unserialize(CheckpointIn &cp) override 326 { 327 UNSERIALIZE_SCALAR(longDescFormat); 328 UNSERIALIZE_SCALAR(pfn); 329 UNSERIALIZE_SCALAR(size); 330 UNSERIALIZE_SCALAR(vpn); 331 UNSERIALIZE_SCALAR(asid); 332 UNSERIALIZE_SCALAR(vmid); 333 UNSERIALIZE_SCALAR(isHyp); 334 UNSERIALIZE_SCALAR(N); 335 UNSERIALIZE_SCALAR(global); 336 UNSERIALIZE_SCALAR(valid); 337 UNSERIALIZE_SCALAR(ns); 338 UNSERIALIZE_SCALAR(nstid); 339 UNSERIALIZE_SCALAR(nonCacheable); 340 UNSERIALIZE_ENUM(lookupLevel); 341 UNSERIALIZE_ENUM(mtype); 342 UNSERIALIZE_SCALAR(innerAttrs); 343 UNSERIALIZE_SCALAR(outerAttrs); 344 UNSERIALIZE_SCALAR(shareable); 345 UNSERIALIZE_SCALAR(outerShareable); 346 UNSERIALIZE_SCALAR(attributes); 347 UNSERIALIZE_SCALAR(xn); 348 UNSERIALIZE_SCALAR(pxn); 349 UNSERIALIZE_SCALAR(ap); 350 UNSERIALIZE_SCALAR(hap); 351 uint8_t domain_; 352 paramIn(cp, "domain", domain_); 353 domain = static_cast<DomainType>(domain_); 354 } 355 356}; 357 358 359 360} 361#endif // __ARCH_ARM_PAGETABLE_H__ 362 363