faults.cc (6326:008930a4ace5) faults.cc (6735:6437ad24a8a0)
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

--- 12 unchanged lines hidden (view full) ---

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 *
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

--- 12 unchanged lines hidden (view full) ---

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
29 * Authors: Ali Saidi
30 * Gabe Black
31 */
32
33#include "arch/arm/faults.hh"
34#include "cpu/thread_context.hh"
35#include "cpu/base.hh"
36#include "base/trace.hh"
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
37
38namespace ArmISA
39{
40
45FaultName MachineCheckFault::_name = "Machine Check";
46FaultVect MachineCheckFault::_vect = 0x0401;
47FaultStat MachineCheckFault::_count;
41template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals =
42 {"reset", 0x00, MODE_SVC, 0, 0, true, true};
48
43
49FaultName AlignmentFault::_name = "Alignment";
50FaultVect AlignmentFault::_vect = 0x0301;
51FaultStat AlignmentFault::_count;
44template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals =
45 {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
52
46
53FaultName ResetFault::_name = "Reset Fault";
54#if FULL_SYSTEM
55FaultVect ResetFault::_vect = 0xBFC00000;
56#else
57FaultVect ResetFault::_vect = 0x001;
58#endif
59FaultStat ResetFault::_count;
47template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals =
48 {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
60
49
61FaultName AddressErrorFault::_name = "Address Error";
62FaultVect AddressErrorFault::_vect = 0x0180;
63FaultStat AddressErrorFault::_count;
50template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals =
51 {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
64
52
65FaultName StoreAddressErrorFault::_name = "Store Address Error";
66FaultVect StoreAddressErrorFault::_vect = 0x0180;
67FaultStat StoreAddressErrorFault::_count;
53template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals =
54 {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
68
55
56template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals =
57 {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
69
58
70FaultName SystemCallFault::_name = "Syscall";
71FaultVect SystemCallFault::_vect = 0x0180;
72FaultStat SystemCallFault::_count;
59template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals =
60 {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
73
61
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)
62Addr
63ArmFaultBase::getVector(ThreadContext *tc)
170{
64{
171 tc->setPC(HandlerBase);
172 tc->setNextPC(HandlerBase+sizeof(MachInst));
173 tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
174}
65 // ARM ARM B1-3
175
66
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 }
67 SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
68
69 // panic if SCTLR.VE because I have no idea what to do with vectored
70 // interrupts
71 assert(!sctlr.ve);
72
73 if (!sctlr.v)
74 return offset();
75 return offset() + HighVecs;
194
76
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
77}
78
224void ArithmeticFault::invoke(ThreadContext *tc)
225{
226 DPRINTF(Arm,"%s encountered.\n", name());
227 setExceptionState(tc,0xC);
79#if FULL_SYSTEM
228
80
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)
81void
82ArmFaultBase::invoke(ThreadContext *tc)
243{
83{
244 DPRINTF(Arm,"%s encountered.\n", name());
245 setExceptionState(tc,0x5);
246 tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
84 // ARM ARM B1.6.3
85 FaultBase::invoke(tc);
86 countStat()++;
247
87
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));
88 SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
89 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
90 CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
91 tc->readIntReg(INTREG_CONDCODES);
92
254
93
255}
94 cpsr.mode = nextMode();
95 cpsr.it1 = cpsr.it2 = 0;
96 cpsr.j = 0;
97
98 if (sctlr.te)
99 cpsr.t = 1;
100 cpsr.a = cpsr.a | abortDisable();
101 cpsr.f = cpsr.f | fiqDisable();
102 cpsr.i = 1;
103 tc->setMiscReg(MISCREG_CPSR, cpsr);
104 tc->setIntReg(INTREG_LR, tc->readPC() +
105 (saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
256
106
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));
107 switch (nextMode()) {
108 case MODE_FIQ:
109 tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
110 break;
111 case MODE_IRQ:
112 tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
113 break;
114 case MODE_SVC:
115 tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
116 break;
117 case MODE_UNDEFINED:
118 tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
119 break;
120 case MODE_ABORT:
121 tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
122 break;
123 default:
124 panic("unknown Mode\n");
125 }
126
127 DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr,
128 tc->readPC(), tc->readIntReg(INTREG_LR));
129 tc->setPC(getVector(tc));
130 tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 );
269}
131}
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 setExceptionState(tc,0x0A);
437 Addr HandlerBase;
438
439
440 uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV);
441 if (IV)// Offset 200 for release 2
442 HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
443 else//Ofset at 180 for release 1
444 HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
445
446 setHandlerPC(HandlerBase,tc);
447#endif
448}
449
450#endif // FULL_SYSTEM
451
132#endif // FULL_SYSTEM
133
452void ResetFault::invoke(ThreadContext *tc)
453{
454#if FULL_SYSTEM
455 DPRINTF(Arm,"%s encountered.\n", name());
456 /* All reset activity must be invoked from here */
457 tc->setPC(vect());
458 tc->setNextPC(vect()+sizeof(MachInst));
459 tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
460 DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
461#endif
134// return via SUBS pc, lr, xxx; rfe, movs, ldm
462
135
463 // Set Coprocessor 1 (Floating Point) To Usable
464 //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000);
465}
466
136
467void ReservedInstructionFault::invoke(ThreadContext *tc)
468{
469#if FULL_SYSTEM
470 DPRINTF(Arm,"%s encountered.\n", name());
471 setExceptionState(tc,0x0A);
472 Addr HandlerBase;
473 HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector
474 setHandlerPC(HandlerBase,tc);
475#else
476 panic("%s encountered.\n", name());
477#endif
478}
479
137
480void ThreadFault::invoke(ThreadContext *tc)
481{
482 DPRINTF(Arm,"%s encountered.\n", name());
483 panic("%s encountered.\n", name());
484}
485
486void DspStateDisabledFault::invoke(ThreadContext *tc)
487{
488 DPRINTF(Arm,"%s encountered.\n", name());
489 panic("%s encountered.\n", name());
490}
491
492void CoprocessorUnusableFault::invoke(ThreadContext *tc)
493{
494#if FULL_SYSTEM
495 DPRINTF(Arm,"%s encountered.\n", name());
496 setExceptionState(tc,0xb);
497 /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
498 MiscReg cause = tc->readMiscReg(ArmISA::Cause);
499 replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
500 tc->setMiscRegNoEffect(ArmISA::Cause,cause);
501
502 Addr HandlerBase;
503 HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
504 setHandlerPC(HandlerBase,tc);
505
506 // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause));
507#else
508 warn("%s (CP%d) encountered.\n", name(), coProcID);
509#endif
510}
511
512} // namespace ArmISA
513
138} // namespace ArmISA
139