table_walker.hh revision 7439
17404SAli.Saidi@ARM.com/* 210717Sandreas.hansson@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 3810037SARM gem5 Developers */ 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" 447578Sdam.sunwoo@arm.com#include "arch/arm/tlb.hh" 457578Sdam.sunwoo@arm.com#include "mem/mem_object.hh" 467404SAli.Saidi@ARM.com#include "mem/request.hh" 4710037SARM gem5 Developers#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#include "base/fifo_buffer.hh" 527404SAli.Saidi@ARM.com 537404SAli.Saidi@ARM.comclass DmaPort; 547404SAli.Saidi@ARM.comclass ThreadContext; 5510873Sandreas.sandberg@arm.com 5610873Sandreas.sandberg@arm.comnamespace ArmISA { 577404SAli.Saidi@ARM.comclass Translation; 587404SAli.Saidi@ARM.comclass TLB; 597404SAli.Saidi@ARM.com 6010037SARM gem5 Developersclass TableWalker : public MemObject 617404SAli.Saidi@ARM.com{ 627404SAli.Saidi@ARM.com protected: 637404SAli.Saidi@ARM.com struct L1Descriptor { 647694SAli.Saidi@ARM.com /** Type of page table entry ARM DDI 0406B: B3-8*/ 6510037SARM gem5 Developers enum EntryType { 6610037SARM gem5 Developers Ignore, 6710037SARM gem5 Developers PageTable, 6810037SARM gem5 Developers Section, 6910037SARM gem5 Developers Reserved 7010037SARM gem5 Developers }; 7110037SARM gem5 Developers 7210037SARM gem5 Developers /** The raw bits of the entry */ 7310037SARM gem5 Developers uint32_t data; 7410037SARM gem5 Developers 7510037SARM gem5 Developers /** This entry has been modified (access flag set) and needs to be 7610037SARM gem5 Developers * written back to memory */ 7710037SARM gem5 Developers bool _dirty; 7810037SARM gem5 Developers 7910037SARM gem5 Developers EntryType type() const 8010037SARM gem5 Developers { 8110037SARM gem5 Developers return (EntryType)(data & 0x3); 8210037SARM gem5 Developers } 8310037SARM gem5 Developers 8410037SARM gem5 Developers /** Is the page a Supersection (16MB)?*/ 8510037SARM gem5 Developers bool supersection() const 8610037SARM gem5 Developers { 8710037SARM gem5 Developers return bits(data, 18); 8810037SARM gem5 Developers } 8910037SARM gem5 Developers 9010037SARM gem5 Developers /** Return the physcal address of the entry, bits in position*/ 9110037SARM gem5 Developers Addr paddr() const 9210037SARM gem5 Developers { 937404SAli.Saidi@ARM.com if (supersection()) 947404SAli.Saidi@ARM.com panic("Super sections not implemented\n"); 957404SAli.Saidi@ARM.com return mbits(data, 31,20); 967404SAli.Saidi@ARM.com } 977404SAli.Saidi@ARM.com 987404SAli.Saidi@ARM.com /** Return the physical frame, bits shifted right */ 997404SAli.Saidi@ARM.com Addr pfn() const 1007404SAli.Saidi@ARM.com { 1017436Sdam.sunwoo@arm.com if (supersection()) 1027404SAli.Saidi@ARM.com panic("Super sections not implemented\n"); 1037404SAli.Saidi@ARM.com return bits(data, 31,20); 1047436Sdam.sunwoo@arm.com } 1057436Sdam.sunwoo@arm.com 1067436Sdam.sunwoo@arm.com /** Is the translation global (no asid used)? */ 1077436Sdam.sunwoo@arm.com bool global() const 10810037SARM gem5 Developers { 10910537Sandreas.hansson@arm.com return bits(data, 4); 11010037SARM gem5 Developers } 11110037SARM gem5 Developers 11210037SARM gem5 Developers /** Is the translation not allow execution? */ 11310037SARM gem5 Developers bool xn() const 11410037SARM gem5 Developers { 11510037SARM gem5 Developers return bits(data, 17); 11610037SARM gem5 Developers } 11710037SARM gem5 Developers 11810037SARM gem5 Developers /** Three bit access protection flags */ 11910037SARM gem5 Developers uint8_t ap() const 12010037SARM gem5 Developers { 12110037SARM gem5 Developers return (bits(data, 15) << 2) | bits(data,11,10); 12210037SARM gem5 Developers } 12310037SARM gem5 Developers 12410037SARM gem5 Developers /** Domain Client/Manager: ARM DDI 0406B: B3-31 */ 12510037SARM gem5 Developers uint8_t domain() const 12610037SARM gem5 Developers { 12710037SARM gem5 Developers return bits(data,8,5); 12810037SARM gem5 Developers } 1297404SAli.Saidi@ARM.com 1307404SAli.Saidi@ARM.com /** Address of L2 descriptor if it exists */ 1317404SAli.Saidi@ARM.com Addr l2Addr() const 1327404SAli.Saidi@ARM.com { 1337404SAli.Saidi@ARM.com return mbits(data, 31,10); 1347404SAli.Saidi@ARM.com } 1357404SAli.Saidi@ARM.com 1367404SAli.Saidi@ARM.com /** Memory region attributes: ARM DDI 0406B: B3-32. 1377404SAli.Saidi@ARM.com * These bits are largly ignored by M5 and only used to 1387404SAli.Saidi@ARM.com * provide the illusion that the memory system cares about 1397404SAli.Saidi@ARM.com * anything but cachable vs. uncachable. 1407404SAli.Saidi@ARM.com */ 1417404SAli.Saidi@ARM.com uint8_t texcb() const 1427404SAli.Saidi@ARM.com { 1437404SAli.Saidi@ARM.com return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2; 1447404SAli.Saidi@ARM.com } 1457946SGiacomo.Gabrielli@arm.com 1467404SAli.Saidi@ARM.com /** If the section is shareable. See texcb() comment. */ 1477694SAli.Saidi@ARM.com bool shareable() const 1487694SAli.Saidi@ARM.com { 1497694SAli.Saidi@ARM.com return bits(data, 16); 1507694SAli.Saidi@ARM.com } 1517694SAli.Saidi@ARM.com 1527946SGiacomo.Gabrielli@arm.com /** Set access flag that this entry has been touched. Mark 1537694SAli.Saidi@ARM.com * the entry as requiring a writeback, in the future. 1547694SAli.Saidi@ARM.com */ 1557404SAli.Saidi@ARM.com void setAp0() 1567404SAli.Saidi@ARM.com { 1577404SAli.Saidi@ARM.com data |= 1 << 10; 1587404SAli.Saidi@ARM.com _dirty = true; 1597404SAli.Saidi@ARM.com } 1607404SAli.Saidi@ARM.com 1617946SGiacomo.Gabrielli@arm.com /** This entry needs to be written back to memory */ 1627404SAli.Saidi@ARM.com bool dirty() const 1637404SAli.Saidi@ARM.com { 1647404SAli.Saidi@ARM.com return _dirty; 16510037SARM gem5 Developers } 1667404SAli.Saidi@ARM.com }; 16710037SARM gem5 Developers 1687404SAli.Saidi@ARM.com /** Level 2 page table descriptor */ 1697404SAli.Saidi@ARM.com struct L2Descriptor { 1707404SAli.Saidi@ARM.com 1717404SAli.Saidi@ARM.com /** The raw bits of the entry. */ 1727404SAli.Saidi@ARM.com uint32_t data; 1737608SGene.Wu@arm.com 1747404SAli.Saidi@ARM.com /** This entry has been modified (access flag set) and needs to be 1757404SAli.Saidi@ARM.com * written back to memory */ 1767404SAli.Saidi@ARM.com bool _dirty; 1777404SAli.Saidi@ARM.com 1787404SAli.Saidi@ARM.com /** Is the entry invalid */ 1797946SGiacomo.Gabrielli@arm.com bool invalid() const 1807404SAli.Saidi@ARM.com { 1817404SAli.Saidi@ARM.com return bits(data, 1,0) == 0;; 1827404SAli.Saidi@ARM.com } 18310037SARM gem5 Developers 1847404SAli.Saidi@ARM.com /** What is the size of the mapping? */ 18510037SARM gem5 Developers bool large() const 1867404SAli.Saidi@ARM.com { 1877404SAli.Saidi@ARM.com return bits(data, 1) == 0; 1887404SAli.Saidi@ARM.com } 1897404SAli.Saidi@ARM.com 1907404SAli.Saidi@ARM.com /** Is execution allowed on this mapping? */ 1917946SGiacomo.Gabrielli@arm.com bool xn() const 1927404SAli.Saidi@ARM.com { 1937404SAli.Saidi@ARM.com return large() ? bits(data, 15) : bits(data, 0); 1947436Sdam.sunwoo@arm.com } 1957436Sdam.sunwoo@arm.com 1967436Sdam.sunwoo@arm.com /** Is the translation global (no asid used)? */ 1977436Sdam.sunwoo@arm.com bool global() const 1987436Sdam.sunwoo@arm.com { 1997404SAli.Saidi@ARM.com return !bits(data, 11); 2007404SAli.Saidi@ARM.com } 2017946SGiacomo.Gabrielli@arm.com 2027404SAli.Saidi@ARM.com /** Three bit access protection flags */ 2037404SAli.Saidi@ARM.com uint8_t ap() const 2047436Sdam.sunwoo@arm.com { 2057436Sdam.sunwoo@arm.com return bits(data, 5, 4) | (bits(data, 9) << 2); 2067436Sdam.sunwoo@arm.com } 2077436Sdam.sunwoo@arm.com 2087436Sdam.sunwoo@arm.com /** Memory region attributes: ARM DDI 0406B: B3-32 */ 2097436Sdam.sunwoo@arm.com uint8_t texcb() const 2107436Sdam.sunwoo@arm.com { 2117436Sdam.sunwoo@arm.com return large() ? 2127436Sdam.sunwoo@arm.com (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 14, 12) << 2)) : 2137436Sdam.sunwoo@arm.com (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 8, 6) << 2)); 2147436Sdam.sunwoo@arm.com } 2157436Sdam.sunwoo@arm.com 2167436Sdam.sunwoo@arm.com /** Return the physical frame, bits shifted right */ 2177436Sdam.sunwoo@arm.com Addr pfn() const 2187436Sdam.sunwoo@arm.com { 2197436Sdam.sunwoo@arm.com return large() ? bits(data, 31, 16) : bits(data, 31, 12); 2207436Sdam.sunwoo@arm.com } 2217436Sdam.sunwoo@arm.com 2227436Sdam.sunwoo@arm.com /** If the section is shareable. See texcb() comment. */ 2237436Sdam.sunwoo@arm.com bool shareable() const 22410037SARM gem5 Developers { 22510037SARM gem5 Developers return bits(data, 10); 22610037SARM gem5 Developers } 22710037SARM gem5 Developers 22810037SARM gem5 Developers /** Set access flag that this entry has been touched. Mark 22910037SARM gem5 Developers * the entry as requiring a writeback, in the future. 23010037SARM gem5 Developers */ 23110037SARM gem5 Developers void setAp0() 23210037SARM gem5 Developers { 23310037SARM gem5 Developers data |= 1 << 4; 23410037SARM gem5 Developers _dirty = true; 23510037SARM gem5 Developers } 23610037SARM gem5 Developers 23710037SARM gem5 Developers /** This entry needs to be written back to memory */ 23810037SARM gem5 Developers bool dirty() const 2397404SAli.Saidi@ARM.com { 2407404SAli.Saidi@ARM.com return _dirty; 2417404SAli.Saidi@ARM.com } 24210037SARM gem5 Developers 24310037SARM gem5 Developers }; 2447436Sdam.sunwoo@arm.com 24510037SARM gem5 Developers struct WalkerState //: public SimObject 24610037SARM gem5 Developers { 2477404SAli.Saidi@ARM.com /** Thread context that we're doing the walk for */ 2487436Sdam.sunwoo@arm.com ThreadContext *tc; 2497436Sdam.sunwoo@arm.com 2507436Sdam.sunwoo@arm.com /** Request that is currently being serviced */ 2517436Sdam.sunwoo@arm.com RequestPtr req; 25210037SARM gem5 Developers 25310537Sandreas.hansson@arm.com /** Context ID that we're servicing the request under */ 25410037SARM gem5 Developers uint8_t contextId; 25510037SARM gem5 Developers 25610037SARM gem5 Developers /** Translation state for delayed requests */ 25710037SARM gem5 Developers TLB::Translation *transState; 25810537Sandreas.hansson@arm.com 25910537Sandreas.hansson@arm.com /** The fault that we are going to return */ 26010037SARM gem5 Developers Fault fault; 26110037SARM gem5 Developers 26210037SARM gem5 Developers /** The virtual address that is being translated */ 26310037SARM gem5 Developers Addr vaddr; 26410037SARM gem5 Developers 26510037SARM gem5 Developers /** Cached copy of the sctlr as it existed when translation began */ 26610037SARM gem5 Developers SCTLR sctlr; 26710037SARM gem5 Developers 26810037SARM gem5 Developers /** Cached copy of the cpsr as it existed when the translation began */ 26910037SARM gem5 Developers CPSR cpsr; 27010037SARM gem5 Developers 27110037SARM gem5 Developers /** Width of the base address held in TTRB0 */ 27210037SARM gem5 Developers uint32_t N; 27310037SARM gem5 Developers 27410037SARM gem5 Developers /** If the access is a write */ 27510037SARM gem5 Developers bool isWrite; 27610037SARM gem5 Developers 27710037SARM gem5 Developers /** If the access is not from user mode */ 27810037SARM gem5 Developers bool isPriv; 27910037SARM gem5 Developers 28010037SARM gem5 Developers /** If the access is a fetch (for execution, and no-exec) must be checked?*/ 28110037SARM gem5 Developers bool isFetch; 28210037SARM gem5 Developers 28310037SARM gem5 Developers /** If the mode is timing or atomic */ 28410037SARM gem5 Developers bool timing; 28510037SARM gem5 Developers 28610037SARM gem5 Developers /** Save mode for use in delayed response */ 28710037SARM gem5 Developers BaseTLB::Mode mode; 28810037SARM gem5 Developers 2897404SAli.Saidi@ARM.com L1Descriptor l1Desc; 2907404SAli.Saidi@ARM.com L2Descriptor l2Desc; 2917404SAli.Saidi@ARM.com 2927946SGiacomo.Gabrielli@arm.com /** Whether L1/L2 descriptor response is delayed in timing mode */ 2937404SAli.Saidi@ARM.com bool delayed; 2947404SAli.Saidi@ARM.com 2957404SAli.Saidi@ARM.com TableWalker *tableWalker; 2967404SAli.Saidi@ARM.com 2977404SAli.Saidi@ARM.com void doL1Descriptor(); 2987404SAli.Saidi@ARM.com void doL2Descriptor(); 2997404SAli.Saidi@ARM.com 3007404SAli.Saidi@ARM.com std::string name() const {return tableWalker->name();} 3017404SAli.Saidi@ARM.com }; 3027404SAli.Saidi@ARM.com 3037404SAli.Saidi@ARM.com 3047404SAli.Saidi@ARM.com FifoBuffer<WalkerState> stateQueue; 3057404SAli.Saidi@ARM.com 3067404SAli.Saidi@ARM.com /** Port to issue translation requests from */ 3077404SAli.Saidi@ARM.com DmaPort *port; 30810037SARM gem5 Developers 3097404SAli.Saidi@ARM.com /** TLB that is initiating these table walks */ 3107404SAli.Saidi@ARM.com TLB *tlb; 3117404SAli.Saidi@ARM.com 3127404SAli.Saidi@ARM.com /** Cached copy of the sctlr as it existed when translation began */ 3137404SAli.Saidi@ARM.com SCTLR sctlr; 3147404SAli.Saidi@ARM.com 3157404SAli.Saidi@ARM.com WalkerState *currState; 3167404SAli.Saidi@ARM.com 3177404SAli.Saidi@ARM.com public: 3187404SAli.Saidi@ARM.com typedef ArmTableWalkerParams Params; 3197404SAli.Saidi@ARM.com TableWalker(const Params *p); 3207404SAli.Saidi@ARM.com virtual ~TableWalker(); 3217404SAli.Saidi@ARM.com 3227404SAli.Saidi@ARM.com const Params * 3237946SGiacomo.Gabrielli@arm.com params() const 3247946SGiacomo.Gabrielli@arm.com { 3257404SAli.Saidi@ARM.com return dynamic_cast<const Params *>(_params); 3267404SAli.Saidi@ARM.com } 3277404SAli.Saidi@ARM.com 3287404SAli.Saidi@ARM.com virtual unsigned int drain(Event *de) { panic("write me\n"); } 3297404SAli.Saidi@ARM.com virtual Port *getPort(const std::string &if_name, int idx = -1); 3307404SAli.Saidi@ARM.com 3317404SAli.Saidi@ARM.com Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, 3327404SAli.Saidi@ARM.com TLB::Translation *_trans, bool timing); 3337694SAli.Saidi@ARM.com 3347694SAli.Saidi@ARM.com void setTlb(TLB *_tlb) { tlb = _tlb; } 3357694SAli.Saidi@ARM.com void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, 3367694SAli.Saidi@ARM.com uint8_t texcb, bool s); 3377694SAli.Saidi@ARM.com 3387694SAli.Saidi@ARM.com private: 3397694SAli.Saidi@ARM.com 3407694SAli.Saidi@ARM.com void doL1Descriptor(); 3417694SAli.Saidi@ARM.com void doL1DescriptorWrapper(); 3427436Sdam.sunwoo@arm.com EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent; 3437436Sdam.sunwoo@arm.com 3447436Sdam.sunwoo@arm.com void doL2Descriptor(); 3457436Sdam.sunwoo@arm.com void doL2DescriptorWrapper(); 3467436Sdam.sunwoo@arm.com EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent; 3477436Sdam.sunwoo@arm.com 3487436Sdam.sunwoo@arm.com 3497436Sdam.sunwoo@arm.com}; 3507436Sdam.sunwoo@arm.com 3517436Sdam.sunwoo@arm.com 3527436Sdam.sunwoo@arm.com} // namespace ArmISA 3537436Sdam.sunwoo@arm.com 3547436Sdam.sunwoo@arm.com#endif //__ARCH_ARM_TABLE_WALKER_HH__ 3557436Sdam.sunwoo@arm.com 3567436Sdam.sunwoo@arm.com