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/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__
|