diff options
Diffstat (limited to 'src/cpu/translation.hh')
-rw-r--r-- | src/cpu/translation.hh | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/src/cpu/translation.hh b/src/cpu/translation.hh new file mode 100644 index 000000000..33e810710 --- /dev/null +++ b/src/cpu/translation.hh @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __CPU_TRANSLATION_HH__ +#define __CPU_TRANSLATION_HH__ + +#include "sim/tlb.hh" + +class WholeTranslationState +{ + protected: + int outstanding; + Fault faults[2]; + + public: + bool isSplit; + RequestPtr mainReq; + RequestPtr sreqLow; + RequestPtr sreqHigh; + uint8_t *data; + uint64_t *res; + BaseTLB::Mode mode; + + /** Single translation state. */ + WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res, + BaseTLB::Mode _mode) + : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL), + sreqHigh(NULL), data(_data), res(_res), mode(_mode) + { + faults[0] = faults[1] = NoFault; + assert(mode == BaseTLB::Read || mode == BaseTLB::Write); + } + + /** Split translation state. */ + WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow, + RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res, + BaseTLB::Mode _mode) + : outstanding(2), isSplit(true), mainReq(_req), sreqLow(_sreqLow), + sreqHigh(_sreqHigh), data(_data), res(_res), mode(_mode) + { + faults[0] = faults[1] = NoFault; + assert(mode == BaseTLB::Read || mode == BaseTLB::Write); + } + + bool + finish(Fault fault, int index) + { + assert(outstanding); + faults[index] = fault; + outstanding--; + if (isSplit && outstanding == 0) { + + // For ease later, we copy some state to the main request. + if (faults[0] == NoFault) { + mainReq->setPaddr(sreqLow->getPaddr()); + } + mainReq->setFlags(sreqLow->getFlags()); + mainReq->setFlags(sreqHigh->getFlags()); + } + return outstanding == 0; + } + + Fault + getFault() const + { + if (!isSplit) + return faults[0]; + else if (faults[0] != NoFault) + return faults[0]; + else if (faults[1] != NoFault) + return faults[1]; + else + return NoFault; + } + + void + setNoFault() + { + faults[0] = faults[1] = NoFault; + } + + bool + isUncacheable() const + { + return mainReq->isUncacheable(); + } + + bool + isPrefetch() const + { + return mainReq->isPrefetch(); + } + + Addr + getPaddr() const + { + return mainReq->getPaddr(); + } + + unsigned + getFlags() + { + return mainReq->getFlags(); + } + + void + deleteReqs() + { + delete mainReq; + if (isSplit) { + delete sreqLow; + delete sreqHigh; + } + } +}; + +template <class ExecContext> +class DataTranslation : public BaseTLB::Translation +{ + protected: + ExecContext *xc; + WholeTranslationState *state; + int index; + + public: + DataTranslation(ExecContext *_xc, WholeTranslationState* _state) + : xc(_xc), state(_state), index(0) + { + } + + DataTranslation(ExecContext *_xc, WholeTranslationState* _state, + int _index) + : xc(_xc), state(_state), index(_index) + { + } + + void + finish(Fault fault, RequestPtr req, ThreadContext *tc, + BaseTLB::Mode mode) + { + assert(state); + assert(mode == state->mode); + if (state->finish(fault, index)) { + xc->finishTranslation(state); + } + delete this; + } +}; + +#endif // __CPU_TRANSLATION_HH__ |