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