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#include "arch/mips/faults.hh" 35#include "arch/mips/pra_constants.hh" 36#include "base/trace.hh" 37#include "cpu/base.hh" 38#include "cpu/thread_context.hh" 39#include "debug/MipsPRA.hh" 40 41#if !FULL_SYSTEM 42#include "mem/page_table.hh" 43#include "sim/process.hh" 44#endif 45 46namespace MipsISA 47{ 48
| 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#include "arch/mips/faults.hh" 35#include "arch/mips/pra_constants.hh" 36#include "base/trace.hh" 37#include "cpu/base.hh" 38#include "cpu/thread_context.hh" 39#include "debug/MipsPRA.hh" 40 41#if !FULL_SYSTEM 42#include "mem/page_table.hh" 43#include "sim/process.hh" 44#endif 45 46namespace MipsISA 47{ 48
|
49FaultName MachineCheckFault::_name = "Machine Check"; 50FaultVect MachineCheckFault::_vect = 0x0401; 51FaultStat MachineCheckFault::_count;
| 49typedef MipsFaultBase::FaultVals FaultVals;
|
52
| 50
|
53FaultName AlignmentFault::_name = "Alignment"; 54FaultVect AlignmentFault::_vect = 0x0301; 55FaultStat AlignmentFault::_count;
| 51template <> FaultVals MipsFault<MachineCheckFault>::vals = 52 { "Machine Check", 0x0401 };
|
56
| 53
|
57FaultName ResetFault::_name = "Reset Fault";
| 54template <> FaultVals MipsFault<AlignmentFault>::vals = 55 { "Alignment", 0x0301 }; 56 57template <> FaultVals MipsFault<ResetFault>::vals =
|
58#if FULL_SYSTEM
| 58#if FULL_SYSTEM
|
59FaultVect ResetFault::_vect = 0xBFC00000;
| 59 { "Reset Fault", 0xBFC00000};
|
60#else
| 60#else
|
61FaultVect ResetFault::_vect = 0x001;
| 61 { "Reset Fault", 0x001};
|
62#endif
| 62#endif
|
63FaultStat ResetFault::_count;
| |
64
| 63
|
65FaultName AddressErrorFault::_name = "Address Error"; 66FaultVect AddressErrorFault::_vect = 0x0180; 67FaultStat AddressErrorFault::_count;
| 64template <> FaultVals MipsFault<AddressErrorFault>::vals = 65 { "Address Error", 0x0180 };
|
68
| 66
|
69FaultName StoreAddressErrorFault::_name = "Store Address Error"; 70FaultVect StoreAddressErrorFault::_vect = 0x0180; 71FaultStat StoreAddressErrorFault::_count;
| 67template <> FaultVals MipsFault<StoreAddressErrorFault>::vals = 68 { "Store Address Error", 0x0180 };
|
72
| 69
|
| 70template <> FaultVals MipsFault<SystemCallFault>::vals = 71 { "Syscall", 0x0180 };
|
73
| 72
|
74FaultName SystemCallFault::_name = "Syscall"; 75FaultVect SystemCallFault::_vect = 0x0180; 76FaultStat SystemCallFault::_count;
| 73template <> FaultVals MipsFault<CoprocessorUnusableFault>::vals = 74 { "Coprocessor Unusable Fault", 0x180 };
|
77
| 75
|
78FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault"; 79FaultVect CoprocessorUnusableFault::_vect = 0x180; 80FaultStat CoprocessorUnusableFault::_count;
| 76template <> FaultVals MipsFault<ReservedInstructionFault>::vals = 77 { "Reserved Instruction Fault", 0x0180 };
|
81
| 78
|
82FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault"; 83FaultVect ReservedInstructionFault::_vect = 0x0180; 84FaultStat ReservedInstructionFault::_count;
| 79template <> FaultVals MipsFault<ThreadFault>::vals = 80 { "Thread Fault", 0x00F1 };
|
85
| 81
|
86FaultName ThreadFault::_name = "Thread Fault"; 87FaultVect ThreadFault::_vect = 0x00F1; 88FaultStat ThreadFault::_count;
| 82template <> FaultVals MipsFault<ArithmeticFault>::vals = 83 { "Arithmetic Overflow Exception", 0x180 };
|
89
| 84
|
90FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception"; 91FaultVect ArithmeticFault::_vect = 0x180; 92FaultStat ArithmeticFault::_count;
| 85template <> FaultVals MipsFault<UnimplementedOpcodeFault>::vals = 86 { "opdec", 0x0481 };
|
93
| 87
|
94FaultName UnimplementedOpcodeFault::_name = "opdec"; 95FaultVect UnimplementedOpcodeFault::_vect = 0x0481; 96FaultStat UnimplementedOpcodeFault::_count;
| 88template <> FaultVals MipsFault<InterruptFault>::vals = 89 { "interrupt", 0x0180 };
|
97
| 90
|
98FaultName InterruptFault::_name = "interrupt"; 99FaultVect InterruptFault::_vect = 0x0180; 100FaultStat InterruptFault::_count;
| 91template <> FaultVals MipsFault<TrapFault>::vals = 92 { "Trap", 0x0180 };
|
101
| 93
|
102FaultName TrapFault::_name = "Trap"; 103FaultVect TrapFault::_vect = 0x0180; 104FaultStat TrapFault::_count;
| 94template <> FaultVals MipsFault<BreakpointFault>::vals = 95 { "Breakpoint", 0x0180 };
|
105
| 96
|
106FaultName BreakpointFault::_name = "Breakpoint"; 107FaultVect BreakpointFault::_vect = 0x0180; 108FaultStat BreakpointFault::_count;
| 97template <> FaultVals MipsFault<ItbInvalidFault>::vals = 98 { "Invalid TLB Entry Exception (I-Fetch/LW)", 0x0180 };
|
109
| 99
|
110FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)"; 111FaultVect ItbInvalidFault::_vect = 0x0180; 112FaultStat ItbInvalidFault::_count;
| 100template <> FaultVals MipsFault<ItbPageFault>::vals = 101 { "itbmiss", 0x0181 };
|
113
| 102
|
114FaultName ItbPageFault::_name = "itbmiss"; 115FaultVect ItbPageFault::_vect = 0x0181; 116FaultStat ItbPageFault::_count;
| 103template <> FaultVals MipsFault<ItbMissFault>::vals = 104 { "itbmiss", 0x0181 };
|
117
| 105
|
118FaultName ItbMissFault::_name = "itbmiss"; 119FaultVect ItbMissFault::_vect = 0x0181; 120FaultStat ItbMissFault::_count;
| 106template <> FaultVals MipsFault<ItbAcvFault>::vals = 107 { "iaccvio", 0x0081 };
|
121
| 108
|
122FaultName ItbAcvFault::_name = "iaccvio"; 123FaultVect ItbAcvFault::_vect = 0x0081; 124FaultStat ItbAcvFault::_count;
| 109template <> FaultVals MipsFault<ItbRefillFault>::vals = 110 { "TLB Refill Exception (I-Fetch/LW)", 0x0180 };
|
125
| 111
|
126FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)"; 127FaultVect ItbRefillFault::_vect = 0x0180; 128FaultStat ItbRefillFault::_count;
| 112template <> FaultVals MipsFault<NDtbMissFault>::vals = 113 { "dtb_miss_single", 0x0201 };
|
129
| 114
|
130FaultName NDtbMissFault::_name = "dtb_miss_single"; 131FaultVect NDtbMissFault::_vect = 0x0201; 132FaultStat NDtbMissFault::_count;
| 115template <> FaultVals MipsFault<PDtbMissFault>::vals = 116 { "dtb_miss_double", 0x0281 };
|
133
| 117
|
134FaultName PDtbMissFault::_name = "dtb_miss_double"; 135FaultVect PDtbMissFault::_vect = 0x0281; 136FaultStat PDtbMissFault::_count;
| 118template <> FaultVals MipsFault<DtbPageFault>::vals = 119 { "dfault", 0x0381 };
|
137
| 120
|
138FaultName DtbPageFault::_name = "dfault"; 139FaultVect DtbPageFault::_vect = 0x0381; 140FaultStat DtbPageFault::_count;
| 121template <> FaultVals MipsFault<DtbAcvFault>::vals = 122 { "dfault", 0x0381 };
|
141
| 123
|
142FaultName DtbAcvFault::_name = "dfault"; 143FaultVect DtbAcvFault::_vect = 0x0381; 144FaultStat DtbAcvFault::_count;
| 124template <> FaultVals MipsFault<DtbInvalidFault>::vals = 125 { "Invalid TLB Entry Exception (Store)", 0x0180 };
|
145
| 126
|
146FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)"; 147FaultVect DtbInvalidFault::_vect = 0x0180; 148FaultStat DtbInvalidFault::_count;
| 127template <> FaultVals MipsFault<DtbRefillFault>::vals = 128 { "TLB Refill Exception (Store)", 0x0180 };
|
149
| 129
|
150FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)"; 151FaultVect DtbRefillFault::_vect = 0x0180; 152FaultStat DtbRefillFault::_count;
| 130template <> FaultVals MipsFault<TLBModifiedFault>::vals = 131 { "TLB Modified Exception", 0x0180 };
|
153
| 132
|
154FaultName TLBModifiedFault::_name = "TLB Modified Exception"; 155FaultVect TLBModifiedFault::_vect = 0x0180; 156FaultStat TLBModifiedFault::_count;
| 133template <> FaultVals MipsFault<FloatEnableFault>::vals = 134 { "float_enable_fault", 0x0581 };
|
157
| 135
|
158FaultName FloatEnableFault::_name = "float_enable_fault"; 159FaultVect FloatEnableFault::_vect = 0x0581; 160FaultStat FloatEnableFault::_count;
| 136template <> FaultVals MipsFault<IntegerOverflowFault>::vals = 137 { "Integer Overflow Fault", 0x0501 };
|
161
| 138
|
162FaultName IntegerOverflowFault::_name = "Integer Overflow Fault"; 163FaultVect IntegerOverflowFault::_vect = 0x0501; 164FaultStat IntegerOverflowFault::_count;
| 139template <> FaultVals MipsFault<DspStateDisabledFault>::vals = 140 { "DSP Disabled Fault", 0x001a };
|
165
| 141
|
166FaultName DspStateDisabledFault::_name = "DSP Disabled Fault"; 167FaultVect DspStateDisabledFault::_vect = 0x001a; 168FaultStat DspStateDisabledFault::_count; 169
| |
170#if FULL_SYSTEM 171void
| 142#if FULL_SYSTEM 143void
|
172MipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
| 144MipsFaultBase::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
|
173{ 174 tc->setPC(HandlerBase); 175 tc->setNextPC(HandlerBase + sizeof(MachInst)); 176 tc->setNextNPC(HandlerBase + 2 * sizeof(MachInst)); 177} 178 179void
| 145{ 146 tc->setPC(HandlerBase); 147 tc->setNextPC(HandlerBase + sizeof(MachInst)); 148 tc->setNextNPC(HandlerBase + 2 * sizeof(MachInst)); 149} 150 151void
|
180MipsFault::setExceptionState(ThreadContext *tc, uint8_t excCode)
| 152MipsFaultBase::setExceptionState(ThreadContext *tc, uint8_t excCode)
|
181{ 182 // modify SRS Ctl - Save CSS, put ESS into CSS 183 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 184 if (status.exl != 1 && status.bev != 1) { 185 // SRS Ctl is modified only if Status_EXL and Status_BEV are not set 186 SRSCtlReg srsCtl = tc->readMiscReg(MISCREG_SRSCTL); 187 srsCtl.pss = srsCtl.css; 188 srsCtl.css = srsCtl.ess; 189 tc->setMiscRegNoEffect(MISCREG_SRSCTL, srsCtl); 190 } 191 192 // set EXL bit (don't care if it is already set!) 193 status.exl = 1; 194 tc->setMiscRegNoEffect(MISCREG_STATUS, status); 195 196 // write EPC 197 // CHECK ME or FIXME or FIX ME or POSSIBLE HACK 198 // Check to see if the exception occurred in the branch delay slot 199 DPRINTF(MipsPRA, "PC: %x, NextPC: %x, NNPC: %x\n", 200 tc->readPC(), tc->readNextPC(), tc->readNextNPC()); 201 int bd = 0; 202 if (tc->readPC() + sizeof(MachInst) != tc->readNextPC()) { 203 tc->setMiscRegNoEffect(MISCREG_EPC, tc->readPC() - sizeof(MachInst)); 204 // In the branch delay slot? set CAUSE_31 205 bd = 1; 206 } else { 207 tc->setMiscRegNoEffect(MISCREG_EPC, tc->readPC()); 208 // In the branch delay slot? reset CAUSE_31 209 bd = 0; 210 } 211 212 // Set Cause_EXCCODE field 213 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 214 cause.excCode = excCode; 215 cause.bd = bd; 216 cause.ce = 0; 217 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 218} 219 220void 221ArithmeticFault::invoke(ThreadContext *tc, StaticInstPtr inst) 222{ 223 DPRINTF(MipsPRA, "%s encountered.\n", name()); 224 setExceptionState(tc, 0xC); 225 226 // Set new PC 227 Addr HandlerBase; 228 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 229 // Here, the handler is dependent on BEV, which is not modified by 230 // setExceptionState() 231 if (!status.bev) { 232 // See MIPS ARM Vol 3, Revision 2, Page 38 233 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 234 } else { 235 HandlerBase = 0xBFC00200; 236 } 237 setHandlerPC(HandlerBase, tc); 238} 239 240void 241StoreAddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) 242{ 243 DPRINTF(MipsPRA, "%s encountered.\n", name()); 244 setExceptionState(tc, 0x5); 245 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 246 247 // Set new PC 248 Addr HandlerBase; 249 // Offset 0x180 - General Exception Vector 250 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 251 setHandlerPC(HandlerBase, tc); 252} 253 254void 255TrapFault::invoke(ThreadContext *tc, StaticInstPtr inst) 256{ 257 DPRINTF(MipsPRA, "%s encountered.\n", name()); 258 setExceptionState(tc, 0xD); 259 260 // Set new PC 261 Addr HandlerBase; 262 // Offset 0x180 - General Exception Vector 263 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 264 setHandlerPC(HandlerBase, tc); 265} 266 267void 268BreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst) 269{ 270 setExceptionState(tc, 0x9); 271 272 // Set new PC 273 Addr HandlerBase; 274 // Offset 0x180 - General Exception Vector 275 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 276 setHandlerPC(HandlerBase, tc); 277} 278 279void 280DtbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst) 281{ 282 DPRINTF(MipsPRA, "%s encountered.\n", name()); 283 284 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 285 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 286 entryHi.asid = entryHiAsid; 287 entryHi.vpn2 = entryHiVPN2; 288 entryHi.vpn2x = entryHiVPN2X; 289 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 290 291 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 292 context.badVPN2 = contextBadVPN2; 293 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 294 setExceptionState(tc, 0x3); 295 296 297 // Set new PC 298 Addr HandlerBase; 299 // Offset 0x180 - General Exception Vector 300 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 301 setHandlerPC(HandlerBase, tc); 302} 303 304void 305AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) 306{ 307 DPRINTF(MipsPRA, "%s encountered.\n", name()); 308 setExceptionState(tc, 0x4); 309 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 310 311 // Set new PC 312 Addr HandlerBase; 313 // Offset 0x180 - General Exception Vector 314 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 315 setHandlerPC(HandlerBase, tc); 316} 317 318void 319ItbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst) 320{ 321 DPRINTF(MipsPRA, "%s encountered.\n", name()); 322 setExceptionState(tc, 0x2); 323 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 324 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 325 entryHi.asid = entryHiAsid; 326 entryHi.vpn2 = entryHiVPN2; 327 entryHi.vpn2x = entryHiVPN2X; 328 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 329 330 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 331 context.badVPN2 = contextBadVPN2; 332 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 333 334 335 // Set new PC 336 Addr HandlerBase; 337 // Offset 0x180 - General Exception Vector 338 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 339 setHandlerPC(HandlerBase,tc); 340 DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n", 341 HandlerBase, tc->readMiscReg(MISCREG_EPC)); 342} 343 344void 345ItbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) 346{ 347 DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR); 348 Addr HandlerBase; 349 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 350 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 351 entryHi.asid = entryHiAsid; 352 entryHi.vpn2 = entryHiVPN2; 353 entryHi.vpn2x = entryHiVPN2X; 354 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 355 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 356 context.badVPN2 = contextBadVPN2; 357 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 358 359 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 360 // Since handler depends on EXL bit, must check EXL bit before setting it!! 361 // See MIPS ARM Vol 3, Revision 2, Page 38 362 if (status.exl == 1) { 363 // Offset 0x180 - General Exception Vector 364 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 365 } else { 366 // Offset 0x000 367 HandlerBase = tc->readMiscReg(MISCREG_EBASE); 368 } 369 370 setExceptionState(tc, 0x2); 371 setHandlerPC(HandlerBase, tc); 372} 373 374void 375DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) 376{ 377 // Set new PC 378 DPRINTF(MipsPRA, "%s encountered.\n", name()); 379 Addr HandlerBase; 380 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 381 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 382 entryHi.asid = entryHiAsid; 383 entryHi.vpn2 = entryHiVPN2; 384 entryHi.vpn2x = entryHiVPN2X; 385 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 386 387 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 388 context.badVPN2 = contextBadVPN2; 389 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 390 391 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 392 // Since handler depends on EXL bit, must check EXL bit before setting it!! 393 // See MIPS ARM Vol 3, Revision 2, Page 38 394 if (status.exl) { 395 // Offset 0x180 - General Exception Vector 396 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 397 } else { 398 // Offset 0x000 399 HandlerBase = tc->readMiscReg(MISCREG_EBASE); 400 } 401 402 setExceptionState(tc, 0x3); 403 404 setHandlerPC(HandlerBase, tc); 405} 406 407void 408TLBModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst) 409{ 410 DPRINTF(MipsPRA, "%s encountered.\n", name()); 411 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 412 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 413 entryHi.asid = entryHiAsid; 414 entryHi.vpn2 = entryHiVPN2; 415 entryHi.vpn2x = entryHiVPN2X; 416 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 417 418 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 419 context.badVPN2 = contextBadVPN2; 420 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 421 422 // Set new PC 423 Addr HandlerBase; 424 // Offset 0x180 - General Exception Vector 425 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 426 setExceptionState(tc, 0x1); 427 setHandlerPC(HandlerBase, tc); 428 429} 430 431void 432SystemCallFault::invoke(ThreadContext *tc, StaticInstPtr inst) 433{ 434 DPRINTF(MipsPRA, "%s encountered.\n", name()); 435 setExceptionState(tc, 0x8); 436 437 // Set new PC 438 Addr HandlerBase; 439 // Offset 0x180 - General Exception Vector 440 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 441 setHandlerPC(HandlerBase, tc); 442} 443 444void 445InterruptFault::invoke(ThreadContext *tc, StaticInstPtr inst) 446{ 447#if FULL_SYSTEM 448 DPRINTF(MipsPRA, "%s encountered.\n", name()); 449 setExceptionState(tc, 0x0A); 450 Addr HandlerBase; 451 452 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 453 if (cause.iv) { 454 // Offset 200 for release 2 455 HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 456 } else { 457 //Ofset at 180 for release 1 458 HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 459 } 460 461 setHandlerPC(HandlerBase, tc); 462#endif 463} 464 465#endif // FULL_SYSTEM 466 467void 468ResetFault::invoke(ThreadContext *tc, StaticInstPtr inst) 469{ 470#if FULL_SYSTEM 471 DPRINTF(MipsPRA, "%s encountered.\n", name()); 472 /* All reset activity must be invoked from here */ 473 tc->setPC(vect()); 474 tc->setNextPC(vect() + sizeof(MachInst)); 475 tc->setNextNPC(vect() + sizeof(MachInst) + sizeof(MachInst)); 476 DPRINTF(MipsPRA, "ResetFault::invoke : PC set to %x", tc->readPC()); 477#endif 478 479 // Set Coprocessor 1 (Floating Point) To Usable 480 StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 481 status.cu.cu1 = 1; 482 tc->setMiscReg(MISCREG_STATUS, status); 483} 484 485void 486ReservedInstructionFault::invoke(ThreadContext *tc, StaticInstPtr inst) 487{ 488#if FULL_SYSTEM 489 DPRINTF(MipsPRA, "%s encountered.\n", name()); 490 setExceptionState(tc, 0x0A); 491 Addr HandlerBase; 492 // Offset 0x180 - General Exception Vector 493 HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 494 setHandlerPC(HandlerBase, tc); 495#else 496 panic("%s encountered.\n", name()); 497#endif 498} 499 500void 501ThreadFault::invoke(ThreadContext *tc, StaticInstPtr inst) 502{ 503 DPRINTF(MipsPRA, "%s encountered.\n", name()); 504 panic("%s encountered.\n", name()); 505} 506 507void 508DspStateDisabledFault::invoke(ThreadContext *tc, StaticInstPtr inst) 509{ 510 DPRINTF(MipsPRA, "%s encountered.\n", name()); 511 panic("%s encountered.\n", name()); 512} 513 514void 515CoprocessorUnusableFault::invoke(ThreadContext *tc, StaticInstPtr inst) 516{ 517#if FULL_SYSTEM 518 DPRINTF(MipsPRA, "%s encountered.\n", name()); 519 setExceptionState(tc, 0xb); 520 // The ID of the coprocessor causing the exception is stored in 521 // CoprocessorUnusableFault::coProcID 522 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 523 cause.ce = coProcID; 524 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 525 526 Addr HandlerBase; 527 // Offset 0x180 - General Exception Vector 528 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 529 setHandlerPC(HandlerBase, tc); 530 531#else 532 warn("%s (CP%d) encountered.\n", name(), coProcID); 533#endif 534} 535 536} // namespace MipsISA 537
| 153{ 154 // modify SRS Ctl - Save CSS, put ESS into CSS 155 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 156 if (status.exl != 1 && status.bev != 1) { 157 // SRS Ctl is modified only if Status_EXL and Status_BEV are not set 158 SRSCtlReg srsCtl = tc->readMiscReg(MISCREG_SRSCTL); 159 srsCtl.pss = srsCtl.css; 160 srsCtl.css = srsCtl.ess; 161 tc->setMiscRegNoEffect(MISCREG_SRSCTL, srsCtl); 162 } 163 164 // set EXL bit (don't care if it is already set!) 165 status.exl = 1; 166 tc->setMiscRegNoEffect(MISCREG_STATUS, status); 167 168 // write EPC 169 // CHECK ME or FIXME or FIX ME or POSSIBLE HACK 170 // Check to see if the exception occurred in the branch delay slot 171 DPRINTF(MipsPRA, "PC: %x, NextPC: %x, NNPC: %x\n", 172 tc->readPC(), tc->readNextPC(), tc->readNextNPC()); 173 int bd = 0; 174 if (tc->readPC() + sizeof(MachInst) != tc->readNextPC()) { 175 tc->setMiscRegNoEffect(MISCREG_EPC, tc->readPC() - sizeof(MachInst)); 176 // In the branch delay slot? set CAUSE_31 177 bd = 1; 178 } else { 179 tc->setMiscRegNoEffect(MISCREG_EPC, tc->readPC()); 180 // In the branch delay slot? reset CAUSE_31 181 bd = 0; 182 } 183 184 // Set Cause_EXCCODE field 185 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 186 cause.excCode = excCode; 187 cause.bd = bd; 188 cause.ce = 0; 189 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 190} 191 192void 193ArithmeticFault::invoke(ThreadContext *tc, StaticInstPtr inst) 194{ 195 DPRINTF(MipsPRA, "%s encountered.\n", name()); 196 setExceptionState(tc, 0xC); 197 198 // Set new PC 199 Addr HandlerBase; 200 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 201 // Here, the handler is dependent on BEV, which is not modified by 202 // setExceptionState() 203 if (!status.bev) { 204 // See MIPS ARM Vol 3, Revision 2, Page 38 205 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 206 } else { 207 HandlerBase = 0xBFC00200; 208 } 209 setHandlerPC(HandlerBase, tc); 210} 211 212void 213StoreAddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) 214{ 215 DPRINTF(MipsPRA, "%s encountered.\n", name()); 216 setExceptionState(tc, 0x5); 217 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 218 219 // Set new PC 220 Addr HandlerBase; 221 // Offset 0x180 - General Exception Vector 222 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 223 setHandlerPC(HandlerBase, tc); 224} 225 226void 227TrapFault::invoke(ThreadContext *tc, StaticInstPtr inst) 228{ 229 DPRINTF(MipsPRA, "%s encountered.\n", name()); 230 setExceptionState(tc, 0xD); 231 232 // Set new PC 233 Addr HandlerBase; 234 // Offset 0x180 - General Exception Vector 235 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 236 setHandlerPC(HandlerBase, tc); 237} 238 239void 240BreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst) 241{ 242 setExceptionState(tc, 0x9); 243 244 // Set new PC 245 Addr HandlerBase; 246 // Offset 0x180 - General Exception Vector 247 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 248 setHandlerPC(HandlerBase, tc); 249} 250 251void 252DtbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst) 253{ 254 DPRINTF(MipsPRA, "%s encountered.\n", name()); 255 256 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 257 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 258 entryHi.asid = entryHiAsid; 259 entryHi.vpn2 = entryHiVPN2; 260 entryHi.vpn2x = entryHiVPN2X; 261 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 262 263 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 264 context.badVPN2 = contextBadVPN2; 265 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 266 setExceptionState(tc, 0x3); 267 268 269 // Set new PC 270 Addr HandlerBase; 271 // Offset 0x180 - General Exception Vector 272 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 273 setHandlerPC(HandlerBase, tc); 274} 275 276void 277AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) 278{ 279 DPRINTF(MipsPRA, "%s encountered.\n", name()); 280 setExceptionState(tc, 0x4); 281 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 282 283 // Set new PC 284 Addr HandlerBase; 285 // Offset 0x180 - General Exception Vector 286 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 287 setHandlerPC(HandlerBase, tc); 288} 289 290void 291ItbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst) 292{ 293 DPRINTF(MipsPRA, "%s encountered.\n", name()); 294 setExceptionState(tc, 0x2); 295 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 296 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 297 entryHi.asid = entryHiAsid; 298 entryHi.vpn2 = entryHiVPN2; 299 entryHi.vpn2x = entryHiVPN2X; 300 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 301 302 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 303 context.badVPN2 = contextBadVPN2; 304 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 305 306 307 // Set new PC 308 Addr HandlerBase; 309 // Offset 0x180 - General Exception Vector 310 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 311 setHandlerPC(HandlerBase,tc); 312 DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n", 313 HandlerBase, tc->readMiscReg(MISCREG_EPC)); 314} 315 316void 317ItbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) 318{ 319 DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR); 320 Addr HandlerBase; 321 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 322 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 323 entryHi.asid = entryHiAsid; 324 entryHi.vpn2 = entryHiVPN2; 325 entryHi.vpn2x = entryHiVPN2X; 326 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 327 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 328 context.badVPN2 = contextBadVPN2; 329 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 330 331 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 332 // Since handler depends on EXL bit, must check EXL bit before setting it!! 333 // See MIPS ARM Vol 3, Revision 2, Page 38 334 if (status.exl == 1) { 335 // Offset 0x180 - General Exception Vector 336 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 337 } else { 338 // Offset 0x000 339 HandlerBase = tc->readMiscReg(MISCREG_EBASE); 340 } 341 342 setExceptionState(tc, 0x2); 343 setHandlerPC(HandlerBase, tc); 344} 345 346void 347DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) 348{ 349 // Set new PC 350 DPRINTF(MipsPRA, "%s encountered.\n", name()); 351 Addr HandlerBase; 352 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 353 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 354 entryHi.asid = entryHiAsid; 355 entryHi.vpn2 = entryHiVPN2; 356 entryHi.vpn2x = entryHiVPN2X; 357 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 358 359 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 360 context.badVPN2 = contextBadVPN2; 361 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 362 363 StatusReg status = tc->readMiscReg(MISCREG_STATUS); 364 // Since handler depends on EXL bit, must check EXL bit before setting it!! 365 // See MIPS ARM Vol 3, Revision 2, Page 38 366 if (status.exl) { 367 // Offset 0x180 - General Exception Vector 368 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 369 } else { 370 // Offset 0x000 371 HandlerBase = tc->readMiscReg(MISCREG_EBASE); 372 } 373 374 setExceptionState(tc, 0x3); 375 376 setHandlerPC(HandlerBase, tc); 377} 378 379void 380TLBModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst) 381{ 382 DPRINTF(MipsPRA, "%s encountered.\n", name()); 383 tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 384 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 385 entryHi.asid = entryHiAsid; 386 entryHi.vpn2 = entryHiVPN2; 387 entryHi.vpn2x = entryHiVPN2X; 388 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 389 390 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 391 context.badVPN2 = contextBadVPN2; 392 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 393 394 // Set new PC 395 Addr HandlerBase; 396 // Offset 0x180 - General Exception Vector 397 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 398 setExceptionState(tc, 0x1); 399 setHandlerPC(HandlerBase, tc); 400 401} 402 403void 404SystemCallFault::invoke(ThreadContext *tc, StaticInstPtr inst) 405{ 406 DPRINTF(MipsPRA, "%s encountered.\n", name()); 407 setExceptionState(tc, 0x8); 408 409 // Set new PC 410 Addr HandlerBase; 411 // Offset 0x180 - General Exception Vector 412 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 413 setHandlerPC(HandlerBase, tc); 414} 415 416void 417InterruptFault::invoke(ThreadContext *tc, StaticInstPtr inst) 418{ 419#if FULL_SYSTEM 420 DPRINTF(MipsPRA, "%s encountered.\n", name()); 421 setExceptionState(tc, 0x0A); 422 Addr HandlerBase; 423 424 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 425 if (cause.iv) { 426 // Offset 200 for release 2 427 HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 428 } else { 429 //Ofset at 180 for release 1 430 HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 431 } 432 433 setHandlerPC(HandlerBase, tc); 434#endif 435} 436 437#endif // FULL_SYSTEM 438 439void 440ResetFault::invoke(ThreadContext *tc, StaticInstPtr inst) 441{ 442#if FULL_SYSTEM 443 DPRINTF(MipsPRA, "%s encountered.\n", name()); 444 /* All reset activity must be invoked from here */ 445 tc->setPC(vect()); 446 tc->setNextPC(vect() + sizeof(MachInst)); 447 tc->setNextNPC(vect() + sizeof(MachInst) + sizeof(MachInst)); 448 DPRINTF(MipsPRA, "ResetFault::invoke : PC set to %x", tc->readPC()); 449#endif 450 451 // Set Coprocessor 1 (Floating Point) To Usable 452 StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 453 status.cu.cu1 = 1; 454 tc->setMiscReg(MISCREG_STATUS, status); 455} 456 457void 458ReservedInstructionFault::invoke(ThreadContext *tc, StaticInstPtr inst) 459{ 460#if FULL_SYSTEM 461 DPRINTF(MipsPRA, "%s encountered.\n", name()); 462 setExceptionState(tc, 0x0A); 463 Addr HandlerBase; 464 // Offset 0x180 - General Exception Vector 465 HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 466 setHandlerPC(HandlerBase, tc); 467#else 468 panic("%s encountered.\n", name()); 469#endif 470} 471 472void 473ThreadFault::invoke(ThreadContext *tc, StaticInstPtr inst) 474{ 475 DPRINTF(MipsPRA, "%s encountered.\n", name()); 476 panic("%s encountered.\n", name()); 477} 478 479void 480DspStateDisabledFault::invoke(ThreadContext *tc, StaticInstPtr inst) 481{ 482 DPRINTF(MipsPRA, "%s encountered.\n", name()); 483 panic("%s encountered.\n", name()); 484} 485 486void 487CoprocessorUnusableFault::invoke(ThreadContext *tc, StaticInstPtr inst) 488{ 489#if FULL_SYSTEM 490 DPRINTF(MipsPRA, "%s encountered.\n", name()); 491 setExceptionState(tc, 0xb); 492 // The ID of the coprocessor causing the exception is stored in 493 // CoprocessorUnusableFault::coProcID 494 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 495 cause.ce = coProcID; 496 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 497 498 Addr HandlerBase; 499 // Offset 0x180 - General Exception Vector 500 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 501 setHandlerPC(HandlerBase, tc); 502 503#else 504 warn("%s (CP%d) encountered.\n", name(), coProcID); 505#endif 506} 507 508} // namespace MipsISA 509
|