faults.cc revision 8063
12SN/A/* 21762SN/A * Copyright (c) 2010 ARM Limited 32SN/A * All rights reserved 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 152SN/A * Copyright (c) 2007-2008 The Florida State University 162SN/A * All rights reserved. 172SN/A * 182SN/A * Redistribution and use in source and binary forms, with or without 192SN/A * modification, are permitted provided that the following conditions are 202SN/A * met: redistributions of source code must retain the above copyright 212SN/A * notice, this list of conditions and the following disclaimer; 222SN/A * redistributions in binary form must reproduce the above copyright 232SN/A * notice, this list of conditions and the following disclaimer in the 242SN/A * documentation and/or other materials provided with the distribution; 252SN/A * neither the name of the copyright holders nor the names of its 262SN/A * contributors may be used to endorse or promote products derived from 272665SN/A * this software without specific prior written permission. 282665SN/A * 292665SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341298SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351298SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361259SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39146SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40146SN/A * 417632SBrad.Beckmann@amd.com * Authors: Ali Saidi 423348SN/A * Gabe Black 433348SN/A */ 443348SN/A 453348SN/A#include "arch/arm/faults.hh" 4656SN/A#include "cpu/thread_context.hh" 47695SN/A#include "cpu/base.hh" 482SN/A#include "base/trace.hh" 492SN/A 502SN/Anamespace ArmISA 511298SN/A{ 521298SN/A 533187SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = 543349SN/A {"reset", 0x00, MODE_SVC, 0, 0, true, true}; 553187SN/A 564898SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = 574898SN/A {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ; 584898SN/A 594898SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = 604898SN/A {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false}; 614898SN/A 624898SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = 633187SN/A {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false}; 643187SN/A 653187SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = 663187SN/A {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false}; 673349SN/A 683187SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = 694895SN/A {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false}; 704895SN/A 714895SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = 723187SN/A {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; 733187SN/A 743187SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = 753187SN/A {"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values 763349SN/A 773187SN/AAddr 783204SN/AArmFault::getVector(ThreadContext *tc) 793340SN/A{ 803340SN/A // ARM ARM B1-3 813262SN/A 823204SN/A SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 833187SN/A 843187SN/A // panic if SCTLR.VE because I have no idea what to do with vectored 853187SN/A // interrupts 863187SN/A assert(!sctlr.ve); 873187SN/A 883647SN/A if (!sctlr.v) 893647SN/A return offset(); 903647SN/A return offset() + HighVecs; 913647SN/A 923647SN/A} 933187SN/A 943647SN/A#if FULL_SYSTEM 953187SN/A 963187SN/Avoid 973187SN/AArmFault::invoke(ThreadContext *tc, StaticInstPtr inst) 983187SN/A{ 993187SN/A // ARM ARM B1.6.3 1003187SN/A FaultBase::invoke(tc); 1013187SN/A countStat()++; 1023187SN/A 1033187SN/A SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 1043187SN/A CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 1053262SN/A CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) | 1063349SN/A tc->readIntReg(INTREG_CONDCODES); 1073262SN/A Addr curPc M5_VAR_USED = tc->pcState().pc(); 1083262SN/A 1093262SN/A 1103262SN/A cpsr.mode = nextMode(); 1113262SN/A cpsr.it1 = cpsr.it2 = 0; 1127544SN/A cpsr.j = 0; 1137544SN/A 1147544SN/A cpsr.t = sctlr.te; 1157544SN/A cpsr.a = cpsr.a | abortDisable(); 1167544SN/A cpsr.f = cpsr.f | fiqDisable(); 1177544SN/A cpsr.i = 1; 1187544SN/A cpsr.e = sctlr.ee; 1197544SN/A tc->setMiscReg(MISCREG_CPSR, cpsr); 1203262SN/A tc->setIntReg(INTREG_LR, curPc + 1213262SN/A (saved_cpsr.t ? thumbPcOffset() : armPcOffset())); 1227544SN/A 1237544SN/A switch (nextMode()) { 1247544SN/A case MODE_FIQ: 1257544SN/A tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 1263262SN/A break; 1273262SN/A case MODE_IRQ: 1283262SN/A tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 1293262SN/A break; 1305034SN/A case MODE_SVC: 1315034SN/A tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 1322SN/A break; 1333187SN/A case MODE_UNDEFINED: 1343187SN/A tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 1353187SN/A break; 1363187SN/A case MODE_ABORT: 1373187SN/A tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 1385034SN/A break; 1395034SN/A default: 1405034SN/A panic("unknown Mode\n"); 1415034SN/A } 1427544SN/A 1435034SN/A Addr newPc = getVector(tc); 1445034SN/A DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n", 1455034SN/A name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc); 1465034SN/A PCState pc(newPc); 1475034SN/A pc.thumb(cpsr.t); 1485034SN/A pc.nextThumb(pc.thumb()); 1492SN/A pc.jazelle(cpsr.j); 1507544SN/A pc.nextJazelle(pc.jazelle()); 1512SN/A tc->pcState(pc); 1522SN/A} 1532SN/A 1543187SN/Avoid 1552SN/AReset::invoke(ThreadContext *tc, StaticInstPtr inst) 1562SN/A{ 1573647SN/A tc->getCpuPtr()->clearInterrupts(); 1583647SN/A tc->clearArchRegs(); 1593647SN/A ArmFault::invoke(tc); 1607544SN/A} 1617544SN/A 1623187SN/A#else 1635034SN/A 1642SN/Avoid 1652SN/AUndefinedInstruction::invoke(ThreadContext *tc, StaticInstPtr inst) 1662SN/A{ 1672SN/A // If the mnemonic isn't defined this has to be an unknown instruction. 1682SN/A assert(unknown || mnemonic != NULL); 1692SN/A if (disabled) { 1702SN/A panic("Attempted to execute disabled instruction " 1715606SN/A "'%s' (inst 0x%08x)", mnemonic, machInst); 1721298SN/A } else if (unknown) { 1733187SN/A panic("Attempted to execute unknown instruction (inst 0x%08x)", 1747544SN/A machInst); 1753187SN/A } else { 1763187SN/A panic("Attempted to execute unimplemented instruction " 1773187SN/A "'%s' (inst 0x%08x)", mnemonic, machInst); 1783187SN/A } 1793187SN/A} 1803187SN/A 1813187SN/Avoid 1823187SN/ASupervisorCall::invoke(ThreadContext *tc, StaticInstPtr inst) 1833187SN/A{ 1843187SN/A // As of now, there isn't a 32 bit thumb version of this instruction. 1853187SN/A assert(!machInst.bigThumb); 1863187SN/A uint32_t callNum; 1873187SN/A callNum = tc->readIntReg(INTREG_R7); 1883187SN/A tc->syscall(callNum); 1893187SN/A 1903187SN/A // Advance the PC since that won't happen automatically. 1913187SN/A PCState pc = tc->pcState(); 1923187SN/A assert(inst); 1933187SN/A inst->advancePC(pc); 1943187SN/A tc->pcState(pc); 1953187SN/A} 1964579SN/A 1974579SN/A#endif // FULL_SYSTEM 1982SN/A 1992SN/Atemplate<class T> 2002SN/Avoid 2012SN/AAbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst) 2023349SN/A{ 2032SN/A ArmFaultVals<T>::invoke(tc); 2044628SN/A FSR fsr = 0; 2054628SN/A fsr.fsLow = bits(status, 3, 0); 2067544SN/A fsr.fsHigh = bits(status, 4); 2077544SN/A fsr.domain = domain; 2087544SN/A fsr.wnr = (write ? 1 : 0); 2097544SN/A fsr.ext = 0; 2104628SN/A tc->setMiscReg(T::FsrIndex, fsr); 2114628SN/A tc->setMiscReg(T::FarIndex, faultAddr); 2124628SN/A} 2134628SN/A 2143187SN/Avoid 2153187SN/AFlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) { 2163187SN/A DPRINTF(Faults, "Invoking FlushPipe Fault\n"); 2173187SN/A 2183187SN/A // Set the PC to the next instruction of the faulting instruction. 2193187SN/A // Net effect is simply squashing all instructions behind and 2201298SN/A // start refetching from the next instruction. 2214628SN/A PCState pc = tc->pcState(); 2224628SN/A assert(inst); 2231298SN/A inst->advancePC(pc); 2241298SN/A tc->pcState(pc); 2251298SN/A} 2265319SN/A 2273187SN/Atemplate void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc, 2284626SN/A StaticInstPtr inst); 2294626SN/Atemplate void AbortFault<DataAbort>::invoke(ThreadContext *tc, 2304626SN/A StaticInstPtr inst); 2314626SN/A 2322SN/A// return via SUBS pc, lr, xxx; rfe, movs, ldm 2332SN/A 2342SN/A} // namespace ArmISA 235695SN/A