faults.cc revision 5222:bb733a878f85
1/*
2 * Copyright N) 2007 MIPS Technologies, Inc.  All Rights Reserved
3 *
4 * This software is part of the M5 simulator.
5 *
6 * THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING
7 * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
8 * TO THESE TERMS AND CONDITIONS.
9 *
10 * Permission is granted to use, copy, create derivative works and
11 * distribute this software and such derivative works for any purpose,
12 * so long as (1) the copyright notice above, this grant of permission,
13 * and the disclaimer below appear in all copies and derivative works
14 * made, (2) the copyright notice above is augmented as appropriate to
15 * reflect the addition of any new copyrightable work in a derivative
16 * work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3)
17 * the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any
18 * advertising or publicity pertaining to the use or distribution of
19 * this software without specific, written prior authorization.
20 *
21 * THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B  MIPS MAKES NO WARRANTIES AND
22 * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
23 * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
25 * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
26 * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
27 * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
28 * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
29 * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
30 * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
31 * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
32 * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
33 *
34 * Authors: Gabe M. Black
35 *          Korey L. Sewell
36 *          Jaidev Patwardhan
37 */
38
39#include "arch/mips/faults.hh"
40#include "cpu/thread_context.hh"
41#include "cpu/base.hh"
42#include "base/trace.hh"
43#include "arch/mips/pra_constants.hh"
44#if !FULL_SYSTEM
45#include "sim/process.hh"
46#include "mem/page_table.hh"
47#endif
48
49namespace MipsISA
50{
51
52FaultName MachineCheckFault::_name = "Machine Check";
53FaultVect MachineCheckFault::_vect = 0x0401;
54FaultStat MachineCheckFault::_count;
55
56FaultName AlignmentFault::_name = "Alignment";
57FaultVect AlignmentFault::_vect = 0x0301;
58FaultStat AlignmentFault::_count;
59
60FaultName ResetFault::_name = "reset";
61#if  FULL_SYSTEM
62FaultVect ResetFault::_vect = 0xBFC00000;
63#else
64FaultVect ResetFault::_vect = 0x001;
65#endif
66FaultStat ResetFault::_count;
67
68FaultName AddressErrorFault::_name = "Address Error";
69FaultVect AddressErrorFault::_vect = 0x0180;
70FaultStat AddressErrorFault::_count;
71
72FaultName StoreAddressErrorFault::_name = "Store Address Error";
73FaultVect StoreAddressErrorFault::_vect = 0x0180;
74FaultStat StoreAddressErrorFault::_count;
75
76
77FaultName SystemCallFault::_name = "Syscall";
78FaultVect SystemCallFault::_vect = 0x0180;
79FaultStat SystemCallFault::_count;
80
81FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable";
82FaultVect CoprocessorUnusableFault::_vect = 0x180;
83FaultStat CoprocessorUnusableFault::_count;
84
85FaultName ReservedInstructionFault::_name = "Reserved Instruction";
86FaultVect ReservedInstructionFault::_vect = 0x0180;
87FaultStat ReservedInstructionFault::_count;
88
89FaultName ThreadFault::_name = "thread";
90FaultVect ThreadFault::_vect = 0x00F1;
91FaultStat ThreadFault::_count;
92
93
94FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
95FaultVect ArithmeticFault::_vect = 0x180;
96FaultStat ArithmeticFault::_count;
97
98FaultName UnimplementedOpcodeFault::_name = "opdec";
99FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
100FaultStat UnimplementedOpcodeFault::_count;
101
102FaultName InterruptFault::_name = "interrupt";
103FaultVect InterruptFault::_vect = 0x0180;
104FaultStat InterruptFault::_count;
105
106FaultName TrapFault::_name = "Trap";
107FaultVect TrapFault::_vect = 0x0180;
108FaultStat TrapFault::_count;
109
110FaultName BreakpointFault::_name = "Breakpoint";
111FaultVect BreakpointFault::_vect = 0x0180;
112FaultStat BreakpointFault::_count;
113
114
115FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
116FaultVect ItbInvalidFault::_vect = 0x0180;
117FaultStat ItbInvalidFault::_count;
118
119FaultName ItbPageFault::_name = "itbmiss";
120FaultVect ItbPageFault::_vect = 0x0181;
121FaultStat ItbPageFault::_count;
122
123FaultName ItbMissFault::_name = "itbmiss";
124FaultVect ItbMissFault::_vect = 0x0181;
125FaultStat ItbMissFault::_count;
126
127FaultName ItbAcvFault::_name = "iaccvio";
128FaultVect ItbAcvFault::_vect = 0x0081;
129FaultStat ItbAcvFault::_count;
130
131FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
132FaultVect ItbRefillFault::_vect = 0x0180;
133FaultStat ItbRefillFault::_count;
134
135FaultName NDtbMissFault::_name = "dtb_miss_single";
136FaultVect NDtbMissFault::_vect = 0x0201;
137FaultStat NDtbMissFault::_count;
138
139FaultName PDtbMissFault::_name = "dtb_miss_double";
140FaultVect PDtbMissFault::_vect = 0x0281;
141FaultStat PDtbMissFault::_count;
142
143FaultName DtbPageFault::_name = "dfault";
144FaultVect DtbPageFault::_vect = 0x0381;
145FaultStat DtbPageFault::_count;
146
147FaultName DtbAcvFault::_name = "dfault";
148FaultVect DtbAcvFault::_vect = 0x0381;
149FaultStat DtbAcvFault::_count;
150
151FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
152FaultVect DtbInvalidFault::_vect = 0x0180;
153FaultStat DtbInvalidFault::_count;
154
155FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
156FaultVect DtbRefillFault::_vect = 0x0180;
157FaultStat DtbRefillFault::_count;
158
159FaultName TLBModifiedFault::_name = "TLB Modified Exception";
160FaultVect TLBModifiedFault::_vect = 0x0180;
161FaultStat TLBModifiedFault::_count;
162
163FaultName FloatEnableFault::_name = "float_enable_fault";
164FaultVect FloatEnableFault::_vect = 0x0581;
165FaultStat FloatEnableFault::_count;
166
167FaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
168FaultVect IntegerOverflowFault::_vect = 0x0501;
169FaultStat IntegerOverflowFault::_count;
170
171FaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
172FaultVect DspStateDisabledFault::_vect = 0x001a;
173FaultStat DspStateDisabledFault::_count;
174
175#if FULL_SYSTEM
176void MipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
177{
178  tc->setPC(HandlerBase);
179  tc->setNextPC(HandlerBase+sizeof(MachInst));
180  tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
181}
182
183void MipsFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
184{
185  // modify SRS Ctl - Save CSS, put ESS into CSS
186  MiscReg stat = tc->readMiscReg(MipsISA::Status);
187  if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1)
188    {
189      // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
190      MiscReg srs = tc->readMiscReg(MipsISA::SRSCtl);
191      uint8_t CSS,ESS;
192      CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO);
193      ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO);
194      // Move CSS to PSS
195      replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS);
196      // Move ESS to CSS
197      replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS);
198      tc->setMiscRegNoEffect(MipsISA::SRSCtl,srs);
199      tc->setShadowSet(ESS);
200    }
201
202  // set EXL bit (don't care if it is already set!)
203  replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
204  tc->setMiscRegNoEffect(MipsISA::Status,stat);
205
206  // write EPC
207  //  warn("Set EPC to %x\n",tc->readPC());
208  // CHECK ME  or FIXME or FIX ME or POSSIBLE HACK
209  // Check to see if the exception occurred in the branch delay slot
210  DPRINTF(MipsPRA,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC());
211  int C_BD=0;
212  if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){
213    tc->setMiscRegNoEffect(MipsISA::EPC,tc->readPC()-sizeof(MachInst));
214    // In the branch delay slot? set CAUSE_31
215    C_BD = 1;
216  } else {
217    tc->setMiscRegNoEffect(MipsISA::EPC,tc->readPC());
218    // In the branch delay slot? reset CAUSE_31
219    C_BD = 0;
220  }
221
222  // Set Cause_EXCCODE field
223  MiscReg cause = tc->readMiscReg(MipsISA::Cause);
224  replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode);
225  replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD);
226  replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0);
227  tc->setMiscRegNoEffect(MipsISA::Cause,cause);
228
229}
230
231void ArithmeticFault::invoke(ThreadContext *tc)
232{
233  DPRINTF(MipsPRA,"%s encountered.\n", name());
234  setExceptionState(tc,0xC);
235
236  // Set new PC
237  Addr HandlerBase;
238  MiscReg stat = tc->readMiscReg(MipsISA::Status);
239  // Here, the handler is dependent on BEV, which is not modified by setExceptionState()
240  if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38
241    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase);
242  }else{
243    HandlerBase = 0xBFC00200;
244  }
245  setHandlerPC(HandlerBase,tc);
246  //      warn("Exception Handler At: %x \n",HandlerBase);
247}
248
249void StoreAddressErrorFault::invoke(ThreadContext *tc)
250{
251  DPRINTF(MipsPRA,"%s encountered.\n", name());
252  setExceptionState(tc,0x5);
253  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
254
255  // Set new PC
256  Addr HandlerBase;
257  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
258  setHandlerPC(HandlerBase,tc);
259  //      warn("Exception Handler At: %x \n",HandlerBase);
260  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
261
262}
263
264void TrapFault::invoke(ThreadContext *tc)
265{
266  DPRINTF(MipsPRA,"%s encountered.\n", name());
267  //  warn("%s encountered.\n", name());
268  setExceptionState(tc,0xD);
269
270  // Set new PC
271  Addr HandlerBase;
272  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
273  setHandlerPC(HandlerBase,tc);
274  //      warn("Exception Handler At: %x \n",HandlerBase);
275  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
276}
277
278void BreakpointFault::invoke(ThreadContext *tc)
279{
280      setExceptionState(tc,0x9);
281
282      // Set new PC
283      Addr HandlerBase;
284      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
285      setHandlerPC(HandlerBase,tc);
286      //      warn("Exception Handler At: %x \n",HandlerBase);
287      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
288
289}
290
291void DtbInvalidFault::invoke(ThreadContext *tc)
292{
293  DPRINTF(MipsPRA,"%s encountered.\n", name());
294  //    warn("%s encountered.\n", name());
295  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
296  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
297  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
298  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
299  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
300  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
301  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
302  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
303  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
304  setExceptionState(tc,0x3);
305
306
307  // Set new PC
308  Addr HandlerBase;
309  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
310  setHandlerPC(HandlerBase,tc);
311  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
312}
313
314void AddressErrorFault::invoke(ThreadContext *tc)
315{
316  DPRINTF(MipsPRA,"%s encountered.\n", name());
317      setExceptionState(tc,0x4);
318      tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
319
320      // Set new PC
321      Addr HandlerBase;
322      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
323      setHandlerPC(HandlerBase,tc);
324}
325
326void ItbInvalidFault::invoke(ThreadContext *tc)
327{
328  DPRINTF(MipsPRA,"%s encountered.\n", name());
329      setExceptionState(tc,0x2);
330      tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
331      MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
332      replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
333      replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
334      replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
335      tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
336      MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
337      replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
338      tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
339
340
341      // Set new PC
342      Addr HandlerBase;
343      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
344      setHandlerPC(HandlerBase,tc);
345      DPRINTF(MipsPRA,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
346}
347
348void ItbRefillFault::invoke(ThreadContext *tc)
349{
350  DPRINTF(MipsPRA,"%s encountered (%x).\n", name(),BadVAddr);
351  Addr HandlerBase;
352  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
353  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
354  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
355  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
356  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
357  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
358  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
359  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
360  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
361
362  MiscReg stat = tc->readMiscReg(MipsISA::Status);
363  // Since handler depends on EXL bit, must check EXL bit before setting it!!
364  if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
365    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
366  }else{
367    HandlerBase = tc->readMiscReg(MipsISA::EBase); // Offset 0x000
368  }
369
370  setExceptionState(tc,0x2);
371  setHandlerPC(HandlerBase,tc);
372}
373
374void DtbRefillFault::invoke(ThreadContext *tc)
375{
376  // Set new PC
377  DPRINTF(MipsPRA,"%s encountered.\n", name());
378  Addr HandlerBase;
379  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
380  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
381  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
382  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
383  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
384  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
385  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
386  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
387  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
388
389  MiscReg stat = tc->readMiscReg(MipsISA::Status);
390  // Since handler depends on EXL bit, must check EXL bit before setting it!!
391  if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
392    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
393  }else{
394    HandlerBase = tc->readMiscReg(MipsISA::EBase); // Offset 0x000
395  }
396
397
398  setExceptionState(tc,0x3);
399
400  setHandlerPC(HandlerBase,tc);
401}
402
403void TLBModifiedFault::invoke(ThreadContext *tc)
404{
405  DPRINTF(MipsPRA,"%s encountered.\n", name());
406  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
407  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
408  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
409  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
410  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
411  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
412  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
413  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
414  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
415
416    // Set new PC
417      Addr HandlerBase;
418      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
419      setExceptionState(tc,0x1);
420      setHandlerPC(HandlerBase,tc);
421      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
422
423}
424
425void SystemCallFault::invoke(ThreadContext *tc)
426{
427  DPRINTF(MipsPRA,"%s encountered.\n", name());
428      setExceptionState(tc,0x8);
429
430      // Set new PC
431      Addr HandlerBase;
432      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
433      setHandlerPC(HandlerBase,tc);
434      //      warn("Exception Handler At: %x \n",HandlerBase);
435      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
436
437}
438
439void InterruptFault::invoke(ThreadContext *tc)
440{
441#if  FULL_SYSTEM
442  DPRINTF(MipsPRA,"%s encountered.\n", name());
443  //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
444  setExceptionState(tc,0x0A);
445  Addr HandlerBase;
446
447
448  uint8_t IV = bits(tc->readMiscRegNoEffect(MipsISA::Cause),Cause_IV);
449  if (IV)// Offset 200 for release 2
450      HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
451  else//Ofset at 180 for release 1
452      HandlerBase= vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
453
454  setHandlerPC(HandlerBase,tc);
455#endif
456}
457
458#endif // FULL_SYSTEM
459
460void ResetFault::invoke(ThreadContext *tc)
461{
462  DPRINTF(MipsPRA,"%s encountered.\n", name());
463  /* All reset activity must be invoked from here */
464  tc->setPC(vect());
465  tc->setNextPC(vect()+sizeof(MachInst));
466  tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
467  DPRINTF(MipsPRA,"(%x)  -  ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
468}
469
470void ReservedInstructionFault::invoke(ThreadContext *tc)
471{
472#if  FULL_SYSTEM
473  DPRINTF(MipsPRA,"%s encountered.\n", name());
474  //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
475  setExceptionState(tc,0x0A);
476  Addr HandlerBase;
477  HandlerBase= vect() + tc->readMiscRegNoEffect(MipsISA::EBase); // Offset 0x180 - General Exception Vector
478  setHandlerPC(HandlerBase,tc);
479#else
480    panic("%s encountered.\n", name());
481#endif
482}
483
484void ThreadFault::invoke(ThreadContext *tc)
485{
486  DPRINTF(MipsPRA,"%s encountered.\n", name());
487  panic("%s encountered.\n", name());
488}
489
490void DspStateDisabledFault::invoke(ThreadContext *tc)
491{
492  DPRINTF(MipsPRA,"%s encountered.\n", name());
493  panic("%s encountered.\n", name());
494}
495
496void CoprocessorUnusableFault::invoke(ThreadContext *tc)
497{
498#if FULL_SYSTEM
499  DPRINTF(MipsPRA,"%s encountered.\n", name());
500  setExceptionState(tc,0xb);
501  /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
502  MiscReg cause = tc->readMiscReg(MipsISA::Cause);
503  replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
504  tc->setMiscRegNoEffect(MipsISA::Cause,cause);
505
506  Addr HandlerBase;
507  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
508  setHandlerPC(HandlerBase,tc);
509
510  //      warn("Status: %x, Cause: %x\n",tc->readMiscReg(MipsISA::Status),tc->readMiscReg(MipsISA::Cause));
511#else
512    panic("%s encountered.\n", name());
513#endif
514}
515
516} // namespace MipsISA
517
518