faults.cc revision 6378
12330SN/A/*
22330SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32330SN/A * Copyright (c) 2007 MIPS Technologies, Inc.
42330SN/A * All rights reserved.
52330SN/A *
62330SN/A * Redistribution and use in source and binary forms, with or without
72330SN/A * modification, are permitted provided that the following conditions are
82330SN/A * met: redistributions of source code must retain the above copyright
92330SN/A * notice, this list of conditions and the following disclaimer;
102330SN/A * redistributions in binary form must reproduce the above copyright
112330SN/A * notice, this list of conditions and the following disclaimer in the
122330SN/A * documentation and/or other materials provided with the distribution;
132330SN/A * neither the name of the copyright holders nor the names of its
142330SN/A * contributors may be used to endorse or promote products derived from
152330SN/A * this software without specific prior written permission.
162330SN/A *
172330SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182330SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192330SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202330SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212330SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222330SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232330SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242330SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252330SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262330SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272330SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282292SN/A *
292292SN/A * Authors: Gabe Black
302292SN/A *          Korey Sewell
312292SN/A *          Jaidev Patwardhan
322683Sktlim@umich.edu */
332680Sktlim@umich.edu
342292SN/A#include "arch/mips/faults.hh"
352678Sktlim@umich.edu#include "cpu/thread_context.hh"
362683Sktlim@umich.edu#include "cpu/base.hh"
372678Sktlim@umich.edu#include "base/trace.hh"
382683Sktlim@umich.edu#include "arch/mips/pra_constants.hh"
392678Sktlim@umich.edu#if !FULL_SYSTEM
402678Sktlim@umich.edu#include "sim/process.hh"
412292SN/A#include "mem/page_table.hh"
422292SN/A#endif
432292SN/A
442292SN/Anamespace MipsISA
452330SN/A{
462330SN/A
472330SN/AFaultName MachineCheckFault::_name = "Machine Check";
482292SN/AFaultVect MachineCheckFault::_vect = 0x0401;
492292SN/AFaultStat MachineCheckFault::_count;
502330SN/A
512330SN/AFaultName AlignmentFault::_name = "Alignment";
522330SN/AFaultVect AlignmentFault::_vect = 0x0301;
532330SN/AFaultStat AlignmentFault::_count;
542330SN/A
552330SN/AFaultName ResetFault::_name = "Reset Fault";
562292SN/A#if  FULL_SYSTEM
572683Sktlim@umich.eduFaultVect ResetFault::_vect = 0xBFC00000;
582683Sktlim@umich.edu#else
592292SN/AFaultVect ResetFault::_vect = 0x001;
602683Sktlim@umich.edu#endif
612292SN/AFaultStat ResetFault::_count;
622678Sktlim@umich.edu
632683Sktlim@umich.eduFaultName AddressErrorFault::_name = "Address Error";
642292SN/AFaultVect AddressErrorFault::_vect = 0x0180;
652683Sktlim@umich.eduFaultStat AddressErrorFault::_count;
662683Sktlim@umich.edu
672683Sktlim@umich.eduFaultName StoreAddressErrorFault::_name = "Store Address Error";
682683Sktlim@umich.eduFaultVect StoreAddressErrorFault::_vect = 0x0180;
692683Sktlim@umich.eduFaultStat StoreAddressErrorFault::_count;
702683Sktlim@umich.edu
712683Sktlim@umich.edu
722683Sktlim@umich.eduFaultName SystemCallFault::_name = "Syscall";
732683Sktlim@umich.eduFaultVect SystemCallFault::_vect = 0x0180;
742683Sktlim@umich.eduFaultStat SystemCallFault::_count;
752683Sktlim@umich.edu
762683Sktlim@umich.eduFaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
772683Sktlim@umich.eduFaultVect CoprocessorUnusableFault::_vect = 0x180;
782683Sktlim@umich.eduFaultStat CoprocessorUnusableFault::_count;
792683Sktlim@umich.edu
802683Sktlim@umich.eduFaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
812683Sktlim@umich.eduFaultVect ReservedInstructionFault::_vect = 0x0180;
822683Sktlim@umich.eduFaultStat ReservedInstructionFault::_count;
832683Sktlim@umich.edu
842683Sktlim@umich.eduFaultName ThreadFault::_name = "Thread Fault";
852683Sktlim@umich.eduFaultVect ThreadFault::_vect = 0x00F1;
862683Sktlim@umich.eduFaultStat ThreadFault::_count;
872683Sktlim@umich.edu
882683Sktlim@umich.eduFaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
892683Sktlim@umich.eduFaultVect ArithmeticFault::_vect = 0x180;
902683Sktlim@umich.eduFaultStat ArithmeticFault::_count;
912683Sktlim@umich.edu
922683Sktlim@umich.eduFaultName UnimplementedOpcodeFault::_name = "opdec";
932683Sktlim@umich.eduFaultVect UnimplementedOpcodeFault::_vect = 0x0481;
942683Sktlim@umich.eduFaultStat UnimplementedOpcodeFault::_count;
952683Sktlim@umich.edu
962683Sktlim@umich.eduFaultName InterruptFault::_name = "interrupt";
972683Sktlim@umich.eduFaultVect InterruptFault::_vect = 0x0180;
982683Sktlim@umich.eduFaultStat InterruptFault::_count;
992683Sktlim@umich.edu
1002683Sktlim@umich.eduFaultName TrapFault::_name = "Trap";
1012678Sktlim@umich.eduFaultVect TrapFault::_vect = 0x0180;
1022292SN/AFaultStat TrapFault::_count;
1032683Sktlim@umich.edu
1042683Sktlim@umich.eduFaultName BreakpointFault::_name = "Breakpoint";
1052292SN/AFaultVect BreakpointFault::_vect = 0x0180;
1062683Sktlim@umich.eduFaultStat BreakpointFault::_count;
1072683Sktlim@umich.edu
1082683Sktlim@umich.eduFaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
1092683Sktlim@umich.eduFaultVect ItbInvalidFault::_vect = 0x0180;
1102683Sktlim@umich.eduFaultStat ItbInvalidFault::_count;
1112683Sktlim@umich.edu
1122683Sktlim@umich.eduFaultName ItbPageFault::_name = "itbmiss";
1132683Sktlim@umich.eduFaultVect ItbPageFault::_vect = 0x0181;
1142683Sktlim@umich.eduFaultStat ItbPageFault::_count;
1152683Sktlim@umich.edu
1162683Sktlim@umich.eduFaultName ItbMissFault::_name = "itbmiss";
1172683Sktlim@umich.eduFaultVect ItbMissFault::_vect = 0x0181;
1182683Sktlim@umich.eduFaultStat ItbMissFault::_count;
1192683Sktlim@umich.edu
1202683Sktlim@umich.eduFaultName ItbAcvFault::_name = "iaccvio";
1212683Sktlim@umich.eduFaultVect ItbAcvFault::_vect = 0x0081;
1222683Sktlim@umich.eduFaultStat ItbAcvFault::_count;
1232683Sktlim@umich.edu
1242683Sktlim@umich.eduFaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
1252683Sktlim@umich.eduFaultVect ItbRefillFault::_vect = 0x0180;
1262683Sktlim@umich.eduFaultStat ItbRefillFault::_count;
1272683Sktlim@umich.edu
1282683Sktlim@umich.eduFaultName NDtbMissFault::_name = "dtb_miss_single";
1292683Sktlim@umich.eduFaultVect NDtbMissFault::_vect = 0x0201;
1302683Sktlim@umich.eduFaultStat NDtbMissFault::_count;
1312683Sktlim@umich.edu
1322683Sktlim@umich.eduFaultName PDtbMissFault::_name = "dtb_miss_double";
1332683Sktlim@umich.eduFaultVect PDtbMissFault::_vect = 0x0281;
1342683Sktlim@umich.eduFaultStat PDtbMissFault::_count;
1352683Sktlim@umich.edu
1362683Sktlim@umich.eduFaultName DtbPageFault::_name = "dfault";
1372683Sktlim@umich.eduFaultVect DtbPageFault::_vect = 0x0381;
1382683Sktlim@umich.eduFaultStat DtbPageFault::_count;
1392683Sktlim@umich.edu
1402683Sktlim@umich.eduFaultName DtbAcvFault::_name = "dfault";
1412683Sktlim@umich.eduFaultVect DtbAcvFault::_vect = 0x0381;
1422683Sktlim@umich.eduFaultStat DtbAcvFault::_count;
1432683Sktlim@umich.edu
1442683Sktlim@umich.eduFaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
1452292SN/AFaultVect DtbInvalidFault::_vect = 0x0180;
1462292SN/AFaultStat DtbInvalidFault::_count;
1472292SN/A
1482292SN/AFaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
1492292SN/AFaultVect DtbRefillFault::_vect = 0x0180;
1502683Sktlim@umich.eduFaultStat DtbRefillFault::_count;
1512683Sktlim@umich.edu
1522292SN/AFaultName TLBModifiedFault::_name = "TLB Modified Exception";
1532683Sktlim@umich.eduFaultVect TLBModifiedFault::_vect = 0x0180;
1542683Sktlim@umich.eduFaultStat TLBModifiedFault::_count;
1552292SN/A
1562292SN/AFaultName FloatEnableFault::_name = "float_enable_fault";
1572683Sktlim@umich.eduFaultVect FloatEnableFault::_vect = 0x0581;
1582292SN/AFaultStat FloatEnableFault::_count;
1592292SN/A
1602292SN/AFaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
1612292SN/AFaultVect IntegerOverflowFault::_vect = 0x0501;
1622292SN/AFaultStat IntegerOverflowFault::_count;
1632330SN/A
1642683Sktlim@umich.eduFaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
1652683Sktlim@umich.eduFaultVect DspStateDisabledFault::_vect = 0x001a;
1662683Sktlim@umich.eduFaultStat DspStateDisabledFault::_count;
1672683Sktlim@umich.edu
1682683Sktlim@umich.edu#if FULL_SYSTEM
1692683Sktlim@umich.eduvoid
1702683Sktlim@umich.eduMipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
1712683Sktlim@umich.edu{
1722292SN/A    tc->setPC(HandlerBase);
1732678Sktlim@umich.edu    tc->setNextPC(HandlerBase + sizeof(MachInst));
1742678Sktlim@umich.edu    tc->setNextNPC(HandlerBase + 2 * sizeof(MachInst));
1752292SN/A}
1762292SN/A
1772292SN/Avoid
1782292SN/AMipsFault::setExceptionState(ThreadContext *tc, uint8_t ExcCode)
1792292SN/A{
1802292SN/A    // modify SRS Ctl - Save CSS, put ESS into CSS
1812683Sktlim@umich.edu    MiscReg stat = tc->readMiscReg(MipsISA::Status);
1822292SN/A    if (bits(stat, Status_EXL) != 1 && bits(stat, Status_BEV) != 1) {
1832683Sktlim@umich.edu        // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
1842683Sktlim@umich.edu        MiscReg srs = tc->readMiscReg(MipsISA::SRSCtl);
1852683Sktlim@umich.edu        uint8_t CSS, ESS;
1862683Sktlim@umich.edu        CSS = bits(srs, SRSCtl_CSS_HI, SRSCtl_CSS_LO);
1872292SN/A        ESS = bits(srs, SRSCtl_ESS_HI, SRSCtl_ESS_LO);
1882292SN/A        // Move CSS to PSS
1892292SN/A        replaceBits(srs, SRSCtl_PSS_HI, SRSCtl_PSS_LO, CSS);
1902292SN/A        // Move ESS to CSS
1912292SN/A        replaceBits(srs, SRSCtl_CSS_HI, SRSCtl_CSS_LO, ESS);
1922292SN/A        tc->setMiscRegNoEffect(MipsISA::SRSCtl, srs);
1932292SN/A    }
1942292SN/A
1952292SN/A    // set EXL bit (don't care if it is already set!)
1962292SN/A    replaceBits(stat, Status_EXL_HI, Status_EXL_LO, 1);
1972292SN/A    tc->setMiscRegNoEffect(MipsISA::Status, stat);
1982292SN/A
1992292SN/A    // write EPC
2002683Sktlim@umich.edu    // CHECK ME  or FIXME or FIX ME or POSSIBLE HACK
2012292SN/A    // Check to see if the exception occurred in the branch delay slot
2022292SN/A    DPRINTF(MipsPRA, "PC: %x, NextPC: %x, NNPC: %x\n",
2032292SN/A            tc->readPC(), tc->readNextPC(), tc->readNextNPC());
2042292SN/A    int C_BD = 0;
2052292SN/A    if (tc->readPC() + sizeof(MachInst) != tc->readNextPC()) {
2062292SN/A        tc->setMiscRegNoEffect(MipsISA::EPC, tc->readPC() - sizeof(MachInst));
2072292SN/A        // In the branch delay slot? set CAUSE_31
2082292SN/A        C_BD = 1;
2092292SN/A    } else {
2102292SN/A        tc->setMiscRegNoEffect(MipsISA::EPC, tc->readPC());
2112292SN/A        // In the branch delay slot? reset CAUSE_31
2122292SN/A        C_BD = 0;
2132292SN/A    }
214
215    // Set Cause_EXCCODE field
216    MiscReg cause = tc->readMiscReg(MipsISA::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(MipsISA::Cause, cause);
221}
222
223void
224ArithmeticFault::invoke(ThreadContext *tc)
225{
226    DPRINTF(MipsPRA, "%s encountered.\n", name());
227    setExceptionState(tc, 0xC);
228
229    // Set new PC
230    Addr HandlerBase;
231    MiscReg stat = tc->readMiscReg(MipsISA::Status);
232    // Here, the handler is dependent on BEV, which is not modified by
233    // setExceptionState()
234    if (bits(stat, Status_BEV) == 0 ) {
235        // See MIPS ARM Vol 3, Revision 2, Page 38
236        HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
237    } else {
238        HandlerBase = 0xBFC00200;
239    }
240    setHandlerPC(HandlerBase, tc);
241}
242
243void
244StoreAddressErrorFault::invoke(ThreadContext *tc)
245{
246    DPRINTF(MipsPRA, "%s encountered.\n", name());
247    setExceptionState(tc, 0x5);
248    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
249
250    // Set new PC
251    Addr HandlerBase;
252    // Offset 0x180 - General Exception Vector
253    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
254    setHandlerPC(HandlerBase, tc);
255}
256
257void
258TrapFault::invoke(ThreadContext *tc)
259{
260    DPRINTF(MipsPRA, "%s encountered.\n", name());
261    setExceptionState(tc, 0xD);
262
263    // Set new PC
264    Addr HandlerBase;
265    // Offset 0x180 - General Exception Vector
266    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
267    setHandlerPC(HandlerBase, tc);
268}
269
270void
271BreakpointFault::invoke(ThreadContext *tc)
272{
273    setExceptionState(tc, 0x9);
274
275    // Set new PC
276    Addr HandlerBase;
277    // Offset 0x180 - General Exception Vector
278    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
279    setHandlerPC(HandlerBase, tc);
280}
281
282void
283DtbInvalidFault::invoke(ThreadContext *tc)
284{
285    DPRINTF(MipsPRA, "%s encountered.\n", name());
286
287    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
288    MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
289    replaceBits(eh, EntryHi_ASID_HI, EntryHi_ASID_LO, EntryHi_Asid);
290    replaceBits(eh, EntryHi_VPN2_HI, EntryHi_VPN2_LO, EntryHi_VPN2);
291    replaceBits(eh, EntryHi_VPN2X_HI, EntryHi_VPN2X_LO, EntryHi_VPN2X);
292    tc->setMiscRegNoEffect(MipsISA::EntryHi, eh);
293    MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
294    replaceBits(ctxt, Context_BadVPN2_HI, Context_BadVPN2_LO, Context_BadVPN2);
295    tc->setMiscRegNoEffect(MipsISA::Context, ctxt);
296    setExceptionState(tc, 0x3);
297
298
299    // Set new PC
300    Addr HandlerBase;
301    // Offset 0x180 - General Exception Vector
302    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
303    setHandlerPC(HandlerBase,tc);
304}
305
306void
307AddressErrorFault::invoke(ThreadContext *tc)
308{
309    DPRINTF(MipsPRA, "%s encountered.\n", name());
310    setExceptionState(tc, 0x4);
311    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
312
313    // Set new PC
314    Addr HandlerBase;
315    // Offset 0x180 - General Exception Vector
316    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
317    setHandlerPC(HandlerBase, tc);
318}
319
320void
321ItbInvalidFault::invoke(ThreadContext *tc)
322{
323    DPRINTF(MipsPRA, "%s encountered.\n", name());
324    setExceptionState(tc, 0x2);
325    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
326    MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
327    replaceBits(eh, EntryHi_ASID_HI, EntryHi_ASID_LO, EntryHi_Asid);
328    replaceBits(eh, EntryHi_VPN2_HI, EntryHi_VPN2_LO, EntryHi_VPN2);
329    replaceBits(eh, EntryHi_VPN2X_HI, EntryHi_VPN2X_LO, EntryHi_VPN2X);
330    tc->setMiscRegNoEffect(MipsISA::EntryHi, eh);
331    MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
332    replaceBits(ctxt, Context_BadVPN2_HI, Context_BadVPN2_LO, Context_BadVPN2);
333    tc->setMiscRegNoEffect(MipsISA::Context, ctxt);
334
335
336    // Set new PC
337    Addr HandlerBase;
338    // Offset 0x180 - General Exception Vector
339    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase);
340    setHandlerPC(HandlerBase,tc);
341    DPRINTF(MipsPRA,"Exception Handler At: %x , EPC set to %x\n",
342            HandlerBase, tc->readMiscReg(MipsISA::EPC));
343}
344
345void
346ItbRefillFault::invoke(ThreadContext *tc)
347{
348    DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), BadVAddr);
349    Addr HandlerBase;
350    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
351    MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
352    replaceBits(eh, EntryHi_ASID_HI, EntryHi_ASID_LO, EntryHi_Asid);
353    replaceBits(eh, EntryHi_VPN2_HI, EntryHi_VPN2_LO, EntryHi_VPN2);
354    replaceBits(eh, EntryHi_VPN2X_HI, EntryHi_VPN2X_LO, EntryHi_VPN2X);
355    tc->setMiscRegNoEffect(MipsISA::EntryHi, eh);
356    MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
357    replaceBits(ctxt, Context_BadVPN2_HI, Context_BadVPN2_LO, Context_BadVPN2);
358    tc->setMiscRegNoEffect(MipsISA::Context, ctxt);
359
360    MiscReg stat = tc->readMiscReg(MipsISA::Status);
361    // Since handler depends on EXL bit, must check EXL bit before setting it!!
362    // See MIPS ARM Vol 3, Revision 2, Page 38
363    if (bits(stat, Status_EXL) == 1) {
364        // Offset 0x180 - General Exception Vector
365        HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
366    } else {
367        // Offset 0x000
368        HandlerBase = tc->readMiscReg(MipsISA::EBase);
369    }
370
371    setExceptionState(tc, 0x2);
372    setHandlerPC(HandlerBase, tc);
373}
374
375void
376DtbRefillFault::invoke(ThreadContext *tc)
377{
378    // Set new PC
379    DPRINTF(MipsPRA, "%s encountered.\n", name());
380    Addr HandlerBase;
381    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
382    MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
383    replaceBits(eh, EntryHi_ASID_HI, EntryHi_ASID_LO, EntryHi_Asid);
384    replaceBits(eh, EntryHi_VPN2_HI, EntryHi_VPN2_LO, EntryHi_VPN2);
385    replaceBits(eh, EntryHi_VPN2X_HI, EntryHi_VPN2X_LO, EntryHi_VPN2X);
386    tc->setMiscRegNoEffect(MipsISA::EntryHi, eh);
387    MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
388    replaceBits(ctxt, Context_BadVPN2_HI, Context_BadVPN2_LO, Context_BadVPN2);
389    tc->setMiscRegNoEffect(MipsISA::Context, ctxt);
390
391    MiscReg stat = tc->readMiscReg(MipsISA::Status);
392    // Since handler depends on EXL bit, must check EXL bit before setting it!!
393    // See MIPS ARM Vol 3, Revision 2, Page 38
394    if(bits(stat, Status_EXL) == 1) {
395        // Offset 0x180 - General Exception Vector
396        HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
397    } else {
398        // Offset 0x000
399        HandlerBase = tc->readMiscReg(MipsISA::EBase);
400    }
401
402    setExceptionState(tc, 0x3);
403
404    setHandlerPC(HandlerBase, tc);
405}
406
407void
408TLBModifiedFault::invoke(ThreadContext *tc)
409{
410    DPRINTF(MipsPRA, "%s encountered.\n", name());
411    tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr);
412    MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
413    replaceBits(eh, EntryHi_ASID_HI, EntryHi_ASID_LO, EntryHi_Asid);
414    replaceBits(eh, EntryHi_VPN2_HI, EntryHi_VPN2_LO, EntryHi_VPN2);
415    replaceBits(eh, EntryHi_VPN2X_HI, EntryHi_VPN2X_LO, EntryHi_VPN2X);
416    tc->setMiscRegNoEffect(MipsISA::EntryHi, eh);
417    MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
418    replaceBits(ctxt, Context_BadVPN2_HI, Context_BadVPN2_LO, Context_BadVPN2);
419    tc->setMiscRegNoEffect(MipsISA::Context, ctxt);
420
421    // Set new PC
422    Addr HandlerBase;
423    // Offset 0x180 - General Exception Vector
424    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
425    setExceptionState(tc, 0x1);
426    setHandlerPC(HandlerBase, tc);
427
428}
429
430void
431SystemCallFault::invoke(ThreadContext *tc)
432{
433    DPRINTF(MipsPRA, "%s encountered.\n", name());
434    setExceptionState(tc, 0x8);
435
436    // Set new PC
437    Addr HandlerBase;
438    // Offset 0x180 - General Exception Vector
439    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
440    setHandlerPC(HandlerBase, tc);
441}
442
443void
444InterruptFault::invoke(ThreadContext *tc)
445{
446#if  FULL_SYSTEM
447    DPRINTF(MipsPRA, "%s encountered.\n", name());
448    setExceptionState(tc, 0x0A);
449    Addr HandlerBase;
450
451    uint8_t IV = bits(tc->readMiscRegNoEffect(MipsISA::Cause), Cause_IV);
452    if (IV) {
453        // Offset 200 for release 2
454        HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
455    } else {
456        //Ofset at 180 for release 1
457        HandlerBase = vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
458    }
459
460    setHandlerPC(HandlerBase, tc);
461#endif
462}
463
464#endif // FULL_SYSTEM
465
466void
467ResetFault::invoke(ThreadContext *tc)
468{
469#if FULL_SYSTEM
470    DPRINTF(MipsPRA, "%s encountered.\n", name());
471    /* All reset activity must be invoked from here */
472    tc->setPC(vect());
473    tc->setNextPC(vect() + sizeof(MachInst));
474    tc->setNextNPC(vect() + sizeof(MachInst) + sizeof(MachInst));
475    DPRINTF(MipsPRA, "(%x)  -  ResetFault::invoke : PC set to %x",
476            (unsigned)tc, (unsigned)tc->readPC());
477#endif
478
479    // Set Coprocessor 1 (Floating Point) To Usable
480    tc->setMiscReg(MipsISA::Status, MipsISA::Status | 0x20000000);
481}
482
483void
484ReservedInstructionFault::invoke(ThreadContext *tc)
485{
486#if  FULL_SYSTEM
487    DPRINTF(MipsPRA, "%s encountered.\n", name());
488    setExceptionState(tc, 0x0A);
489    Addr HandlerBase;
490    // Offset 0x180 - General Exception Vector
491    HandlerBase = vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
492    setHandlerPC(HandlerBase, tc);
493#else
494    panic("%s encountered.\n", name());
495#endif
496}
497
498void
499ThreadFault::invoke(ThreadContext *tc)
500{
501    DPRINTF(MipsPRA, "%s encountered.\n", name());
502    panic("%s encountered.\n", name());
503}
504
505void
506DspStateDisabledFault::invoke(ThreadContext *tc)
507{
508    DPRINTF(MipsPRA, "%s encountered.\n", name());
509    panic("%s encountered.\n", name());
510}
511
512void
513CoprocessorUnusableFault::invoke(ThreadContext *tc)
514{
515#if FULL_SYSTEM
516    DPRINTF(MipsPRA, "%s encountered.\n", name());
517    setExceptionState(tc, 0xb);
518    // The ID of the coprocessor causing the exception is stored in
519    // CoprocessorUnusableFault::coProcID
520    MiscReg cause = tc->readMiscReg(MipsISA::Cause);
521    replaceBits(cause, Cause_CE_HI, Cause_CE_LO, coProcID);
522    tc->setMiscRegNoEffect(MipsISA::Cause, cause);
523
524    Addr HandlerBase;
525    // Offset 0x180 - General Exception Vector
526    HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase);
527    setHandlerPC(HandlerBase, tc);
528
529#else
530    warn("%s (CP%d) encountered.\n", name(), coProcID);
531#endif
532}
533
534} // namespace MipsISA
535
536