translation.hh revision 6973
1/*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * Copyright (c) 2009 The University of Edinburgh
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Authors: Gabe Black
30 *          Timothy M. Jones
31 */
32
33#ifndef __CPU_TRANSLATION_HH__
34#define __CPU_TRANSLATION_HH__
35
36#include "sim/tlb.hh"
37
38class WholeTranslationState
39{
40  protected:
41    int outstanding;
42    Fault faults[2];
43
44  public:
45    bool isSplit;
46    RequestPtr mainReq;
47    RequestPtr sreqLow;
48    RequestPtr sreqHigh;
49    uint8_t *data;
50    uint64_t *res;
51    BaseTLB::Mode mode;
52
53    /** Single translation state. */
54    WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
55                          BaseTLB::Mode _mode)
56        : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL),
57          sreqHigh(NULL), data(_data), res(_res), mode(_mode)
58    {
59        faults[0] = faults[1] = NoFault;
60        assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
61    }
62
63    /** Split translation state. */
64    WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
65                          RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
66                          BaseTLB::Mode _mode)
67        : outstanding(2), isSplit(true), mainReq(_req), sreqLow(_sreqLow),
68          sreqHigh(_sreqHigh), data(_data), res(_res), mode(_mode)
69    {
70        faults[0] = faults[1] = NoFault;
71        assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
72    }
73
74    bool
75    finish(Fault fault, int index)
76    {
77        assert(outstanding);
78        faults[index] = fault;
79        outstanding--;
80        if (isSplit && outstanding == 0) {
81
82            // For ease later, we copy some state to the main request.
83            if (faults[0] == NoFault) {
84                mainReq->setPaddr(sreqLow->getPaddr());
85            }
86            mainReq->setFlags(sreqLow->getFlags());
87            mainReq->setFlags(sreqHigh->getFlags());
88        }
89        return outstanding == 0;
90    }
91
92    Fault
93    getFault() const
94    {
95        if (!isSplit)
96            return faults[0];
97        else if (faults[0] != NoFault)
98            return faults[0];
99        else if (faults[1] != NoFault)
100            return faults[1];
101        else
102            return NoFault;
103    }
104
105    void
106    setNoFault()
107    {
108        faults[0] = faults[1] = NoFault;
109    }
110
111    bool
112    isUncacheable() const
113    {
114        return mainReq->isUncacheable();
115    }
116
117    bool
118    isPrefetch() const
119    {
120        return mainReq->isPrefetch();
121    }
122
123    Addr
124    getPaddr() const
125    {
126        return mainReq->getPaddr();
127    }
128
129    unsigned
130    getFlags()
131    {
132        return mainReq->getFlags();
133    }
134
135    void
136    deleteReqs()
137    {
138        delete mainReq;
139        if (isSplit) {
140            delete sreqLow;
141            delete sreqHigh;
142        }
143    }
144};
145
146template <class ExecContext>
147class DataTranslation : public BaseTLB::Translation
148{
149  protected:
150    ExecContext *xc;
151    WholeTranslationState *state;
152    int index;
153
154  public:
155    DataTranslation(ExecContext *_xc, WholeTranslationState* _state)
156        : xc(_xc), state(_state), index(0)
157    {
158    }
159
160    DataTranslation(ExecContext *_xc, WholeTranslationState* _state,
161                    int _index)
162        : xc(_xc), state(_state), index(_index)
163    {
164    }
165
166    void
167    finish(Fault fault, RequestPtr req, ThreadContext *tc,
168           BaseTLB::Mode mode)
169    {
170        assert(state);
171        assert(mode == state->mode);
172        if (state->finish(fault, index)) {
173            xc->finishTranslation(state);
174        }
175        delete this;
176    }
177};
178
179#endif // __CPU_TRANSLATION_HH__
180