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