translation.hh revision 6973
16973Stjones1@inf.ed.ac.uk/*
26973Stjones1@inf.ed.ac.uk * Copyright (c) 2002-2005 The Regents of The University of Michigan
36973Stjones1@inf.ed.ac.uk * Copyright (c) 2009 The University of Edinburgh
46973Stjones1@inf.ed.ac.uk * All rights reserved.
56973Stjones1@inf.ed.ac.uk *
66973Stjones1@inf.ed.ac.uk * Redistribution and use in source and binary forms, with or without
76973Stjones1@inf.ed.ac.uk * modification, are permitted provided that the following conditions are
86973Stjones1@inf.ed.ac.uk * met: redistributions of source code must retain the above copyright
96973Stjones1@inf.ed.ac.uk * notice, this list of conditions and the following disclaimer;
106973Stjones1@inf.ed.ac.uk * redistributions in binary form must reproduce the above copyright
116973Stjones1@inf.ed.ac.uk * notice, this list of conditions and the following disclaimer in the
126973Stjones1@inf.ed.ac.uk * documentation and/or other materials provided with the distribution;
136973Stjones1@inf.ed.ac.uk * neither the name of the copyright holders nor the names of its
146973Stjones1@inf.ed.ac.uk * contributors may be used to endorse or promote products derived from
156973Stjones1@inf.ed.ac.uk * this software without specific prior written permission.
166973Stjones1@inf.ed.ac.uk *
176973Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186973Stjones1@inf.ed.ac.uk * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196973Stjones1@inf.ed.ac.uk * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206973Stjones1@inf.ed.ac.uk * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216973Stjones1@inf.ed.ac.uk * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226973Stjones1@inf.ed.ac.uk * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236973Stjones1@inf.ed.ac.uk * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246973Stjones1@inf.ed.ac.uk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256973Stjones1@inf.ed.ac.uk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266973Stjones1@inf.ed.ac.uk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276973Stjones1@inf.ed.ac.uk * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286973Stjones1@inf.ed.ac.uk *
296973Stjones1@inf.ed.ac.uk * Authors: Gabe Black
306973Stjones1@inf.ed.ac.uk *          Timothy M. Jones
316973Stjones1@inf.ed.ac.uk */
326973Stjones1@inf.ed.ac.uk
336973Stjones1@inf.ed.ac.uk#ifndef __CPU_TRANSLATION_HH__
346973Stjones1@inf.ed.ac.uk#define __CPU_TRANSLATION_HH__
356973Stjones1@inf.ed.ac.uk
366973Stjones1@inf.ed.ac.uk#include "sim/tlb.hh"
376973Stjones1@inf.ed.ac.uk
386973Stjones1@inf.ed.ac.ukclass WholeTranslationState
396973Stjones1@inf.ed.ac.uk{
406973Stjones1@inf.ed.ac.uk  protected:
416973Stjones1@inf.ed.ac.uk    int outstanding;
426973Stjones1@inf.ed.ac.uk    Fault faults[2];
436973Stjones1@inf.ed.ac.uk
446973Stjones1@inf.ed.ac.uk  public:
456973Stjones1@inf.ed.ac.uk    bool isSplit;
466973Stjones1@inf.ed.ac.uk    RequestPtr mainReq;
476973Stjones1@inf.ed.ac.uk    RequestPtr sreqLow;
486973Stjones1@inf.ed.ac.uk    RequestPtr sreqHigh;
496973Stjones1@inf.ed.ac.uk    uint8_t *data;
506973Stjones1@inf.ed.ac.uk    uint64_t *res;
516973Stjones1@inf.ed.ac.uk    BaseTLB::Mode mode;
526973Stjones1@inf.ed.ac.uk
536973Stjones1@inf.ed.ac.uk    /** Single translation state. */
546973Stjones1@inf.ed.ac.uk    WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
556973Stjones1@inf.ed.ac.uk                          BaseTLB::Mode _mode)
566973Stjones1@inf.ed.ac.uk        : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL),
576973Stjones1@inf.ed.ac.uk          sreqHigh(NULL), data(_data), res(_res), mode(_mode)
586973Stjones1@inf.ed.ac.uk    {
596973Stjones1@inf.ed.ac.uk        faults[0] = faults[1] = NoFault;
606973Stjones1@inf.ed.ac.uk        assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
616973Stjones1@inf.ed.ac.uk    }
626973Stjones1@inf.ed.ac.uk
636973Stjones1@inf.ed.ac.uk    /** Split translation state. */
646973Stjones1@inf.ed.ac.uk    WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
656973Stjones1@inf.ed.ac.uk                          RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
666973Stjones1@inf.ed.ac.uk                          BaseTLB::Mode _mode)
676973Stjones1@inf.ed.ac.uk        : outstanding(2), isSplit(true), mainReq(_req), sreqLow(_sreqLow),
686973Stjones1@inf.ed.ac.uk          sreqHigh(_sreqHigh), data(_data), res(_res), mode(_mode)
696973Stjones1@inf.ed.ac.uk    {
706973Stjones1@inf.ed.ac.uk        faults[0] = faults[1] = NoFault;
716973Stjones1@inf.ed.ac.uk        assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
726973Stjones1@inf.ed.ac.uk    }
736973Stjones1@inf.ed.ac.uk
746973Stjones1@inf.ed.ac.uk    bool
756973Stjones1@inf.ed.ac.uk    finish(Fault fault, int index)
766973Stjones1@inf.ed.ac.uk    {
776973Stjones1@inf.ed.ac.uk        assert(outstanding);
786973Stjones1@inf.ed.ac.uk        faults[index] = fault;
796973Stjones1@inf.ed.ac.uk        outstanding--;
806973Stjones1@inf.ed.ac.uk        if (isSplit && outstanding == 0) {
816973Stjones1@inf.ed.ac.uk
826973Stjones1@inf.ed.ac.uk            // For ease later, we copy some state to the main request.
836973Stjones1@inf.ed.ac.uk            if (faults[0] == NoFault) {
846973Stjones1@inf.ed.ac.uk                mainReq->setPaddr(sreqLow->getPaddr());
856973Stjones1@inf.ed.ac.uk            }
866973Stjones1@inf.ed.ac.uk            mainReq->setFlags(sreqLow->getFlags());
876973Stjones1@inf.ed.ac.uk            mainReq->setFlags(sreqHigh->getFlags());
886973Stjones1@inf.ed.ac.uk        }
896973Stjones1@inf.ed.ac.uk        return outstanding == 0;
906973Stjones1@inf.ed.ac.uk    }
916973Stjones1@inf.ed.ac.uk
926973Stjones1@inf.ed.ac.uk    Fault
936973Stjones1@inf.ed.ac.uk    getFault() const
946973Stjones1@inf.ed.ac.uk    {
956973Stjones1@inf.ed.ac.uk        if (!isSplit)
966973Stjones1@inf.ed.ac.uk            return faults[0];
976973Stjones1@inf.ed.ac.uk        else if (faults[0] != NoFault)
986973Stjones1@inf.ed.ac.uk            return faults[0];
996973Stjones1@inf.ed.ac.uk        else if (faults[1] != NoFault)
1006973Stjones1@inf.ed.ac.uk            return faults[1];
1016973Stjones1@inf.ed.ac.uk        else
1026973Stjones1@inf.ed.ac.uk            return NoFault;
1036973Stjones1@inf.ed.ac.uk    }
1046973Stjones1@inf.ed.ac.uk
1056973Stjones1@inf.ed.ac.uk    void
1066973Stjones1@inf.ed.ac.uk    setNoFault()
1076973Stjones1@inf.ed.ac.uk    {
1086973Stjones1@inf.ed.ac.uk        faults[0] = faults[1] = NoFault;
1096973Stjones1@inf.ed.ac.uk    }
1106973Stjones1@inf.ed.ac.uk
1116973Stjones1@inf.ed.ac.uk    bool
1126973Stjones1@inf.ed.ac.uk    isUncacheable() const
1136973Stjones1@inf.ed.ac.uk    {
1146973Stjones1@inf.ed.ac.uk        return mainReq->isUncacheable();
1156973Stjones1@inf.ed.ac.uk    }
1166973Stjones1@inf.ed.ac.uk
1176973Stjones1@inf.ed.ac.uk    bool
1186973Stjones1@inf.ed.ac.uk    isPrefetch() const
1196973Stjones1@inf.ed.ac.uk    {
1206973Stjones1@inf.ed.ac.uk        return mainReq->isPrefetch();
1216973Stjones1@inf.ed.ac.uk    }
1226973Stjones1@inf.ed.ac.uk
1236973Stjones1@inf.ed.ac.uk    Addr
1246973Stjones1@inf.ed.ac.uk    getPaddr() const
1256973Stjones1@inf.ed.ac.uk    {
1266973Stjones1@inf.ed.ac.uk        return mainReq->getPaddr();
1276973Stjones1@inf.ed.ac.uk    }
1286973Stjones1@inf.ed.ac.uk
1296973Stjones1@inf.ed.ac.uk    unsigned
1306973Stjones1@inf.ed.ac.uk    getFlags()
1316973Stjones1@inf.ed.ac.uk    {
1326973Stjones1@inf.ed.ac.uk        return mainReq->getFlags();
1336973Stjones1@inf.ed.ac.uk    }
1346973Stjones1@inf.ed.ac.uk
1356973Stjones1@inf.ed.ac.uk    void
1366973Stjones1@inf.ed.ac.uk    deleteReqs()
1376973Stjones1@inf.ed.ac.uk    {
1386973Stjones1@inf.ed.ac.uk        delete mainReq;
1396973Stjones1@inf.ed.ac.uk        if (isSplit) {
1406973Stjones1@inf.ed.ac.uk            delete sreqLow;
1416973Stjones1@inf.ed.ac.uk            delete sreqHigh;
1426973Stjones1@inf.ed.ac.uk        }
1436973Stjones1@inf.ed.ac.uk    }
1446973Stjones1@inf.ed.ac.uk};
1456973Stjones1@inf.ed.ac.uk
1466973Stjones1@inf.ed.ac.uktemplate <class ExecContext>
1476973Stjones1@inf.ed.ac.ukclass DataTranslation : public BaseTLB::Translation
1486973Stjones1@inf.ed.ac.uk{
1496973Stjones1@inf.ed.ac.uk  protected:
1506973Stjones1@inf.ed.ac.uk    ExecContext *xc;
1516973Stjones1@inf.ed.ac.uk    WholeTranslationState *state;
1526973Stjones1@inf.ed.ac.uk    int index;
1536973Stjones1@inf.ed.ac.uk
1546973Stjones1@inf.ed.ac.uk  public:
1556973Stjones1@inf.ed.ac.uk    DataTranslation(ExecContext *_xc, WholeTranslationState* _state)
1566973Stjones1@inf.ed.ac.uk        : xc(_xc), state(_state), index(0)
1576973Stjones1@inf.ed.ac.uk    {
1586973Stjones1@inf.ed.ac.uk    }
1596973Stjones1@inf.ed.ac.uk
1606973Stjones1@inf.ed.ac.uk    DataTranslation(ExecContext *_xc, WholeTranslationState* _state,
1616973Stjones1@inf.ed.ac.uk                    int _index)
1626973Stjones1@inf.ed.ac.uk        : xc(_xc), state(_state), index(_index)
1636973Stjones1@inf.ed.ac.uk    {
1646973Stjones1@inf.ed.ac.uk    }
1656973Stjones1@inf.ed.ac.uk
1666973Stjones1@inf.ed.ac.uk    void
1676973Stjones1@inf.ed.ac.uk    finish(Fault fault, RequestPtr req, ThreadContext *tc,
1686973Stjones1@inf.ed.ac.uk           BaseTLB::Mode mode)
1696973Stjones1@inf.ed.ac.uk    {
1706973Stjones1@inf.ed.ac.uk        assert(state);
1716973Stjones1@inf.ed.ac.uk        assert(mode == state->mode);
1726973Stjones1@inf.ed.ac.uk        if (state->finish(fault, index)) {
1736973Stjones1@inf.ed.ac.uk            xc->finishTranslation(state);
1746973Stjones1@inf.ed.ac.uk        }
1756973Stjones1@inf.ed.ac.uk        delete this;
1766973Stjones1@inf.ed.ac.uk    }
1776973Stjones1@inf.ed.ac.uk};
1786973Stjones1@inf.ed.ac.uk
1796973Stjones1@inf.ed.ac.uk#endif // __CPU_TRANSLATION_HH__
180