translation.hh (7049:a06e95c99294) translation.hh (7678:f19b6a3a8cec)
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
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/faults.hh"
36#include "sim/tlb.hh"
37
38/**
39 * This class captures the state of an address translation. A translation
40 * can be split in two if the ISA supports it and the memory access crosses
41 * a page boundary. In this case, this class is shared by two data
42 * translations (below). Otherwise it is used by a single data translation
43 * class. When each part of the translation is finished, the finish
44 * function is called which will indicate whether the whole translation is
45 * completed or not. There are also functions for accessing parts of the
46 * translation state which deal with the possible split correctly.
47 */
48class WholeTranslationState
49{
50 protected:
51 int outstanding;
52 Fault faults[2];
53
54 public:
55 bool isSplit;
56 RequestPtr mainReq;
57 RequestPtr sreqLow;
58 RequestPtr sreqHigh;
59 uint8_t *data;
60 uint64_t *res;
61 BaseTLB::Mode mode;
62
63 /**
64 * Single translation state. We set the number of outstanding
65 * translations to one and indicate that it is not split.
66 */
67 WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
68 BaseTLB::Mode _mode)
69 : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL),
70 sreqHigh(NULL), data(_data), res(_res), mode(_mode)
71 {
72 faults[0] = faults[1] = NoFault;
73 assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
74 }
75
76 /**
77 * Split translation state. We copy all state into this class, set the
78 * number of outstanding translations to two and then mark this as a
79 * split translation.
80 */
81 WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
82 RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
83 BaseTLB::Mode _mode)
84 : outstanding(2), isSplit(true), mainReq(_req), sreqLow(_sreqLow),
85 sreqHigh(_sreqHigh), data(_data), res(_res), mode(_mode)
86 {
87 faults[0] = faults[1] = NoFault;
88 assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
89 }
90
91 /**
92 * Finish part of a translation. If there is only one request then this
93 * translation is completed. If the request has been split in two then
94 * the outstanding count determines whether the translation is complete.
95 * In this case, flags from the split request are copied to the main
96 * request to make it easier to access them later on.
97 */
98 bool
99 finish(Fault fault, int index)
100 {
101 assert(outstanding);
102 faults[index] = fault;
103 outstanding--;
104 if (isSplit && outstanding == 0) {
105
106 // For ease later, we copy some state to the main request.
107 if (faults[0] == NoFault) {
108 mainReq->setPaddr(sreqLow->getPaddr());
109 }
110 mainReq->setFlags(sreqLow->getFlags());
111 mainReq->setFlags(sreqHigh->getFlags());
112 }
113 return outstanding == 0;
114 }
115
116 /**
117 * Determine whether this translation produced a fault. Both parts of the
118 * translation must be checked if this is a split translation.
119 */
120 Fault
121 getFault() const
122 {
123 if (!isSplit)
124 return faults[0];
125 else if (faults[0] != NoFault)
126 return faults[0];
127 else if (faults[1] != NoFault)
128 return faults[1];
129 else
130 return NoFault;
131 }
132
133 /** Remove all faults from the translation. */
134 void
135 setNoFault()
136 {
137 faults[0] = faults[1] = NoFault;
138 }
139
140 /**
141 * Check if this request is uncacheable. We only need to check the main
142 * request because the flags will have been copied here on a split
143 * translation.
144 */
145 bool
146 isUncacheable() const
147 {
148 return mainReq->isUncacheable();
149 }
150
151 /**
152 * Check if this request is a prefetch. We only need to check the main
153 * request because the flags will have been copied here on a split
154 * translation.
155 */
156 bool
157 isPrefetch() const
158 {
159 return mainReq->isPrefetch();
160 }
161
162 /** Get the physical address of this request. */
163 Addr
164 getPaddr() const
165 {
166 return mainReq->getPaddr();
167 }
168
169 /**
170 * Get the flags associated with this request. We only need to access
171 * the main request because the flags will have been copied here on a
172 * split translation.
173 */
174 unsigned
175 getFlags()
176 {
177 return mainReq->getFlags();
178 }
179
180 /** Delete all requests that make up this translation. */
181 void
182 deleteReqs()
183 {
184 delete mainReq;
185 if (isSplit) {
186 delete sreqLow;
187 delete sreqHigh;
188 }
189 }
190};
191
192
193/**
194 * This class represents part of a data address translation. All state for
195 * the translation is held in WholeTranslationState (above). Therefore this
196 * class does not need to know whether the translation is split or not. The
197 * index variable determines this but is simply passed on to the state class.
198 * When this part of the translation is completed, finish is called. If the
199 * translation state class indicate that the whole translation is complete
200 * then the execution context is informed.
201 */
202template <class ExecContext>
203class DataTranslation : public BaseTLB::Translation
204{
205 protected:
206 ExecContext *xc;
207 WholeTranslationState *state;
208 int index;
209
210 public:
211 DataTranslation(ExecContext *_xc, WholeTranslationState* _state)
212 : xc(_xc), state(_state), index(0)
213 {
214 }
215
216 DataTranslation(ExecContext *_xc, WholeTranslationState* _state,
217 int _index)
218 : xc(_xc), state(_state), index(_index)
219 {
220 }
221
222 /**
223 * Finish this part of the translation and indicate that the whole
224 * translation is complete if the state says so.
225 */
226 void
227 finish(Fault fault, RequestPtr req, ThreadContext *tc,
228 BaseTLB::Mode mode)
229 {
230 assert(state);
231 assert(mode == state->mode);
232 if (state->finish(fault, index)) {
233 xc->finishTranslation(state);
234 }
235 delete this;
236 }
237};
238
239#endif // __CPU_TRANSLATION_HH__
37#include "sim/tlb.hh"
38
39/**
40 * This class captures the state of an address translation. A translation
41 * can be split in two if the ISA supports it and the memory access crosses
42 * a page boundary. In this case, this class is shared by two data
43 * translations (below). Otherwise it is used by a single data translation
44 * class. When each part of the translation is finished, the finish
45 * function is called which will indicate whether the whole translation is
46 * completed or not. There are also functions for accessing parts of the
47 * translation state which deal with the possible split correctly.
48 */
49class WholeTranslationState
50{
51 protected:
52 int outstanding;
53 Fault faults[2];
54
55 public:
56 bool isSplit;
57 RequestPtr mainReq;
58 RequestPtr sreqLow;
59 RequestPtr sreqHigh;
60 uint8_t *data;
61 uint64_t *res;
62 BaseTLB::Mode mode;
63
64 /**
65 * Single translation state. We set the number of outstanding
66 * translations to one and indicate that it is not split.
67 */
68 WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
69 BaseTLB::Mode _mode)
70 : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL),
71 sreqHigh(NULL), data(_data), res(_res), mode(_mode)
72 {
73 faults[0] = faults[1] = NoFault;
74 assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
75 }
76
77 /**
78 * Split translation state. We copy all state into this class, set the
79 * number of outstanding translations to two and then mark this as a
80 * split translation.
81 */
82 WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
83 RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
84 BaseTLB::Mode _mode)
85 : outstanding(2), isSplit(true), mainReq(_req), sreqLow(_sreqLow),
86 sreqHigh(_sreqHigh), data(_data), res(_res), mode(_mode)
87 {
88 faults[0] = faults[1] = NoFault;
89 assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
90 }
91
92 /**
93 * Finish part of a translation. If there is only one request then this
94 * translation is completed. If the request has been split in two then
95 * the outstanding count determines whether the translation is complete.
96 * In this case, flags from the split request are copied to the main
97 * request to make it easier to access them later on.
98 */
99 bool
100 finish(Fault fault, int index)
101 {
102 assert(outstanding);
103 faults[index] = fault;
104 outstanding--;
105 if (isSplit && outstanding == 0) {
106
107 // For ease later, we copy some state to the main request.
108 if (faults[0] == NoFault) {
109 mainReq->setPaddr(sreqLow->getPaddr());
110 }
111 mainReq->setFlags(sreqLow->getFlags());
112 mainReq->setFlags(sreqHigh->getFlags());
113 }
114 return outstanding == 0;
115 }
116
117 /**
118 * Determine whether this translation produced a fault. Both parts of the
119 * translation must be checked if this is a split translation.
120 */
121 Fault
122 getFault() const
123 {
124 if (!isSplit)
125 return faults[0];
126 else if (faults[0] != NoFault)
127 return faults[0];
128 else if (faults[1] != NoFault)
129 return faults[1];
130 else
131 return NoFault;
132 }
133
134 /** Remove all faults from the translation. */
135 void
136 setNoFault()
137 {
138 faults[0] = faults[1] = NoFault;
139 }
140
141 /**
142 * Check if this request is uncacheable. We only need to check the main
143 * request because the flags will have been copied here on a split
144 * translation.
145 */
146 bool
147 isUncacheable() const
148 {
149 return mainReq->isUncacheable();
150 }
151
152 /**
153 * Check if this request is a prefetch. We only need to check the main
154 * request because the flags will have been copied here on a split
155 * translation.
156 */
157 bool
158 isPrefetch() const
159 {
160 return mainReq->isPrefetch();
161 }
162
163 /** Get the physical address of this request. */
164 Addr
165 getPaddr() const
166 {
167 return mainReq->getPaddr();
168 }
169
170 /**
171 * Get the flags associated with this request. We only need to access
172 * the main request because the flags will have been copied here on a
173 * split translation.
174 */
175 unsigned
176 getFlags()
177 {
178 return mainReq->getFlags();
179 }
180
181 /** Delete all requests that make up this translation. */
182 void
183 deleteReqs()
184 {
185 delete mainReq;
186 if (isSplit) {
187 delete sreqLow;
188 delete sreqHigh;
189 }
190 }
191};
192
193
194/**
195 * This class represents part of a data address translation. All state for
196 * the translation is held in WholeTranslationState (above). Therefore this
197 * class does not need to know whether the translation is split or not. The
198 * index variable determines this but is simply passed on to the state class.
199 * When this part of the translation is completed, finish is called. If the
200 * translation state class indicate that the whole translation is complete
201 * then the execution context is informed.
202 */
203template <class ExecContext>
204class DataTranslation : public BaseTLB::Translation
205{
206 protected:
207 ExecContext *xc;
208 WholeTranslationState *state;
209 int index;
210
211 public:
212 DataTranslation(ExecContext *_xc, WholeTranslationState* _state)
213 : xc(_xc), state(_state), index(0)
214 {
215 }
216
217 DataTranslation(ExecContext *_xc, WholeTranslationState* _state,
218 int _index)
219 : xc(_xc), state(_state), index(_index)
220 {
221 }
222
223 /**
224 * Finish this part of the translation and indicate that the whole
225 * translation is complete if the state says so.
226 */
227 void
228 finish(Fault fault, RequestPtr req, ThreadContext *tc,
229 BaseTLB::Mode mode)
230 {
231 assert(state);
232 assert(mode == state->mode);
233 if (state->finish(fault, index)) {
234 xc->finishTranslation(state);
235 }
236 delete this;
237 }
238};
239
240#endif // __CPU_TRANSLATION_HH__