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