faults.cc revision 8574:16a168a366d8
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#include "debug/MipsPRA.hh" 401519SN/A 411519SN/A#if !FULL_SYSTEM 421519SN/A#include "mem/page_table.hh" 431519SN/A#include "sim/process.hh" 441519SN/A#endif 451519SN/A 461519SN/Anamespace MipsISA 471519SN/A{ 481519SN/A 491519SN/Atypedef MipsFaultBase::FaultVals FaultVals; 501519SN/A 511519SN/Atemplate <> FaultVals MipsFault<MachineCheckFault>::vals = 521519SN/A { "Machine Check", 0x0401 }; 531519SN/A 541519SN/Atemplate <> FaultVals MipsFault<ResetFault>::vals = 551606SN/A#if FULL_SYSTEM 561519SN/A { "Reset Fault", 0xBFC00000}; 571606SN/A#else 581606SN/A { "Reset Fault", 0x001}; 591606SN/A#endif 601606SN/A 611519SN/Atemplate <> FaultVals MipsFault<AddressErrorFault>::vals = 621606SN/A { "Address Error", 0x0180 }; 631519SN/A 641606SN/Atemplate <> FaultVals MipsFault<SystemCallFault>::vals = 651519SN/A { "Syscall", 0x0180 }; 661606SN/A 671519SN/Atemplate <> FaultVals MipsFault<CoprocessorUnusableFault>::vals = 681606SN/A { "Coprocessor Unusable Fault", 0x180 }; 691519SN/A 701606SN/Atemplate <> FaultVals MipsFault<ReservedInstructionFault>::vals = 711519SN/A { "Reserved Instruction Fault", 0x0180 }; 721606SN/A 731519SN/Atemplate <> FaultVals MipsFault<ThreadFault>::vals = 741606SN/A { "Thread Fault", 0x00F1 }; 751519SN/A 761606SN/Atemplate <> FaultVals MipsFault<IntegerOverflowFault>::vals = 771519SN/A { "Integer Overflow Exception", 0x180 }; 781606SN/A 791519SN/Atemplate <> FaultVals MipsFault<InterruptFault>::vals = 801606SN/A { "interrupt", 0x0180 }; 811519SN/A 821606SN/Atemplate <> FaultVals MipsFault<TrapFault>::vals = 831519SN/A { "Trap", 0x0180 }; 841606SN/A 851519SN/Atemplate <> FaultVals MipsFault<BreakpointFault>::vals = 861606SN/A { "Breakpoint", 0x0180 }; 871519SN/A 881606SN/Atemplate <> FaultVals MipsFault<TlbInvalidFault>::vals = 891519SN/A { "Invalid TLB Entry Exception", 0x0180 }; 901606SN/A 911519SN/Atemplate <> FaultVals MipsFault<TlbRefillFault>::vals = 921606SN/A { "TLB Refill Exception", 0x0180 }; 931519SN/A 941606SN/Atemplate <> FaultVals MipsFault<TLBModifiedFault>::vals = 951606SN/A { "TLB Modified Exception", 0x0180 }; 961606SN/A 971606SN/Atemplate <> FaultVals MipsFault<DspStateDisabledFault>::vals = 981944SN/A { "DSP Disabled Fault", 0x001a }; 991606SN/A 1001606SN/Avoid 1011519SN/AMipsFaultBase::setExceptionState(ThreadContext *tc, uint8_t excCode) 1021606SN/A{ 1031606SN/A // modify SRS Ctl - Save CSS, put ESS into CSS 1041858SN/A StatusReg status = tc->readMiscReg(MISCREG_STATUS); 1051858SN/A if (status.exl != 1 && status.bev != 1) { 1061858SN/A // SRS Ctl is modified only if Status_EXL and Status_BEV are not set 1071858SN/A SRSCtlReg srsCtl = tc->readMiscReg(MISCREG_SRSCTL); 1081858SN/A srsCtl.pss = srsCtl.css; 1091606SN/A srsCtl.css = srsCtl.ess; 1101606SN/A tc->setMiscRegNoEffect(MISCREG_SRSCTL, srsCtl); 1111606SN/A } 1121606SN/A 1131606SN/A // set EXL bit (don't care if it is already set!) 1141858SN/A status.exl = 1; 1151858SN/A tc->setMiscRegNoEffect(MISCREG_STATUS, status); 1161858SN/A 1171858SN/A // write EPC 1181519SN/A PCState pc = tc->pcState(); 1191589SN/A DPRINTF(MipsPRA, "PC: %s\n", pc); 1201519SN/A bool delay_slot = pc.pc() + sizeof(MachInst) != pc.npc(); 1211606SN/A tc->setMiscRegNoEffect(MISCREG_EPC, 1221606SN/A pc.pc() - delay_slot ? sizeof(MachInst) : 0); 1231606SN/A 1241606SN/A // Set Cause_EXCCODE field 1251519SN/A CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 1261606SN/A cause.excCode = excCode; 1271519SN/A cause.bd = delay_slot ? 1 : 0; 1281606SN/A cause.ce = 0; 1291519SN/A tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 1301606SN/A} 1311519SN/A 1321606SN/A#if FULL_SYSTEM 1331519SN/Avoid 1341606SN/AMipsFaultBase::setHandlerPC(Addr HandlerBase, ThreadContext *tc) 1351519SN/A{ 1361589SN/A tc->setPC(HandlerBase); 1371519SN/A tc->setNextPC(HandlerBase + sizeof(MachInst)); 1381606SN/A tc->setNextNPC(HandlerBase + 2 * sizeof(MachInst)); 1391606SN/A} 1401606SN/A 1411606SN/Avoid 1421519SN/AIntegerOverflowFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1431606SN/A{ 1441519SN/A DPRINTF(MipsPRA, "%s encountered.\n", name()); 1451606SN/A setExceptionState(tc, 0xC); 1461519SN/A 1471606SN/A // Set new PC 1481519SN/A Addr HandlerBase; 1491606SN/A StatusReg status = tc->readMiscReg(MISCREG_STATUS); 1501519SN/A // Here, the handler is dependent on BEV, which is not modified by 1511606SN/A // setExceptionState() 1521606SN/A if (!status.bev) { 1534167SN/A // See MIPS ARM Vol 3, Revision 2, Page 38 1541606SN/A HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 1551606SN/A } else { 1561606SN/A HandlerBase = 0xBFC00200; 1571606SN/A } 1581606SN/A setHandlerPC(HandlerBase, tc); 1591606SN/A} 1601606SN/A 1611606SN/Avoid 1621606SN/ATrapFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1631606SN/A{ 1641606SN/A DPRINTF(MipsPRA, "%s encountered.\n", name()); 1651606SN/A setExceptionState(tc, 0xD); 1661606SN/A 1671606SN/A // Set new PC 1681606SN/A Addr HandlerBase; 1691606SN/A // Offset 0x180 - General Exception Vector 1701606SN/A HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 1711606SN/A setHandlerPC(HandlerBase, tc); 1721606SN/A} 1731606SN/A 1741606SN/Avoid 1754167SN/ABreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1764167SN/A{ 1774167SN/A setExceptionState(tc, 0x9); 1784167SN/A 1794167SN/A // Set new PC 1804167SN/A Addr HandlerBase; 1814167SN/A // Offset 0x180 - General Exception Vector 1824167SN/A HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 1834167SN/A setHandlerPC(HandlerBase, tc); 1844167SN/A} 1854167SN/A 1864167SN/Avoid 1874167SN/ATlbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst) 1884167SN/A{ 1894167SN/A DPRINTF(MipsPRA, "%s encountered.\n", name()); 1904167SN/A setExceptionState(tc, store ? 0x3 : 0x2); 1914167SN/A 1924167SN/A tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 1934167SN/A EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 1944167SN/A entryHi.asid = entryHiAsid; 1954167SN/A entryHi.vpn2 = entryHiVPN2; 1961519SN/A entryHi.vpn2x = entryHiVPN2X; 1971589SN/A tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 1981519SN/A 1991606SN/A ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 2001606SN/A context.badVPN2 = contextBadVPN2; 2011606SN/A tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 2021627SN/A 2031519SN/A // Set new PC 2041627SN/A Addr HandlerBase; 2051519SN/A // Offset 0x180 - General Exception Vector 2061627SN/A HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 2071519SN/A setHandlerPC(HandlerBase, tc); 2081627SN/A} 2091519SN/A 2101627SN/Avoid 2111519SN/AAddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2121606SN/A{ 2131519SN/A DPRINTF(MipsPRA, "%s encountered.\n", name()); 2141606SN/A setExceptionState(tc, store ? 0x5 : 0x4); 2151519SN/A tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); 2161589SN/A 2171519SN/A // Set new PC 2181606SN/A Addr HandlerBase; 2191606SN/A // Offset 0x180 - General Exception Vector 2201606SN/A HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 2211606SN/A setHandlerPC(HandlerBase, tc); 2221519SN/A} 2231606SN/A 2241519SN/Avoid 2251606SN/ATlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2261519SN/A{ 2271606SN/A DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR); 2281519SN/A setExceptionState(tc, store ? 0x3 : 0x2); 2291606SN/A 2301519SN/A Addr HandlerBase; 2311606SN/A tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 2321519SN/A EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 2331606SN/A entryHi.asid = entryHiAsid; 2341519SN/A entryHi.vpn2 = entryHiVPN2; 2351589SN/A entryHi.vpn2x = entryHiVPN2X; 2361519SN/A tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 2371606SN/A ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 2381606SN/A context.badVPN2 = contextBadVPN2; 2391606SN/A tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 2401944SN/A 2411519SN/A StatusReg status = tc->readMiscReg(MISCREG_STATUS); 2421944SN/A // Since handler depends on EXL bit, must check EXL bit before setting it!! 2431519SN/A // See MIPS ARM Vol 3, Revision 2, Page 38 2441944SN/A if (status.exl == 1) { 2451519SN/A // Offset 0x180 - General Exception Vector 2461944SN/A HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 2471519SN/A } else { 2481944SN/A // Offset 0x000 2491519SN/A HandlerBase = tc->readMiscReg(MISCREG_EBASE); 2501944SN/A } 2511519SN/A setHandlerPC(HandlerBase, tc); 2521606SN/A} 2537777Sgblack@eecs.umich.edu 2547777Sgblack@eecs.umich.eduvoid 2557777Sgblack@eecs.umich.eduTLBModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2567777Sgblack@eecs.umich.edu{ 2577777Sgblack@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2587777Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr); 2597777Sgblack@eecs.umich.edu EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI); 2607777Sgblack@eecs.umich.edu entryHi.asid = entryHiAsid; 2617777Sgblack@eecs.umich.edu entryHi.vpn2 = entryHiVPN2; 2627777Sgblack@eecs.umich.edu entryHi.vpn2x = entryHiVPN2X; 2637777Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi); 2647777Sgblack@eecs.umich.edu 2657777Sgblack@eecs.umich.edu ContextReg context = tc->readMiscReg(MISCREG_CONTEXT); 2667777Sgblack@eecs.umich.edu context.badVPN2 = contextBadVPN2; 2677777Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_CONTEXT, context); 2687777Sgblack@eecs.umich.edu 2697777Sgblack@eecs.umich.edu // Set new PC 2707777Sgblack@eecs.umich.edu Addr HandlerBase; 2717777Sgblack@eecs.umich.edu // Offset 0x180 - General Exception Vector 2727777Sgblack@eecs.umich.edu HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 2737777Sgblack@eecs.umich.edu setExceptionState(tc, 0x1); 2747777Sgblack@eecs.umich.edu setHandlerPC(HandlerBase, tc); 2757777Sgblack@eecs.umich.edu 2767777Sgblack@eecs.umich.edu} 2777777Sgblack@eecs.umich.edu 2787777Sgblack@eecs.umich.eduvoid 2797777Sgblack@eecs.umich.eduSystemCallFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2807777Sgblack@eecs.umich.edu{ 2817777Sgblack@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2827777Sgblack@eecs.umich.edu setExceptionState(tc, 0x8); 2837777Sgblack@eecs.umich.edu 2847777Sgblack@eecs.umich.edu // Set new PC 2857777Sgblack@eecs.umich.edu Addr HandlerBase; 2867777Sgblack@eecs.umich.edu // Offset 0x180 - General Exception Vector 2877777Sgblack@eecs.umich.edu HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 2887777Sgblack@eecs.umich.edu setHandlerPC(HandlerBase, tc); 2897777Sgblack@eecs.umich.edu} 2907777Sgblack@eecs.umich.edu 2917777Sgblack@eecs.umich.eduvoid 2927777Sgblack@eecs.umich.eduInterruptFault::invoke(ThreadContext *tc, StaticInstPtr inst) 2937777Sgblack@eecs.umich.edu{ 2947777Sgblack@eecs.umich.edu#if FULL_SYSTEM 2957777Sgblack@eecs.umich.edu DPRINTF(MipsPRA, "%s encountered.\n", name()); 2967777Sgblack@eecs.umich.edu setExceptionState(tc, 0x0A); 2977777Sgblack@eecs.umich.edu Addr HandlerBase; 2987777Sgblack@eecs.umich.edu 2997777Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 3007777Sgblack@eecs.umich.edu if (cause.iv) { 3017777Sgblack@eecs.umich.edu // Offset 200 for release 2 3029827Sakash.bagdia@arm.com HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 3039827Sakash.bagdia@arm.com } else { 3049827Sakash.bagdia@arm.com //Ofset at 180 for release 1 3059827Sakash.bagdia@arm.com HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 3069827Sakash.bagdia@arm.com } 3079827Sakash.bagdia@arm.com 3089827Sakash.bagdia@arm.com setHandlerPC(HandlerBase, tc); 3099827Sakash.bagdia@arm.com#endif 3109827Sakash.bagdia@arm.com} 3119827Sakash.bagdia@arm.com 3129827Sakash.bagdia@arm.com#endif // FULL_SYSTEM 3139827Sakash.bagdia@arm.com 31410427Sandreas.hansson@arm.comvoid 31510427Sandreas.hansson@arm.comResetFault::invoke(ThreadContext *tc, StaticInstPtr inst) 31610427Sandreas.hansson@arm.com{ 31710427Sandreas.hansson@arm.com#if FULL_SYSTEM 31810427Sandreas.hansson@arm.com DPRINTF(MipsPRA, "%s encountered.\n", name()); 31910427Sandreas.hansson@arm.com /* All reset activity must be invoked from here */ 32010427Sandreas.hansson@arm.com tc->setPC(vect()); 32110427Sandreas.hansson@arm.com tc->setNextPC(vect() + sizeof(MachInst)); 322 tc->setNextNPC(vect() + sizeof(MachInst) + sizeof(MachInst)); 323 DPRINTF(MipsPRA, "ResetFault::invoke : PC set to %x", tc->readPC()); 324#endif 325 326 // Set Coprocessor 1 (Floating Point) To Usable 327 StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 328 status.cu.cu1 = 1; 329 tc->setMiscReg(MISCREG_STATUS, status); 330} 331 332void 333ReservedInstructionFault::invoke(ThreadContext *tc, StaticInstPtr inst) 334{ 335#if FULL_SYSTEM 336 DPRINTF(MipsPRA, "%s encountered.\n", name()); 337 setExceptionState(tc, 0x0A); 338 Addr HandlerBase; 339 // Offset 0x180 - General Exception Vector 340 HandlerBase = vect() + tc->readMiscRegNoEffect(MISCREG_EBASE); 341 setHandlerPC(HandlerBase, tc); 342#else 343 panic("%s encountered.\n", name()); 344#endif 345} 346 347void 348ThreadFault::invoke(ThreadContext *tc, StaticInstPtr inst) 349{ 350 DPRINTF(MipsPRA, "%s encountered.\n", name()); 351 panic("%s encountered.\n", name()); 352} 353 354void 355DspStateDisabledFault::invoke(ThreadContext *tc, StaticInstPtr inst) 356{ 357 DPRINTF(MipsPRA, "%s encountered.\n", name()); 358 panic("%s encountered.\n", name()); 359} 360 361void 362CoprocessorUnusableFault::invoke(ThreadContext *tc, StaticInstPtr inst) 363{ 364#if FULL_SYSTEM 365 DPRINTF(MipsPRA, "%s encountered.\n", name()); 366 setExceptionState(tc, 0xb); 367 // The ID of the coprocessor causing the exception is stored in 368 // CoprocessorUnusableFault::coProcID 369 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); 370 cause.ce = coProcID; 371 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 372 373 Addr HandlerBase; 374 // Offset 0x180 - General Exception Vector 375 HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); 376 setHandlerPC(HandlerBase, tc); 377 378#else 379 warn("%s (CP%d) encountered.\n", name(), coProcID); 380#endif 381} 382 383} // namespace MipsISA 384 385