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