faults.cc revision 7362
17405SAli.Saidi@ARM.com/*
214128Sgiacomo.travaglini@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 "cpu/thread_context.hh"
478887Sgeoffrey.blake@arm.com#include "cpu/base.hh"
488232Snate@binkert.org#include "base/trace.hh"
498232Snate@binkert.org
5010844Sandreas.sandberg@arm.comnamespace ArmISA
5113531Sjairo.balart@metempsy.com{
5213531Sjairo.balart@metempsy.com
539384SAndreas.Sandberg@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals =
547678Sgblack@eecs.umich.edu    {"reset", 0x00, MODE_SVC, 0, 0, true, true};
558059SAli.Saidi@ARM.com
568284SAli.Saidi@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals =
577405SAli.Saidi@ARM.com    {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
587405SAli.Saidi@ARM.com
597405SAli.Saidi@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals =
607405SAli.Saidi@ARM.com    {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
619384SAndreas.Sandberg@arm.com
6210461SAndreas.Sandberg@ARM.comtemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals =
6310461SAndreas.Sandberg@ARM.com    {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
6411165SRekai.GonzalezAlberquilla@arm.com
6513599Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals =
6612714Sgiacomo.travaglini@arm.com    {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
6713691Sgiacomo.travaglini@arm.com
6814000Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals =
6914000Sgiacomo.travaglini@arm.com    {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
709384SAndreas.Sandberg@arm.com
7111770SCurtis.Dunham@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals =
7210037SARM gem5 Developers    {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
7310461SAndreas.Sandberg@ARM.com
7410461SAndreas.Sandberg@ARM.comAddr
7510461SAndreas.Sandberg@ARM.comArmFault::getVector(ThreadContext *tc)
7610461SAndreas.Sandberg@ARM.com{
7710461SAndreas.Sandberg@ARM.com    // ARM ARM B1-3
7810461SAndreas.Sandberg@ARM.com
7910609Sandreas.sandberg@arm.com    SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
8010609Sandreas.sandberg@arm.com
8110609Sandreas.sandberg@arm.com    // panic if SCTLR.VE because I have no idea what to do with vectored
8210037SARM gem5 Developers    // interrupts
8310037SARM gem5 Developers    assert(!sctlr.ve);
8410037SARM gem5 Developers
8510037SARM gem5 Developers    if (!sctlr.v)
8611771SCurtis.Dunham@arm.com        return offset();
8710037SARM gem5 Developers    return offset() + HighVecs;
8810037SARM gem5 Developers
8913173Sgiacomo.travaglini@arm.com}
9010037SARM gem5 Developers
9110037SARM gem5 Developers#if FULL_SYSTEM
9213114Sgiacomo.travaglini@arm.com
9313759Sgiacomo.gabrielli@arm.comvoid
9414128Sgiacomo.travaglini@arm.comArmFault::invoke(ThreadContext *tc)
9513759Sgiacomo.gabrielli@arm.com{
9614133Sjordi.vaquero@metempsy.com    // ARM ARM B1.6.3
9710037SARM gem5 Developers    FaultBase::invoke(tc);
9811771SCurtis.Dunham@arm.com    countStat()++;
9910037SARM gem5 Developers
10013499Sgiacomo.travaglini@arm.com    SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
10110037SARM gem5 Developers    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
10213114Sgiacomo.travaglini@arm.com    CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
10313759Sgiacomo.gabrielli@arm.com                      tc->readIntReg(INTREG_CONDCODES);
10414128Sgiacomo.travaglini@arm.com
10513759Sgiacomo.gabrielli@arm.com
10614133Sjordi.vaquero@metempsy.com    cpsr.mode = nextMode();
10710037SARM gem5 Developers    cpsr.it1 = cpsr.it2 = 0;
10810037SARM gem5 Developers    cpsr.j = 0;
10913599Sgiacomo.travaglini@arm.com
11013599Sgiacomo.travaglini@arm.com    cpsr.t = sctlr.te;
11113599Sgiacomo.travaglini@arm.com    cpsr.a = cpsr.a | abortDisable();
11213599Sgiacomo.travaglini@arm.com    cpsr.f = cpsr.f | fiqDisable();
11312477SCurtis.Dunham@arm.com    cpsr.i = 1;
11410037SARM gem5 Developers    cpsr.e = sctlr.ee;
11510037SARM gem5 Developers    tc->setMiscReg(MISCREG_CPSR, cpsr);
1169384SAndreas.Sandberg@arm.com    tc->setIntReg(INTREG_LR, tc->readPC() +
1179384SAndreas.Sandberg@arm.com            (saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
1189384SAndreas.Sandberg@arm.com
11912479SCurtis.Dunham@arm.com    switch (nextMode()) {
12012479SCurtis.Dunham@arm.com      case MODE_FIQ:
1219384SAndreas.Sandberg@arm.com        tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
1229384SAndreas.Sandberg@arm.com        break;
1239384SAndreas.Sandberg@arm.com      case MODE_IRQ:
1249384SAndreas.Sandberg@arm.com        tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
1259384SAndreas.Sandberg@arm.com        break;
1269384SAndreas.Sandberg@arm.com      case MODE_SVC:
1277427Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
1287427Sgblack@eecs.umich.edu        break;
1297427Sgblack@eecs.umich.edu      case MODE_UNDEFINED:
1309385SAndreas.Sandberg@arm.com        tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
1319385SAndreas.Sandberg@arm.com        break;
1327427Sgblack@eecs.umich.edu      case MODE_ABORT:
1337427Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
13410037SARM gem5 Developers        break;
13513114Sgiacomo.travaglini@arm.com      default:
13610037SARM gem5 Developers        panic("unknown Mode\n");
13713114Sgiacomo.travaglini@arm.com    }
13813114Sgiacomo.travaglini@arm.com
13913114Sgiacomo.travaglini@arm.com    Addr pc = tc->readPC();
14013114Sgiacomo.travaglini@arm.com    DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n",
14113114Sgiacomo.travaglini@arm.com            name(), cpsr, pc, tc->readIntReg(INTREG_LR));
14212690Sgiacomo.travaglini@arm.com    Addr newPc = getVector(tc) | (sctlr.te ? (ULL(1) << PcTBitShift) : 0);
14310037SARM gem5 Developers    tc->setPC(newPc);
1447427Sgblack@eecs.umich.edu    tc->setNextPC(newPc + cpsr.t ? 2 : 4 );
1457427Sgblack@eecs.umich.edu    tc->setMicroPC(0);
14610037SARM gem5 Developers}
1477427Sgblack@eecs.umich.edu
1487427Sgblack@eecs.umich.edu#else
1497427Sgblack@eecs.umich.edu
1507427Sgblack@eecs.umich.eduvoid
1517427Sgblack@eecs.umich.eduUndefinedInstruction::invoke(ThreadContext *tc)
1527427Sgblack@eecs.umich.edu{
1537427Sgblack@eecs.umich.edu    assert(unknown || mnemonic != NULL);
1547427Sgblack@eecs.umich.edu    if (unknown) {
1557427Sgblack@eecs.umich.edu        panic("Attempted to execute unknown instruction "
1567427Sgblack@eecs.umich.edu              "(inst 0x%08x, opcode 0x%x, binary:%s)",
1577427Sgblack@eecs.umich.edu              machInst, machInst.opcode, inst2string(machInst));
1587427Sgblack@eecs.umich.edu    } else {
1597427Sgblack@eecs.umich.edu        panic("Attempted to execute unimplemented instruction '%s' "
1607427Sgblack@eecs.umich.edu              "(inst 0x%08x, opcode 0x%x, binary:%s)",
1617427Sgblack@eecs.umich.edu              mnemonic, machInst, machInst.opcode, inst2string(machInst));
1627427Sgblack@eecs.umich.edu    }
1637427Sgblack@eecs.umich.edu}
1647427Sgblack@eecs.umich.edu
1657427Sgblack@eecs.umich.eduvoid
1667427Sgblack@eecs.umich.eduSupervisorCall::invoke(ThreadContext *tc)
1677427Sgblack@eecs.umich.edu{
1687427Sgblack@eecs.umich.edu    // As of now, there isn't a 32 bit thumb version of this instruction.
1697427Sgblack@eecs.umich.edu    assert(!machInst.bigThumb);
1707436Sdam.sunwoo@arm.com    uint32_t callNum;
1717436Sdam.sunwoo@arm.com    if (machInst.thumb) {
17210037SARM gem5 Developers        callNum = bits(machInst, 7, 0);
17310037SARM gem5 Developers    } else {
1747436Sdam.sunwoo@arm.com        callNum = bits(machInst, 23, 0);
1757436Sdam.sunwoo@arm.com    }
1767436Sdam.sunwoo@arm.com    if (callNum == 0) {
1777436Sdam.sunwoo@arm.com        callNum = tc->readIntReg(INTREG_R7);
1787436Sdam.sunwoo@arm.com    }
1797436Sdam.sunwoo@arm.com    tc->syscall(callNum);
1807436Sdam.sunwoo@arm.com
1817436Sdam.sunwoo@arm.com    // Advance the PC since that won't happen automatically.
1827436Sdam.sunwoo@arm.com    tc->setPC(tc->readNextPC());
1837436Sdam.sunwoo@arm.com    tc->setNextPC(tc->readNextNPC());
1847436Sdam.sunwoo@arm.com}
1857436Sdam.sunwoo@arm.com
18613393Sgiacomo.travaglini@arm.com#endif // FULL_SYSTEM
18710037SARM gem5 Developers
1887436Sdam.sunwoo@arm.comtemplate<class T>
1897436Sdam.sunwoo@arm.comvoid
1907436Sdam.sunwoo@arm.comAbortFault<T>::invoke(ThreadContext *tc)
1917436Sdam.sunwoo@arm.com{
1927436Sdam.sunwoo@arm.com    ArmFaultVals<T>::invoke(tc);
1937436Sdam.sunwoo@arm.com    FSR fsr = 0;
1947436Sdam.sunwoo@arm.com    fsr.fsLow = bits(status, 3, 0);
1957436Sdam.sunwoo@arm.com    fsr.fsHigh = bits(status, 4);
1967436Sdam.sunwoo@arm.com    fsr.domain = domain;
1977436Sdam.sunwoo@arm.com    fsr.wnr = (write ? 1 : 0);
1987436Sdam.sunwoo@arm.com    fsr.ext = 0;
1997436Sdam.sunwoo@arm.com    tc->setMiscReg(T::FsrIndex, fsr);
2007436Sdam.sunwoo@arm.com    tc->setMiscReg(T::FarIndex, faultAddr);
2017436Sdam.sunwoo@arm.com}
2027436Sdam.sunwoo@arm.com
2037436Sdam.sunwoo@arm.comtemplate void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc);
20413393Sgiacomo.travaglini@arm.comtemplate void AbortFault<DataAbort>::invoke(ThreadContext *tc);
20513393Sgiacomo.travaglini@arm.com
20613393Sgiacomo.travaglini@arm.com// return via SUBS pc, lr, xxx; rfe, movs, ldm
20713393Sgiacomo.travaglini@arm.com
20813393Sgiacomo.travaglini@arm.com
20913393Sgiacomo.travaglini@arm.com
21013393Sgiacomo.travaglini@arm.com} // namespace ArmISA
21113393Sgiacomo.travaglini@arm.com
21213393Sgiacomo.travaglini@arm.com