table_walker.hh revision 7878:d3e6ebcccabf
16019Shines@cs.fsu.edu/* 210037SARM gem5 Developers * Copyright (c) 2010 ARM Limited 37093Sgblack@eecs.umich.edu * All rights reserved 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu * 146019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 156019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 166019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 176019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 186019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 196019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 206019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 216019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 226019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 236019Shines@cs.fsu.edu * this software without specific prior written permission. 246019Shines@cs.fsu.edu * 256019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366019Shines@cs.fsu.edu * 376019Shines@cs.fsu.edu * Authors: Ali Saidi 386019Shines@cs.fsu.edu */ 396019Shines@cs.fsu.edu 407399SAli.Saidi@ARM.com#ifndef __ARCH_ARM_TABLE_WALKER_HH__ 417399SAli.Saidi@ARM.com#define __ARCH_ARM_TABLE_WALKER_HH__ 426019Shines@cs.fsu.edu 436019Shines@cs.fsu.edu#include <list> 446019Shines@cs.fsu.edu 4510873Sandreas.sandberg@arm.com#include "arch/arm/miscregs.hh" 4610873Sandreas.sandberg@arm.com#include "arch/arm/tlb.hh" 4710474Sandreas.hansson@arm.com#include "mem/mem_object.hh" 486019Shines@cs.fsu.edu#include "mem/request.hh" 496019Shines@cs.fsu.edu#include "mem/request.hh" 506019Shines@cs.fsu.edu#include "params/ArmTableWalker.hh" 516116Snate@binkert.org#include "sim/eventq.hh" 526019Shines@cs.fsu.edu#include "sim/fault_fwd.hh" 538782Sgblack@eecs.umich.edu 548756Sgblack@eecs.umich.educlass DmaPort; 5510037SARM gem5 Developersclass ThreadContext; 5610037SARM gem5 Developers 576019Shines@cs.fsu.edunamespace ArmISA { 586019Shines@cs.fsu.educlass Translation; 596019Shines@cs.fsu.educlass TLB; 606019Shines@cs.fsu.edu 6110024Sdam.sunwoo@arm.comclass TableWalker : public MemObject 626019Shines@cs.fsu.edu{ 638232Snate@binkert.org public: 648232Snate@binkert.org struct L1Descriptor { 658232Snate@binkert.org /** Type of page table entry ARM DDI 0406B: B3-8*/ 666116Snate@binkert.org enum EntryType { 676116Snate@binkert.org Ignore, 688756Sgblack@eecs.umich.edu PageTable, 696019Shines@cs.fsu.edu Section, 706019Shines@cs.fsu.edu Reserved 716019Shines@cs.fsu.edu }; 726019Shines@cs.fsu.edu 736019Shines@cs.fsu.edu /** The raw bits of the entry */ 7410037SARM gem5 Developers uint32_t data; 7510037SARM gem5 Developers 7610418Sandreas.hansson@arm.com /** This entry has been modified (access flag set) and needs to be 7710418Sandreas.hansson@arm.com * written back to memory */ 7810822Sandreas.hansson@arm.com bool _dirty; 7910537Sandreas.hansson@arm.com 8010537Sandreas.hansson@arm.com EntryType type() const 8111152Smitch.hayenga@arm.com { 826019Shines@cs.fsu.edu return (EntryType)(data & 0x3); 8310037SARM gem5 Developers } 847399SAli.Saidi@ARM.com 8510037SARM gem5 Developers /** Is the page a Supersection (16MB)?*/ 8610037SARM gem5 Developers bool supersection() const 8710037SARM gem5 Developers { 8810037SARM gem5 Developers return bits(data, 18); 896019Shines@cs.fsu.edu } 906019Shines@cs.fsu.edu 916019Shines@cs.fsu.edu /** Return the physcal address of the entry, bits in position*/ 926019Shines@cs.fsu.edu Addr paddr() const 9310037SARM gem5 Developers { 9410037SARM gem5 Developers if (supersection()) 9510037SARM gem5 Developers panic("Super sections not implemented\n"); 9610037SARM gem5 Developers return mbits(data, 31,20); 9710037SARM gem5 Developers } 9810037SARM gem5 Developers /** Return the physcal address of the entry, bits in position*/ 9910037SARM gem5 Developers Addr paddr(Addr va) const 10010037SARM gem5 Developers { 10110037SARM gem5 Developers if (supersection()) 10210037SARM gem5 Developers panic("Super sections not implemented\n"); 10310037SARM gem5 Developers return mbits(data, 31,20) | mbits(va, 20, 0); 10410717Sandreas.hansson@arm.com } 10510037SARM gem5 Developers 10610037SARM gem5 Developers 10710717Sandreas.hansson@arm.com /** Return the physical frame, bits shifted right */ 1086019Shines@cs.fsu.edu Addr pfn() const 1096019Shines@cs.fsu.edu { 1107694SAli.Saidi@ARM.com if (supersection()) 1117694SAli.Saidi@ARM.com panic("Super sections not implemented\n"); 1127694SAli.Saidi@ARM.com return bits(data, 31,20); 11310037SARM gem5 Developers } 11410037SARM gem5 Developers 11510037SARM gem5 Developers /** Is the translation global (no asid used)? */ 11610037SARM gem5 Developers bool global() const 11710037SARM gem5 Developers { 11810037SARM gem5 Developers return bits(data, 17); 11910037SARM gem5 Developers } 12010037SARM gem5 Developers 12110037SARM gem5 Developers /** Is the translation not allow execution? */ 1227694SAli.Saidi@ARM.com bool xn() const 1237694SAli.Saidi@ARM.com { 1247694SAli.Saidi@ARM.com return bits(data, 4); 1257694SAli.Saidi@ARM.com } 1267694SAli.Saidi@ARM.com 1277694SAli.Saidi@ARM.com /** Three bit access protection flags */ 1289738Sandreas@sandberg.pp.se uint8_t ap() const 1299738Sandreas@sandberg.pp.se { 1309738Sandreas@sandberg.pp.se return (bits(data, 15) << 2) | bits(data,11,10); 1319738Sandreas@sandberg.pp.se } 1329738Sandreas@sandberg.pp.se 1339738Sandreas@sandberg.pp.se /** Domain Client/Manager: ARM DDI 0406B: B3-31 */ 1347404SAli.Saidi@ARM.com uint8_t domain() const 13510037SARM gem5 Developers { 13610037SARM gem5 Developers return bits(data,8,5); 1376019Shines@cs.fsu.edu } 1387404SAli.Saidi@ARM.com 1397404SAli.Saidi@ARM.com /** Address of L2 descriptor if it exists */ 1407404SAli.Saidi@ARM.com Addr l2Addr() const 14110037SARM gem5 Developers { 1427404SAli.Saidi@ARM.com return mbits(data, 31,10); 1437404SAli.Saidi@ARM.com } 14410037SARM gem5 Developers 14510037SARM gem5 Developers /** Memory region attributes: ARM DDI 0406B: B3-32. 14610037SARM gem5 Developers * These bits are largly ignored by M5 and only used to 14710037SARM gem5 Developers * provide the illusion that the memory system cares about 14810037SARM gem5 Developers * anything but cachable vs. uncachable. 1499535Smrinmoy.ghosh@arm.com */ 1507697SAli.Saidi@ARM.com uint8_t texcb() const 1517697SAli.Saidi@ARM.com { 15210037SARM gem5 Developers return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2; 1537697SAli.Saidi@ARM.com } 1547697SAli.Saidi@ARM.com 1557697SAli.Saidi@ARM.com /** If the section is shareable. See texcb() comment. */ 1567697SAli.Saidi@ARM.com bool shareable() const 1577697SAli.Saidi@ARM.com { 1587404SAli.Saidi@ARM.com return bits(data, 16); 1597404SAli.Saidi@ARM.com } 16010037SARM gem5 Developers 1617404SAli.Saidi@ARM.com /** Set access flag that this entry has been touched. Mark 1627404SAli.Saidi@ARM.com * the entry as requiring a writeback, in the future. 16310037SARM gem5 Developers */ 16410037SARM gem5 Developers void setAp0() 16510037SARM gem5 Developers { 16610037SARM gem5 Developers data |= 1 << 10; 16710037SARM gem5 Developers _dirty = true; 16810037SARM gem5 Developers } 16910037SARM gem5 Developers 17010037SARM gem5 Developers /** This entry needs to be written back to memory */ 17110367SAndrew.Bardsley@arm.com bool dirty() const 17210037SARM gem5 Developers { 1737404SAli.Saidi@ARM.com return _dirty; 1746019Shines@cs.fsu.edu } 1756019Shines@cs.fsu.edu }; 1766019Shines@cs.fsu.edu 1776019Shines@cs.fsu.edu /** Level 2 page table descriptor */ 1787404SAli.Saidi@ARM.com struct L2Descriptor { 1796019Shines@cs.fsu.edu 1807404SAli.Saidi@ARM.com /** The raw bits of the entry. */ 18110037SARM gem5 Developers uint32_t data; 18210037SARM gem5 Developers 18310037SARM gem5 Developers /** This entry has been modified (access flag set) and needs to be 18410037SARM gem5 Developers * written back to memory */ 18510037SARM gem5 Developers bool _dirty; 18610037SARM gem5 Developers 1877404SAli.Saidi@ARM.com /** Is the entry invalid */ 18810037SARM gem5 Developers bool invalid() const 18910037SARM gem5 Developers { 19010037SARM gem5 Developers return bits(data, 1,0) == 0;; 1917697SAli.Saidi@ARM.com } 19210037SARM gem5 Developers 19310037SARM gem5 Developers /** What is the size of the mapping? */ 19410037SARM gem5 Developers bool large() const 19510037SARM gem5 Developers { 1967404SAli.Saidi@ARM.com return bits(data, 1) == 0; 1977697SAli.Saidi@ARM.com } 1987404SAli.Saidi@ARM.com 19910037SARM gem5 Developers /** Is execution allowed on this mapping? */ 20010037SARM gem5 Developers bool xn() const 2017697SAli.Saidi@ARM.com { 2027734SAli.Saidi@ARM.com return large() ? bits(data, 15) : bits(data, 0); 2037734SAli.Saidi@ARM.com } 20410463SAndreas.Sandberg@ARM.com 2056019Shines@cs.fsu.edu /** Is the translation global (no asid used)? */ 2066019Shines@cs.fsu.edu bool global() const 2076019Shines@cs.fsu.edu { 20810037SARM gem5 Developers return !bits(data, 11); 2097404SAli.Saidi@ARM.com } 2107404SAli.Saidi@ARM.com 2117404SAli.Saidi@ARM.com /** Three bit access protection flags */ 2127404SAli.Saidi@ARM.com uint8_t ap() const 2137404SAli.Saidi@ARM.com { 21410037SARM gem5 Developers return bits(data, 5, 4) | (bits(data, 9) << 2); 21510037SARM gem5 Developers } 21610037SARM gem5 Developers 21710037SARM gem5 Developers /** Memory region attributes: ARM DDI 0406B: B3-32 */ 2187404SAli.Saidi@ARM.com uint8_t texcb() const 2197404SAli.Saidi@ARM.com { 2207404SAli.Saidi@ARM.com return large() ? 2217404SAli.Saidi@ARM.com (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 14, 12) << 2)) : 22210037SARM gem5 Developers (bits(data, 2) | (bits(data,3) << 1) | (bits(data, 8, 6) << 2)); 2236019Shines@cs.fsu.edu } 22410037SARM gem5 Developers 22510037SARM gem5 Developers /** Return the physical frame, bits shifted right */ 2267404SAli.Saidi@ARM.com Addr pfn() const 2277404SAli.Saidi@ARM.com { 2287404SAli.Saidi@ARM.com return large() ? bits(data, 31, 16) : bits(data, 31, 12); 22910037SARM gem5 Developers } 23010037SARM gem5 Developers 23110037SARM gem5 Developers /** Return complete physical address given a VA */ 23210037SARM gem5 Developers Addr paddr(Addr va) const 23310037SARM gem5 Developers { 23410037SARM gem5 Developers if (large()) 23510037SARM gem5 Developers return mbits(data, 31, 16) | mbits(va, 15, 0); 23610037SARM gem5 Developers else 23710037SARM gem5 Developers return mbits(data, 31, 12) | mbits(va, 11, 0); 23810037SARM gem5 Developers } 2397404SAli.Saidi@ARM.com 2407404SAli.Saidi@ARM.com /** If the section is shareable. See texcb() comment. */ 24110037SARM gem5 Developers bool shareable() const 24210037SARM gem5 Developers { 24310037SARM gem5 Developers return bits(data, 10); 24410037SARM gem5 Developers } 24510037SARM gem5 Developers 24610037SARM gem5 Developers /** Set access flag that this entry has been touched. Mark 24710037SARM gem5 Developers * the entry as requiring a writeback, in the future. 24810037SARM gem5 Developers */ 24910037SARM gem5 Developers void setAp0() 25010037SARM gem5 Developers { 25110037SARM gem5 Developers data |= 1 << 4; 25210037SARM gem5 Developers _dirty = true; 25310037SARM gem5 Developers } 25410037SARM gem5 Developers 25510037SARM gem5 Developers /** This entry needs to be written back to memory */ 25610037SARM gem5 Developers bool dirty() const 25710037SARM gem5 Developers { 25810037SARM gem5 Developers return _dirty; 25910037SARM gem5 Developers } 26010037SARM gem5 Developers 26110037SARM gem5 Developers }; 26210037SARM gem5 Developers 26310037SARM gem5 Developers struct WalkerState //: public SimObject 26410037SARM gem5 Developers { 26510037SARM gem5 Developers /** Thread context that we're doing the walk for */ 26610037SARM gem5 Developers ThreadContext *tc; 26710037SARM gem5 Developers 2687734SAli.Saidi@ARM.com /** Request that is currently being serviced */ 2697734SAli.Saidi@ARM.com RequestPtr req; 27010037SARM gem5 Developers 27110037SARM gem5 Developers /** Context ID that we're servicing the request under */ 27210037SARM gem5 Developers uint8_t contextId; 27310037SARM gem5 Developers 27410037SARM gem5 Developers /** Translation state for delayed requests */ 2756019Shines@cs.fsu.edu TLB::Translation *transState; 2766019Shines@cs.fsu.edu 2777404SAli.Saidi@ARM.com /** The fault that we are going to return */ 27810037SARM gem5 Developers Fault fault; 2797404SAli.Saidi@ARM.com 28010037SARM gem5 Developers /** The virtual address that is being translated */ 28110037SARM gem5 Developers Addr vaddr; 28210037SARM gem5 Developers 28310037SARM gem5 Developers /** Cached copy of the sctlr as it existed when translation began */ 2847734SAli.Saidi@ARM.com SCTLR sctlr; 2857404SAli.Saidi@ARM.com 2867404SAli.Saidi@ARM.com /** Width of the base address held in TTRB0 */ 2877404SAli.Saidi@ARM.com uint32_t N; 28810037SARM gem5 Developers 2897404SAli.Saidi@ARM.com /** If the access is a write */ 29010037SARM gem5 Developers bool isWrite; 29110037SARM gem5 Developers 2927404SAli.Saidi@ARM.com /** If the access is a fetch (for execution, and no-exec) must be checked?*/ 29310037SARM gem5 Developers bool isFetch; 2947404SAli.Saidi@ARM.com 2957404SAli.Saidi@ARM.com /** If the mode is timing or atomic */ 2967404SAli.Saidi@ARM.com bool timing; 2977404SAli.Saidi@ARM.com 29810037SARM gem5 Developers /** Save mode for use in delayed response */ 29910037SARM gem5 Developers BaseTLB::Mode mode; 30010037SARM gem5 Developers 30110037SARM gem5 Developers L1Descriptor l1Desc; 3027404SAli.Saidi@ARM.com L2Descriptor l2Desc; 30310037SARM gem5 Developers 3047734SAli.Saidi@ARM.com /** Whether L1/L2 descriptor response is delayed in timing mode */ 3057404SAli.Saidi@ARM.com bool delayed; 30610037SARM gem5 Developers 3077404SAli.Saidi@ARM.com TableWalker *tableWalker; 3087734SAli.Saidi@ARM.com 3097404SAli.Saidi@ARM.com void doL1Descriptor(); 3107404SAli.Saidi@ARM.com void doL2Descriptor(); 3117404SAli.Saidi@ARM.com 31210037SARM gem5 Developers std::string name() const {return tableWalker->name();} 3137404SAli.Saidi@ARM.com }; 31410037SARM gem5 Developers 31510037SARM gem5 Developers 31610037SARM gem5 Developers /** Queue of requests that need processing first level translation */ 31710037SARM gem5 Developers std::list<WalkerState *> stateQueueL1; 31810037SARM gem5 Developers 3197404SAli.Saidi@ARM.com /** Queue of requests that have passed first level translation and 32010037SARM gem5 Developers * require an additional level. */ 32110037SARM gem5 Developers std::list<WalkerState *> stateQueueL2; 32210037SARM gem5 Developers 32310037SARM gem5 Developers /** Queue of requests that have passed are waiting because the walker is 3247404SAli.Saidi@ARM.com * currently busy. */ 32510037SARM gem5 Developers std::list<WalkerState *> pendingQueue;; 32610037SARM gem5 Developers 32710037SARM gem5 Developers 32810037SARM gem5 Developers /** Port to issue translation requests from */ 32910037SARM gem5 Developers DmaPort *port; 33010037SARM gem5 Developers 33110037SARM gem5 Developers /** TLB that is initiating these table walks */ 3327404SAli.Saidi@ARM.com TLB *tlb; 3337734SAli.Saidi@ARM.com 3347404SAli.Saidi@ARM.com /** Cached copy of the sctlr as it existed when translation began */ 33510037SARM gem5 Developers SCTLR sctlr; 33610037SARM gem5 Developers 3377404SAli.Saidi@ARM.com WalkerState *currState; 33810037SARM gem5 Developers 33910037SARM gem5 Developers /** If a timing translation is currently in progress */ 34010037SARM gem5 Developers bool pending; 34110037SARM gem5 Developers 34210037SARM gem5 Developers public: 34310037SARM gem5 Developers typedef ArmTableWalkerParams Params; 34410037SARM gem5 Developers TableWalker(const Params *p); 34510037SARM gem5 Developers virtual ~TableWalker(); 34610037SARM gem5 Developers 34710037SARM gem5 Developers const Params * 34810037SARM gem5 Developers params() const 34910037SARM gem5 Developers { 35010037SARM gem5 Developers return dynamic_cast<const Params *>(_params); 35110037SARM gem5 Developers } 3527404SAli.Saidi@ARM.com 3537404SAli.Saidi@ARM.com virtual unsigned int drain(Event *de); 3546019Shines@cs.fsu.edu virtual void resume(); 3559439SAndreas.Sandberg@ARM.com virtual Port *getPort(const std::string &if_name, int idx = -1); 3569439SAndreas.Sandberg@ARM.com 3579439SAndreas.Sandberg@ARM.com Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, 3589439SAndreas.Sandberg@ARM.com TLB::Translation *_trans, bool timing); 3599439SAndreas.Sandberg@ARM.com 3609439SAndreas.Sandberg@ARM.com void setTlb(TLB *_tlb) { tlb = _tlb; } 3619439SAndreas.Sandberg@ARM.com void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, 3629439SAndreas.Sandberg@ARM.com uint8_t texcb, bool s); 36310194SGeoffrey.Blake@arm.com 36410194SGeoffrey.Blake@arm.com private: 36510194SGeoffrey.Blake@arm.com 36610194SGeoffrey.Blake@arm.com void doL1Descriptor(); 36710194SGeoffrey.Blake@arm.com void doL1DescriptorWrapper(); 36810194SGeoffrey.Blake@arm.com EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent; 36910194SGeoffrey.Blake@arm.com 37010194SGeoffrey.Blake@arm.com void doL2Descriptor(); 37110194SGeoffrey.Blake@arm.com void doL2DescriptorWrapper(); 37210194SGeoffrey.Blake@arm.com EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent; 37310194SGeoffrey.Blake@arm.com 37410194SGeoffrey.Blake@arm.com Fault processWalk(); 37510194SGeoffrey.Blake@arm.com void processWalkWrapper(); 37610194SGeoffrey.Blake@arm.com EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent; 37710194SGeoffrey.Blake@arm.com 37810194SGeoffrey.Blake@arm.com void nextWalk(ThreadContext *tc); 37910194SGeoffrey.Blake@arm.com}; 38010194SGeoffrey.Blake@arm.com 38110194SGeoffrey.Blake@arm.com 38210194SGeoffrey.Blake@arm.com} // namespace ArmISA 38310194SGeoffrey.Blake@arm.com 38410194SGeoffrey.Blake@arm.com#endif //__ARCH_ARM_TABLE_WALKER_HH__ 38510194SGeoffrey.Blake@arm.com 38610905Sandreas.sandberg@arm.com