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