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