1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * Copyright (c) 2007 MIPS Technologies, Inc. 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 * Korey Sewell 31 * Jaidev Patwardhan
| 1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * Copyright (c) 2007 MIPS Technologies, Inc. 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 * Korey Sewell 31 * Jaidev Patwardhan
|
32 * Zhengxing Li 33 * Deyuan Guo
| |
34 */ 35 36#ifndef __MIPS_FAULTS_HH__ 37#define __MIPS_FAULTS_HH__ 38 39#include "arch/mips/pra_constants.hh" 40#include "cpu/thread_context.hh" 41#include "debug/MipsPRA.hh" 42#include "sim/faults.hh"
| 32 */ 33 34#ifndef __MIPS_FAULTS_HH__ 35#define __MIPS_FAULTS_HH__ 36 37#include "arch/mips/pra_constants.hh" 38#include "cpu/thread_context.hh" 39#include "debug/MipsPRA.hh" 40#include "sim/faults.hh"
|
| 41#include "sim/full_system.hh"
|
43 44namespace MipsISA 45{ 46 47typedef const Addr FaultVect; 48 49enum ExcCode { 50 // A dummy value to use when the code isn't defined or doesn't matter. 51 ExcCodeDummy = 0, 52 53 ExcCodeInt = 0, 54 ExcCodeMod = 1, 55 ExcCodeTlbL = 2, 56 ExcCodeTlbS = 3, 57 ExcCodeAdEL = 4, 58 ExcCodeAdES = 5, 59 ExcCodeIBE = 6, 60 ExcCodeDBE = 7, 61 ExcCodeSys = 8, 62 ExcCodeBp = 9, 63 ExcCodeRI = 10, 64 ExcCodeCpU = 11, 65 ExcCodeOv = 12, 66 ExcCodeTr = 13, 67 ExcCodeC2E = 18, 68 ExcCodeMDMX = 22, 69 ExcCodeWatch = 23, 70 ExcCodeMCheck = 24, 71 ExcCodeThread = 25, 72 ExcCodeCacheErr = 30 73}; 74 75class MipsFaultBase : public FaultBase 76{ 77 public: 78 struct FaultVals 79 { 80 const FaultName name; 81 const FaultVect offset; 82 const ExcCode code; 83 }; 84 85 void setExceptionState(ThreadContext *, uint8_t); 86 87 virtual FaultVect offset(ThreadContext *tc) const = 0; 88 virtual ExcCode code() const = 0; 89 virtual FaultVect base(ThreadContext *tc) const 90 { 91 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
| 42 43namespace MipsISA 44{ 45 46typedef const Addr FaultVect; 47 48enum ExcCode { 49 // A dummy value to use when the code isn't defined or doesn't matter. 50 ExcCodeDummy = 0, 51 52 ExcCodeInt = 0, 53 ExcCodeMod = 1, 54 ExcCodeTlbL = 2, 55 ExcCodeTlbS = 3, 56 ExcCodeAdEL = 4, 57 ExcCodeAdES = 5, 58 ExcCodeIBE = 6, 59 ExcCodeDBE = 7, 60 ExcCodeSys = 8, 61 ExcCodeBp = 9, 62 ExcCodeRI = 10, 63 ExcCodeCpU = 11, 64 ExcCodeOv = 12, 65 ExcCodeTr = 13, 66 ExcCodeC2E = 18, 67 ExcCodeMDMX = 22, 68 ExcCodeWatch = 23, 69 ExcCodeMCheck = 24, 70 ExcCodeThread = 25, 71 ExcCodeCacheErr = 30 72}; 73 74class MipsFaultBase : public FaultBase 75{ 76 public: 77 struct FaultVals 78 { 79 const FaultName name; 80 const FaultVect offset; 81 const ExcCode code; 82 }; 83 84 void setExceptionState(ThreadContext *, uint8_t); 85 86 virtual FaultVect offset(ThreadContext *tc) const = 0; 87 virtual ExcCode code() const = 0; 88 virtual FaultVect base(ThreadContext *tc) const 89 { 90 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
|
92 if (!status.bev)
| 91 if (status.bev)
|
93 return tc->readMiscReg(MISCREG_EBASE); 94 else 95 return 0xbfc00200; 96 } 97 98 FaultVect 99 vect(ThreadContext *tc) const 100 { 101 return base(tc) + offset(tc); 102 } 103 104 void invoke(ThreadContext * tc, 105 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 106}; 107 108template <typename T> 109class MipsFault : public MipsFaultBase 110{ 111 protected: 112 static FaultVals vals; 113 public: 114 FaultName name() const { return vals.name; } 115 FaultVect offset(ThreadContext *tc) const { return vals.offset; } 116 ExcCode code() const { return vals.code; } 117}; 118 119class SystemCallFault : public MipsFault<SystemCallFault> {}; 120class ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {}; 121class ThreadFault : public MipsFault<ThreadFault> {}; 122class IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {}; 123class TrapFault : public MipsFault<TrapFault> {}; 124class BreakpointFault : public MipsFault<BreakpointFault> {}; 125class DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {}; 126 127class MachineCheckFault : public MipsFault<MachineCheckFault> 128{ 129 public: 130 bool isMachineCheckFault() { return true; } 131}; 132 133class ResetFault : public MipsFault<ResetFault> 134{ 135 public: 136 void invoke(ThreadContext * tc, 137 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 138 139}; 140 141class SoftResetFault : public MipsFault<SoftResetFault> 142{ 143 public: 144 void invoke(ThreadContext * tc, 145 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 146}; 147 148class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt> 149{ 150 public: 151 void invoke(ThreadContext * tc, 152 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 153}; 154 155class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault> 156{ 157 protected: 158 int coProcID; 159 public: 160 CoprocessorUnusableFault(int _procid) : coProcID(_procid) 161 {} 162 163 void 164 invoke(ThreadContext * tc, 165 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 166 { 167 MipsFault<CoprocessorUnusableFault>::invoke(tc, inst);
| 92 return tc->readMiscReg(MISCREG_EBASE); 93 else 94 return 0xbfc00200; 95 } 96 97 FaultVect 98 vect(ThreadContext *tc) const 99 { 100 return base(tc) + offset(tc); 101 } 102 103 void invoke(ThreadContext * tc, 104 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 105}; 106 107template <typename T> 108class MipsFault : public MipsFaultBase 109{ 110 protected: 111 static FaultVals vals; 112 public: 113 FaultName name() const { return vals.name; } 114 FaultVect offset(ThreadContext *tc) const { return vals.offset; } 115 ExcCode code() const { return vals.code; } 116}; 117 118class SystemCallFault : public MipsFault<SystemCallFault> {}; 119class ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {}; 120class ThreadFault : public MipsFault<ThreadFault> {}; 121class IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {}; 122class TrapFault : public MipsFault<TrapFault> {}; 123class BreakpointFault : public MipsFault<BreakpointFault> {}; 124class DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {}; 125 126class MachineCheckFault : public MipsFault<MachineCheckFault> 127{ 128 public: 129 bool isMachineCheckFault() { return true; } 130}; 131 132class ResetFault : public MipsFault<ResetFault> 133{ 134 public: 135 void invoke(ThreadContext * tc, 136 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 137 138}; 139 140class SoftResetFault : public MipsFault<SoftResetFault> 141{ 142 public: 143 void invoke(ThreadContext * tc, 144 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 145}; 146 147class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt> 148{ 149 public: 150 void invoke(ThreadContext * tc, 151 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 152}; 153 154class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault> 155{ 156 protected: 157 int coProcID; 158 public: 159 CoprocessorUnusableFault(int _procid) : coProcID(_procid) 160 {} 161 162 void 163 invoke(ThreadContext * tc, 164 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 165 { 166 MipsFault<CoprocessorUnusableFault>::invoke(tc, inst);
|
168 if (FULL_SYSTEM) {
| 167 if (FullSystem) {
|
169 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 170 cause.ce = coProcID;
| 168 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 169 cause.ce = coProcID;
|
171 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
| 170 tc->setMiscReg(MISCREG_CAUSE, cause);
|
172 } 173 } 174}; 175 176class InterruptFault : public MipsFault<InterruptFault> 177{ 178 public: 179 FaultVect 180 offset(ThreadContext *tc) const 181 { 182 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
| 171 } 172 } 173}; 174 175class InterruptFault : public MipsFault<InterruptFault> 176{ 177 public: 178 FaultVect 179 offset(ThreadContext *tc) const 180 { 181 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
|
183 // offset 0x200 for release 2, 0x180 for release 1. 184 return cause.iv ? 0x200 : 0x180;
| 182 return cause.iv ? 0x200 : 0x000;
|
185 } 186}; 187 188template <typename T> 189class AddressFault : public MipsFault<T> 190{ 191 protected: 192 Addr vaddr; 193 bool store; 194 195 AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store) 196 {} 197 198 void 199 invoke(ThreadContext * tc, 200 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 201 { 202 MipsFault<T>::invoke(tc, inst);
| 183 } 184}; 185 186template <typename T> 187class AddressFault : public MipsFault<T> 188{ 189 protected: 190 Addr vaddr; 191 bool store; 192 193 AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store) 194 {} 195 196 void 197 invoke(ThreadContext * tc, 198 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 199 { 200 MipsFault<T>::invoke(tc, inst);
|
203 if (FULL_SYSTEM)
| 201 if (FullSystem)
|
204 tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); 205 } 206}; 207 208class AddressErrorFault : public AddressFault<AddressErrorFault> 209{ 210 public: 211 AddressErrorFault(Addr _vaddr, bool _store) : 212 AddressFault<AddressErrorFault>(_vaddr, _store) 213 {} 214 215 ExcCode 216 code() const 217 { 218 return store ? ExcCodeAdES : ExcCodeAdEL; 219 } 220 221}; 222 223template <typename T> 224class TlbFault : public AddressFault<T> 225{ 226 protected: 227 Addr asid; 228 Addr vpn; 229 230 TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) : 231 AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn) 232 {} 233 234 void 235 setTlbExceptionState(ThreadContext *tc, uint8_t excCode) 236 { 237 this->setExceptionState(tc, excCode); 238 239 tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr); 240 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 241 entryHi.asid = this->asid; 242 entryHi.vpn2 = this->vpn >> 2; 243 entryHi.vpn2x = this->vpn & 0x3; 244 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 245 246 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 247 context.badVPN2 = this->vpn >> 2; 248 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 249 } 250 251 void 252 invoke(ThreadContext * tc, 253 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 254 {
| 202 tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); 203 } 204}; 205 206class AddressErrorFault : public AddressFault<AddressErrorFault> 207{ 208 public: 209 AddressErrorFault(Addr _vaddr, bool _store) : 210 AddressFault<AddressErrorFault>(_vaddr, _store) 211 {} 212 213 ExcCode 214 code() const 215 { 216 return store ? ExcCodeAdES : ExcCodeAdEL; 217 } 218 219}; 220 221template <typename T> 222class TlbFault : public AddressFault<T> 223{ 224 protected: 225 Addr asid; 226 Addr vpn; 227 228 TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) : 229 AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn) 230 {} 231 232 void 233 setTlbExceptionState(ThreadContext *tc, uint8_t excCode) 234 { 235 this->setExceptionState(tc, excCode); 236 237 tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr); 238 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 239 entryHi.asid = this->asid; 240 entryHi.vpn2 = this->vpn >> 2; 241 entryHi.vpn2x = this->vpn & 0x3; 242 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 243 244 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 245 context.badVPN2 = this->vpn >> 2; 246 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 247 } 248 249 void 250 invoke(ThreadContext * tc, 251 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 252 {
|
255 if (FULL_SYSTEM) { 256 DPRINTF(MipsPRA, "Fault %s encountered.\n", this->name()); 257 Addr vect = this->vect(tc);
| 253 if (FullSystem) { 254 DPRINTF(MipsPRA, "Fault %s encountered.\n", name()); 255 tc->pcState(this->vect(tc));
|
258 setTlbExceptionState(tc, this->code());
| 256 setTlbExceptionState(tc, this->code());
|
259 tc->pcState(vect);
| |
260 } else { 261 AddressFault<T>::invoke(tc, inst); 262 } 263 } 264 265 ExcCode 266 code() const 267 { 268 return this->store ? ExcCodeTlbS : ExcCodeTlbL; 269 } 270}; 271 272class TlbRefillFault : public TlbFault<TlbRefillFault> 273{ 274 public: 275 TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) : 276 TlbFault<TlbRefillFault>(asid, vaddr, vpn, store) 277 {} 278 279 FaultVect 280 offset(ThreadContext *tc) const 281 { 282 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 283 return status.exl ? 0x180 : 0x000; 284 } 285}; 286 287class TlbInvalidFault : public TlbFault<TlbInvalidFault> 288{ 289 public: 290 TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) : 291 TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store) 292 {} 293}; 294 295class TlbModifiedFault : public TlbFault<TlbModifiedFault> 296{ 297 public: 298 TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) : 299 TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false) 300 {} 301
| 257 } else { 258 AddressFault<T>::invoke(tc, inst); 259 } 260 } 261 262 ExcCode 263 code() const 264 { 265 return this->store ? ExcCodeTlbS : ExcCodeTlbL; 266 } 267}; 268 269class TlbRefillFault : public TlbFault<TlbRefillFault> 270{ 271 public: 272 TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) : 273 TlbFault<TlbRefillFault>(asid, vaddr, vpn, store) 274 {} 275 276 FaultVect 277 offset(ThreadContext *tc) const 278 { 279 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 280 return status.exl ? 0x180 : 0x000; 281 } 282}; 283 284class TlbInvalidFault : public TlbFault<TlbInvalidFault> 285{ 286 public: 287 TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) : 288 TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store) 289 {} 290}; 291 292class TlbModifiedFault : public TlbFault<TlbModifiedFault> 293{ 294 public: 295 TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) : 296 TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false) 297 {} 298
|
302 ExcCode code() const { return MipsFault<TlbModifiedFault>::code(); }
| 299 ExcCode code() const { return vals.code; }
|
303}; 304 305} // namespace MipsISA 306 307#endif // __MIPS_FAULTS_HH__
| 300}; 301 302} // namespace MipsISA 303 304#endif // __MIPS_FAULTS_HH__
|