faults.cc revision 7676
11736SN/A/*
27778Sgblack@eecs.umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
31736SN/A * Copyright (c) 2007 MIPS Technologies, Inc.
41736SN/A * All rights reserved.
51736SN/A *
61736SN/A * Redistribution and use in source and binary forms, with or without
71736SN/A * modification, are permitted provided that the following conditions are
81736SN/A * met: redistributions of source code must retain the above copyright
91736SN/A * notice, this list of conditions and the following disclaimer;
101736SN/A * redistributions in binary form must reproduce the above copyright
111736SN/A * notice, this list of conditions and the following disclaimer in the
121736SN/A * documentation and/or other materials provided with the distribution;
131736SN/A * neither the name of the copyright holders nor the names of its
141736SN/A * contributors may be used to endorse or promote products derived from
151736SN/A * this software without specific prior written permission.
161736SN/A *
171736SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181736SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191736SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201736SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211736SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221736SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231736SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241736SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251736SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261736SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665SN/A *
297778Sgblack@eecs.umich.edu * Authors: Gabe Black
301736SN/A *          Korey Sewell
311519SN/A *          Jaidev Patwardhan
321519SN/A */
331519SN/A
341519SN/A#include "arch/mips/faults.hh"
351519SN/A#include "arch/mips/pra_constants.hh"
361519SN/A#include "base/trace.hh"
371519SN/A#include "cpu/base.hh"
381519SN/A#include "cpu/thread_context.hh"
391519SN/A
401519SN/A#if !FULL_SYSTEM
411519SN/A#include "mem/page_table.hh"
421519SN/A#include "sim/process.hh"
431519SN/A#endif
441519SN/A
451519SN/Anamespace MipsISA
461519SN/A{
471519SN/A
481519SN/AFaultName MachineCheckFault::_name = "Machine Check";
491519SN/AFaultVect MachineCheckFault::_vect = 0x0401;
501519SN/AFaultStat MachineCheckFault::_count;
511519SN/A
521519SN/AFaultName AlignmentFault::_name = "Alignment";
531519SN/AFaultVect AlignmentFault::_vect = 0x0301;
541519SN/AFaultStat AlignmentFault::_count;
551606SN/A
561519SN/AFaultName ResetFault::_name = "Reset Fault";
571606SN/A#if  FULL_SYSTEM
581606SN/AFaultVect ResetFault::_vect = 0xBFC00000;
591606SN/A#else
601606SN/AFaultVect ResetFault::_vect = 0x001;
611519SN/A#endif
621606SN/AFaultStat ResetFault::_count;
631519SN/A
641606SN/AFaultName AddressErrorFault::_name = "Address Error";
651519SN/AFaultVect AddressErrorFault::_vect = 0x0180;
661606SN/AFaultStat AddressErrorFault::_count;
671519SN/A
681606SN/AFaultName StoreAddressErrorFault::_name = "Store Address Error";
691519SN/AFaultVect StoreAddressErrorFault::_vect = 0x0180;
701606SN/AFaultStat StoreAddressErrorFault::_count;
711519SN/A
721606SN/A
731519SN/AFaultName SystemCallFault::_name = "Syscall";
741606SN/AFaultVect SystemCallFault::_vect = 0x0180;
751519SN/AFaultStat SystemCallFault::_count;
761606SN/A
771519SN/AFaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
781606SN/AFaultVect CoprocessorUnusableFault::_vect = 0x180;
791519SN/AFaultStat CoprocessorUnusableFault::_count;
801606SN/A
811519SN/AFaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
821606SN/AFaultVect ReservedInstructionFault::_vect = 0x0180;
831519SN/AFaultStat ReservedInstructionFault::_count;
841606SN/A
851519SN/AFaultName ThreadFault::_name = "Thread Fault";
861606SN/AFaultVect ThreadFault::_vect = 0x00F1;
871519SN/AFaultStat ThreadFault::_count;
881606SN/A
891519SN/AFaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
901606SN/AFaultVect ArithmeticFault::_vect = 0x180;
911519SN/AFaultStat ArithmeticFault::_count;
921606SN/A
931519SN/AFaultName UnimplementedOpcodeFault::_name = "opdec";
941606SN/AFaultVect UnimplementedOpcodeFault::_vect = 0x0481;
951606SN/AFaultStat UnimplementedOpcodeFault::_count;
961606SN/A
971606SN/AFaultName InterruptFault::_name = "interrupt";
981944SN/AFaultVect InterruptFault::_vect = 0x0180;
991606SN/AFaultStat InterruptFault::_count;
1001606SN/A
1011519SN/AFaultName TrapFault::_name = "Trap";
1021606SN/AFaultVect TrapFault::_vect = 0x0180;
1031606SN/AFaultStat TrapFault::_count;
1041858SN/A
1051858SN/AFaultName BreakpointFault::_name = "Breakpoint";
1061858SN/AFaultVect BreakpointFault::_vect = 0x0180;
1071858SN/AFaultStat BreakpointFault::_count;
1081858SN/A
1091606SN/AFaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
1101606SN/AFaultVect ItbInvalidFault::_vect = 0x0180;
1111606SN/AFaultStat ItbInvalidFault::_count;
1121606SN/A
1131606SN/AFaultName ItbPageFault::_name = "itbmiss";
1141858SN/AFaultVect ItbPageFault::_vect = 0x0181;
1151858SN/AFaultStat ItbPageFault::_count;
1161858SN/A
1171858SN/AFaultName ItbMissFault::_name = "itbmiss";
1181519SN/AFaultVect ItbMissFault::_vect = 0x0181;
1191589SN/AFaultStat ItbMissFault::_count;
1201519SN/A
1211606SN/AFaultName ItbAcvFault::_name = "iaccvio";
1221606SN/AFaultVect ItbAcvFault::_vect = 0x0081;
1231606SN/AFaultStat ItbAcvFault::_count;
1241606SN/A
1251519SN/AFaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
1261606SN/AFaultVect ItbRefillFault::_vect = 0x0180;
1271519SN/AFaultStat ItbRefillFault::_count;
1281606SN/A
1291519SN/AFaultName NDtbMissFault::_name = "dtb_miss_single";
1301606SN/AFaultVect NDtbMissFault::_vect = 0x0201;
1311519SN/AFaultStat NDtbMissFault::_count;
1321606SN/A
1331519SN/AFaultName PDtbMissFault::_name = "dtb_miss_double";
1341606SN/AFaultVect PDtbMissFault::_vect = 0x0281;
1351519SN/AFaultStat PDtbMissFault::_count;
1361589SN/A
1371519SN/AFaultName DtbPageFault::_name = "dfault";
1381606SN/AFaultVect DtbPageFault::_vect = 0x0381;
1391606SN/AFaultStat DtbPageFault::_count;
1401606SN/A
1411606SN/AFaultName DtbAcvFault::_name = "dfault";
1421519SN/AFaultVect DtbAcvFault::_vect = 0x0381;
1431606SN/AFaultStat DtbAcvFault::_count;
1441519SN/A
1451606SN/AFaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
1461519SN/AFaultVect DtbInvalidFault::_vect = 0x0180;
1471606SN/AFaultStat DtbInvalidFault::_count;
1481519SN/A
1491606SN/AFaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
1501519SN/AFaultVect DtbRefillFault::_vect = 0x0180;
1511606SN/AFaultStat DtbRefillFault::_count;
1521606SN/A
1534167SN/AFaultName TLBModifiedFault::_name = "TLB Modified Exception";
1541606SN/AFaultVect TLBModifiedFault::_vect = 0x0180;
1551606SN/AFaultStat TLBModifiedFault::_count;
1561606SN/A
1571606SN/AFaultName FloatEnableFault::_name = "float_enable_fault";
1581606SN/AFaultVect FloatEnableFault::_vect = 0x0581;
1591606SN/AFaultStat FloatEnableFault::_count;
1601606SN/A
1611606SN/AFaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
1621606SN/AFaultVect IntegerOverflowFault::_vect = 0x0501;
1631606SN/AFaultStat IntegerOverflowFault::_count;
1641606SN/A
1651606SN/AFaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
1661606SN/AFaultVect DspStateDisabledFault::_vect = 0x001a;
1671606SN/AFaultStat DspStateDisabledFault::_count;
1681606SN/A
1691606SN/A#if FULL_SYSTEM
1701606SN/Avoid
1711606SN/AMipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
1721606SN/A{
1731606SN/A    tc->setPC(HandlerBase);
1741606SN/A    tc->setNextPC(HandlerBase + sizeof(MachInst));
1754167SN/A    tc->setNextNPC(HandlerBase + 2 * sizeof(MachInst));
1764167SN/A}
1774167SN/A
1784167SN/Avoid
1794167SN/AMipsFault::setExceptionState(ThreadContext *tc, uint8_t excCode)
1804167SN/A{
1814167SN/A    // modify SRS Ctl - Save CSS, put ESS into CSS
1824167SN/A    StatusReg status = tc->readMiscReg(MISCREG_STATUS);
1834167SN/A    if (status.exl != 1 && status.bev != 1) {
1844167SN/A        // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
1854167SN/A        SRSCtlReg srsCtl = tc->readMiscReg(MISCREG_SRSCTL);
1864167SN/A        srsCtl.pss = srsCtl.css;
1874167SN/A        srsCtl.css = srsCtl.ess;
1884167SN/A        tc->setMiscRegNoEffect(MISCREG_SRSCTL, srsCtl);
1894167SN/A    }
1904167SN/A
1914167SN/A    // set EXL bit (don't care if it is already set!)
1924167SN/A    status.exl = 1;
1934167SN/A    tc->setMiscRegNoEffect(MISCREG_STATUS, status);
1944167SN/A
1954167SN/A    // write EPC
1961519SN/A    // CHECK ME  or FIXME or FIX ME or POSSIBLE HACK
1971589SN/A    // Check to see if the exception occurred in the branch delay slot
1981519SN/A    DPRINTF(MipsPRA, "PC: %x, NextPC: %x, NNPC: %x\n",
1991606SN/A            tc->readPC(), tc->readNextPC(), tc->readNextNPC());
2001606SN/A    int bd = 0;
2011606SN/A    if (tc->readPC() + sizeof(MachInst) != tc->readNextPC()) {
2021627SN/A        tc->setMiscRegNoEffect(MISCREG_EPC, tc->readPC() - sizeof(MachInst));
2031519SN/A        // In the branch delay slot? set CAUSE_31
2041627SN/A        bd = 1;
2051519SN/A    } else {
2061627SN/A        tc->setMiscRegNoEffect(MISCREG_EPC, tc->readPC());
2071519SN/A        // In the branch delay slot? reset CAUSE_31
2081627SN/A        bd = 0;
2091519SN/A    }
2101627SN/A
2111519SN/A    // Set Cause_EXCCODE field
2121606SN/A    CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
2131519SN/A    cause.excCode = excCode;
2141606SN/A    cause.bd = bd;
2151519SN/A    cause.ce = 0;
2161589SN/A    tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
2171519SN/A}
2181606SN/A
2191606SN/Avoid
2201606SN/AArithmeticFault::invoke(ThreadContext *tc)
2211606SN/A{
2221519SN/A    DPRINTF(MipsPRA, "%s encountered.\n", name());
2231606SN/A    setExceptionState(tc, 0xC);
2241519SN/A
2251606SN/A    // Set new PC
2261519SN/A    Addr HandlerBase;
2271606SN/A    StatusReg status = tc->readMiscReg(MISCREG_STATUS);
2281519SN/A    // Here, the handler is dependent on BEV, which is not modified by
2291606SN/A    // setExceptionState()
2301519SN/A    if (!status.bev) {
2311606SN/A        // See MIPS ARM Vol 3, Revision 2, Page 38
2321519SN/A        HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
2331606SN/A    } else {
2341519SN/A        HandlerBase = 0xBFC00200;
2351589SN/A    }
2361519SN/A    setHandlerPC(HandlerBase, tc);
2371606SN/A}
2381606SN/A
2391606SN/Avoid
2401944SN/AStoreAddressErrorFault::invoke(ThreadContext *tc)
2411519SN/A{
2421944SN/A    DPRINTF(MipsPRA, "%s encountered.\n", name());
2431519SN/A    setExceptionState(tc, 0x5);
2441944SN/A    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
2451519SN/A
2461944SN/A    // Set new PC
2471519SN/A    Addr HandlerBase;
2481944SN/A    // Offset 0x180 - General Exception Vector
2491519SN/A    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
2501944SN/A    setHandlerPC(HandlerBase, tc);
2511519SN/A}
2521606SN/A
2537777Sgblack@eecs.umich.eduvoid
2547777Sgblack@eecs.umich.eduTrapFault::invoke(ThreadContext *tc)
2557777Sgblack@eecs.umich.edu{
2567777Sgblack@eecs.umich.edu    DPRINTF(MipsPRA, "%s encountered.\n", name());
2577777Sgblack@eecs.umich.edu    setExceptionState(tc, 0xD);
2587777Sgblack@eecs.umich.edu
2597777Sgblack@eecs.umich.edu    // Set new PC
2607777Sgblack@eecs.umich.edu    Addr HandlerBase;
2617777Sgblack@eecs.umich.edu    // Offset 0x180 - General Exception Vector
2627777Sgblack@eecs.umich.edu    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
2637777Sgblack@eecs.umich.edu    setHandlerPC(HandlerBase, tc);
2647777Sgblack@eecs.umich.edu}
2657777Sgblack@eecs.umich.edu
2667777Sgblack@eecs.umich.eduvoid
2677777Sgblack@eecs.umich.eduBreakpointFault::invoke(ThreadContext *tc)
2687777Sgblack@eecs.umich.edu{
2697777Sgblack@eecs.umich.edu    setExceptionState(tc, 0x9);
2707777Sgblack@eecs.umich.edu
2717777Sgblack@eecs.umich.edu    // Set new PC
2727777Sgblack@eecs.umich.edu    Addr HandlerBase;
2737777Sgblack@eecs.umich.edu    // Offset 0x180 - General Exception Vector
2747777Sgblack@eecs.umich.edu    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
2757777Sgblack@eecs.umich.edu    setHandlerPC(HandlerBase, tc);
2767777Sgblack@eecs.umich.edu}
2777777Sgblack@eecs.umich.edu
2787777Sgblack@eecs.umich.eduvoid
2797777Sgblack@eecs.umich.eduDtbInvalidFault::invoke(ThreadContext *tc)
2807777Sgblack@eecs.umich.edu{
2817777Sgblack@eecs.umich.edu    DPRINTF(MipsPRA, "%s encountered.\n", name());
2827777Sgblack@eecs.umich.edu
2837777Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
2847777Sgblack@eecs.umich.edu    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
2857777Sgblack@eecs.umich.edu    entryHi.asid = entryHiAsid;
2867777Sgblack@eecs.umich.edu    entryHi.vpn2 = entryHiVPN2;
2877777Sgblack@eecs.umich.edu    entryHi.vpn2x = entryHiVPN2X;
2887777Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
2897777Sgblack@eecs.umich.edu
2907777Sgblack@eecs.umich.edu    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
2917777Sgblack@eecs.umich.edu    context.badVPN2 = contextBadVPN2;
2927777Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
2937777Sgblack@eecs.umich.edu    setExceptionState(tc, 0x3);
2947777Sgblack@eecs.umich.edu
2957777Sgblack@eecs.umich.edu
2967777Sgblack@eecs.umich.edu    // Set new PC
2977777Sgblack@eecs.umich.edu    Addr HandlerBase;
2987777Sgblack@eecs.umich.edu    // Offset 0x180 - General Exception Vector
2997777Sgblack@eecs.umich.edu    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
3007777Sgblack@eecs.umich.edu    setHandlerPC(HandlerBase, tc);
3017777Sgblack@eecs.umich.edu}
3029827Sakash.bagdia@arm.com
3039827Sakash.bagdia@arm.comvoid
3049827Sakash.bagdia@arm.comAddressErrorFault::invoke(ThreadContext *tc)
3059827Sakash.bagdia@arm.com{
3069827Sakash.bagdia@arm.com    DPRINTF(MipsPRA, "%s encountered.\n", name());
3079827Sakash.bagdia@arm.com    setExceptionState(tc, 0x4);
3089827Sakash.bagdia@arm.com    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
3099827Sakash.bagdia@arm.com
3109827Sakash.bagdia@arm.com    // Set new PC
3119827Sakash.bagdia@arm.com    Addr HandlerBase;
3129827Sakash.bagdia@arm.com    // Offset 0x180 - General Exception Vector
3139827Sakash.bagdia@arm.com    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
314    setHandlerPC(HandlerBase, tc);
315}
316
317void
318ItbInvalidFault::invoke(ThreadContext *tc)
319{
320    DPRINTF(MipsPRA, "%s encountered.\n", name());
321    setExceptionState(tc, 0x2);
322    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
323    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
324    entryHi.asid = entryHiAsid;
325    entryHi.vpn2 = entryHiVPN2;
326    entryHi.vpn2x = entryHiVPN2X;
327    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
328
329    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
330    context.badVPN2 = contextBadVPN2;
331    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
332
333
334    // Set new PC
335    Addr HandlerBase;
336    // Offset 0x180 - General Exception Vector
337    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
338    setHandlerPC(HandlerBase,tc);
339    DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n",
340            HandlerBase, tc->readMiscReg(MISCREG_EPC));
341}
342
343void
344ItbRefillFault::invoke(ThreadContext *tc)
345{
346    DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR);
347    Addr HandlerBase;
348    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
349    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
350    entryHi.asid = entryHiAsid;
351    entryHi.vpn2 = entryHiVPN2;
352    entryHi.vpn2x = entryHiVPN2X;
353    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
354    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
355    context.badVPN2 = contextBadVPN2;
356    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
357
358    StatusReg status = tc->readMiscReg(MISCREG_STATUS);
359    // Since handler depends on EXL bit, must check EXL bit before setting it!!
360    // See MIPS ARM Vol 3, Revision 2, Page 38
361    if (status.exl == 1) {
362        // Offset 0x180 - General Exception Vector
363        HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
364    } else {
365        // Offset 0x000
366        HandlerBase = tc->readMiscReg(MISCREG_EBASE);
367    }
368
369    setExceptionState(tc, 0x2);
370    setHandlerPC(HandlerBase, tc);
371}
372
373void
374DtbRefillFault::invoke(ThreadContext *tc)
375{
376    // Set new PC
377    DPRINTF(MipsPRA, "%s encountered.\n", name());
378    Addr HandlerBase;
379    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
380    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
381    entryHi.asid = entryHiAsid;
382    entryHi.vpn2 = entryHiVPN2;
383    entryHi.vpn2x = entryHiVPN2X;
384    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
385
386    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
387    context.badVPN2 = contextBadVPN2;
388    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
389
390    StatusReg status = tc->readMiscReg(MISCREG_STATUS);
391    // Since handler depends on EXL bit, must check EXL bit before setting it!!
392    // See MIPS ARM Vol 3, Revision 2, Page 38
393    if (status.exl) {
394        // Offset 0x180 - General Exception Vector
395        HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
396    } else {
397        // Offset 0x000
398        HandlerBase = tc->readMiscReg(MISCREG_EBASE);
399    }
400
401    setExceptionState(tc, 0x3);
402
403    setHandlerPC(HandlerBase, tc);
404}
405
406void
407TLBModifiedFault::invoke(ThreadContext *tc)
408{
409    DPRINTF(MipsPRA, "%s encountered.\n", name());
410    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
411    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
412    entryHi.asid = entryHiAsid;
413    entryHi.vpn2 = entryHiVPN2;
414    entryHi.vpn2x = entryHiVPN2X;
415    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
416
417    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
418    context.badVPN2 = contextBadVPN2;
419    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
420
421    // Set new PC
422    Addr HandlerBase;
423    // Offset 0x180 - General Exception Vector
424    HandlerBase = vect() + tc->readMiscReg(MISCREG_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(MISCREG_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    CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
452    if (cause.iv) {
453        // Offset 200 for release 2
454        HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(MISCREG_EBASE);
455    } else {
456        //Ofset at 180 for release 1
457        HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_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, "ResetFault::invoke : PC set to %x", tc->readPC());
476#endif
477
478    // Set Coprocessor 1 (Floating Point) To Usable
479    StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS);
480    status.cu.cu1 = 1;
481    tc->setMiscReg(MISCREG_STATUS, status);
482}
483
484void
485ReservedInstructionFault::invoke(ThreadContext *tc)
486{
487#if  FULL_SYSTEM
488    DPRINTF(MipsPRA, "%s encountered.\n", name());
489    setExceptionState(tc, 0x0A);
490    Addr HandlerBase;
491    // Offset 0x180 - General Exception Vector
492    HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE);
493    setHandlerPC(HandlerBase, tc);
494#else
495    panic("%s encountered.\n", name());
496#endif
497}
498
499void
500ThreadFault::invoke(ThreadContext *tc)
501{
502    DPRINTF(MipsPRA, "%s encountered.\n", name());
503    panic("%s encountered.\n", name());
504}
505
506void
507DspStateDisabledFault::invoke(ThreadContext *tc)
508{
509    DPRINTF(MipsPRA, "%s encountered.\n", name());
510    panic("%s encountered.\n", name());
511}
512
513void
514CoprocessorUnusableFault::invoke(ThreadContext *tc)
515{
516#if FULL_SYSTEM
517    DPRINTF(MipsPRA, "%s encountered.\n", name());
518    setExceptionState(tc, 0xb);
519    // The ID of the coprocessor causing the exception is stored in
520    // CoprocessorUnusableFault::coProcID
521    CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
522    cause.ce = coProcID;
523    tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
524
525    Addr HandlerBase;
526    // Offset 0x180 - General Exception Vector
527    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
528    setHandlerPC(HandlerBase, tc);
529
530#else
531    warn("%s (CP%d) encountered.\n", name(), coProcID);
532#endif
533}
534
535} // namespace MipsISA
536
537