2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * Copyright (c) 2007-2008 The Florida State University
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.
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.
33 #include "arch/arm/faults.hh"
34 #include "cpu/thread_context.hh"
35 #include "cpu/base.hh"
36 #include "base/trace.hh"
38 #include "sim/process.hh"
39 #include "mem/page_table.hh"
45 FaultName
MachineCheckFault::_name
= "Machine Check";
46 FaultVect
MachineCheckFault::_vect
= 0x0401;
47 FaultStat
MachineCheckFault::_count
;
49 FaultName
AlignmentFault::_name
= "Alignment";
50 FaultVect
AlignmentFault::_vect
= 0x0301;
51 FaultStat
AlignmentFault::_count
;
53 FaultName
ResetFault::_name
= "Reset Fault";
55 FaultVect
ResetFault::_vect
= 0xBFC00000;
57 FaultVect
ResetFault::_vect
= 0x001;
59 FaultStat
ResetFault::_count
;
61 FaultName
AddressErrorFault::_name
= "Address Error";
62 FaultVect
AddressErrorFault::_vect
= 0x0180;
63 FaultStat
AddressErrorFault::_count
;
65 FaultName
StoreAddressErrorFault::_name
= "Store Address Error";
66 FaultVect
StoreAddressErrorFault::_vect
= 0x0180;
67 FaultStat
StoreAddressErrorFault::_count
;
70 FaultName
SystemCallFault::_name
= "Syscall";
71 FaultVect
SystemCallFault::_vect
= 0x0180;
72 FaultStat
SystemCallFault::_count
;
74 FaultName
CoprocessorUnusableFault::_name
= "Coprocessor Unusable Fault";
75 FaultVect
CoprocessorUnusableFault::_vect
= 0x180;
76 FaultStat
CoprocessorUnusableFault::_count
;
78 FaultName
ReservedInstructionFault::_name
= "Reserved Instruction Fault";
79 FaultVect
ReservedInstructionFault::_vect
= 0x0180;
80 FaultStat
ReservedInstructionFault::_count
;
82 FaultName
ThreadFault::_name
= "Thread Fault";
83 FaultVect
ThreadFault::_vect
= 0x00F1;
84 FaultStat
ThreadFault::_count
;
87 FaultName
ArithmeticFault::_name
= "Arithmetic Overflow Exception";
88 FaultVect
ArithmeticFault::_vect
= 0x180;
89 FaultStat
ArithmeticFault::_count
;
91 FaultName
UnimplementedOpcodeFault::_name
= "opdec";
92 FaultVect
UnimplementedOpcodeFault::_vect
= 0x0481;
93 FaultStat
UnimplementedOpcodeFault::_count
;
95 FaultName
InterruptFault::_name
= "interrupt";
96 FaultVect
InterruptFault::_vect
= 0x0180;
97 FaultStat
InterruptFault::_count
;
99 FaultName
TrapFault::_name
= "Trap";
100 FaultVect
TrapFault::_vect
= 0x0180;
101 FaultStat
TrapFault::_count
;
103 FaultName
BreakpointFault::_name
= "Breakpoint";
104 FaultVect
BreakpointFault::_vect
= 0x0180;
105 FaultStat
BreakpointFault::_count
;
108 FaultName
ItbInvalidFault::_name
= "Invalid TLB Entry Exception (I-Fetch/LW)";
109 FaultVect
ItbInvalidFault::_vect
= 0x0180;
110 FaultStat
ItbInvalidFault::_count
;
112 FaultName
ItbPageFault::_name
= "itbmiss";
113 FaultVect
ItbPageFault::_vect
= 0x0181;
114 FaultStat
ItbPageFault::_count
;
116 FaultName
ItbMissFault::_name
= "itbmiss";
117 FaultVect
ItbMissFault::_vect
= 0x0181;
118 FaultStat
ItbMissFault::_count
;
120 FaultName
ItbAcvFault::_name
= "iaccvio";
121 FaultVect
ItbAcvFault::_vect
= 0x0081;
122 FaultStat
ItbAcvFault::_count
;
124 FaultName
ItbRefillFault::_name
= "TLB Refill Exception (I-Fetch/LW)";
125 FaultVect
ItbRefillFault::_vect
= 0x0180;
126 FaultStat
ItbRefillFault::_count
;
128 FaultName
NDtbMissFault::_name
= "dtb_miss_single";
129 FaultVect
NDtbMissFault::_vect
= 0x0201;
130 FaultStat
NDtbMissFault::_count
;
132 FaultName
PDtbMissFault::_name
= "dtb_miss_double";
133 FaultVect
PDtbMissFault::_vect
= 0x0281;
134 FaultStat
PDtbMissFault::_count
;
136 FaultName
DtbPageFault::_name
= "dfault";
137 FaultVect
DtbPageFault::_vect
= 0x0381;
138 FaultStat
DtbPageFault::_count
;
140 FaultName
DtbAcvFault::_name
= "dfault";
141 FaultVect
DtbAcvFault::_vect
= 0x0381;
142 FaultStat
DtbAcvFault::_count
;
144 FaultName
DtbInvalidFault::_name
= "Invalid TLB Entry Exception (Store)";
145 FaultVect
DtbInvalidFault::_vect
= 0x0180;
146 FaultStat
DtbInvalidFault::_count
;
148 FaultName
DtbRefillFault::_name
= "TLB Refill Exception (Store)";
149 FaultVect
DtbRefillFault::_vect
= 0x0180;
150 FaultStat
DtbRefillFault::_count
;
152 FaultName
TLBModifiedFault::_name
= "TLB Modified Exception";
153 FaultVect
TLBModifiedFault::_vect
= 0x0180;
154 FaultStat
TLBModifiedFault::_count
;
156 FaultName
FloatEnableFault::_name
= "float_enable_fault";
157 FaultVect
FloatEnableFault::_vect
= 0x0581;
158 FaultStat
FloatEnableFault::_count
;
160 FaultName
IntegerOverflowFault::_name
= "Integer Overflow Fault";
161 FaultVect
IntegerOverflowFault::_vect
= 0x0501;
162 FaultStat
IntegerOverflowFault::_count
;
164 FaultName
DspStateDisabledFault::_name
= "DSP Disabled Fault";
165 FaultVect
DspStateDisabledFault::_vect
= 0x001a;
166 FaultStat
DspStateDisabledFault::_count
;
169 void ArmFault::setHandlerPC(Addr HandlerBase
, ThreadContext
*tc
)
171 tc
->setPC(HandlerBase
);
172 tc
->setNextPC(HandlerBase
+sizeof(MachInst
));
173 tc
->setNextNPC(HandlerBase
+2*sizeof(MachInst
));
176 void ArmFault::setExceptionState(ThreadContext
*tc
,uint8_t ExcCode
)
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)
182 // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
183 MiscReg srs
= tc
->readMiscReg(ArmISA::SRSCtl
);
185 CSS
= bits(srs
,SRSCtl_CSS_HI
,SRSCtl_CSS_LO
);
186 ESS
= bits(srs
,SRSCtl_ESS_HI
,SRSCtl_ESS_LO
);
188 replaceBits(srs
,SRSCtl_PSS_HI
,SRSCtl_PSS_LO
,CSS
);
190 replaceBits(srs
,SRSCtl_CSS_HI
,SRSCtl_CSS_LO
,ESS
);
191 tc
->setMiscRegNoEffect(ArmISA::SRSCtl
,srs
);
192 //tc->setShadowSet(ESS);
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
);
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());
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
210 tc
->setMiscRegNoEffect(ArmISA::EPC
,tc
->readPC());
211 // In the branch delay slot? reset CAUSE_31
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
);
224 void ArithmeticFault::invoke(ThreadContext
*tc
)
226 DPRINTF(Arm
,"%s encountered.\n", name());
227 setExceptionState(tc
,0xC);
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
);
236 HandlerBase
= 0xBFC00200;
238 setHandlerPC(HandlerBase
,tc
);
239 // warn("Exception Handler At: %x \n",HandlerBase);
242 void StoreAddressErrorFault::invoke(ThreadContext
*tc
)
244 DPRINTF(Arm
,"%s encountered.\n", name());
245 setExceptionState(tc
,0x5);
246 tc
->setMiscRegNoEffect(ArmISA::BadVAddr
,BadVAddr
);
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));
257 void TrapFault::invoke(ThreadContext
*tc
)
259 DPRINTF(Arm
,"%s encountered.\n", name());
260 // warn("%s encountered.\n", name());
261 setExceptionState(tc
,0xD);
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));
271 void BreakpointFault::invoke(ThreadContext
*tc
)
273 setExceptionState(tc
,0x9);
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));
284 void DtbInvalidFault::invoke(ThreadContext
*tc
)
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);
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));
307 void AddressErrorFault::invoke(ThreadContext
*tc
)
309 DPRINTF(Arm
,"%s encountered.\n", name());
310 setExceptionState(tc
,0x4);
311 tc
->setMiscRegNoEffect(ArmISA::BadVAddr
,BadVAddr
);
315 HandlerBase
= vect() + tc
->readMiscReg(ArmISA::EBase
); // Offset 0x180 - General Exception Vector
316 setHandlerPC(HandlerBase
,tc
);
319 void ItbInvalidFault::invoke(ThreadContext
*tc
)
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
);
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
));
341 void ItbRefillFault::invoke(ThreadContext
*tc
)
343 DPRINTF(Arm
,"%s encountered (%x).\n", name(),BadVAddr
);
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
);
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
360 HandlerBase
= tc
->readMiscReg(ArmISA::EBase
); // Offset 0x000
363 setExceptionState(tc
,0x2);
364 setHandlerPC(HandlerBase
,tc
);
367 void DtbRefillFault::invoke(ThreadContext
*tc
)
370 DPRINTF(Arm
,"%s encountered.\n", name());
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
);
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
387 HandlerBase
= tc
->readMiscReg(ArmISA::EBase
); // Offset 0x000
391 setExceptionState(tc
,0x3);
393 setHandlerPC(HandlerBase
,tc
);
396 void TLBModifiedFault::invoke(ThreadContext
*tc
)
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
);
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));
418 void SystemCallFault::invoke(ThreadContext
*tc
)
420 DPRINTF(Arm
,"%s encountered.\n", name());
421 setExceptionState(tc
,0x8);
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));
432 void InterruptFault::invoke(ThreadContext
*tc
)
435 DPRINTF(Arm
,"%s encountered.\n", name());
436 //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
437 setExceptionState(tc
,0x0A);
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
);
447 setHandlerPC(HandlerBase
,tc
);
451 #endif // FULL_SYSTEM
453 void ResetFault::invoke(ThreadContext
*tc
)
456 DPRINTF(Arm
,"%s encountered.\n", name());
457 /* All reset activity must be invoked from here */
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());
464 // Set Coprocessor 1 (Floating Point) To Usable
465 //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000);
468 void ReservedInstructionFault::invoke(ThreadContext
*tc
)
471 DPRINTF(Arm
,"%s encountered.\n", name());
472 //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
473 setExceptionState(tc
,0x0A);
475 HandlerBase
= vect() + tc
->readMiscRegNoEffect(ArmISA::EBase
); // Offset 0x180 - General Exception Vector
476 setHandlerPC(HandlerBase
,tc
);
478 panic("%s encountered.\n", name());
482 void ThreadFault::invoke(ThreadContext
*tc
)
484 DPRINTF(Arm
,"%s encountered.\n", name());
485 panic("%s encountered.\n", name());
488 void DspStateDisabledFault::invoke(ThreadContext
*tc
)
490 DPRINTF(Arm
,"%s encountered.\n", name());
491 panic("%s encountered.\n", name());
494 void CoprocessorUnusableFault::invoke(ThreadContext
*tc
)
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
);
505 HandlerBase
= vect() + tc
->readMiscReg(ArmISA::EBase
); // Offset 0x180 - General Exception Vector
506 setHandlerPC(HandlerBase
,tc
);
508 // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause));
510 warn("%s (CP%d) encountered.\n", name(), coProcID
);
514 } // namespace ArmISA