faults.cc revision 8782
12735Sktlim@umich.edu/* 213953Sgiacomo.gabrielli@arm.com * Copyright (c) 2010 ARM Limited 310319SAndreas.Sandberg@ARM.com * All rights reserved 410319SAndreas.Sandberg@ARM.com * 510319SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 610319SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 710319SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 810319SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 910319SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 1010319SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 1110319SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 1210319SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 1310319SAndreas.Sandberg@ARM.com * 142735Sktlim@umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 1511303Ssteve.reinhardt@amd.com * Copyright (c) 2007-2008 The Florida State University 162735Sktlim@umich.edu * All rights reserved. 172735Sktlim@umich.edu * 182735Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 192735Sktlim@umich.edu * modification, are permitted provided that the following conditions are 202735Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 212735Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 222735Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 232735Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 242735Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 252735Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 262735Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 272735Sktlim@umich.edu * this software without specific prior written permission. 282735Sktlim@umich.edu * 292735Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302735Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312735Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322735Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332735Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342735Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352735Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362735Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372735Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382735Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392735Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402735Sktlim@umich.edu * 412735Sktlim@umich.edu * Authors: Ali Saidi 4210319SAndreas.Sandberg@ARM.com * Gabe Black 432735Sktlim@umich.edu */ 442735Sktlim@umich.edu 4510319SAndreas.Sandberg@ARM.com#include "arch/arm/faults.hh" 4610319SAndreas.Sandberg@ARM.com#include "base/trace.hh" 4710319SAndreas.Sandberg@ARM.com#include "cpu/base.hh" 4810319SAndreas.Sandberg@ARM.com#include "cpu/thread_context.hh" 4910319SAndreas.Sandberg@ARM.com#include "debug/Faults.hh" 5010319SAndreas.Sandberg@ARM.com#include "sim/full_system.hh" 5110529Smorr@cs.wisc.edu 5212104Snathanael.premillieu@arm.comnamespace ArmISA 5310319SAndreas.Sandberg@ARM.com{ 5410319SAndreas.Sandberg@ARM.com 5511608Snikos.nikoleris@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = 562735Sktlim@umich.edu {"reset", 0x00, MODE_SVC, 0, 0, true, true}; 572735Sktlim@umich.edu 5810319SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = 5910319SAndreas.Sandberg@ARM.com {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ; 6010319SAndreas.Sandberg@ARM.com 6110319SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = 6210319SAndreas.Sandberg@ARM.com {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false}; 6310319SAndreas.Sandberg@ARM.com 6410319SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = 6510319SAndreas.Sandberg@ARM.com {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false}; 6610319SAndreas.Sandberg@ARM.com 6710319SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = 6810319SAndreas.Sandberg@ARM.com {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false}; 6910319SAndreas.Sandberg@ARM.com 7010319SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = 7110319SAndreas.Sandberg@ARM.com {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false}; 722735Sktlim@umich.edu 732735Sktlim@umich.edutemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = 7410319SAndreas.Sandberg@ARM.com {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; 7510319SAndreas.Sandberg@ARM.com 7610319SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = 7712109SRekai.GonzalezAlberquilla@arm.com {"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values 7812109SRekai.GonzalezAlberquilla@arm.com 7913610Sgiacomo.gabrielli@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = 8010319SAndreas.Sandberg@ARM.com {"ArmSev Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values 8110319SAndreas.Sandberg@ARM.comAddr 8210319SAndreas.Sandberg@ARM.comArmFault::getVector(ThreadContext *tc) 8310319SAndreas.Sandberg@ARM.com{ 8410319SAndreas.Sandberg@ARM.com // ARM ARM B1-3 8510319SAndreas.Sandberg@ARM.com 8610319SAndreas.Sandberg@ARM.com SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 872735Sktlim@umich.edu 882735Sktlim@umich.edu // panic if SCTLR.VE because I have no idea what to do with vectored 8913557Sgabeblack@google.com // interrupts 9010319SAndreas.Sandberg@ARM.com assert(!sctlr.ve); 9110319SAndreas.Sandberg@ARM.com 9210319SAndreas.Sandberg@ARM.com if (!sctlr.v) 9313557Sgabeblack@google.com return offset(); 9410319SAndreas.Sandberg@ARM.com return offset() + HighVecs; 9510319SAndreas.Sandberg@ARM.com 9610319SAndreas.Sandberg@ARM.com} 9710319SAndreas.Sandberg@ARM.com 9810319SAndreas.Sandberg@ARM.comvoid 9910319SAndreas.Sandberg@ARM.comArmFault::invoke(ThreadContext *tc, StaticInstPtr inst) 10010319SAndreas.Sandberg@ARM.com{ 10110319SAndreas.Sandberg@ARM.com // ARM ARM B1.6.3 1022735Sktlim@umich.edu FaultBase::invoke(tc); 1032735Sktlim@umich.edu if (!FullSystem) 1042735Sktlim@umich.edu return; 10513557Sgabeblack@google.com countStat()++; 1062735Sktlim@umich.edu 1072735Sktlim@umich.edu SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 1082735Sktlim@umich.edu CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 10910319SAndreas.Sandberg@ARM.com CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR); 11013557Sgabeblack@google.com saved_cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ); 1112735Sktlim@umich.edu saved_cpsr.c = tc->readIntReg(INTREG_CONDCODES_C); 11210319SAndreas.Sandberg@ARM.com saved_cpsr.v = tc->readIntReg(INTREG_CONDCODES_V); 1132735Sktlim@umich.edu saved_cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE); 11412109SRekai.GonzalezAlberquilla@arm.com 11512109SRekai.GonzalezAlberquilla@arm.com Addr curPc M5_VAR_USED = tc->pcState().pc(); 11612109SRekai.GonzalezAlberquilla@arm.com ITSTATE it = tc->pcState().itstate(); 11712109SRekai.GonzalezAlberquilla@arm.com saved_cpsr.it2 = it.top6; 11812109SRekai.GonzalezAlberquilla@arm.com saved_cpsr.it1 = it.bottom2; 11912109SRekai.GonzalezAlberquilla@arm.com 12012109SRekai.GonzalezAlberquilla@arm.com cpsr.mode = nextMode(); 12112109SRekai.GonzalezAlberquilla@arm.com cpsr.it1 = cpsr.it2 = 0; 12212109SRekai.GonzalezAlberquilla@arm.com cpsr.j = 0; 12312109SRekai.GonzalezAlberquilla@arm.com 12412109SRekai.GonzalezAlberquilla@arm.com cpsr.t = sctlr.te; 12512109SRekai.GonzalezAlberquilla@arm.com cpsr.a = cpsr.a | abortDisable(); 12612109SRekai.GonzalezAlberquilla@arm.com cpsr.f = cpsr.f | fiqDisable(); 12712109SRekai.GonzalezAlberquilla@arm.com cpsr.i = 1; 12812109SRekai.GonzalezAlberquilla@arm.com cpsr.e = sctlr.ee; 12912109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_CPSR, cpsr); 13012109SRekai.GonzalezAlberquilla@arm.com // Make sure mailbox sets to one always 13112109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 13212109SRekai.GonzalezAlberquilla@arm.com tc->setIntReg(INTREG_LR, curPc + 13312109SRekai.GonzalezAlberquilla@arm.com (saved_cpsr.t ? thumbPcOffset() : armPcOffset())); 13412109SRekai.GonzalezAlberquilla@arm.com 13512109SRekai.GonzalezAlberquilla@arm.com switch (nextMode()) { 13612109SRekai.GonzalezAlberquilla@arm.com case MODE_FIQ: 13712109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 13812109SRekai.GonzalezAlberquilla@arm.com break; 13912109SRekai.GonzalezAlberquilla@arm.com case MODE_IRQ: 14012109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 14112109SRekai.GonzalezAlberquilla@arm.com break; 14212109SRekai.GonzalezAlberquilla@arm.com case MODE_SVC: 14312109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 14412109SRekai.GonzalezAlberquilla@arm.com break; 14512109SRekai.GonzalezAlberquilla@arm.com case MODE_UNDEFINED: 14612109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 14712109SRekai.GonzalezAlberquilla@arm.com break; 14812109SRekai.GonzalezAlberquilla@arm.com case MODE_ABORT: 14912109SRekai.GonzalezAlberquilla@arm.com tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 15012109SRekai.GonzalezAlberquilla@arm.com break; 15112109SRekai.GonzalezAlberquilla@arm.com default: 15212109SRekai.GonzalezAlberquilla@arm.com panic("unknown Mode\n"); 15312109SRekai.GonzalezAlberquilla@arm.com } 15412109SRekai.GonzalezAlberquilla@arm.com 15512109SRekai.GonzalezAlberquilla@arm.com Addr newPc = getVector(tc); 15612109SRekai.GonzalezAlberquilla@arm.com DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n", 15712109SRekai.GonzalezAlberquilla@arm.com name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc); 15812109SRekai.GonzalezAlberquilla@arm.com PCState pc(newPc); 15912109SRekai.GonzalezAlberquilla@arm.com pc.thumb(cpsr.t); 16012109SRekai.GonzalezAlberquilla@arm.com pc.nextThumb(pc.thumb()); 16112109SRekai.GonzalezAlberquilla@arm.com pc.jazelle(cpsr.j); 16212109SRekai.GonzalezAlberquilla@arm.com pc.nextJazelle(pc.jazelle()); 16312109SRekai.GonzalezAlberquilla@arm.com tc->pcState(pc); 16412109SRekai.GonzalezAlberquilla@arm.com} 16512109SRekai.GonzalezAlberquilla@arm.com 16612109SRekai.GonzalezAlberquilla@arm.comvoid 16712109SRekai.GonzalezAlberquilla@arm.comReset::invoke(ThreadContext *tc, StaticInstPtr inst) 16812109SRekai.GonzalezAlberquilla@arm.com{ 16912109SRekai.GonzalezAlberquilla@arm.com if (FullSystem) { 17012109SRekai.GonzalezAlberquilla@arm.com tc->getCpuPtr()->clearInterrupts(); 17113610Sgiacomo.gabrielli@arm.com tc->clearArchRegs(); 17213610Sgiacomo.gabrielli@arm.com } 17313610Sgiacomo.gabrielli@arm.com ArmFault::invoke(tc, inst); 17413610Sgiacomo.gabrielli@arm.com} 17513610Sgiacomo.gabrielli@arm.com 17613610Sgiacomo.gabrielli@arm.comvoid 17713610Sgiacomo.gabrielli@arm.comUndefinedInstruction::invoke(ThreadContext *tc, StaticInstPtr inst) 17813610Sgiacomo.gabrielli@arm.com{ 17913610Sgiacomo.gabrielli@arm.com if (FullSystem) { 18013610Sgiacomo.gabrielli@arm.com ArmFault::invoke(tc, inst); 18113610Sgiacomo.gabrielli@arm.com } else { 18213610Sgiacomo.gabrielli@arm.com // If the mnemonic isn't defined this has to be an unknown instruction. 18313610Sgiacomo.gabrielli@arm.com assert(unknown || mnemonic != NULL); 18413610Sgiacomo.gabrielli@arm.com if (disabled) { 18513610Sgiacomo.gabrielli@arm.com panic("Attempted to execute disabled instruction " 18613610Sgiacomo.gabrielli@arm.com "'%s' (inst 0x%08x)", mnemonic, machInst); 18710319SAndreas.Sandberg@ARM.com } else if (unknown) { 18810319SAndreas.Sandberg@ARM.com panic("Attempted to execute unknown instruction (inst 0x%08x)", 18910319SAndreas.Sandberg@ARM.com machInst); 19010319SAndreas.Sandberg@ARM.com } else { 19113622Sgabeblack@google.com panic("Attempted to execute unimplemented instruction " 19213622Sgabeblack@google.com "'%s' (inst 0x%08x)", mnemonic, machInst); 19313622Sgabeblack@google.com } 19410319SAndreas.Sandberg@ARM.com } 1952735Sktlim@umich.edu} 19610319SAndreas.Sandberg@ARM.com 19710319SAndreas.Sandberg@ARM.comvoid 19810319SAndreas.Sandberg@ARM.comSupervisorCall::invoke(ThreadContext *tc, StaticInstPtr inst) 19910319SAndreas.Sandberg@ARM.com{ 20013557Sgabeblack@google.com if (FullSystem) { 20110319SAndreas.Sandberg@ARM.com ArmFault::invoke(tc, inst); 20213582Sgabeblack@google.com } else { 2032735Sktlim@umich.edu // As of now, there isn't a 32 bit thumb version of this instruction. 20410319SAndreas.Sandberg@ARM.com assert(!machInst.bigThumb); 20510319SAndreas.Sandberg@ARM.com uint32_t callNum; 20610319SAndreas.Sandberg@ARM.com callNum = tc->readIntReg(INTREG_R7); 20710319SAndreas.Sandberg@ARM.com tc->syscall(callNum); 20813557Sgabeblack@google.com 2092735Sktlim@umich.edu // Advance the PC since that won't happen automatically. 21010319SAndreas.Sandberg@ARM.com PCState pc = tc->pcState(); 21110319SAndreas.Sandberg@ARM.com assert(inst); 21210319SAndreas.Sandberg@ARM.com inst->advancePC(pc); 21310319SAndreas.Sandberg@ARM.com tc->pcState(pc); 21413582Sgabeblack@google.com } 2152735Sktlim@umich.edu} 21610319SAndreas.Sandberg@ARM.com 2172735Sktlim@umich.edutemplate<class T> 21810319SAndreas.Sandberg@ARM.comvoid 21910319SAndreas.Sandberg@ARM.comAbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst) 22010319SAndreas.Sandberg@ARM.com{ 22110319SAndreas.Sandberg@ARM.com ArmFaultVals<T>::invoke(tc, inst); 22210319SAndreas.Sandberg@ARM.com FSR fsr = 0; 22310319SAndreas.Sandberg@ARM.com fsr.fsLow = bits(status, 3, 0); 22410319SAndreas.Sandberg@ARM.com fsr.fsHigh = bits(status, 4); 22510319SAndreas.Sandberg@ARM.com fsr.domain = domain; 22610319SAndreas.Sandberg@ARM.com fsr.wnr = (write ? 1 : 0); 22710319SAndreas.Sandberg@ARM.com fsr.ext = 0; 22810319SAndreas.Sandberg@ARM.com tc->setMiscReg(T::FsrIndex, fsr); 22910319SAndreas.Sandberg@ARM.com tc->setMiscReg(T::FarIndex, faultAddr); 23010319SAndreas.Sandberg@ARM.com 23111303Ssteve.reinhardt@amd.com DPRINTF(Faults, "Abort Fault fsr=%#x faultAddr=%#x\n", fsr, faultAddr); 23211303Ssteve.reinhardt@amd.com} 23311303Ssteve.reinhardt@amd.com 23411303Ssteve.reinhardt@amd.comvoid 23511303Ssteve.reinhardt@amd.comFlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) { 23611303Ssteve.reinhardt@amd.com DPRINTF(Faults, "Invoking FlushPipe Fault\n"); 23710319SAndreas.Sandberg@ARM.com 23813954Sgiacomo.gabrielli@arm.com // Set the PC to the next instruction of the faulting instruction. 23913954Sgiacomo.gabrielli@arm.com // Net effect is simply squashing all instructions behind and 24011303Ssteve.reinhardt@amd.com // start refetching from the next instruction. 24111303Ssteve.reinhardt@amd.com PCState pc = tc->pcState(); 24211303Ssteve.reinhardt@amd.com assert(inst); 24310319SAndreas.Sandberg@ARM.com inst->advancePC(pc); 24411303Ssteve.reinhardt@amd.com tc->pcState(pc); 24511303Ssteve.reinhardt@amd.com} 24611303Ssteve.reinhardt@amd.com 24711303Ssteve.reinhardt@amd.comtemplate void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc, 24811303Ssteve.reinhardt@amd.com StaticInstPtr inst); 24911303Ssteve.reinhardt@amd.comtemplate void AbortFault<DataAbort>::invoke(ThreadContext *tc, 25011303Ssteve.reinhardt@amd.com StaticInstPtr inst); 25111303Ssteve.reinhardt@amd.com 25213954Sgiacomo.gabrielli@arm.comvoid 25313954Sgiacomo.gabrielli@arm.comArmSev::invoke(ThreadContext *tc, StaticInstPtr inst) { 25411303Ssteve.reinhardt@amd.com DPRINTF(Faults, "Invoking ArmSev Fault\n"); 25511303Ssteve.reinhardt@amd.com if (FullSystem) { 25611303Ssteve.reinhardt@amd.com // Set sev_mailbox to 1, clear the pending interrupt from remote 25711303Ssteve.reinhardt@amd.com // SEV execution and let pipeline continue as pcState is still 25811303Ssteve.reinhardt@amd.com // valid. 25911303Ssteve.reinhardt@amd.com tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 26011303Ssteve.reinhardt@amd.com tc->getCpuPtr()->clearInterrupt(INT_SEV, 0); 26111303Ssteve.reinhardt@amd.com } 26210319SAndreas.Sandberg@ARM.com} 26313954Sgiacomo.gabrielli@arm.com 26413954Sgiacomo.gabrielli@arm.com// return via SUBS pc, lr, xxx; rfe, movs, ldm 26513954Sgiacomo.gabrielli@arm.com 26610319SAndreas.Sandberg@ARM.com} // namespace ArmISA 26710319SAndreas.Sandberg@ARM.com