table_walker.hh revision 7437:5853fbdfba9b
13062Sgblack@eecs.umich.edu/* 23062Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited 33062Sgblack@eecs.umich.edu * All rights reserved 43062Sgblack@eecs.umich.edu * 53062Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 63062Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 73062Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 83062Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 93062Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 103062Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 113062Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 123062Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 133062Sgblack@eecs.umich.edu * 143062Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 153062Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 163062Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 173062Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 183062Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 193062Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 203062Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 213062Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 223062Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 233062Sgblack@eecs.umich.edu * this software without specific prior written permission. 243062Sgblack@eecs.umich.edu * 253062Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 263062Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 273062Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 283062Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 293804Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 303062Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 313062Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 323062Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 333062Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 343062Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 353062Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 363062Sgblack@eecs.umich.edu * 373062Sgblack@eecs.umich.edu * Authors: Ali Saidi 383062Sgblack@eecs.umich.edu */ 393062Sgblack@eecs.umich.edu 403062Sgblack@eecs.umich.edu#ifndef __ARCH_ARM_TABLE_WALKER_HH__ 413062Sgblack@eecs.umich.edu#define __ARCH_ARM_TABLE_WALKER_HH__ 423062Sgblack@eecs.umich.edu 433062Sgblack@eecs.umich.edu#include "arch/arm/miscregs.hh" 443062Sgblack@eecs.umich.edu#include "arch/arm/tlb.hh" 453062Sgblack@eecs.umich.edu#include "mem/mem_object.hh" 463062Sgblack@eecs.umich.edu#include "mem/request.hh" 473062Sgblack@eecs.umich.edu#include "mem/request.hh" 483062Sgblack@eecs.umich.edu#include "params/ArmTableWalker.hh" 493062Sgblack@eecs.umich.edu#include "sim/faults.hh" 503062Sgblack@eecs.umich.edu#include "sim/eventq.hh" 513062Sgblack@eecs.umich.edu 523062Sgblack@eecs.umich.educlass DmaPort; 533062Sgblack@eecs.umich.educlass ThreadContext; 543062Sgblack@eecs.umich.edu 553062Sgblack@eecs.umich.edunamespace ArmISA { 563062Sgblack@eecs.umich.educlass Translation; 573804Ssaidi@eecs.umich.educlass TLB; 583804Ssaidi@eecs.umich.edu 593804Ssaidi@eecs.umich.educlass TableWalker : public MemObject 603804Ssaidi@eecs.umich.edu{ 613062Sgblack@eecs.umich.edu protected: 623062Sgblack@eecs.umich.edu struct L1Descriptor { 633062Sgblack@eecs.umich.edu /** Type of page table entry ARM DDI 0406B: B3-8*/ 643062Sgblack@eecs.umich.edu enum EntryType { 653062Sgblack@eecs.umich.edu Ignore, 663804Ssaidi@eecs.umich.edu PageTable, 673804Ssaidi@eecs.umich.edu Section, 683804Ssaidi@eecs.umich.edu Reserved 693804Ssaidi@eecs.umich.edu }; 703062Sgblack@eecs.umich.edu 713804Ssaidi@eecs.umich.edu /** The raw bits of the entry */ 723062Sgblack@eecs.umich.edu uint32_t data; 733062Sgblack@eecs.umich.edu 743062Sgblack@eecs.umich.edu /** This entry has been modified (access flag set) and needs to be 753062Sgblack@eecs.umich.edu * written back to memory */ 763804Ssaidi@eecs.umich.edu bool _dirty; 773062Sgblack@eecs.umich.edu 783804Ssaidi@eecs.umich.edu EntryType type() const 793804Ssaidi@eecs.umich.edu { 803062Sgblack@eecs.umich.edu return (EntryType)(data & 0x3); 813062Sgblack@eecs.umich.edu } 823804Ssaidi@eecs.umich.edu 833804Ssaidi@eecs.umich.edu /** Is the page a Supersection (16MB)?*/ 843062Sgblack@eecs.umich.edu bool supersection() const 853804Ssaidi@eecs.umich.edu { 863804Ssaidi@eecs.umich.edu return bits(data, 18); 873804Ssaidi@eecs.umich.edu } 883804Ssaidi@eecs.umich.edu 893804Ssaidi@eecs.umich.edu /** Return the physcal address of the entry, bits in position*/ 903804Ssaidi@eecs.umich.edu Addr paddr() const 913804Ssaidi@eecs.umich.edu { 923804Ssaidi@eecs.umich.edu if (supersection()) 933804Ssaidi@eecs.umich.edu panic("Super sections not implemented\n"); 943804Ssaidi@eecs.umich.edu return mbits(data, 31,20); 953804Ssaidi@eecs.umich.edu } 963062Sgblack@eecs.umich.edu 973062Sgblack@eecs.umich.edu /** Return the physical frame, bits shifted right */ 983062Sgblack@eecs.umich.edu Addr pfn() const 993062Sgblack@eecs.umich.edu { 1003804Ssaidi@eecs.umich.edu if (supersection()) 1013804Ssaidi@eecs.umich.edu panic("Super sections not implemented\n"); 1023804Ssaidi@eecs.umich.edu return bits(data, 31,20); 1033804Ssaidi@eecs.umich.edu } 1043804Ssaidi@eecs.umich.edu 1053804Ssaidi@eecs.umich.edu /** Is the translation global (no asid used)? */ 1063804Ssaidi@eecs.umich.edu bool global() const 1073804Ssaidi@eecs.umich.edu { 1083804Ssaidi@eecs.umich.edu return bits(data, 4); 1093804Ssaidi@eecs.umich.edu } 1103804Ssaidi@eecs.umich.edu 1113804Ssaidi@eecs.umich.edu /** Is the translation not allow execution? */ 1123804Ssaidi@eecs.umich.edu bool xn() const 1133804Ssaidi@eecs.umich.edu { 1143804Ssaidi@eecs.umich.edu return bits(data, 17); 1153804Ssaidi@eecs.umich.edu } 1163804Ssaidi@eecs.umich.edu 1173804Ssaidi@eecs.umich.edu /** Three bit access protection flags */ 1183804Ssaidi@eecs.umich.edu uint8_t ap() const 1193804Ssaidi@eecs.umich.edu { 1203804Ssaidi@eecs.umich.edu return (bits(data, 15) << 2) | bits(data,11,10); 1213804Ssaidi@eecs.umich.edu } 1223804Ssaidi@eecs.umich.edu 1233804Ssaidi@eecs.umich.edu /** Domain Client/Manager: ARM DDI 0406B: B3-31 */ 1243804Ssaidi@eecs.umich.edu uint8_t domain() const 1253804Ssaidi@eecs.umich.edu { 1263804Ssaidi@eecs.umich.edu return bits(data,8,5); 1273804Ssaidi@eecs.umich.edu } 1283804Ssaidi@eecs.umich.edu 1293804Ssaidi@eecs.umich.edu /** Address of L2 descriptor if it exists */ 1303804Ssaidi@eecs.umich.edu Addr l2Addr() const 1313804Ssaidi@eecs.umich.edu { 1323804Ssaidi@eecs.umich.edu return mbits(data, 31,10); 1333062Sgblack@eecs.umich.edu } 1343062Sgblack@eecs.umich.edu 1353804Ssaidi@eecs.umich.edu /** Memory region attributes: ARM DDI 0406B: B3-32. 1363804Ssaidi@eecs.umich.edu * These bits are largly ignored by M5 and only used to 1373062Sgblack@eecs.umich.edu * provide the illusion that the memory system cares about 1383804Ssaidi@eecs.umich.edu * anything but cachable vs. uncachable. 1393062Sgblack@eecs.umich.edu */ 1403062Sgblack@eecs.umich.edu uint8_t texcb() const 1413062Sgblack@eecs.umich.edu { 1423062Sgblack@eecs.umich.edu return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2; 1433804Ssaidi@eecs.umich.edu } 1443804Ssaidi@eecs.umich.edu 1453804Ssaidi@eecs.umich.edu /** If the section is shareable. See texcb() comment. */ 1463062Sgblack@eecs.umich.edu bool shareable() const 1473062Sgblack@eecs.umich.edu { 1483062Sgblack@eecs.umich.edu return bits(data, 16); 1493062Sgblack@eecs.umich.edu } 1503804Ssaidi@eecs.umich.edu 1513804Ssaidi@eecs.umich.edu /** Set access flag that this entry has been touched. Mark 1523062Sgblack@eecs.umich.edu * the entry as requiring a writeback, in the future. 1533804Ssaidi@eecs.umich.edu */ 1543804Ssaidi@eecs.umich.edu void setAp0() 1553804Ssaidi@eecs.umich.edu { 1563804Ssaidi@eecs.umich.edu data |= 1 << 10; 1573804Ssaidi@eecs.umich.edu _dirty = true; 1583804Ssaidi@eecs.umich.edu } 1593804Ssaidi@eecs.umich.edu 1603804Ssaidi@eecs.umich.edu /** This entry needs to be written back to memory */ 1613062Sgblack@eecs.umich.edu bool dirty() const 1623062Sgblack@eecs.umich.edu { 1633062Sgblack@eecs.umich.edu return _dirty; 1643062Sgblack@eecs.umich.edu } 1653062Sgblack@eecs.umich.edu }; 1663062Sgblack@eecs.umich.edu 1673062Sgblack@eecs.umich.edu /** Level 2 page table descriptor */ 1683062Sgblack@eecs.umich.edu struct L2Descriptor { 1693062Sgblack@eecs.umich.edu 1703062Sgblack@eecs.umich.edu /** The raw bits of the entry. */ 1713062Sgblack@eecs.umich.edu uint32_t data; 1723062Sgblack@eecs.umich.edu 1733062Sgblack@eecs.umich.edu /** This entry has been modified (access flag set) and needs to be 1743062Sgblack@eecs.umich.edu * written back to memory */ 1753062Sgblack@eecs.umich.edu bool _dirty; 1763062Sgblack@eecs.umich.edu 1773062Sgblack@eecs.umich.edu /** Is the entry invalid */ 1783062Sgblack@eecs.umich.edu bool invalid() const 1793062Sgblack@eecs.umich.edu { 1803062Sgblack@eecs.umich.edu return bits(data, 1,0) == 0;; 1813062Sgblack@eecs.umich.edu } 1823062Sgblack@eecs.umich.edu 1833062Sgblack@eecs.umich.edu /** What is the size of the mapping? */ 1843062Sgblack@eecs.umich.edu bool large() const 1853062Sgblack@eecs.umich.edu { 1863062Sgblack@eecs.umich.edu return bits(data, 1) == 0; 1873062Sgblack@eecs.umich.edu } 1883062Sgblack@eecs.umich.edu 1893062Sgblack@eecs.umich.edu /** Is execution allowed on this mapping? */ 1903063Sgblack@eecs.umich.edu bool xn() const 1913062Sgblack@eecs.umich.edu { 1923062Sgblack@eecs.umich.edu return large() ? bits(data, 15) : bits(data, 0); 1933063Sgblack@eecs.umich.edu } 1943062Sgblack@eecs.umich.edu 1953062Sgblack@eecs.umich.edu /** Is the translation global (no asid used)? */ 1963062Sgblack@eecs.umich.edu bool global() const 1973062Sgblack@eecs.umich.edu { 1983062Sgblack@eecs.umich.edu return !bits(data, 11); 1993062Sgblack@eecs.umich.edu } 2003062Sgblack@eecs.umich.edu 2013062Sgblack@eecs.umich.edu /** Three bit access protection flags */ 2023062Sgblack@eecs.umich.edu uint8_t ap() const 2033062Sgblack@eecs.umich.edu { 2043062Sgblack@eecs.umich.edu return bits(data, 5, 4) | (bits(data, 9) << 2); 2053062Sgblack@eecs.umich.edu } 2063123Sgblack@eecs.umich.edu 2073123Sgblack@eecs.umich.edu /** Memory region attributes: ARM DDI 0406B: B3-32 */ 2083123Sgblack@eecs.umich.edu uint8_t texcb() const 2093123Sgblack@eecs.umich.edu { 2103123Sgblack@eecs.umich.edu return large() ? 2113123Sgblack@eecs.umich.edu (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 14, 12) << 2)) : 2123123Sgblack@eecs.umich.edu (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 8, 6) << 2)); 2133123Sgblack@eecs.umich.edu } 2143062Sgblack@eecs.umich.edu 2153123Sgblack@eecs.umich.edu /** Return the physical frame, bits shifted right */ 2163123Sgblack@eecs.umich.edu Addr pfn() const 2173123Sgblack@eecs.umich.edu { 2183123Sgblack@eecs.umich.edu return large() ? bits(data, 31, 16) : bits(data, 31, 12); 2193123Sgblack@eecs.umich.edu } 2203123Sgblack@eecs.umich.edu 2213123Sgblack@eecs.umich.edu /** If the section is shareable. See texcb() comment. */ 2223123Sgblack@eecs.umich.edu bool shareable() const 2233062Sgblack@eecs.umich.edu { 2243062Sgblack@eecs.umich.edu return bits(data, 10); 2253062Sgblack@eecs.umich.edu } 2263062Sgblack@eecs.umich.edu 2273062Sgblack@eecs.umich.edu /** Set access flag that this entry has been touched. Mark 2283062Sgblack@eecs.umich.edu * the entry as requiring a writeback, in the future. 2293062Sgblack@eecs.umich.edu */ 2303062Sgblack@eecs.umich.edu void setAp0() 2313062Sgblack@eecs.umich.edu { 2323062Sgblack@eecs.umich.edu data |= 1 << 4; 2333062Sgblack@eecs.umich.edu _dirty = true; 2343062Sgblack@eecs.umich.edu } 2353062Sgblack@eecs.umich.edu 2363062Sgblack@eecs.umich.edu /** This entry needs to be written back to memory */ 2373062Sgblack@eecs.umich.edu bool dirty() const 2383062Sgblack@eecs.umich.edu { 2393062Sgblack@eecs.umich.edu return _dirty; 2403062Sgblack@eecs.umich.edu } 2413062Sgblack@eecs.umich.edu 2423062Sgblack@eecs.umich.edu }; 2433123Sgblack@eecs.umich.edu 2443062Sgblack@eecs.umich.edu /** Port to issue translation requests from */ 2453804Ssaidi@eecs.umich.edu DmaPort *port; 2463123Sgblack@eecs.umich.edu 2473062Sgblack@eecs.umich.edu /** TLB that is initiating these table walks */ 2483123Sgblack@eecs.umich.edu TLB *tlb; 2493123Sgblack@eecs.umich.edu 2503123Sgblack@eecs.umich.edu /** Thread context that we're doing the walk for */ 2513123Sgblack@eecs.umich.edu ThreadContext *tc; 2523123Sgblack@eecs.umich.edu 2533123Sgblack@eecs.umich.edu /** Request that is currently being serviced */ 2543123Sgblack@eecs.umich.edu RequestPtr req; 2553123Sgblack@eecs.umich.edu 2563123Sgblack@eecs.umich.edu /** Context ID that we're servicing the request under */ 2573123Sgblack@eecs.umich.edu uint8_t contextId; 2583123Sgblack@eecs.umich.edu 2593123Sgblack@eecs.umich.edu /** Translation state for delayed requests */ 2603123Sgblack@eecs.umich.edu TLB::Translation *transState; 2613123Sgblack@eecs.umich.edu 2623123Sgblack@eecs.umich.edu /** The fault that we are going to return */ 2633123Sgblack@eecs.umich.edu Fault fault; 2643123Sgblack@eecs.umich.edu 2653123Sgblack@eecs.umich.edu /** The virtual address that is being translated */ 2663123Sgblack@eecs.umich.edu Addr vaddr; 2673804Ssaidi@eecs.umich.edu 2683804Ssaidi@eecs.umich.edu /** Cached copy of the sctlr as it existed when translation began */ 2693804Ssaidi@eecs.umich.edu SCTLR sctlr; 2703804Ssaidi@eecs.umich.edu 2713123Sgblack@eecs.umich.edu /** Cached copy of the cpsr as it existed when the translation began */ 2723062Sgblack@eecs.umich.edu CPSR cpsr; 2733062Sgblack@eecs.umich.edu 2743519Sgblack@eecs.umich.edu /** Width of the base address held in TTRB0 */ 275 uint32_t N; 276 277 /** If the access is a write */ 278 bool isWrite; 279 280 /** If the access is not from user mode */ 281 bool isPriv; 282 283 /** If the access is a fetch (for execution, and no-exec) must be checked?*/ 284 bool isFetch; 285 286 /** If the mode is timing or atomic */ 287 bool timing; 288 289 L1Descriptor l1Desc; 290 L2Descriptor l2Desc; 291 292 /** Save mode for use in delayed response */ 293 BaseTLB::Mode mode; 294 295 /** Whether L1/L2 descriptor response is delayed in timing mode */ 296 bool delayed; 297 298 public: 299 typedef ArmTableWalkerParams Params; 300 TableWalker(const Params *p); 301 virtual ~TableWalker(); 302 303 const Params * 304 params() const 305 { 306 return dynamic_cast<const Params *>(_params); 307 } 308 309 virtual unsigned int drain(Event *de) { panic("write me\n"); } 310 virtual Port *getPort(const std::string &if_name, int idx = -1); 311 312 Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, 313 TLB::Translation *_trans, bool timing); 314 315 void setTlb(TLB *_tlb) { tlb = _tlb; } 316 void memAttrs(TlbEntry &te, uint8_t texcb, bool s); 317 318 private: 319 320 void doL1Descriptor(); 321 void doL1DescriptorWrapper(); 322 EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent; 323 324 void doL2Descriptor(); 325 void doL2DescriptorWrapper(); 326 EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent; 327 328 329}; 330 331 332} // namespace ArmISA 333 334#endif //__ARCH_ARM_TABLE_WALKER_HH__ 335 336