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