faults.hh revision 8591:8f23aeaf6a91
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 */ 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 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 73class MipsFaultBase : public FaultBase 74{ 75 public: 76 struct FaultVals 77 { 78 const FaultName name; 79 const FaultVect offset; 80 const ExcCode code; 81 }; 82 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); 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; } 113 FaultVect offset(ThreadContext *tc) const { return vals.offset; } 114 ExcCode code() const { return vals.code; } 115}; 116 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> {}; 124 125class MachineCheckFault : public MipsFault<MachineCheckFault> 126{ 127 public: 128 bool isMachineCheckFault() { return true; } 129}; 130 131class ResetFault : public MipsFault<ResetFault> 132{ 133 public: 134 void invoke(ThreadContext * tc, 135 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 136 137}; 138 139class SoftResetFault : public MipsFault<SoftResetFault> 140{ 141 public: 142 void invoke(ThreadContext * tc, 143 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 144}; 145 146class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt> 147{ 148 public: 149 void invoke(ThreadContext * tc, 150 StaticInstPtr inst = StaticInst::nullStaticInstPtr); 151}; 152 153class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault> 154{ 155 protected: 156 int coProcID; 157 public: 158 CoprocessorUnusableFault(int _procid) : coProcID(_procid) 159 {} 160 161 void 162 invoke(ThreadContext * tc, 163 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 164 { 165 MipsFault<CoprocessorUnusableFault>::invoke(tc, inst); 166 if (FULL_SYSTEM) { 167 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 168 cause.ce = coProcID; 169 tc->setMiscReg(MISCREG_CAUSE, cause); 170 } 171 } 172}; 173 174class InterruptFault : public MipsFault<InterruptFault> 175{ 176 public: 177 FaultVect 178 offset(ThreadContext *tc) const 179 { 180 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 181 return cause.iv ? 0x200 : 0x000; 182 } 183}; 184 185template <typename T> 186class AddressFault : public MipsFault<T> 187{ 188 protected: 189 Addr vaddr; 190 bool store; 191 192 AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store) 193 {} 194 195 void 196 invoke(ThreadContext * tc, 197 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 198 { 199 MipsFault<T>::invoke(tc, inst); 200 if (FULL_SYSTEM) 201 tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); 202 } 203}; 204 205class AddressErrorFault : public AddressFault<AddressErrorFault> 206{ 207 public: 208 AddressErrorFault(Addr _vaddr, bool _store) : 209 AddressFault<AddressErrorFault>(_vaddr, _store) 210 {} 211 212 ExcCode 213 code() const 214 { 215 return store ? ExcCodeAdES : ExcCodeAdEL; 216 } 217 218}; 219 220template <typename T> 221class TlbFault : public AddressFault<T> 222{ 223 protected: 224 Addr asid; 225 Addr vpn; 226 227 TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) : 228 AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn) 229 {} 230 231 void 232 setTlbExceptionState(ThreadContext *tc, uint8_t excCode) 233 { 234 this->setExceptionState(tc, excCode); 235 236 tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr); 237 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 238 entryHi.asid = this->asid; 239 entryHi.vpn2 = this->vpn >> 2; 240 entryHi.vpn2x = this->vpn & 0x3; 241 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 242 243 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 244 context.badVPN2 = this->vpn >> 2; 245 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 246 } 247 248 void 249 invoke(ThreadContext * tc, 250 StaticInstPtr inst = StaticInst::nullStaticInstPtr) 251 { 252 if (FULL_SYSTEM) { 253 DPRINTF(MipsPRA, "Fault %s encountered.\n", name()); 254 tc->pcState(this->vect(tc)); 255 setTlbExceptionState(tc, this->code()); 256 } else { 257 AddressFault<T>::invoke(tc, inst); 258 } 259 } 260 261 ExcCode 262 code() const 263 { 264 return this->store ? ExcCodeTlbS : ExcCodeTlbL; 265 } 266}; 267 268class TlbRefillFault : public TlbFault<TlbRefillFault> 269{ 270 public: 271 TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) : 272 TlbFault<TlbRefillFault>(asid, vaddr, vpn, store) 273 {} 274 275 FaultVect 276 offset(ThreadContext *tc) const 277 { 278 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 279 return status.exl ? 0x180 : 0x000; 280 } 281}; 282 283class TlbInvalidFault : public TlbFault<TlbInvalidFault> 284{ 285 public: 286 TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) : 287 TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store) 288 {} 289}; 290 291class TlbModifiedFault : public TlbFault<TlbModifiedFault> 292{ 293 public: 294 TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) : 295 TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false) 296 {} 297 298 ExcCode code() const { return vals.code; } 299}; 300 301} // namespace MipsISA 302 303#endif // __MIPS_FAULTS_HH__ 304