faults.hh revision 12176
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 312855Sgabeblack@google.com * Copyright (c) 2007 MIPS Technologies, Inc. 412855Sgabeblack@google.com * All rights reserved. 512855Sgabeblack@google.com * 612855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 712855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 812855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 912855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1012855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1112855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1212855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1312855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1412855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1512855Sgabeblack@google.com * this software without specific prior written permission. 1612855Sgabeblack@google.com * 1712855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1812855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1912855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2012855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2112855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2212855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2312855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2412855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2512855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2612855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2712855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2812855Sgabeblack@google.com * 2912855Sgabeblack@google.com * Authors: Gabe Black 3012855Sgabeblack@google.com * Korey Sewell 3112855Sgabeblack@google.com * Jaidev Patwardhan 3212855Sgabeblack@google.com * Zhengxing Li 3312855Sgabeblack@google.com * Deyuan Guo 3412855Sgabeblack@google.com */ 3512855Sgabeblack@google.com 3612855Sgabeblack@google.com#ifndef __MIPS_FAULTS_HH__ 3712855Sgabeblack@google.com#define __MIPS_FAULTS_HH__ 3812855Sgabeblack@google.com 3912855Sgabeblack@google.com#include "arch/mips/pra_constants.hh" 4012855Sgabeblack@google.com#include "cpu/thread_context.hh" 4112855Sgabeblack@google.com#include "debug/MipsPRA.hh" 4212855Sgabeblack@google.com#include "sim/faults.hh" 4312855Sgabeblack@google.com#include "sim/full_system.hh" 4412855Sgabeblack@google.com 4512855Sgabeblack@google.comnamespace MipsISA 4612855Sgabeblack@google.com{ 4712855Sgabeblack@google.com 4812855Sgabeblack@google.comtypedef Addr FaultVect; 4912855Sgabeblack@google.com 5012855Sgabeblack@google.comenum ExcCode { 5112855Sgabeblack@google.com // A dummy value to use when the code isn't defined or doesn't matter. 5212855Sgabeblack@google.com ExcCodeDummy = 0, 5312855Sgabeblack@google.com 5412855Sgabeblack@google.com ExcCodeInt = 0, 5512855Sgabeblack@google.com ExcCodeMod = 1, 5612855Sgabeblack@google.com ExcCodeTlbL = 2, 5712855Sgabeblack@google.com ExcCodeTlbS = 3, 5812855Sgabeblack@google.com ExcCodeAdEL = 4, 5912855Sgabeblack@google.com ExcCodeAdES = 5, 6012855Sgabeblack@google.com ExcCodeIBE = 6, 6112855Sgabeblack@google.com ExcCodeDBE = 7, 6212855Sgabeblack@google.com ExcCodeSys = 8, 6312855Sgabeblack@google.com ExcCodeBp = 9, 6412855Sgabeblack@google.com ExcCodeRI = 10, 6512855Sgabeblack@google.com ExcCodeCpU = 11, 66 ExcCodeOv = 12, 67 ExcCodeTr = 13, 68 ExcCodeC2E = 18, 69 ExcCodeMDMX = 22, 70 ExcCodeWatch = 23, 71 ExcCodeMCheck = 24, 72 ExcCodeThread = 25, 73 ExcCodeCacheErr = 30 74}; 75 76class MipsFaultBase : public FaultBase 77{ 78 public: 79 struct FaultVals 80 { 81 const FaultName name; 82 const FaultVect offset; 83 const ExcCode code; 84 }; 85 86 void setExceptionState(ThreadContext *, uint8_t); 87 88 virtual FaultVect offset(ThreadContext *tc) const = 0; 89 virtual ExcCode code() const = 0; 90 virtual FaultVect base(ThreadContext *tc) const 91 { 92 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 93 if (!status.bev) 94 return tc->readMiscReg(MISCREG_EBASE); 95 else 96 return 0xbfc00200; 97 } 98 99 FaultVect 100 vect(ThreadContext *tc) const 101 { 102 return base(tc) + offset(tc); 103 } 104 105 void invoke(ThreadContext * tc, const StaticInstPtr &inst = 106 StaticInst::nullStaticInstPtr); 107}; 108 109template <typename T> 110class MipsFault : public MipsFaultBase 111{ 112 protected: 113 static FaultVals vals; 114 public: 115 FaultName name() const { return vals.name; } 116 FaultVect offset(ThreadContext *tc) const { return vals.offset; } 117 ExcCode code() const { return vals.code; } 118}; 119 120class SystemCallFault : public MipsFault<SystemCallFault> {}; 121class ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {}; 122class ThreadFault : public MipsFault<ThreadFault> {}; 123class IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {}; 124class TrapFault : public MipsFault<TrapFault> {}; 125class BreakpointFault : public MipsFault<BreakpointFault> {}; 126class DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {}; 127 128class MachineCheckFault : public MipsFault<MachineCheckFault> 129{ 130 public: 131 bool isMachineCheckFault() { return true; } 132}; 133 134class ResetFault : public MipsFault<ResetFault> 135{ 136 public: 137 void invoke(ThreadContext * tc, const StaticInstPtr &inst = 138 StaticInst::nullStaticInstPtr); 139 140}; 141 142class SoftResetFault : public MipsFault<SoftResetFault> 143{ 144 public: 145 void invoke(ThreadContext * tc, const StaticInstPtr &inst = 146 StaticInst::nullStaticInstPtr); 147}; 148 149class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt> 150{ 151 public: 152 void invoke(ThreadContext * tc, const StaticInstPtr &inst = 153 StaticInst::nullStaticInstPtr); 154}; 155 156class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault> 157{ 158 protected: 159 int coProcID; 160 public: 161 CoprocessorUnusableFault(int _procid) : coProcID(_procid) 162 {} 163 164 void 165 invoke(ThreadContext * tc, const StaticInstPtr &inst = 166 StaticInst::nullStaticInstPtr) 167 { 168 MipsFault<CoprocessorUnusableFault>::invoke(tc, inst); 169 if (FullSystem) { 170 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 171 cause.ce = coProcID; 172 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 173 } 174 } 175}; 176 177class InterruptFault : public MipsFault<InterruptFault> 178{ 179 public: 180 FaultVect 181 offset(ThreadContext *tc) const 182 { 183 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 184 // offset 0x200 for release 2, 0x180 for release 1. 185 return cause.iv ? 0x200 : 0x180; 186 } 187}; 188 189template <typename T> 190class AddressFault : public MipsFault<T> 191{ 192 protected: 193 Addr vaddr; 194 bool store; 195 196 AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store) 197 {} 198 199 void 200 invoke(ThreadContext * tc, const StaticInstPtr &inst = 201 StaticInst::nullStaticInstPtr) 202 { 203 MipsFault<T>::invoke(tc, inst); 204 if (FullSystem) 205 tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); 206 } 207}; 208 209class AddressErrorFault : public AddressFault<AddressErrorFault> 210{ 211 public: 212 AddressErrorFault(Addr _vaddr, bool _store) : 213 AddressFault<AddressErrorFault>(_vaddr, _store) 214 {} 215 216 ExcCode 217 code() const 218 { 219 return store ? ExcCodeAdES : ExcCodeAdEL; 220 } 221 222}; 223 224template <typename T> 225class TlbFault : public AddressFault<T> 226{ 227 protected: 228 Addr asid; 229 Addr vpn; 230 231 TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) : 232 AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn) 233 {} 234 235 void 236 setTlbExceptionState(ThreadContext *tc, uint8_t excCode) 237 { 238 this->setExceptionState(tc, excCode); 239 240 tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr); 241 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 242 entryHi.asid = this->asid; 243 entryHi.vpn2 = this->vpn >> 2; 244 entryHi.vpn2x = this->vpn & 0x3; 245 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 246 247 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 248 context.badVPN2 = this->vpn >> 2; 249 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 250 } 251 252 void 253 invoke(ThreadContext * tc, const StaticInstPtr &inst = 254 StaticInst::nullStaticInstPtr) 255 { 256 if (FullSystem) { 257 DPRINTF(MipsPRA, "Fault %s encountered.\n", this->name()); 258 Addr vect = this->vect(tc); 259 setTlbExceptionState(tc, this->code()); 260 tc->pcState(vect); 261 } else { 262 AddressFault<T>::invoke(tc, inst); 263 } 264 } 265 266 ExcCode 267 code() const 268 { 269 return this->store ? ExcCodeTlbS : ExcCodeTlbL; 270 } 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 {} 279 280 FaultVect 281 offset(ThreadContext *tc) const 282 { 283 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 284 return status.exl ? 0x180 : 0x000; 285 } 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 {} 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 {} 302 303 ExcCode code() const { return MipsFault<TlbModifiedFault>::code(); } 304}; 305 306/* 307 * Explicitly declare template static member variables to avoid warnings 308 * in some clang versions 309 */ 310template<> MipsFaultBase::FaultVals MipsFault<SystemCallFault>::vals; 311template<> MipsFaultBase::FaultVals MipsFault<ReservedInstructionFault>::vals; 312template<> MipsFaultBase::FaultVals MipsFault<ThreadFault>::vals; 313template<> MipsFaultBase::FaultVals MipsFault<IntegerOverflowFault>::vals; 314template<> MipsFaultBase::FaultVals MipsFault<TrapFault>::vals; 315template<> MipsFaultBase::FaultVals MipsFault<BreakpointFault>::vals; 316template<> MipsFaultBase::FaultVals MipsFault<DspStateDisabledFault>::vals; 317template<> MipsFaultBase::FaultVals MipsFault<MachineCheckFault>::vals; 318template<> MipsFaultBase::FaultVals MipsFault<ResetFault>::vals; 319template<> MipsFaultBase::FaultVals MipsFault<SoftResetFault>::vals; 320template<> MipsFaultBase::FaultVals MipsFault<NonMaskableInterrupt>::vals; 321template<> MipsFaultBase::FaultVals MipsFault<CoprocessorUnusableFault>::vals; 322template<> MipsFaultBase::FaultVals MipsFault<InterruptFault>::vals; 323template<> MipsFaultBase::FaultVals MipsFault<AddressErrorFault>::vals; 324template<> MipsFaultBase::FaultVals MipsFault<TlbInvalidFault>::vals; 325template<> MipsFaultBase::FaultVals MipsFault<TlbRefillFault>::vals; 326template<> MipsFaultBase::FaultVals MipsFault<TlbModifiedFault>::vals; 327 328 329 330} // namespace MipsISA 331 332#endif // __MIPS_FAULTS_HH__ 333