translation.hh revision 10824:308771bd2647
15323Sgblack@eecs.umich.edu/* 22934Sktlim@umich.edu * Copyright (c) 2011 ARM Limited 32934Sktlim@umich.edu * All rights reserved. 42934Sktlim@umich.edu * 52934Sktlim@umich.edu * The license below extends only to copyright in the software and shall 62934Sktlim@umich.edu * not be construed as granting a license to any other intellectual 72934Sktlim@umich.edu * property including but not limited to intellectual property relating 82934Sktlim@umich.edu * to a hardware implementation of the functionality of the software 92934Sktlim@umich.edu * licensed hereunder. You may use the software subject to the license 102934Sktlim@umich.edu * terms below provided that you ensure that this notice is replicated 112934Sktlim@umich.edu * unmodified and in its entirety in all distributions of the software, 122934Sktlim@umich.edu * modified or unmodified, in source code or in binary form. 132934Sktlim@umich.edu * 142934Sktlim@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 152934Sktlim@umich.edu * Copyright (c) 2009 The University of Edinburgh 162934Sktlim@umich.edu * All rights reserved. 172934Sktlim@umich.edu * 182934Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 192934Sktlim@umich.edu * modification, are permitted provided that the following conditions are 202934Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 212934Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 222934Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 232934Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 242934Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 252934Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 262934Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 272934Sktlim@umich.edu * this software without specific prior written permission. 282934Sktlim@umich.edu * 292934Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302969Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312934Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322995Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332934Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342934Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352934Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362934Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372934Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382934Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392934Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402934Sktlim@umich.edu * 414520Ssaidi@eecs.umich.edu * Authors: Gabe Black 424520Ssaidi@eecs.umich.edu * Timothy M. Jones 434982Ssaidi@eecs.umich.edu */ 444520Ssaidi@eecs.umich.edu 454520Ssaidi@eecs.umich.edu#ifndef __CPU_TRANSLATION_HH__ 462934Sktlim@umich.edu#define __CPU_TRANSLATION_HH__ 472934Sktlim@umich.edu 483005Sstever@eecs.umich.edu#include "arch/generic/tlb.hh" 493005Sstever@eecs.umich.edu#include "sim/faults.hh" 503304Sstever@eecs.umich.edu 512995Ssaidi@eecs.umich.edu/** 522934Sktlim@umich.edu * This class captures the state of an address translation. A translation 532934Sktlim@umich.edu * can be split in two if the ISA supports it and the memory access crosses 544965Ssaidi@eecs.umich.edu * a page boundary. In this case, this class is shared by two data 555266Sksewell@umich.edu * translations (below). Otherwise it is used by a single data translation 562934Sktlim@umich.edu * class. When each part of the translation is finished, the finish 572934Sktlim@umich.edu * function is called which will indicate whether the whole translation is 582934Sktlim@umich.edu * completed or not. There are also functions for accessing parts of the 592934Sktlim@umich.edu * translation state which deal with the possible split correctly. 602934Sktlim@umich.edu */ 612995Ssaidi@eecs.umich.educlass WholeTranslationState 622934Sktlim@umich.edu{ 632934Sktlim@umich.edu protected: 642934Sktlim@umich.edu int outstanding; 652934Sktlim@umich.edu Fault faults[2]; 662934Sktlim@umich.edu 672995Ssaidi@eecs.umich.edu public: 682934Sktlim@umich.edu bool delay; 692934Sktlim@umich.edu bool isSplit; 702953Sktlim@umich.edu RequestPtr mainReq; 715478Snate@binkert.org RequestPtr sreqLow; 722934Sktlim@umich.edu RequestPtr sreqHigh; 733449Shsul@eecs.umich.edu uint8_t *data; 742934Sktlim@umich.edu uint64_t *res; 752934Sktlim@umich.edu BaseTLB::Mode mode; 762934Sktlim@umich.edu 772934Sktlim@umich.edu /** 782934Sktlim@umich.edu * Single translation state. We set the number of outstanding 793584Ssaidi@eecs.umich.edu * translations to one and indicate that it is not split. 804486Sbinkertn@umich.edu */ 814486Sbinkertn@umich.edu WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res, 824486Sbinkertn@umich.edu BaseTLB::Mode _mode) 834486Sbinkertn@umich.edu : outstanding(1), delay(false), isSplit(false), mainReq(_req), 844486Sbinkertn@umich.edu sreqLow(NULL), sreqHigh(NULL), data(_data), res(_res), mode(_mode) 854486Sbinkertn@umich.edu { 864486Sbinkertn@umich.edu faults[0] = faults[1] = NoFault; 873584Ssaidi@eecs.umich.edu assert(mode == BaseTLB::Read || mode == BaseTLB::Write); 883584Ssaidi@eecs.umich.edu } 893584Ssaidi@eecs.umich.edu 903584Ssaidi@eecs.umich.edu /** 913584Ssaidi@eecs.umich.edu * Split translation state. We copy all state into this class, set the 923743Sgblack@eecs.umich.edu * number of outstanding translations to two and then mark this as a 933584Ssaidi@eecs.umich.edu * split translation. 944972Ssaidi@eecs.umich.edu */ 953743Sgblack@eecs.umich.edu WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow, 964104Ssaidi@eecs.umich.edu RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res, 973743Sgblack@eecs.umich.edu BaseTLB::Mode _mode) 983823Ssaidi@eecs.umich.edu : outstanding(2), delay(false), isSplit(true), mainReq(_req), 993814Ssaidi@eecs.umich.edu sreqLow(_sreqLow), sreqHigh(_sreqHigh), data(_data), res(_res), 1003743Sgblack@eecs.umich.edu mode(_mode) 1013743Sgblack@eecs.umich.edu { 1023584Ssaidi@eecs.umich.edu faults[0] = faults[1] = NoFault; 1033814Ssaidi@eecs.umich.edu assert(mode == BaseTLB::Read || mode == BaseTLB::Write); 1043584Ssaidi@eecs.umich.edu } 1053745Sgblack@eecs.umich.edu 1063745Sgblack@eecs.umich.edu /** 1073745Sgblack@eecs.umich.edu * Finish part of a translation. If there is only one request then this 1083584Ssaidi@eecs.umich.edu * translation is completed. If the request has been split in two then 1093898Ssaidi@eecs.umich.edu * the outstanding count determines whether the translation is complete. 1103898Ssaidi@eecs.umich.edu * In this case, flags from the split request are copied to the main 1113898Ssaidi@eecs.umich.edu * request to make it easier to access them later on. 1124103Ssaidi@eecs.umich.edu */ 1134103Ssaidi@eecs.umich.edu bool 1144103Ssaidi@eecs.umich.edu finish(const Fault &fault, int index) 1153745Sgblack@eecs.umich.edu { 1163745Sgblack@eecs.umich.edu assert(outstanding); 1173745Sgblack@eecs.umich.edu faults[index] = fault; 1183584Ssaidi@eecs.umich.edu outstanding--; 1193584Ssaidi@eecs.umich.edu if (isSplit && outstanding == 0) { 1203584Ssaidi@eecs.umich.edu 1215222Sksewell@umich.edu // For ease later, we copy some state to the main request. 1225222Sksewell@umich.edu if (faults[0] == NoFault) { 1235222Sksewell@umich.edu mainReq->setPaddr(sreqLow->getPaddr()); 1245222Sksewell@umich.edu } 1255222Sksewell@umich.edu mainReq->setFlags(sreqLow->getFlags()); 1265222Sksewell@umich.edu mainReq->setFlags(sreqHigh->getFlags()); 1275222Sksewell@umich.edu } 1285222Sksewell@umich.edu return outstanding == 0; 1295222Sksewell@umich.edu } 1305222Sksewell@umich.edu 1315222Sksewell@umich.edu /** 1325222Sksewell@umich.edu * Determine whether this translation produced a fault. Both parts of the 1335222Sksewell@umich.edu * translation must be checked if this is a split translation. 1345222Sksewell@umich.edu */ 1355222Sksewell@umich.edu Fault 1365222Sksewell@umich.edu getFault() const 1375222Sksewell@umich.edu { 1385222Sksewell@umich.edu if (!isSplit) 1395222Sksewell@umich.edu return faults[0]; 1405222Sksewell@umich.edu else if (faults[0] != NoFault) 1415222Sksewell@umich.edu return faults[0]; 1425222Sksewell@umich.edu else if (faults[1] != NoFault) 1435222Sksewell@umich.edu return faults[1]; 1445222Sksewell@umich.edu else 1455222Sksewell@umich.edu return NoFault; 1465222Sksewell@umich.edu } 1475222Sksewell@umich.edu 1485222Sksewell@umich.edu /** Remove all faults from the translation. */ 1495222Sksewell@umich.edu void 1505222Sksewell@umich.edu setNoFault() 1515478Snate@binkert.org { 1525222Sksewell@umich.edu faults[0] = faults[1] = NoFault; 1535222Sksewell@umich.edu } 1545222Sksewell@umich.edu 1555222Sksewell@umich.edu /** 1565222Sksewell@umich.edu * Check if this request is strictly ordered device access. We 1575222Sksewell@umich.edu * only need to check the main request because the flags will have 1585323Sgblack@eecs.umich.edu * been copied here on a split translation. 1595357Sgblack@eecs.umich.edu */ 1605323Sgblack@eecs.umich.edu bool 1615323Sgblack@eecs.umich.edu isStrictlyOrdered() const 1625613Sgblack@eecs.umich.edu { 1635613Sgblack@eecs.umich.edu return mainReq->isStrictlyOrdered(); 1645613Sgblack@eecs.umich.edu } 1655613Sgblack@eecs.umich.edu 1665133Sgblack@eecs.umich.edu /** 1675133Sgblack@eecs.umich.edu * Check if this request is a prefetch. We only need to check the main 1685133Sgblack@eecs.umich.edu * request because the flags will have been copied here on a split 1695841Sgblack@eecs.umich.edu * translation. 1705133Sgblack@eecs.umich.edu */ 1715133Sgblack@eecs.umich.edu bool 1725133Sgblack@eecs.umich.edu isPrefetch() const 1735323Sgblack@eecs.umich.edu { 1745450Sgblack@eecs.umich.edu return mainReq->isPrefetch(); 1755133Sgblack@eecs.umich.edu } 1765133Sgblack@eecs.umich.edu 1775613Sgblack@eecs.umich.edu /** Get the physical address of this request. */ 1785613Sgblack@eecs.umich.edu Addr 1795613Sgblack@eecs.umich.edu getPaddr() const 1805613Sgblack@eecs.umich.edu { 1815613Sgblack@eecs.umich.edu return mainReq->getPaddr(); 1825613Sgblack@eecs.umich.edu } 1835613Sgblack@eecs.umich.edu 1845638Sgblack@eecs.umich.edu /** 1855613Sgblack@eecs.umich.edu * Get the flags associated with this request. We only need to access 1865613Sgblack@eecs.umich.edu * the main request because the flags will have been copied here on a 1875613Sgblack@eecs.umich.edu * split translation. 1885613Sgblack@eecs.umich.edu */ 1895841Sgblack@eecs.umich.edu unsigned 1905841Sgblack@eecs.umich.edu getFlags() 1915841Sgblack@eecs.umich.edu { 1925841Sgblack@eecs.umich.edu return mainReq->getFlags(); 1935841Sgblack@eecs.umich.edu } 1945841Sgblack@eecs.umich.edu 1955841Sgblack@eecs.umich.edu /** Delete all requests that make up this translation. */ 1965615Sgblack@eecs.umich.edu void 1975615Sgblack@eecs.umich.edu deleteReqs() 1985615Sgblack@eecs.umich.edu { 1995615Sgblack@eecs.umich.edu delete mainReq; 2005641Sgblack@eecs.umich.edu if (isSplit) { 2015641Sgblack@eecs.umich.edu delete sreqLow; 2025641Sgblack@eecs.umich.edu delete sreqHigh; 2035641Sgblack@eecs.umich.edu } 2045641Sgblack@eecs.umich.edu } 2055641Sgblack@eecs.umich.edu}; 2065641Sgblack@eecs.umich.edu 2075644Sgblack@eecs.umich.edu 2085644Sgblack@eecs.umich.edu/** 2095644Sgblack@eecs.umich.edu * This class represents part of a data address translation. All state for 2105644Sgblack@eecs.umich.edu * the translation is held in WholeTranslationState (above). Therefore this 2115644Sgblack@eecs.umich.edu * class does not need to know whether the translation is split or not. The 2125644Sgblack@eecs.umich.edu * index variable determines this but is simply passed on to the state class. 2135644Sgblack@eecs.umich.edu * When this part of the translation is completed, finish is called. If the 2145644Sgblack@eecs.umich.edu * translation state class indicate that the whole translation is complete 2155843Sgblack@eecs.umich.edu * then the execution context is informed. 2165843Sgblack@eecs.umich.edu */ 2175843Sgblack@eecs.umich.edutemplate <class ExecContextPtr> 2185843Sgblack@eecs.umich.educlass DataTranslation : public BaseTLB::Translation 2195843Sgblack@eecs.umich.edu{ 2205843Sgblack@eecs.umich.edu protected: 2215843Sgblack@eecs.umich.edu ExecContextPtr xc; 2225843Sgblack@eecs.umich.edu WholeTranslationState *state; 2235843Sgblack@eecs.umich.edu int index; 2245843Sgblack@eecs.umich.edu 2255843Sgblack@eecs.umich.edu public: 2266044Sgblack@eecs.umich.edu DataTranslation(ExecContextPtr _xc, WholeTranslationState* _state) 2275843Sgblack@eecs.umich.edu : xc(_xc), state(_state), index(0) 2285828Sgblack@eecs.umich.edu { 2295644Sgblack@eecs.umich.edu } 2305644Sgblack@eecs.umich.edu 2315644Sgblack@eecs.umich.edu DataTranslation(ExecContextPtr _xc, WholeTranslationState* _state, 2325644Sgblack@eecs.umich.edu int _index) 2335644Sgblack@eecs.umich.edu : xc(_xc), state(_state), index(_index) 2346044Sgblack@eecs.umich.edu { 2355644Sgblack@eecs.umich.edu } 2365828Sgblack@eecs.umich.edu 2375828Sgblack@eecs.umich.edu /** 2385828Sgblack@eecs.umich.edu * Signal the translation state that the translation has been delayed due 2395828Sgblack@eecs.umich.edu * to a hw page table walk. Split requests are transparently handled. 2405828Sgblack@eecs.umich.edu */ 2415828Sgblack@eecs.umich.edu void 2425828Sgblack@eecs.umich.edu markDelayed() 2436044Sgblack@eecs.umich.edu { 2445828Sgblack@eecs.umich.edu state->delay = true; 2455828Sgblack@eecs.umich.edu } 2465828Sgblack@eecs.umich.edu 2475828Sgblack@eecs.umich.edu /** 2485828Sgblack@eecs.umich.edu * Finish this part of the translation and indicate that the whole 2495828Sgblack@eecs.umich.edu * translation is complete if the state says so. 2505828Sgblack@eecs.umich.edu */ 2515828Sgblack@eecs.umich.edu void 2526044Sgblack@eecs.umich.edu finish(const Fault &fault, RequestPtr req, ThreadContext *tc, 2535828Sgblack@eecs.umich.edu BaseTLB::Mode mode) 2545828Sgblack@eecs.umich.edu { 2555828Sgblack@eecs.umich.edu assert(state); 2565828Sgblack@eecs.umich.edu assert(mode == state->mode); 2575828Sgblack@eecs.umich.edu if (state->finish(fault, index)) { 2585828Sgblack@eecs.umich.edu if (state->getFault() == NoFault) { 2595828Sgblack@eecs.umich.edu // Don't access the request if faulted (due to squash) 2605828Sgblack@eecs.umich.edu req->setTranslateLatency(); 2616044Sgblack@eecs.umich.edu } 2625828Sgblack@eecs.umich.edu xc->finishTranslation(state); 2635828Sgblack@eecs.umich.edu } 2645918Sgblack@eecs.umich.edu delete this; 2655918Sgblack@eecs.umich.edu } 2665918Sgblack@eecs.umich.edu 2675918Sgblack@eecs.umich.edu bool 2685918Sgblack@eecs.umich.edu squashed() const 2695918Sgblack@eecs.umich.edu { 2706044Sgblack@eecs.umich.edu return xc->isSquashed(); 2715918Sgblack@eecs.umich.edu } 2725918Sgblack@eecs.umich.edu}; 2735918Sgblack@eecs.umich.edu 2745918Sgblack@eecs.umich.edu#endif // __CPU_TRANSLATION_HH__ 2755918Sgblack@eecs.umich.edu