translation.hh revision 8486:c4e77a9563f5
14486Sbinkertn@umich.edu/*
27897Shestness@cs.utexas.edu * Copyright (c) 2011 ARM Limited
34486Sbinkertn@umich.edu * All rights reserved.
44486Sbinkertn@umich.edu *
54486Sbinkertn@umich.edu * The license below extends only to copyright in the software and shall
64486Sbinkertn@umich.edu * not be construed as granting a license to any other intellectual
74486Sbinkertn@umich.edu * property including but not limited to intellectual property relating
84486Sbinkertn@umich.edu * to a hardware implementation of the functionality of the software
94486Sbinkertn@umich.edu * licensed hereunder.  You may use the software subject to the license
104486Sbinkertn@umich.edu * terms below provided that you ensure that this notice is replicated
114486Sbinkertn@umich.edu * unmodified and in its entirety in all distributions of the software,
124486Sbinkertn@umich.edu * modified or unmodified, in source code or in binary form.
134486Sbinkertn@umich.edu *
144486Sbinkertn@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
154486Sbinkertn@umich.edu * Copyright (c) 2009 The University of Edinburgh
164486Sbinkertn@umich.edu * All rights reserved.
174486Sbinkertn@umich.edu *
184486Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
194486Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
204486Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
214486Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
224486Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
234486Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
244486Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
254486Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
264486Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
274486Sbinkertn@umich.edu * this software without specific prior written permission.
284486Sbinkertn@umich.edu *
297897Shestness@cs.utexas.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
304486Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
313102SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326654Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
333102SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
343102SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356654Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3610249Sstephan.diestelhorst@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
378931Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382212SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
399524SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
409524SAndreas.Sandberg@ARM.com *
412902SN/A * Authors: Gabe Black
428703Sandreas.hansson@arm.com *          Timothy M. Jones
431783SN/A */
449338SAndreas.Sandberg@arm.com
458839Sandreas.hansson@arm.com#ifndef __CPU_TRANSLATION_HH__
467673Snate@binkert.org#define __CPU_TRANSLATION_HH__
477673Snate@binkert.org
488597Ssteve.reinhardt@amd.com#include "sim/faults.hh"
498597Ssteve.reinhardt@amd.com#include "sim/tlb.hh"
508597Ssteve.reinhardt@amd.com
518597Ssteve.reinhardt@amd.com/**
528597Ssteve.reinhardt@amd.com * This class captures the state of an address translation.  A translation
538597Ssteve.reinhardt@amd.com * can be split in two if the ISA supports it and the memory access crosses
549524SAndreas.Sandberg@ARM.com * a page boundary.  In this case, this class is shared by two data
558597Ssteve.reinhardt@amd.com * translations (below).  Otherwise it is used by a single data translation
568597Ssteve.reinhardt@amd.com * class.  When each part of the translation is finished, the finish
574859Snate@binkert.org * function is called which will indicate whether the whole translation is
588931Sandreas.hansson@arm.com * completed or not.  There are also functions for accessing parts of the
598931Sandreas.hansson@arm.com * translation state which deal with the possible split correctly.
602902SN/A */
619408Sandreas.hansson@arm.comclass WholeTranslationState
6210700Sandreas.hansson@arm.com{
6310700Sandreas.hansson@arm.com  protected:
6410700Sandreas.hansson@arm.com    int outstanding;
6510700Sandreas.hansson@arm.com    Fault faults[2];
6610700Sandreas.hansson@arm.com
6710700Sandreas.hansson@arm.com  public:
6810700Sandreas.hansson@arm.com    bool delay;
699408Sandreas.hansson@arm.com    bool isSplit;
709408Sandreas.hansson@arm.com    RequestPtr mainReq;
719408Sandreas.hansson@arm.com    RequestPtr sreqLow;
729408Sandreas.hansson@arm.com    RequestPtr sreqHigh;
739408Sandreas.hansson@arm.com    uint8_t *data;
749814Sandreas.hansson@arm.com    uint64_t *res;
759814Sandreas.hansson@arm.com    BaseTLB::Mode mode;
7611270Sandreas.sandberg@arm.com
7711270Sandreas.sandberg@arm.com    /**
787914SBrad.Beckmann@amd.com     * Single translation state.  We set the number of outstanding
798666SPrakash.Ramrakhyani@arm.com     * translations to one and indicate that it is not split.
807914SBrad.Beckmann@amd.com     */
817914SBrad.Beckmann@amd.com    WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
827914SBrad.Beckmann@amd.com                          BaseTLB::Mode _mode)
837914SBrad.Beckmann@amd.com        : outstanding(1), delay(false), isSplit(false), mainReq(_req),
847914SBrad.Beckmann@amd.com          sreqLow(NULL), sreqHigh(NULL), data(_data), res(_res), mode(_mode)
857914SBrad.Beckmann@amd.com    {
867914SBrad.Beckmann@amd.com        faults[0] = faults[1] = NoFault;
877914SBrad.Beckmann@amd.com        assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
887914SBrad.Beckmann@amd.com    }
897914SBrad.Beckmann@amd.com
907914SBrad.Beckmann@amd.com    /**
917914SBrad.Beckmann@amd.com     * Split translation state.  We copy all state into this class, set the
927914SBrad.Beckmann@amd.com     * number of outstanding translations to two and then mark this as a
938769Sgblack@eecs.umich.edu     * split translation.
948769Sgblack@eecs.umich.edu     */
958769Sgblack@eecs.umich.edu    WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
9610282Sdam.sunwoo@arm.com                          RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
9710282Sdam.sunwoo@arm.com                          BaseTLB::Mode _mode)
988769Sgblack@eecs.umich.edu        : outstanding(2), delay(false), isSplit(true), mainReq(_req),
998769Sgblack@eecs.umich.edu          sreqLow(_sreqLow), sreqHigh(_sreqHigh), data(_data), res(_res),
1008769Sgblack@eecs.umich.edu          mode(_mode)
10110037SARM gem5 Developers    {
10210037SARM gem5 Developers        faults[0] = faults[1] = NoFault;
10310249Sstephan.diestelhorst@arm.com        assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
10411146Smitch.hayenga@arm.com    }
10511146Smitch.hayenga@arm.com
10611146Smitch.hayenga@arm.com    /**
10710249Sstephan.diestelhorst@arm.com     * Finish part of a translation.  If there is only one request then this
10810249Sstephan.diestelhorst@arm.com     * translation is completed.  If the request has been split in two then
10910249Sstephan.diestelhorst@arm.com     * the outstanding count determines whether the translation is complete.
110     * In this case, flags from the split request are copied to the main
111     * request to make it easier to access them later on.
112     */
113    bool
114    finish(Fault fault, int index)
115    {
116        assert(outstanding);
117        faults[index] = fault;
118        outstanding--;
119        if (isSplit && outstanding == 0) {
120
121            // For ease later, we copy some state to the main request.
122            if (faults[0] == NoFault) {
123                mainReq->setPaddr(sreqLow->getPaddr());
124            }
125            mainReq->setFlags(sreqLow->getFlags());
126            mainReq->setFlags(sreqHigh->getFlags());
127        }
128        return outstanding == 0;
129    }
130
131    /**
132     * Determine whether this translation produced a fault.  Both parts of the
133     * translation must be checked if this is a split translation.
134     */
135    Fault
136    getFault() const
137    {
138        if (!isSplit)
139            return faults[0];
140        else if (faults[0] != NoFault)
141            return faults[0];
142        else if (faults[1] != NoFault)
143            return faults[1];
144        else
145            return NoFault;
146    }
147
148    /** Remove all faults from the translation. */
149    void
150    setNoFault()
151    {
152        faults[0] = faults[1] = NoFault;
153    }
154
155    /**
156     * Check if this request is uncacheable.  We only need to check the main
157     * request because the flags will have been copied here on a split
158     * translation.
159     */
160    bool
161    isUncacheable() const
162    {
163        return mainReq->isUncacheable();
164    }
165
166    /**
167     * Check if this request is a prefetch.  We only need to check the main
168     * request because the flags will have been copied here on a split
169     * translation.
170     */
171    bool
172    isPrefetch() const
173    {
174        return mainReq->isPrefetch();
175    }
176
177    /** Get the physical address of this request. */
178    Addr
179    getPaddr() const
180    {
181        return mainReq->getPaddr();
182    }
183
184    /**
185     * Get the flags associated with this request.  We only need to access
186     * the main request because the flags will have been copied here on a
187     * split translation.
188     */
189    unsigned
190    getFlags()
191    {
192        return mainReq->getFlags();
193    }
194
195    /** Delete all requests that make up this translation. */
196    void
197    deleteReqs()
198    {
199        delete mainReq;
200        if (isSplit) {
201            delete sreqLow;
202            delete sreqHigh;
203        }
204    }
205};
206
207
208/**
209 * This class represents part of a data address translation.  All state for
210 * the translation is held in WholeTranslationState (above).  Therefore this
211 * class does not need to know whether the translation is split or not.  The
212 * index variable determines this but is simply passed on to the state class.
213 * When this part of the translation is completed, finish is called.  If the
214 * translation state class indicate that the whole translation is complete
215 * then the execution context is informed.
216 */
217template <class ExecContextPtr>
218class DataTranslation : public BaseTLB::Translation
219{
220  protected:
221    ExecContextPtr xc;
222    WholeTranslationState *state;
223    int index;
224
225  public:
226    DataTranslation(ExecContextPtr _xc, WholeTranslationState* _state)
227        : xc(_xc), state(_state), index(0)
228    {
229    }
230
231    DataTranslation(ExecContextPtr _xc, WholeTranslationState* _state,
232                    int _index)
233        : xc(_xc), state(_state), index(_index)
234    {
235    }
236
237    /**
238     * Signal the translation state that the translation has been delayed due
239     * to a hw page table walk.  Split requests are transparently handled.
240     */
241    void
242    markDelayed()
243    {
244        state->delay = true;
245    }
246
247    /**
248     * Finish this part of the translation and indicate that the whole
249     * translation is complete if the state says so.
250     */
251    void
252    finish(Fault fault, RequestPtr req, ThreadContext *tc,
253           BaseTLB::Mode mode)
254    {
255        assert(state);
256        assert(mode == state->mode);
257        if (state->finish(fault, index)) {
258            xc->finishTranslation(state);
259        }
260        delete this;
261    }
262};
263
264#endif // __CPU_TRANSLATION_HH__
265