faults.cc revision 5224
12735Sktlim@umich.edu/*
210319SAndreas.Sandberg@ARM.com * Copyright N) 2007 MIPS Technologies, Inc.  All Rights Reserved
310319SAndreas.Sandberg@ARM.com *
410319SAndreas.Sandberg@ARM.com * This software is part of the M5 simulator.
510319SAndreas.Sandberg@ARM.com *
610319SAndreas.Sandberg@ARM.com * THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING
710319SAndreas.Sandberg@ARM.com * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
810319SAndreas.Sandberg@ARM.com * TO THESE TERMS AND CONDITIONS.
910319SAndreas.Sandberg@ARM.com *
1010319SAndreas.Sandberg@ARM.com * Permission is granted to use, copy, create derivative works and
1110319SAndreas.Sandberg@ARM.com * distribute this software and such derivative works for any purpose,
1210319SAndreas.Sandberg@ARM.com * so long as (1) the copyright notice above, this grant of permission,
1310319SAndreas.Sandberg@ARM.com * and the disclaimer below appear in all copies and derivative works
142735Sktlim@umich.edu * made, (2) the copyright notice above is augmented as appropriate to
1511303Ssteve.reinhardt@amd.com * reflect the addition of any new copyrightable work in a derivative
162735Sktlim@umich.edu * work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3)
172735Sktlim@umich.edu * the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any
182735Sktlim@umich.edu * advertising or publicity pertaining to the use or distribution of
192735Sktlim@umich.edu * this software without specific, written prior authorization.
202735Sktlim@umich.edu *
212735Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B  MIPS MAKES NO WARRANTIES AND
222735Sktlim@umich.edu * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
232735Sktlim@umich.edu * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
242735Sktlim@umich.edu * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
252735Sktlim@umich.edu * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
262735Sktlim@umich.edu * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
272735Sktlim@umich.edu * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
282735Sktlim@umich.edu * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
292735Sktlim@umich.edu * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
302735Sktlim@umich.edu * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
312735Sktlim@umich.edu * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
322735Sktlim@umich.edu * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
332735Sktlim@umich.edu *
342735Sktlim@umich.edu * Authors: Gabe M. Black
352735Sktlim@umich.edu *          Korey L. Sewell
362735Sktlim@umich.edu *          Jaidev Patwardhan
372735Sktlim@umich.edu */
382735Sktlim@umich.edu
392735Sktlim@umich.edu#include "arch/mips/faults.hh"
402735Sktlim@umich.edu#include "cpu/thread_context.hh"
412735Sktlim@umich.edu#include "cpu/base.hh"
4210319SAndreas.Sandberg@ARM.com#include "base/trace.hh"
432735Sktlim@umich.edu#include "arch/mips/pra_constants.hh"
442735Sktlim@umich.edu#if !FULL_SYSTEM
4510319SAndreas.Sandberg@ARM.com#include "sim/process.hh"
4610319SAndreas.Sandberg@ARM.com#include "mem/page_table.hh"
4710319SAndreas.Sandberg@ARM.com#endif
4810319SAndreas.Sandberg@ARM.com
4910319SAndreas.Sandberg@ARM.comnamespace MipsISA
5010319SAndreas.Sandberg@ARM.com{
5110529Smorr@cs.wisc.edu
5210319SAndreas.Sandberg@ARM.comFaultName MachineCheckFault::_name = "Machine Check";
5310319SAndreas.Sandberg@ARM.comFaultVect MachineCheckFault::_vect = 0x0401;
542735Sktlim@umich.eduFaultStat MachineCheckFault::_count;
552735Sktlim@umich.edu
5610319SAndreas.Sandberg@ARM.comFaultName AlignmentFault::_name = "Alignment";
5710319SAndreas.Sandberg@ARM.comFaultVect AlignmentFault::_vect = 0x0301;
5810319SAndreas.Sandberg@ARM.comFaultStat AlignmentFault::_count;
5910319SAndreas.Sandberg@ARM.com
6010319SAndreas.Sandberg@ARM.comFaultName ResetFault::_name = "Reset Fault";
6110319SAndreas.Sandberg@ARM.com#if  FULL_SYSTEM
6210319SAndreas.Sandberg@ARM.comFaultVect ResetFault::_vect = 0xBFC00000;
6310319SAndreas.Sandberg@ARM.com#else
6410319SAndreas.Sandberg@ARM.comFaultVect ResetFault::_vect = 0x001;
6510319SAndreas.Sandberg@ARM.com#endif
6610319SAndreas.Sandberg@ARM.comFaultStat ResetFault::_count;
6710319SAndreas.Sandberg@ARM.com
6810319SAndreas.Sandberg@ARM.comFaultName AddressErrorFault::_name = "Address Error";
6910319SAndreas.Sandberg@ARM.comFaultVect AddressErrorFault::_vect = 0x0180;
702735Sktlim@umich.eduFaultStat AddressErrorFault::_count;
712735Sktlim@umich.edu
7210319SAndreas.Sandberg@ARM.comFaultName StoreAddressErrorFault::_name = "Store Address Error";
7310319SAndreas.Sandberg@ARM.comFaultVect StoreAddressErrorFault::_vect = 0x0180;
7410319SAndreas.Sandberg@ARM.comFaultStat StoreAddressErrorFault::_count;
7510319SAndreas.Sandberg@ARM.com
7610319SAndreas.Sandberg@ARM.com
7710319SAndreas.Sandberg@ARM.comFaultName SystemCallFault::_name = "Syscall";
7810319SAndreas.Sandberg@ARM.comFaultVect SystemCallFault::_vect = 0x0180;
7910319SAndreas.Sandberg@ARM.comFaultStat SystemCallFault::_count;
8010319SAndreas.Sandberg@ARM.com
8110319SAndreas.Sandberg@ARM.comFaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
8210319SAndreas.Sandberg@ARM.comFaultVect CoprocessorUnusableFault::_vect = 0x180;
8310319SAndreas.Sandberg@ARM.comFaultStat CoprocessorUnusableFault::_count;
8410319SAndreas.Sandberg@ARM.com
8510319SAndreas.Sandberg@ARM.comFaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
8610319SAndreas.Sandberg@ARM.comFaultVect ReservedInstructionFault::_vect = 0x0180;
872735Sktlim@umich.eduFaultStat ReservedInstructionFault::_count;
882735Sktlim@umich.edu
8910319SAndreas.Sandberg@ARM.comFaultName ThreadFault::_name = "Thread Fault";
9010319SAndreas.Sandberg@ARM.comFaultVect ThreadFault::_vect = 0x00F1;
9110319SAndreas.Sandberg@ARM.comFaultStat ThreadFault::_count;
9210319SAndreas.Sandberg@ARM.com
9310319SAndreas.Sandberg@ARM.com
9410319SAndreas.Sandberg@ARM.comFaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
9510319SAndreas.Sandberg@ARM.comFaultVect ArithmeticFault::_vect = 0x180;
9610319SAndreas.Sandberg@ARM.comFaultStat ArithmeticFault::_count;
9710319SAndreas.Sandberg@ARM.com
9810319SAndreas.Sandberg@ARM.comFaultName UnimplementedOpcodeFault::_name = "opdec";
9910319SAndreas.Sandberg@ARM.comFaultVect UnimplementedOpcodeFault::_vect = 0x0481;
10010319SAndreas.Sandberg@ARM.comFaultStat UnimplementedOpcodeFault::_count;
10110319SAndreas.Sandberg@ARM.com
1022735Sktlim@umich.eduFaultName InterruptFault::_name = "interrupt";
1032735Sktlim@umich.eduFaultVect InterruptFault::_vect = 0x0180;
10410319SAndreas.Sandberg@ARM.comFaultStat InterruptFault::_count;
1052735Sktlim@umich.edu
1062735Sktlim@umich.eduFaultName TrapFault::_name = "Trap";
1072735Sktlim@umich.eduFaultVect TrapFault::_vect = 0x0180;
10810319SAndreas.Sandberg@ARM.comFaultStat TrapFault::_count;
10910319SAndreas.Sandberg@ARM.com
1102735Sktlim@umich.eduFaultName BreakpointFault::_name = "Breakpoint";
1112735Sktlim@umich.eduFaultVect BreakpointFault::_vect = 0x0180;
11210319SAndreas.Sandberg@ARM.comFaultStat BreakpointFault::_count;
11310319SAndreas.Sandberg@ARM.com
1142735Sktlim@umich.edu
1152735Sktlim@umich.eduFaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
1162735Sktlim@umich.eduFaultVect ItbInvalidFault::_vect = 0x0180;
11710319SAndreas.Sandberg@ARM.comFaultStat ItbInvalidFault::_count;
11810319SAndreas.Sandberg@ARM.com
1192735Sktlim@umich.eduFaultName ItbPageFault::_name = "itbmiss";
12010319SAndreas.Sandberg@ARM.comFaultVect ItbPageFault::_vect = 0x0181;
1212735Sktlim@umich.eduFaultStat ItbPageFault::_count;
12210319SAndreas.Sandberg@ARM.com
12310319SAndreas.Sandberg@ARM.comFaultName ItbMissFault::_name = "itbmiss";
12410319SAndreas.Sandberg@ARM.comFaultVect ItbMissFault::_vect = 0x0181;
12510319SAndreas.Sandberg@ARM.comFaultStat ItbMissFault::_count;
12610319SAndreas.Sandberg@ARM.com
12710319SAndreas.Sandberg@ARM.comFaultName ItbAcvFault::_name = "iaccvio";
12810319SAndreas.Sandberg@ARM.comFaultVect ItbAcvFault::_vect = 0x0081;
1292735Sktlim@umich.eduFaultStat ItbAcvFault::_count;
13010319SAndreas.Sandberg@ARM.com
13110319SAndreas.Sandberg@ARM.comFaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
13210319SAndreas.Sandberg@ARM.comFaultVect ItbRefillFault::_vect = 0x0180;
13310319SAndreas.Sandberg@ARM.comFaultStat ItbRefillFault::_count;
13410319SAndreas.Sandberg@ARM.com
13510319SAndreas.Sandberg@ARM.comFaultName NDtbMissFault::_name = "dtb_miss_single";
13610319SAndreas.Sandberg@ARM.comFaultVect NDtbMissFault::_vect = 0x0201;
1372735Sktlim@umich.eduFaultStat NDtbMissFault::_count;
13810319SAndreas.Sandberg@ARM.com
13910319SAndreas.Sandberg@ARM.comFaultName PDtbMissFault::_name = "dtb_miss_double";
14010319SAndreas.Sandberg@ARM.comFaultVect PDtbMissFault::_vect = 0x0281;
14110319SAndreas.Sandberg@ARM.comFaultStat PDtbMissFault::_count;
14210319SAndreas.Sandberg@ARM.com
1432735Sktlim@umich.eduFaultName DtbPageFault::_name = "dfault";
14410319SAndreas.Sandberg@ARM.comFaultVect DtbPageFault::_vect = 0x0381;
14510319SAndreas.Sandberg@ARM.comFaultStat DtbPageFault::_count;
14610319SAndreas.Sandberg@ARM.com
14710319SAndreas.Sandberg@ARM.comFaultName DtbAcvFault::_name = "dfault";
14810319SAndreas.Sandberg@ARM.comFaultVect DtbAcvFault::_vect = 0x0381;
1492735Sktlim@umich.eduFaultStat DtbAcvFault::_count;
15010319SAndreas.Sandberg@ARM.com
1512735Sktlim@umich.eduFaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
15210319SAndreas.Sandberg@ARM.comFaultVect DtbInvalidFault::_vect = 0x0180;
15310319SAndreas.Sandberg@ARM.comFaultStat DtbInvalidFault::_count;
15410319SAndreas.Sandberg@ARM.com
15510319SAndreas.Sandberg@ARM.comFaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
15610319SAndreas.Sandberg@ARM.comFaultVect DtbRefillFault::_vect = 0x0180;
15710319SAndreas.Sandberg@ARM.comFaultStat DtbRefillFault::_count;
15810319SAndreas.Sandberg@ARM.com
15910319SAndreas.Sandberg@ARM.comFaultName TLBModifiedFault::_name = "TLB Modified Exception";
16010319SAndreas.Sandberg@ARM.comFaultVect TLBModifiedFault::_vect = 0x0180;
16110319SAndreas.Sandberg@ARM.comFaultStat TLBModifiedFault::_count;
16210319SAndreas.Sandberg@ARM.com
16310319SAndreas.Sandberg@ARM.comFaultName FloatEnableFault::_name = "float_enable_fault";
16410319SAndreas.Sandberg@ARM.comFaultVect FloatEnableFault::_vect = 0x0581;
16510319SAndreas.Sandberg@ARM.comFaultStat FloatEnableFault::_count;
16610319SAndreas.Sandberg@ARM.com
16710319SAndreas.Sandberg@ARM.comFaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
16810319SAndreas.Sandberg@ARM.comFaultVect IntegerOverflowFault::_vect = 0x0501;
16910319SAndreas.Sandberg@ARM.comFaultStat IntegerOverflowFault::_count;
17010319SAndreas.Sandberg@ARM.com
17110319SAndreas.Sandberg@ARM.comFaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
17210319SAndreas.Sandberg@ARM.comFaultVect DspStateDisabledFault::_vect = 0x001a;
17310319SAndreas.Sandberg@ARM.comFaultStat DspStateDisabledFault::_count;
17410319SAndreas.Sandberg@ARM.com
17510319SAndreas.Sandberg@ARM.com#if FULL_SYSTEM
17610319SAndreas.Sandberg@ARM.comvoid MipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
17711303Ssteve.reinhardt@amd.com{
17811303Ssteve.reinhardt@amd.com  tc->setPC(HandlerBase);
17911303Ssteve.reinhardt@amd.com  tc->setNextPC(HandlerBase+sizeof(MachInst));
18011303Ssteve.reinhardt@amd.com  tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
18111303Ssteve.reinhardt@amd.com}
18211303Ssteve.reinhardt@amd.com
18311303Ssteve.reinhardt@amd.comvoid MipsFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
18410319SAndreas.Sandberg@ARM.com{
18511303Ssteve.reinhardt@amd.com  // modify SRS Ctl - Save CSS, put ESS into CSS
18611303Ssteve.reinhardt@amd.com  MiscReg stat = tc->readMiscReg(MipsISA::Status);
18711303Ssteve.reinhardt@amd.com  if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1)
18811303Ssteve.reinhardt@amd.com    {
18910319SAndreas.Sandberg@ARM.com      // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
19011303Ssteve.reinhardt@amd.com      MiscReg srs = tc->readMiscReg(MipsISA::SRSCtl);
19111303Ssteve.reinhardt@amd.com      uint8_t CSS,ESS;
19211303Ssteve.reinhardt@amd.com      CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO);
19311303Ssteve.reinhardt@amd.com      ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO);
19411303Ssteve.reinhardt@amd.com      // Move CSS to PSS
19511303Ssteve.reinhardt@amd.com      replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS);
19611303Ssteve.reinhardt@amd.com      // Move ESS to CSS
19711303Ssteve.reinhardt@amd.com      replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS);
19811303Ssteve.reinhardt@amd.com      tc->setMiscRegNoEffect(MipsISA::SRSCtl,srs);
19911303Ssteve.reinhardt@amd.com      tc->setShadowSet(ESS);
20011303Ssteve.reinhardt@amd.com    }
20111303Ssteve.reinhardt@amd.com
20211303Ssteve.reinhardt@amd.com  // set EXL bit (don't care if it is already set!)
20311303Ssteve.reinhardt@amd.com  replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
20411303Ssteve.reinhardt@amd.com  tc->setMiscRegNoEffect(MipsISA::Status,stat);
20511303Ssteve.reinhardt@amd.com
20611303Ssteve.reinhardt@amd.com  // write EPC
20710319SAndreas.Sandberg@ARM.com  //  warn("Set EPC to %x\n",tc->readPC());
20810319SAndreas.Sandberg@ARM.com  // CHECK ME  or FIXME or FIX ME or POSSIBLE HACK
20910319SAndreas.Sandberg@ARM.com  // Check to see if the exception occurred in the branch delay slot
21010319SAndreas.Sandberg@ARM.com  DPRINTF(MipsPRA,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC());
21110319SAndreas.Sandberg@ARM.com  int C_BD=0;
21210319SAndreas.Sandberg@ARM.com  if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){
21310319SAndreas.Sandberg@ARM.com    tc->setMiscRegNoEffect(MipsISA::EPC,tc->readPC()-sizeof(MachInst));
21410319SAndreas.Sandberg@ARM.com    // In the branch delay slot? set CAUSE_31
21510319SAndreas.Sandberg@ARM.com    C_BD = 1;
21610319SAndreas.Sandberg@ARM.com  } else {
21710319SAndreas.Sandberg@ARM.com    tc->setMiscRegNoEffect(MipsISA::EPC,tc->readPC());
21810319SAndreas.Sandberg@ARM.com    // In the branch delay slot? reset CAUSE_31
21910319SAndreas.Sandberg@ARM.com    C_BD = 0;
22010319SAndreas.Sandberg@ARM.com  }
22110319SAndreas.Sandberg@ARM.com
22210319SAndreas.Sandberg@ARM.com  // Set Cause_EXCCODE field
22310319SAndreas.Sandberg@ARM.com  MiscReg cause = tc->readMiscReg(MipsISA::Cause);
22410319SAndreas.Sandberg@ARM.com  replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode);
22510319SAndreas.Sandberg@ARM.com  replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD);
22610319SAndreas.Sandberg@ARM.com  replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0);
22710319SAndreas.Sandberg@ARM.com  tc->setMiscRegNoEffect(MipsISA::Cause,cause);
22810319SAndreas.Sandberg@ARM.com
22910319SAndreas.Sandberg@ARM.com}
23010319SAndreas.Sandberg@ARM.com
23110319SAndreas.Sandberg@ARM.comvoid ArithmeticFault::invoke(ThreadContext *tc)
23210319SAndreas.Sandberg@ARM.com{
2332735Sktlim@umich.edu  DPRINTF(MipsPRA,"%s encountered.\n", name());
2342735Sktlim@umich.edu  setExceptionState(tc,0xC);
23510319SAndreas.Sandberg@ARM.com
2362735Sktlim@umich.edu  // Set new PC
23710319SAndreas.Sandberg@ARM.com  Addr HandlerBase;
23810319SAndreas.Sandberg@ARM.com  MiscReg stat = tc->readMiscReg(MipsISA::Status);
23910319SAndreas.Sandberg@ARM.com  // Here, the handler is dependent on BEV, which is not modified by setExceptionState()
24010319SAndreas.Sandberg@ARM.com  if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38
2417520Sgblack@eecs.umich.edu    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase);
24210319SAndreas.Sandberg@ARM.com  }else{
24310319SAndreas.Sandberg@ARM.com    HandlerBase = 0xBFC00200;
24410319SAndreas.Sandberg@ARM.com  }
24510319SAndreas.Sandberg@ARM.com  setHandlerPC(HandlerBase,tc);
24610319SAndreas.Sandberg@ARM.com  //      warn("Exception Handler At: %x \n",HandlerBase);
2475702Ssaidi@eecs.umich.edu}
2485702Ssaidi@eecs.umich.edu
2495702Ssaidi@eecs.umich.eduvoid StoreAddressErrorFault::invoke(ThreadContext *tc)
2505702Ssaidi@eecs.umich.edu{
2515702Ssaidi@eecs.umich.edu  DPRINTF(MipsPRA,"%s encountered.\n", name());
25210319SAndreas.Sandberg@ARM.com  setExceptionState(tc,0x5);
2538779Sgblack@eecs.umich.edu  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
25410319SAndreas.Sandberg@ARM.com
2556973Stjones1@inf.ed.ac.uk  // Set new PC
25610319SAndreas.Sandberg@ARM.com  Addr HandlerBase;
25710319SAndreas.Sandberg@ARM.com  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
25810319SAndreas.Sandberg@ARM.com  setHandlerPC(HandlerBase,tc);
25910319SAndreas.Sandberg@ARM.com  //      warn("Exception Handler At: %x \n",HandlerBase);
26010319SAndreas.Sandberg@ARM.com  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
26110319SAndreas.Sandberg@ARM.com
26210319SAndreas.Sandberg@ARM.com}
26310319SAndreas.Sandberg@ARM.com
26410319SAndreas.Sandberg@ARM.comvoid TrapFault::invoke(ThreadContext *tc)
26510319SAndreas.Sandberg@ARM.com{
26610319SAndreas.Sandberg@ARM.com  DPRINTF(MipsPRA,"%s encountered.\n", name());
26710319SAndreas.Sandberg@ARM.com  //  warn("%s encountered.\n", name());
26810319SAndreas.Sandberg@ARM.com  setExceptionState(tc,0xD);
26910319SAndreas.Sandberg@ARM.com
27010319SAndreas.Sandberg@ARM.com  // Set new PC
27110319SAndreas.Sandberg@ARM.com  Addr HandlerBase;
27210319SAndreas.Sandberg@ARM.com  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
27310319SAndreas.Sandberg@ARM.com  setHandlerPC(HandlerBase,tc);
27410319SAndreas.Sandberg@ARM.com  //      warn("Exception Handler At: %x \n",HandlerBase);
27510529Smorr@cs.wisc.edu  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
27610529Smorr@cs.wisc.edu}
27710529Smorr@cs.wisc.edu
27810529Smorr@cs.wisc.eduvoid BreakpointFault::invoke(ThreadContext *tc)
27910319SAndreas.Sandberg@ARM.com{
28010319SAndreas.Sandberg@ARM.com      setExceptionState(tc,0x9);
28110319SAndreas.Sandberg@ARM.com
28210319SAndreas.Sandberg@ARM.com      // Set new PC
28310319SAndreas.Sandberg@ARM.com      Addr HandlerBase;
28410319SAndreas.Sandberg@ARM.com      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
28510319SAndreas.Sandberg@ARM.com      setHandlerPC(HandlerBase,tc);
28610319SAndreas.Sandberg@ARM.com      //      warn("Exception Handler At: %x \n",HandlerBase);
28710319SAndreas.Sandberg@ARM.com      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
28810319SAndreas.Sandberg@ARM.com
28910319SAndreas.Sandberg@ARM.com}
29010319SAndreas.Sandberg@ARM.com
29110319SAndreas.Sandberg@ARM.comvoid DtbInvalidFault::invoke(ThreadContext *tc)
29210319SAndreas.Sandberg@ARM.com{
29310319SAndreas.Sandberg@ARM.com  DPRINTF(MipsPRA,"%s encountered.\n", name());
29410319SAndreas.Sandberg@ARM.com  //    warn("%s encountered.\n", name());
2952735Sktlim@umich.edu  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
29610319SAndreas.Sandberg@ARM.com  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
29710319SAndreas.Sandberg@ARM.com  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
298  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
299  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
300  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
301  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
302  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
303  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
304  setExceptionState(tc,0x3);
305
306
307  // Set new PC
308  Addr HandlerBase;
309  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
310  setHandlerPC(HandlerBase,tc);
311  //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
312}
313
314void AddressErrorFault::invoke(ThreadContext *tc)
315{
316  DPRINTF(MipsPRA,"%s encountered.\n", name());
317      setExceptionState(tc,0x4);
318      tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
319
320      // Set new PC
321      Addr HandlerBase;
322      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
323      setHandlerPC(HandlerBase,tc);
324}
325
326void ItbInvalidFault::invoke(ThreadContext *tc)
327{
328  DPRINTF(MipsPRA,"%s encountered.\n", name());
329      setExceptionState(tc,0x2);
330      tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
331      MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
332      replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
333      replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
334      replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
335      tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
336      MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
337      replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
338      tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
339
340
341      // Set new PC
342      Addr HandlerBase;
343      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
344      setHandlerPC(HandlerBase,tc);
345      DPRINTF(MipsPRA,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
346}
347
348void ItbRefillFault::invoke(ThreadContext *tc)
349{
350  DPRINTF(MipsPRA,"%s encountered (%x).\n", name(),BadVAddr);
351  Addr HandlerBase;
352  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
353  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
354  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
355  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
356  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
357  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
358  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
359  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
360  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
361
362  MiscReg stat = tc->readMiscReg(MipsISA::Status);
363  // Since handler depends on EXL bit, must check EXL bit before setting it!!
364  if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
365    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
366  }else{
367    HandlerBase = tc->readMiscReg(MipsISA::EBase); // Offset 0x000
368  }
369
370  setExceptionState(tc,0x2);
371  setHandlerPC(HandlerBase,tc);
372}
373
374void DtbRefillFault::invoke(ThreadContext *tc)
375{
376  // Set new PC
377  DPRINTF(MipsPRA,"%s encountered.\n", name());
378  Addr HandlerBase;
379  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
380  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
381  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
382  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
383  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
384  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
385  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
386  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
387  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
388
389  MiscReg stat = tc->readMiscReg(MipsISA::Status);
390  // Since handler depends on EXL bit, must check EXL bit before setting it!!
391  if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
392    HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
393  }else{
394    HandlerBase = tc->readMiscReg(MipsISA::EBase); // Offset 0x000
395  }
396
397
398  setExceptionState(tc,0x3);
399
400  setHandlerPC(HandlerBase,tc);
401}
402
403void TLBModifiedFault::invoke(ThreadContext *tc)
404{
405  DPRINTF(MipsPRA,"%s encountered.\n", name());
406  tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
407  MiscReg eh = tc->readMiscReg(MipsISA::EntryHi);
408  replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
409  replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
410  replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
411  tc->setMiscRegNoEffect(MipsISA::EntryHi,eh);
412  MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
413  replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
414  tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
415
416    // Set new PC
417      Addr HandlerBase;
418      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
419      setExceptionState(tc,0x1);
420      setHandlerPC(HandlerBase,tc);
421      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
422
423}
424
425void SystemCallFault::invoke(ThreadContext *tc)
426{
427  DPRINTF(MipsPRA,"%s encountered.\n", name());
428      setExceptionState(tc,0x8);
429
430      // Set new PC
431      Addr HandlerBase;
432      HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
433      setHandlerPC(HandlerBase,tc);
434      //      warn("Exception Handler At: %x \n",HandlerBase);
435      //      warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
436
437}
438
439void InterruptFault::invoke(ThreadContext *tc)
440{
441#if  FULL_SYSTEM
442  DPRINTF(MipsPRA,"%s encountered.\n", name());
443  //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
444  setExceptionState(tc,0x0A);
445  Addr HandlerBase;
446
447
448  uint8_t IV = bits(tc->readMiscRegNoEffect(MipsISA::Cause),Cause_IV);
449  if (IV)// Offset 200 for release 2
450      HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
451  else//Ofset at 180 for release 1
452      HandlerBase= vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
453
454  setHandlerPC(HandlerBase,tc);
455#endif
456}
457
458#endif // FULL_SYSTEM
459
460void ResetFault::invoke(ThreadContext *tc)
461{
462#if FULL_SYSTEM
463  DPRINTF(MipsPRA,"%s encountered.\n", name());
464  /* All reset activity must be invoked from here */
465  tc->setPC(vect());
466  tc->setNextPC(vect()+sizeof(MachInst));
467  tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
468  DPRINTF(MipsPRA,"(%x)  -  ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
469#endif
470
471  // Set Coprocessor 1 (Floating Point) To Usable
472  tc->setMiscReg(MipsISA::Status, MipsISA::Status | 0x20000000);
473}
474
475void ReservedInstructionFault::invoke(ThreadContext *tc)
476{
477#if  FULL_SYSTEM
478  DPRINTF(MipsPRA,"%s encountered.\n", name());
479  //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
480  setExceptionState(tc,0x0A);
481  Addr HandlerBase;
482  HandlerBase= vect() + tc->readMiscRegNoEffect(MipsISA::EBase); // Offset 0x180 - General Exception Vector
483  setHandlerPC(HandlerBase,tc);
484#else
485    panic("%s encountered.\n", name());
486#endif
487}
488
489void ThreadFault::invoke(ThreadContext *tc)
490{
491  DPRINTF(MipsPRA,"%s encountered.\n", name());
492  panic("%s encountered.\n", name());
493}
494
495void DspStateDisabledFault::invoke(ThreadContext *tc)
496{
497  DPRINTF(MipsPRA,"%s encountered.\n", name());
498  panic("%s encountered.\n", name());
499}
500
501void CoprocessorUnusableFault::invoke(ThreadContext *tc)
502{
503#if FULL_SYSTEM
504  DPRINTF(MipsPRA,"%s encountered.\n", name());
505  setExceptionState(tc,0xb);
506  /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
507  MiscReg cause = tc->readMiscReg(MipsISA::Cause);
508  replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
509  tc->setMiscRegNoEffect(MipsISA::Cause,cause);
510
511  Addr HandlerBase;
512  HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
513  setHandlerPC(HandlerBase,tc);
514
515  //      warn("Status: %x, Cause: %x\n",tc->readMiscReg(MipsISA::Status),tc->readMiscReg(MipsISA::Cause));
516#else
517    warn("%s (CP%d) encountered.\n", name(), coProcID);
518#endif
519}
520
521} // namespace MipsISA
522
523