table_walker.hh revision 7406
17404SAli.Saidi@ARM.com/* 27404SAli.Saidi@ARM.com * Copyright (c) 2010 ARM Limited 37404SAli.Saidi@ARM.com * All rights reserved 47404SAli.Saidi@ARM.com * 57404SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 67404SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 77404SAli.Saidi@ARM.com * property including but not limited to intellectual property relating 87404SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software 97404SAli.Saidi@ARM.com * licensed hereunder. You may use the software subject to the license 107404SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated 117404SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software, 127404SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 137404SAli.Saidi@ARM.com * 147404SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 157404SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 167404SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 177404SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 187404SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 197404SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 207404SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 217404SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 227404SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 237404SAli.Saidi@ARM.com * this software without specific prior written permission. 247404SAli.Saidi@ARM.com * 257404SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 267404SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277404SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 287404SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297404SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307404SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 317404SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 327404SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337404SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 347404SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 357404SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367404SAli.Saidi@ARM.com * 377404SAli.Saidi@ARM.com * Authors: Ali Saidi 387404SAli.Saidi@ARM.com */ 397404SAli.Saidi@ARM.com 407404SAli.Saidi@ARM.com#ifndef __ARCH_ARM_TABLE_WALKER_HH__ 417404SAli.Saidi@ARM.com#define __ARCH_ARM_TABLE_WALKER_HH__ 427404SAli.Saidi@ARM.com 437404SAli.Saidi@ARM.com#include "arch/arm/miscregs.hh" 447404SAli.Saidi@ARM.com#include "arch/arm/tlb.hh" 457404SAli.Saidi@ARM.com#include "mem/mem_object.hh" 467404SAli.Saidi@ARM.com#include "mem/request.hh" 477404SAli.Saidi@ARM.com#include "mem/request.hh" 487404SAli.Saidi@ARM.com#include "params/ArmTableWalker.hh" 497404SAli.Saidi@ARM.com#include "sim/faults.hh" 507404SAli.Saidi@ARM.com#include "sim/eventq.hh" 517404SAli.Saidi@ARM.com 527404SAli.Saidi@ARM.comclass DmaPort; 537404SAli.Saidi@ARM.comclass ThreadContext; 547404SAli.Saidi@ARM.com 557404SAli.Saidi@ARM.comnamespace ArmISA { 567404SAli.Saidi@ARM.comclass Translation; 577404SAli.Saidi@ARM.comclass TLB; 587404SAli.Saidi@ARM.com 597404SAli.Saidi@ARM.comclass TableWalker : public MemObject 607404SAli.Saidi@ARM.com{ 617404SAli.Saidi@ARM.com protected: 627404SAli.Saidi@ARM.com struct L1Descriptor { 637404SAli.Saidi@ARM.com /** Type of page table entry ARM DDI 0406B: B3-8*/ 647404SAli.Saidi@ARM.com enum EntryType { 657404SAli.Saidi@ARM.com Ignore, 667404SAli.Saidi@ARM.com PageTable, 677404SAli.Saidi@ARM.com Section, 687404SAli.Saidi@ARM.com Reserved 697404SAli.Saidi@ARM.com }; 707404SAli.Saidi@ARM.com 717404SAli.Saidi@ARM.com uint32_t data; 727404SAli.Saidi@ARM.com 737404SAli.Saidi@ARM.com EntryType type() const 747404SAli.Saidi@ARM.com { 757404SAli.Saidi@ARM.com return (EntryType)(data & 0x3); 767404SAli.Saidi@ARM.com } 777404SAli.Saidi@ARM.com 787404SAli.Saidi@ARM.com /** Is the page a Supersection (16MB)?*/ 797404SAli.Saidi@ARM.com bool supersection() const 807404SAli.Saidi@ARM.com { 817404SAli.Saidi@ARM.com return bits(data, 18); 827404SAli.Saidi@ARM.com } 837404SAli.Saidi@ARM.com 847404SAli.Saidi@ARM.com /** Return the physcal address of the entry, bits in position*/ 857404SAli.Saidi@ARM.com Addr paddr() const 867404SAli.Saidi@ARM.com { 877404SAli.Saidi@ARM.com if (supersection()) 887404SAli.Saidi@ARM.com panic("Super sections not implemented\n"); 897404SAli.Saidi@ARM.com return mbits(data, 31,20); 907404SAli.Saidi@ARM.com } 917404SAli.Saidi@ARM.com 927404SAli.Saidi@ARM.com /** Return the physical frame, bits shifted right */ 937404SAli.Saidi@ARM.com Addr pfn() const 947404SAli.Saidi@ARM.com { 957404SAli.Saidi@ARM.com if (supersection()) 967404SAli.Saidi@ARM.com panic("Super sections not implemented\n"); 977404SAli.Saidi@ARM.com return bits(data, 31,20); 987404SAli.Saidi@ARM.com } 997404SAli.Saidi@ARM.com 1007404SAli.Saidi@ARM.com /** Is the translation global (no asid used)? */ 1017404SAli.Saidi@ARM.com bool global() const 1027404SAli.Saidi@ARM.com { 1037406SAli.Saidi@ARM.com return bits(data, 4); 1047404SAli.Saidi@ARM.com } 1057404SAli.Saidi@ARM.com 1067404SAli.Saidi@ARM.com /** Is the translation not allow execution? */ 1077404SAli.Saidi@ARM.com bool xn() const 1087404SAli.Saidi@ARM.com { 1097404SAli.Saidi@ARM.com return bits(data, 17); 1107404SAli.Saidi@ARM.com } 1117404SAli.Saidi@ARM.com 1127404SAli.Saidi@ARM.com /** Three bit access protection flags */ 1137404SAli.Saidi@ARM.com uint8_t ap() const 1147404SAli.Saidi@ARM.com { 1157404SAli.Saidi@ARM.com return (bits(data, 15) << 2) | bits(data,11,10); 1167404SAli.Saidi@ARM.com } 1177404SAli.Saidi@ARM.com 1187404SAli.Saidi@ARM.com /** Domain Client/Manager: ARM DDI 0406B: B3-31 */ 1197404SAli.Saidi@ARM.com uint8_t domain() const 1207404SAli.Saidi@ARM.com { 1217404SAli.Saidi@ARM.com return bits(data,8,5); 1227404SAli.Saidi@ARM.com } 1237404SAli.Saidi@ARM.com 1247404SAli.Saidi@ARM.com /** Address of L2 descriptor if it exists */ 1257404SAli.Saidi@ARM.com Addr l2Addr() const 1267404SAli.Saidi@ARM.com { 1277404SAli.Saidi@ARM.com return mbits(data, 31,10); 1287404SAli.Saidi@ARM.com } 1297404SAli.Saidi@ARM.com 1307404SAli.Saidi@ARM.com /** Memory region attributes: ARM DDI 0406B: B3-32 */ 1317404SAli.Saidi@ARM.com uint8_t texcb() const 1327404SAli.Saidi@ARM.com { 1337406SAli.Saidi@ARM.com return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2; 1347404SAli.Saidi@ARM.com } 1357404SAli.Saidi@ARM.com 1367404SAli.Saidi@ARM.com }; 1377404SAli.Saidi@ARM.com 1387404SAli.Saidi@ARM.com /** Level 2 page table descriptor */ 1397404SAli.Saidi@ARM.com struct L2Descriptor { 1407404SAli.Saidi@ARM.com 1417404SAli.Saidi@ARM.com uint32_t data; 1427404SAli.Saidi@ARM.com 1437404SAli.Saidi@ARM.com /** Is the entry invalid */ 1447404SAli.Saidi@ARM.com bool invalid() const 1457404SAli.Saidi@ARM.com { 1467404SAli.Saidi@ARM.com return bits(data, 1,0) == 0;; 1477404SAli.Saidi@ARM.com } 1487404SAli.Saidi@ARM.com 1497404SAli.Saidi@ARM.com /** What is the size of the mapping? */ 1507404SAli.Saidi@ARM.com bool large() const 1517404SAli.Saidi@ARM.com { 1527404SAli.Saidi@ARM.com return bits(data, 1) == 0; 1537404SAli.Saidi@ARM.com } 1547404SAli.Saidi@ARM.com 1557404SAli.Saidi@ARM.com /** Is execution allowed on this mapping? */ 1567404SAli.Saidi@ARM.com bool xn() const 1577404SAli.Saidi@ARM.com { 1587404SAli.Saidi@ARM.com return large() ? bits(data, 15) : bits(data, 0); 1597404SAli.Saidi@ARM.com } 1607404SAli.Saidi@ARM.com 1617404SAli.Saidi@ARM.com /** Is the translation global (no asid used)? */ 1627404SAli.Saidi@ARM.com bool global() const 1637404SAli.Saidi@ARM.com { 1647404SAli.Saidi@ARM.com return !bits(data, 11); 1657404SAli.Saidi@ARM.com } 1667404SAli.Saidi@ARM.com 1677404SAli.Saidi@ARM.com /** Three bit access protection flags */ 1687404SAli.Saidi@ARM.com uint8_t ap() const 1697404SAli.Saidi@ARM.com { 1707404SAli.Saidi@ARM.com return bits(data, 5, 4) | (bits(data, 9) << 2); 1717404SAli.Saidi@ARM.com } 1727404SAli.Saidi@ARM.com 1737404SAli.Saidi@ARM.com /** Memory region attributes: ARM DDI 0406B: B3-32 */ 1747404SAli.Saidi@ARM.com uint8_t texcb() const 1757404SAli.Saidi@ARM.com { 1767404SAli.Saidi@ARM.com return large() ? 1777406SAli.Saidi@ARM.com (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 14, 12) << 2)) : 1787406SAli.Saidi@ARM.com (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 8, 6) << 2)); 1797404SAli.Saidi@ARM.com } 1807404SAli.Saidi@ARM.com 1817404SAli.Saidi@ARM.com /** Return the physical frame, bits shifted right */ 1827404SAli.Saidi@ARM.com Addr pfn() const 1837404SAli.Saidi@ARM.com { 1847404SAli.Saidi@ARM.com return large() ? bits(data, 31, 16) : bits(data, 31, 12); 1857404SAli.Saidi@ARM.com } 1867404SAli.Saidi@ARM.com 1877404SAli.Saidi@ARM.com }; 1887404SAli.Saidi@ARM.com 1897404SAli.Saidi@ARM.com /** Port to issue translation requests from */ 1907404SAli.Saidi@ARM.com DmaPort *port; 1917404SAli.Saidi@ARM.com 1927404SAli.Saidi@ARM.com /** TLB that is initiating these table walks */ 1937404SAli.Saidi@ARM.com TLB *tlb; 1947404SAli.Saidi@ARM.com 1957404SAli.Saidi@ARM.com /** Thread context that we're doing the walk for */ 1967404SAli.Saidi@ARM.com ThreadContext *tc; 1977404SAli.Saidi@ARM.com 1987404SAli.Saidi@ARM.com /** Request that is currently being serviced */ 1997404SAli.Saidi@ARM.com RequestPtr req; 2007404SAli.Saidi@ARM.com 2017404SAli.Saidi@ARM.com /** Context ID that we're servicing the request under */ 2027404SAli.Saidi@ARM.com uint8_t contextId; 2037404SAli.Saidi@ARM.com 2047404SAli.Saidi@ARM.com /** Translation state for delayed requests */ 2057404SAli.Saidi@ARM.com TLB::Translation *transState; 2067404SAli.Saidi@ARM.com 2077404SAli.Saidi@ARM.com /** The fault that we are going to return */ 2087404SAli.Saidi@ARM.com Fault fault; 2097404SAli.Saidi@ARM.com 2107404SAli.Saidi@ARM.com /** The virtual address that is being translated */ 2117404SAli.Saidi@ARM.com Addr vaddr; 2127404SAli.Saidi@ARM.com 2137404SAli.Saidi@ARM.com /** Cached copy of the sctlr as it existed when translation began */ 2147404SAli.Saidi@ARM.com SCTLR sctlr; 2157404SAli.Saidi@ARM.com 2167404SAli.Saidi@ARM.com /** Cached copy of the cpsr as it existed when the translation began */ 2177404SAli.Saidi@ARM.com CPSR cpsr; 2187404SAli.Saidi@ARM.com 2197404SAli.Saidi@ARM.com /** Width of the base address held in TTRB0 */ 2207404SAli.Saidi@ARM.com uint32_t N; 2217404SAli.Saidi@ARM.com 2227404SAli.Saidi@ARM.com /** If the access is a write */ 2237404SAli.Saidi@ARM.com bool isWrite; 2247404SAli.Saidi@ARM.com 2257404SAli.Saidi@ARM.com /** If the access is not from user mode */ 2267404SAli.Saidi@ARM.com bool isPriv; 2277404SAli.Saidi@ARM.com 2287404SAli.Saidi@ARM.com /** If the access is a fetch (for execution, and no-exec) must be checked?*/ 2297404SAli.Saidi@ARM.com bool isFetch; 2307404SAli.Saidi@ARM.com 2317404SAli.Saidi@ARM.com /** If the mode is timing or atomic */ 2327404SAli.Saidi@ARM.com bool timing; 2337404SAli.Saidi@ARM.com 2347404SAli.Saidi@ARM.com L1Descriptor l1Desc; 2357404SAli.Saidi@ARM.com L2Descriptor l2Desc; 2367404SAli.Saidi@ARM.com 2377404SAli.Saidi@ARM.com public: 2387404SAli.Saidi@ARM.com typedef ArmTableWalkerParams Params; 2397404SAli.Saidi@ARM.com TableWalker(const Params *p); 2407404SAli.Saidi@ARM.com virtual ~TableWalker(); 2417404SAli.Saidi@ARM.com 2427404SAli.Saidi@ARM.com const Params * 2437404SAli.Saidi@ARM.com params() const 2447404SAli.Saidi@ARM.com { 2457404SAli.Saidi@ARM.com return dynamic_cast<const Params *>(_params); 2467404SAli.Saidi@ARM.com } 2477404SAli.Saidi@ARM.com 2487404SAli.Saidi@ARM.com virtual unsigned int drain(Event *de) { panic("write me\n"); } 2497404SAli.Saidi@ARM.com virtual Port *getPort(const std::string &if_name, int idx = -1); 2507404SAli.Saidi@ARM.com 2517404SAli.Saidi@ARM.com Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, 2527404SAli.Saidi@ARM.com TLB::Translation *_trans, bool timing); 2537404SAli.Saidi@ARM.com 2547404SAli.Saidi@ARM.com void setTlb(TLB *_tlb) { tlb = _tlb; } 2557404SAli.Saidi@ARM.com 2567404SAli.Saidi@ARM.com private: 2577404SAli.Saidi@ARM.com void memAttrs(TlbEntry &te, uint8_t texcb); 2587404SAli.Saidi@ARM.com 2597404SAli.Saidi@ARM.com void doL1Descriptor(); 2607404SAli.Saidi@ARM.com EventWrapper<TableWalker, &TableWalker::doL1Descriptor> doL1DescEvent; 2617404SAli.Saidi@ARM.com 2627404SAli.Saidi@ARM.com void doL2Descriptor(); 2637404SAli.Saidi@ARM.com EventWrapper<TableWalker, &TableWalker::doL2Descriptor> doL2DescEvent; 2647404SAli.Saidi@ARM.com 2657404SAli.Saidi@ARM.com 2667404SAli.Saidi@ARM.com}; 2677404SAli.Saidi@ARM.com 2687404SAli.Saidi@ARM.com 2697404SAli.Saidi@ARM.com} // namespace ArmISA 2707404SAli.Saidi@ARM.com 2717404SAli.Saidi@ARM.com#endif //__ARCH_ARM_TABLE_WALKER_HH__ 2727404SAli.Saidi@ARM.com 273