faults.cc revision 8577:37dbd858c367
1955SN/A/* 2955SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 35871Snate@binkert.org * Copyright (c) 2007 MIPS Technologies, Inc. 41762SN/A * All rights reserved. 5955SN/A * 6955SN/A * Redistribution and use in source and binary forms, with or without 7955SN/A * modification, are permitted provided that the following conditions are 8955SN/A * met: redistributions of source code must retain the above copyright 9955SN/A * notice, this list of conditions and the following disclaimer; 10955SN/A * redistributions in binary form must reproduce the above copyright 11955SN/A * notice, this list of conditions and the following disclaimer in the 12955SN/A * documentation and/or other materials provided with the distribution; 13955SN/A * neither the name of the copyright holders nor the names of its 14955SN/A * contributors may be used to endorse or promote products derived from 15955SN/A * this software without specific prior written permission. 16955SN/A * 17955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28955SN/A * 292665Ssaidi@eecs.umich.edu * Authors: Gabe Black 302665Ssaidi@eecs.umich.edu * Korey Sewell 315863Snate@binkert.org * Jaidev Patwardhan 32955SN/A */ 33955SN/A 34955SN/A#include "arch/mips/faults.hh" 35955SN/A#include "arch/mips/pra_constants.hh" 36955SN/A#include "base/trace.hh" 372632Sstever@eecs.umich.edu#include "cpu/base.hh" 382632Sstever@eecs.umich.edu#include "cpu/thread_context.hh" 392632Sstever@eecs.umich.edu#include "debug/MipsPRA.hh" 402632Sstever@eecs.umich.edu 41955SN/A#if !FULL_SYSTEM 422632Sstever@eecs.umich.edu#include "mem/page_table.hh" 432632Sstever@eecs.umich.edu#include "sim/process.hh" 442761Sstever@eecs.umich.edu#endif 452632Sstever@eecs.umich.edu 462632Sstever@eecs.umich.edunamespace MipsISA 472632Sstever@eecs.umich.edu{ 482761Sstever@eecs.umich.edu 492761Sstever@eecs.umich.edutypedef MipsFaultBase::FaultVals FaultVals; 502761Sstever@eecs.umich.edu 512632Sstever@eecs.umich.edutemplate <> FaultVals MipsFault<MachineCheckFault>::vals = 522632Sstever@eecs.umich.edu { "Machine Check", 0x0401 }; 532761Sstever@eecs.umich.edu 542761Sstever@eecs.umich.edutemplate <> FaultVals MipsFault<ResetFault>::vals = 552761Sstever@eecs.umich.edu#if FULL_SYSTEM 562761Sstever@eecs.umich.edu { "Reset Fault", 0xBFC00000}; 572761Sstever@eecs.umich.edu#else 582632Sstever@eecs.umich.edu { "Reset Fault", 0x001}; 592632Sstever@eecs.umich.edu#endif 602632Sstever@eecs.umich.edu 612632Sstever@eecs.umich.edutemplate <> FaultVals MipsFault<AddressErrorFault>::vals = 622632Sstever@eecs.umich.edu { "Address Error", 0x0180 }; 632632Sstever@eecs.umich.edu 642632Sstever@eecs.umich.edutemplate <> FaultVals MipsFault<SystemCallFault>::vals = 65955SN/A { "Syscall", 0x0180 }; 66955SN/A 67955SN/Atemplate <> FaultVals MipsFault<CoprocessorUnusableFault>::vals = 685863Snate@binkert.org { "Coprocessor Unusable Fault", 0x180 }; 695863Snate@binkert.org 705863Snate@binkert.orgtemplate <> FaultVals MipsFault<ReservedInstructionFault>::vals = 715863Snate@binkert.org { "Reserved Instruction Fault", 0x0180 }; 725863Snate@binkert.org 735863Snate@binkert.orgtemplate <> FaultVals MipsFault<ThreadFault>::vals = 745863Snate@binkert.org { "Thread Fault", 0x00F1 }; 755863Snate@binkert.org 765863Snate@binkert.orgtemplate <> FaultVals MipsFault<IntegerOverflowFault>::vals = 775863Snate@binkert.org { "Integer Overflow Exception", 0x180 }; 785863Snate@binkert.org 795863Snate@binkert.orgtemplate <> FaultVals MipsFault<InterruptFault>::vals = 805863Snate@binkert.org { "interrupt", 0x0180 }; 815863Snate@binkert.org 825863Snate@binkert.orgtemplate <> FaultVals MipsFault<TrapFault>::vals = 835863Snate@binkert.org { "Trap", 0x0180 }; 845863Snate@binkert.org 855863Snate@binkert.orgtemplate <> FaultVals MipsFault<BreakpointFault>::vals = 865863Snate@binkert.org { "Breakpoint", 0x0180 }; 875863Snate@binkert.org 885863Snate@binkert.orgtemplate <> FaultVals MipsFault<TlbInvalidFault>::vals = 895863Snate@binkert.org { "Invalid TLB Entry Exception", 0x0180 }; 905863Snate@binkert.org 915863Snate@binkert.orgtemplate <> FaultVals MipsFault<TlbRefillFault>::vals = 925863Snate@binkert.org { "TLB Refill Exception", 0x0180 }; 935863Snate@binkert.org 945863Snate@binkert.orgtemplate <> FaultVals MipsFault<TlbModifiedFault>::vals = 955863Snate@binkert.org { "TLB Modified Exception", 0x0180 }; 965863Snate@binkert.org 975863Snate@binkert.orgtemplate <> FaultVals MipsFault<DspStateDisabledFault>::vals = 985863Snate@binkert.org { "DSP Disabled Fault", 0x001a }; 996654Snate@binkert.org 100955SN/Avoid 1015396Ssaidi@eecs.umich.eduMipsFaultBase::setExceptionState(ThreadContext *tc, uint8_t excCode) 1025863Snate@binkert.org{ 1035863Snate@binkert.org // modify SRS Ctl - Save CSS, put ESS into CSS 1044202Sbinkertn@umich.edu StatusReg status = tc->readMiscReg(MISCREG_STATUS); 1055863Snate@binkert.org if (status.exl != 1 && status.bev != 1) { 1065863Snate@binkert.org // SRS Ctl is modified only if Status_EXL and Status_BEV are not set 1075863Snate@binkert.org SRSCtlReg srsCtl = tc->readMiscReg(MISCREG_SRSCTL); 1085863Snate@binkert.org srsCtl.pss = srsCtl.css; 109955SN/A srsCtl.css = srsCtl.ess; 1106654Snate@binkert.org tc->setMiscRegNoEffect(MISCREG_SRSCTL, srsCtl); 1115273Sstever@gmail.com } 1125871Snate@binkert.org 1135273Sstever@gmail.com // set EXL bit (don't care if it is already set!) 1146655Snate@binkert.org status.exl = 1; 1156655Snate@binkert.org tc->setMiscRegNoEffect(MISCREG_STATUS, status); 1166655Snate@binkert.org 1176655Snate@binkert.org // write EPC 1186655Snate@binkert.org PCState pc = tc->pcState(); 1196655Snate@binkert.org DPRINTF(MipsPRA, "PC: %s\n", pc); 1205871Snate@binkert.org bool delay_slot = pc.pc() + sizeof(MachInst) != pc.npc(); 1216654Snate@binkert.org tc->setMiscRegNoEffect(MISCREG_EPC, 1225396Ssaidi@eecs.umich.edu pc.pc() - delay_slot ? sizeof(MachInst) : 0); 1235871Snate@binkert.org 1245871Snate@binkert.org // Set Cause_EXCCODE field 1256121Snate@binkert.org CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 1265871Snate@binkert.org cause.excCode = excCode; 1275871Snate@binkert.org cause.bd = delay_slot ? 1 : 0; 1286003Snate@binkert.org cause.ce = 0; 1296655Snate@binkert.org tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 130955SN/A} 1315871Snate@binkert.org 1325871Snate@binkert.org#if FULL_SYSTEM 1335871Snate@binkert.org 1345871Snate@binkert.orgvoid 135955SN/AIntegerOverflowFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1366121Snate@binkert.org{ 1376121Snate@binkert.org DPRINTF(MipsPRA, "%s encountered.\n", name()); 1386121Snate@binkert.org setExceptionState(tc, 0xC); 1391533SN/A 1406655Snate@binkert.org // Set new PC 1416655Snate@binkert.org StatusReg status = tc->readMiscReg(MISCREG_STATUS); 1426655Snate@binkert.org if (!status.bev) { 1436655Snate@binkert.org // See MIPS ARM Vol 3, Revision 2, Page 38 1445871Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 1455871Snate@binkert.org } else { 1465863Snate@binkert.org tc->pcState(0xBFC00200); 1475871Snate@binkert.org } 1485871Snate@binkert.org} 1495871Snate@binkert.org 1505871Snate@binkert.orgvoid 1515871Snate@binkert.orgTrapFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1525863Snate@binkert.org{ 1536121Snate@binkert.org DPRINTF(MipsPRA, "%s encountered.\n", name()); 1545863Snate@binkert.org setExceptionState(tc, 0xD); 1555871Snate@binkert.org 1564678Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 1574678Snate@binkert.org} 1584678Snate@binkert.org 1594678Snate@binkert.orgvoid 1604678Snate@binkert.orgBreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1614678Snate@binkert.org{ 1624678Snate@binkert.org setExceptionState(tc, 0x9); 1634678Snate@binkert.org 1644678Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 1654678Snate@binkert.org} 1664678Snate@binkert.org 1674678Snate@binkert.orgvoid 1686121Snate@binkert.orgAddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1694678Snate@binkert.org{ 1705871Snate@binkert.org DPRINTF(MipsPRA, "%s encountered.\n", name()); 1715871Snate@binkert.org setExceptionState(tc, store ? 0x5 : 0x4); 1725871Snate@binkert.org tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); 1735871Snate@binkert.org 1745871Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 1755871Snate@binkert.org} 1765871Snate@binkert.org 1775871Snate@binkert.orgvoid 1785871Snate@binkert.orgTlbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1795871Snate@binkert.org{ 1805871Snate@binkert.org setTlbExceptionState(tc, store ? 0x3 : 0x2); 1815871Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 1825871Snate@binkert.org} 1835990Ssaidi@eecs.umich.edu 1845871Snate@binkert.orgvoid 1855871Snate@binkert.orgTlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1865871Snate@binkert.org{ 1874678Snate@binkert.org // Since handler depends on EXL bit, must check EXL bit before setting it!! 1886654Snate@binkert.org StatusReg status = tc->readMiscReg(MISCREG_STATUS); 1895871Snate@binkert.org 1905871Snate@binkert.org setTlbExceptionState(tc, store ? 0x3 : 0x2); 1915871Snate@binkert.org 1925871Snate@binkert.org // See MIPS ARM Vol 3, Revision 2, Page 38 1935871Snate@binkert.org if (status.exl == 1) { 1945871Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 1955871Snate@binkert.org } else { 1965871Snate@binkert.org tc->pcState(tc->readMiscReg(MISCREG_EBASE)); 1975871Snate@binkert.org } 1984678Snate@binkert.org} 1995871Snate@binkert.org 2004678Snate@binkert.orgvoid 2015871Snate@binkert.orgTlbModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2025871Snate@binkert.org{ 2035871Snate@binkert.org setTlbExceptionState(tc, 0x1); 2045871Snate@binkert.org 2055871Snate@binkert.org tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 2065871Snate@binkert.org} 2075871Snate@binkert.org 2085871Snate@binkert.orgvoid 2095871Snate@binkert.orgSystemCallFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2106121Snate@binkert.org{ 2116121Snate@binkert.org DPRINTF(MipsPRA, "%s encountered.\n", name()); 2125863Snate@binkert.org setExceptionState(tc, 0x8); 213955SN/A 214955SN/A tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 2152632Sstever@eecs.umich.edu} 2162632Sstever@eecs.umich.edu 217955SN/Avoid 218955SN/AInterruptFault::invoke(ThreadContext *tc, StaticInstPtr inst) 219955SN/A{ 220955SN/A DPRINTF(MipsPRA, "%s encountered.\n", name()); 2215863Snate@binkert.org setExceptionState(tc, 0x0A); 222955SN/A 2232632Sstever@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 2242632Sstever@eecs.umich.edu if (cause.iv) { 2252632Sstever@eecs.umich.edu // Offset 200 for release 2 2262632Sstever@eecs.umich.edu tc->pcState(0x20 + vect() + tc->readMiscRegNoEffect(MISCREG_EBASE)); 2272632Sstever@eecs.umich.edu } else { 2282632Sstever@eecs.umich.edu //Ofset at 180 for release 1 2292632Sstever@eecs.umich.edu tc->pcState(vect() + tc->readMiscRegNoEffect(MISCREG_EBASE)); 2302632Sstever@eecs.umich.edu } 2312632Sstever@eecs.umich.edu} 2322632Sstever@eecs.umich.edu 2332632Sstever@eecs.umich.edu#endif // FULL_SYSTEM 2342632Sstever@eecs.umich.edu 2352632Sstever@eecs.umich.eduvoid 2363718Sstever@eecs.umich.eduResetFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2373718Sstever@eecs.umich.edu{ 2383718Sstever@eecs.umich.edu#if FULL_SYSTEM 2393718Sstever@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2403718Sstever@eecs.umich.edu /* All reset activity must be invoked from here */ 2415863Snate@binkert.org tc->pcState(vect()); 2425863Snate@binkert.org DPRINTF(MipsPRA, "ResetFault::invoke : PC set to %x", tc->readPC()); 2433718Sstever@eecs.umich.edu#endif 2443718Sstever@eecs.umich.edu 2456121Snate@binkert.org // Set Coprocessor 1 (Floating Point) To Usable 2465863Snate@binkert.org StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 2473718Sstever@eecs.umich.edu status.cu.cu1 = 1; 2483718Sstever@eecs.umich.edu tc->setMiscReg(MISCREG_STATUS, status); 2492634Sstever@eecs.umich.edu} 2502634Sstever@eecs.umich.edu 2515863Snate@binkert.orgvoid 2522638Sstever@eecs.umich.eduReservedInstructionFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2532632Sstever@eecs.umich.edu{ 2542632Sstever@eecs.umich.edu#if FULL_SYSTEM 2552632Sstever@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2562632Sstever@eecs.umich.edu setExceptionState(tc, 0x0A); 2572632Sstever@eecs.umich.edu tc->pcState(vect() + tc->readMiscRegNoEffect(MISCREG_EBASE)); 2582632Sstever@eecs.umich.edu#else 2591858SN/A panic("%s encountered.\n", name()); 2603716Sstever@eecs.umich.edu#endif 2612638Sstever@eecs.umich.edu} 2622638Sstever@eecs.umich.edu 2632638Sstever@eecs.umich.eduvoid 2642638Sstever@eecs.umich.eduThreadFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2652638Sstever@eecs.umich.edu{ 2662638Sstever@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2672638Sstever@eecs.umich.edu panic("%s encountered.\n", name()); 2685863Snate@binkert.org} 2695863Snate@binkert.org 2705863Snate@binkert.orgvoid 271955SN/ADspStateDisabledFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2725341Sstever@gmail.com{ 2735341Sstever@gmail.com DPRINTF(MipsPRA, "%s encountered.\n", name()); 2745863Snate@binkert.org panic("%s encountered.\n", name()); 2755341Sstever@gmail.com} 2766121Snate@binkert.org 2774494Ssaidi@eecs.umich.eduvoid 2786121Snate@binkert.orgCoprocessorUnusableFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2791105SN/A{ 2802667Sstever@eecs.umich.edu#if FULL_SYSTEM 2812667Sstever@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2822667Sstever@eecs.umich.edu setExceptionState(tc, 0xb); 2832667Sstever@eecs.umich.edu // The ID of the coprocessor causing the exception is stored in 2846121Snate@binkert.org // CoprocessorUnusableFault::coProcID 2852667Sstever@eecs.umich.edu CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 2865341Sstever@gmail.com cause.ce = coProcID; 2875863Snate@binkert.org tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 2885341Sstever@gmail.com tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE)); 2895341Sstever@gmail.com#else 2905341Sstever@gmail.com warn("%s (CP%d) encountered.\n", name(), coProcID); 2915863Snate@binkert.org#endif 2925341Sstever@gmail.com} 2935341Sstever@gmail.com 2945341Sstever@gmail.com} // namespace MipsISA 2955863Snate@binkert.org 2965341Sstever@gmail.com