faults.cc revision 8303
17405SAli.Saidi@ARM.com/* 212667Schuan.zhu@arm.com * Copyright (c) 2010 ARM Limited 37405SAli.Saidi@ARM.com * All rights reserved 47405SAli.Saidi@ARM.com * 57405SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 67405SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 77405SAli.Saidi@ARM.com * property including but not limited to intellectual property relating 87405SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software 97405SAli.Saidi@ARM.com * licensed hereunder. You may use the software subject to the license 107405SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated 117405SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software, 127405SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 137405SAli.Saidi@ARM.com * 147405SAli.Saidi@ARM.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 157405SAli.Saidi@ARM.com * Copyright (c) 2007-2008 The Florida State University 167405SAli.Saidi@ARM.com * All rights reserved. 177405SAli.Saidi@ARM.com * 187405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 197405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 207405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 217405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 227405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 237405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 247405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 257405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 267405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 277405SAli.Saidi@ARM.com * this software without specific prior written permission. 287405SAli.Saidi@ARM.com * 297405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 307405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 317405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 327405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 337405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 347405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 357405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 367405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 377405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 387405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 397405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 407405SAli.Saidi@ARM.com * 417405SAli.Saidi@ARM.com * Authors: Ali Saidi 4210461SAndreas.Sandberg@ARM.com * Gabe Black 439050Schander.sudanthi@arm.com */ 4412406Sgabeblack@google.com 4512605Sgiacomo.travaglini@arm.com#include "arch/arm/faults.hh" 4611793Sbrandon.potter@amd.com#include "base/trace.hh" 478887Sgeoffrey.blake@arm.com#include "cpu/base.hh" 488232Snate@binkert.org#include "cpu/thread_context.hh" 498232Snate@binkert.org#include "debug/Faults.hh" 5010844Sandreas.sandberg@arm.com 5113531Sjairo.balart@metempsy.comnamespace ArmISA 5213531Sjairo.balart@metempsy.com{ 539384SAndreas.Sandberg@arm.com 547678Sgblack@eecs.umich.edutemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = 558059SAli.Saidi@ARM.com {"reset", 0x00, MODE_SVC, 0, 0, true, true}; 568284SAli.Saidi@ARM.com 577405SAli.Saidi@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = 587405SAli.Saidi@ARM.com {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ; 597405SAli.Saidi@ARM.com 607405SAli.Saidi@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = 619384SAndreas.Sandberg@arm.com {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false}; 6210461SAndreas.Sandberg@ARM.com 6310461SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = 6411165SRekai.GonzalezAlberquilla@arm.com {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false}; 6513599Sgiacomo.travaglini@arm.com 6612714Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = 6713691Sgiacomo.travaglini@arm.com {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false}; 6812714Sgiacomo.travaglini@arm.com 699384SAndreas.Sandberg@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = 7011770SCurtis.Dunham@arm.com {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false}; 7110037SARM gem5 Developers 7210461SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = 7310461SAndreas.Sandberg@ARM.com {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; 7410461SAndreas.Sandberg@ARM.com 7510461SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = 7610461SAndreas.Sandberg@ARM.com {"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values 7710461SAndreas.Sandberg@ARM.com 7810609Sandreas.sandberg@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<ReExec>::vals = 7910609Sandreas.sandberg@arm.com {"ReExec Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values 8010609Sandreas.sandberg@arm.com 8110037SARM gem5 DevelopersAddr 8210037SARM gem5 DevelopersArmFault::getVector(ThreadContext *tc) 8310037SARM gem5 Developers{ 8410037SARM gem5 Developers // ARM ARM B1-3 8511771SCurtis.Dunham@arm.com 8610037SARM gem5 Developers SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 8710037SARM gem5 Developers 8813173Sgiacomo.travaglini@arm.com // panic if SCTLR.VE because I have no idea what to do with vectored 8910037SARM gem5 Developers // interrupts 9010037SARM gem5 Developers assert(!sctlr.ve); 9113114Sgiacomo.travaglini@arm.com 9213759Sgiacomo.gabrielli@arm.com if (!sctlr.v) 9313759Sgiacomo.gabrielli@arm.com return offset(); 9410037SARM gem5 Developers return offset() + HighVecs; 9511771SCurtis.Dunham@arm.com 9610037SARM gem5 Developers} 9713499Sgiacomo.travaglini@arm.com 9810037SARM gem5 Developers#if FULL_SYSTEM 9913114Sgiacomo.travaglini@arm.com 10013759Sgiacomo.gabrielli@arm.comvoid 10113759Sgiacomo.gabrielli@arm.comArmFault::invoke(ThreadContext *tc, StaticInstPtr inst) 10210037SARM gem5 Developers{ 10310037SARM gem5 Developers // ARM ARM B1.6.3 10413599Sgiacomo.travaglini@arm.com FaultBase::invoke(tc); 10513599Sgiacomo.travaglini@arm.com countStat()++; 10613599Sgiacomo.travaglini@arm.com 10713599Sgiacomo.travaglini@arm.com SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 10812477SCurtis.Dunham@arm.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 10910037SARM gem5 Developers CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR); 11010037SARM gem5 Developers saved_cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ); 1119384SAndreas.Sandberg@arm.com saved_cpsr.c = tc->readIntReg(INTREG_CONDCODES_C); 1129384SAndreas.Sandberg@arm.com saved_cpsr.v = tc->readIntReg(INTREG_CONDCODES_V); 1139384SAndreas.Sandberg@arm.com saved_cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE); 11412479SCurtis.Dunham@arm.com 11512479SCurtis.Dunham@arm.com Addr curPc M5_VAR_USED = tc->pcState().pc(); 1169384SAndreas.Sandberg@arm.com ITSTATE it = tc->pcState().itstate(); 1179384SAndreas.Sandberg@arm.com saved_cpsr.it2 = it.top6; 1189384SAndreas.Sandberg@arm.com saved_cpsr.it1 = it.bottom2; 1199384SAndreas.Sandberg@arm.com 1209384SAndreas.Sandberg@arm.com cpsr.mode = nextMode(); 1219384SAndreas.Sandberg@arm.com cpsr.it1 = cpsr.it2 = 0; 1227427Sgblack@eecs.umich.edu cpsr.j = 0; 1237427Sgblack@eecs.umich.edu 1247427Sgblack@eecs.umich.edu cpsr.t = sctlr.te; 1259385SAndreas.Sandberg@arm.com cpsr.a = cpsr.a | abortDisable(); 1269385SAndreas.Sandberg@arm.com cpsr.f = cpsr.f | fiqDisable(); 1277427Sgblack@eecs.umich.edu cpsr.i = 1; 1287427Sgblack@eecs.umich.edu cpsr.e = sctlr.ee; 12910037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 13013114Sgiacomo.travaglini@arm.com tc->setIntReg(INTREG_LR, curPc + 13110037SARM gem5 Developers (saved_cpsr.t ? thumbPcOffset() : armPcOffset())); 13213114Sgiacomo.travaglini@arm.com 13313114Sgiacomo.travaglini@arm.com switch (nextMode()) { 13413114Sgiacomo.travaglini@arm.com case MODE_FIQ: 13513114Sgiacomo.travaglini@arm.com tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 13613114Sgiacomo.travaglini@arm.com break; 13712690Sgiacomo.travaglini@arm.com case MODE_IRQ: 13810037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 1397427Sgblack@eecs.umich.edu break; 1407427Sgblack@eecs.umich.edu case MODE_SVC: 14110037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 1427427Sgblack@eecs.umich.edu break; 1437427Sgblack@eecs.umich.edu case MODE_UNDEFINED: 1447427Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 1457427Sgblack@eecs.umich.edu break; 1467427Sgblack@eecs.umich.edu case MODE_ABORT: 1477427Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 1487427Sgblack@eecs.umich.edu break; 1497427Sgblack@eecs.umich.edu default: 1507427Sgblack@eecs.umich.edu panic("unknown Mode\n"); 1517427Sgblack@eecs.umich.edu } 1527427Sgblack@eecs.umich.edu 1537427Sgblack@eecs.umich.edu Addr newPc = getVector(tc); 1547427Sgblack@eecs.umich.edu DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n", 1557427Sgblack@eecs.umich.edu name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc); 1567427Sgblack@eecs.umich.edu PCState pc(newPc); 1577427Sgblack@eecs.umich.edu pc.thumb(cpsr.t); 1587427Sgblack@eecs.umich.edu pc.nextThumb(pc.thumb()); 1597427Sgblack@eecs.umich.edu pc.jazelle(cpsr.j); 1607427Sgblack@eecs.umich.edu pc.nextJazelle(pc.jazelle()); 1617427Sgblack@eecs.umich.edu tc->pcState(pc); 1627427Sgblack@eecs.umich.edu} 1637427Sgblack@eecs.umich.edu 1647427Sgblack@eecs.umich.eduvoid 1657436Sdam.sunwoo@arm.comReset::invoke(ThreadContext *tc, StaticInstPtr inst) 1667436Sdam.sunwoo@arm.com{ 16710037SARM gem5 Developers tc->getCpuPtr()->clearInterrupts(); 16810037SARM gem5 Developers tc->clearArchRegs(); 1697436Sdam.sunwoo@arm.com ArmFault::invoke(tc, inst); 1707436Sdam.sunwoo@arm.com} 1717436Sdam.sunwoo@arm.com 1727436Sdam.sunwoo@arm.com#else 1737436Sdam.sunwoo@arm.com 1747436Sdam.sunwoo@arm.comvoid 1757436Sdam.sunwoo@arm.comUndefinedInstruction::invoke(ThreadContext *tc, StaticInstPtr inst) 1767436Sdam.sunwoo@arm.com{ 1777436Sdam.sunwoo@arm.com // If the mnemonic isn't defined this has to be an unknown instruction. 1787436Sdam.sunwoo@arm.com assert(unknown || mnemonic != NULL); 1797436Sdam.sunwoo@arm.com if (disabled) { 1807436Sdam.sunwoo@arm.com panic("Attempted to execute disabled instruction " 18113393Sgiacomo.travaglini@arm.com "'%s' (inst 0x%08x)", mnemonic, machInst); 18210037SARM gem5 Developers } else if (unknown) { 1837436Sdam.sunwoo@arm.com panic("Attempted to execute unknown instruction (inst 0x%08x)", 1847436Sdam.sunwoo@arm.com machInst); 1857436Sdam.sunwoo@arm.com } else { 1867436Sdam.sunwoo@arm.com panic("Attempted to execute unimplemented instruction " 1877436Sdam.sunwoo@arm.com "'%s' (inst 0x%08x)", mnemonic, machInst); 1887436Sdam.sunwoo@arm.com } 1897436Sdam.sunwoo@arm.com} 1907436Sdam.sunwoo@arm.com 1917436Sdam.sunwoo@arm.comvoid 1927436Sdam.sunwoo@arm.comSupervisorCall::invoke(ThreadContext *tc, StaticInstPtr inst) 1937436Sdam.sunwoo@arm.com{ 1947436Sdam.sunwoo@arm.com // As of now, there isn't a 32 bit thumb version of this instruction. 1957436Sdam.sunwoo@arm.com assert(!machInst.bigThumb); 1967436Sdam.sunwoo@arm.com uint32_t callNum; 1977436Sdam.sunwoo@arm.com callNum = tc->readIntReg(INTREG_R7); 1987436Sdam.sunwoo@arm.com tc->syscall(callNum); 19913393Sgiacomo.travaglini@arm.com 20013393Sgiacomo.travaglini@arm.com // Advance the PC since that won't happen automatically. 20113393Sgiacomo.travaglini@arm.com PCState pc = tc->pcState(); 20213393Sgiacomo.travaglini@arm.com assert(inst); 20313393Sgiacomo.travaglini@arm.com inst->advancePC(pc); 20413393Sgiacomo.travaglini@arm.com tc->pcState(pc); 20513393Sgiacomo.travaglini@arm.com} 20613393Sgiacomo.travaglini@arm.com 20713393Sgiacomo.travaglini@arm.com#endif // FULL_SYSTEM 20813393Sgiacomo.travaglini@arm.com 20913393Sgiacomo.travaglini@arm.comtemplate<class T> 21013393Sgiacomo.travaglini@arm.comvoid 21113393Sgiacomo.travaglini@arm.comAbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst) 21213393Sgiacomo.travaglini@arm.com{ 21313393Sgiacomo.travaglini@arm.com ArmFaultVals<T>::invoke(tc, inst); 21413393Sgiacomo.travaglini@arm.com FSR fsr = 0; 21513396Sgiacomo.travaglini@arm.com fsr.fsLow = bits(status, 3, 0); 21613396Sgiacomo.travaglini@arm.com fsr.fsHigh = bits(status, 4); 21713396Sgiacomo.travaglini@arm.com fsr.domain = domain; 21813396Sgiacomo.travaglini@arm.com fsr.wnr = (write ? 1 : 0); 21913393Sgiacomo.travaglini@arm.com fsr.ext = 0; 22013393Sgiacomo.travaglini@arm.com tc->setMiscReg(T::FsrIndex, fsr); 22113393Sgiacomo.travaglini@arm.com tc->setMiscReg(T::FarIndex, faultAddr); 22213393Sgiacomo.travaglini@arm.com} 22313393Sgiacomo.travaglini@arm.com 22413393Sgiacomo.travaglini@arm.comvoid 22513393Sgiacomo.travaglini@arm.comFlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) { 22613393Sgiacomo.travaglini@arm.com DPRINTF(Faults, "Invoking FlushPipe Fault\n"); 22713393Sgiacomo.travaglini@arm.com 22813393Sgiacomo.travaglini@arm.com // Set the PC to the next instruction of the faulting instruction. 22913393Sgiacomo.travaglini@arm.com // Net effect is simply squashing all instructions behind and 23013393Sgiacomo.travaglini@arm.com // start refetching from the next instruction. 23113393Sgiacomo.travaglini@arm.com PCState pc = tc->pcState(); 23213393Sgiacomo.travaglini@arm.com assert(inst); 23313393Sgiacomo.travaglini@arm.com inst->advancePC(pc); 23413393Sgiacomo.travaglini@arm.com tc->pcState(pc); 23513393Sgiacomo.travaglini@arm.com} 23613393Sgiacomo.travaglini@arm.com 2377644Sali.saidi@arm.comvoid 2388147SAli.Saidi@ARM.comReExec::invoke(ThreadContext *tc, StaticInstPtr inst) { 2399385SAndreas.Sandberg@arm.com DPRINTF(Faults, "Invoking ReExec Fault\n"); 2409385SAndreas.Sandberg@arm.com 24110037SARM gem5 Developers // Set the PC to then the faulting instruction. 24210037SARM gem5 Developers // Net effect is simply squashing all instructions including this 24310037SARM gem5 Developers // instruction and refetching/rexecuting current instruction 24410037SARM gem5 Developers PCState pc = tc->pcState(); 24510037SARM gem5 Developers tc->pcState(pc); 24610037SARM gem5 Developers} 24710037SARM gem5 Developers 24810037SARM gem5 Developerstemplate void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc, 24910037SARM gem5 Developers StaticInstPtr inst); 25010037SARM gem5 Developerstemplate void AbortFault<DataAbort>::invoke(ThreadContext *tc, 25110037SARM gem5 Developers StaticInstPtr inst); 25210037SARM gem5 Developers 25310037SARM gem5 Developers// return via SUBS pc, lr, xxx; rfe, movs, ldm 25410037SARM gem5 Developers 25510037SARM gem5 Developers} // namespace ArmISA 25610037SARM gem5 Developers