faults.cc revision 11877
17405SAli.Saidi@ARM.com/* 212667Schuan.zhu@arm.com * Copyright (c) 2010, 2012-2014, 2016 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 * Giacomo Gabrielli 4412406Sgabeblack@google.com * Thomas Grocutt 4512605Sgiacomo.travaglini@arm.com */ 4611793Sbrandon.potter@amd.com 478887Sgeoffrey.blake@arm.com#include "arch/arm/faults.hh" 488232Snate@binkert.org 498232Snate@binkert.org#include "arch/arm/insts/static_inst.hh" 5010844Sandreas.sandberg@arm.com#include "arch/arm/system.hh" 5113531Sjairo.balart@metempsy.com#include "arch/arm/utility.hh" 5213531Sjairo.balart@metempsy.com#include "base/compiler.hh" 539384SAndreas.Sandberg@arm.com#include "base/trace.hh" 547678Sgblack@eecs.umich.edu#include "cpu/base.hh" 558059SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 568284SAli.Saidi@ARM.com#include "debug/Faults.hh" 577405SAli.Saidi@ARM.com#include "sim/full_system.hh" 587405SAli.Saidi@ARM.com 597405SAli.Saidi@ARM.comnamespace ArmISA 607405SAli.Saidi@ARM.com{ 619384SAndreas.Sandberg@arm.com 6210461SAndreas.Sandberg@ARM.comuint8_t ArmFault::shortDescFaultSources[] = { 6310461SAndreas.Sandberg@ARM.com 0x01, // AlignmentFault 6411165SRekai.GonzalezAlberquilla@arm.com 0x04, // InstructionCacheMaintenance 6512109SRekai.GonzalezAlberquilla@arm.com 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 6612714Sgiacomo.travaglini@arm.com 0x0c, // SynchExtAbtOnTranslTableWalkL1 6712714Sgiacomo.travaglini@arm.com 0x0e, // SynchExtAbtOnTranslTableWalkL2 689384SAndreas.Sandberg@arm.com 0xff, // SynchExtAbtOnTranslTableWalkL3 (INVALID) 6911770SCurtis.Dunham@arm.com 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 7010037SARM gem5 Developers 0x1c, // SynchPtyErrOnTranslTableWalkL1 7110461SAndreas.Sandberg@ARM.com 0x1e, // SynchPtyErrOnTranslTableWalkL2 7210461SAndreas.Sandberg@ARM.com 0xff, // SynchPtyErrOnTranslTableWalkL3 (INVALID) 7310461SAndreas.Sandberg@ARM.com 0xff, // TranslationL0 (INVALID) 7410461SAndreas.Sandberg@ARM.com 0x05, // TranslationL1 7510461SAndreas.Sandberg@ARM.com 0x07, // TranslationL2 7610461SAndreas.Sandberg@ARM.com 0xff, // TranslationL3 (INVALID) 7710609Sandreas.sandberg@arm.com 0xff, // AccessFlagL0 (INVALID) 7810609Sandreas.sandberg@arm.com 0x03, // AccessFlagL1 7910609Sandreas.sandberg@arm.com 0x06, // AccessFlagL2 8010037SARM gem5 Developers 0xff, // AccessFlagL3 (INVALID) 8110037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 8210037SARM gem5 Developers 0x09, // DomainL1 8310037SARM gem5 Developers 0x0b, // DomainL2 8411771SCurtis.Dunham@arm.com 0xff, // DomainL3 (INVALID) 8510037SARM gem5 Developers 0xff, // PermissionL0 (INVALID) 8610037SARM gem5 Developers 0x0d, // PermissionL1 8713173Sgiacomo.travaglini@arm.com 0x0f, // PermissionL2 8810037SARM gem5 Developers 0xff, // PermissionL3 (INVALID) 8910037SARM gem5 Developers 0x02, // DebugEvent 9013114Sgiacomo.travaglini@arm.com 0x08, // SynchronousExternalAbort 9110037SARM gem5 Developers 0x10, // TLBConflictAbort 9211771SCurtis.Dunham@arm.com 0x19, // SynchPtyErrOnMemoryAccess 9310037SARM gem5 Developers 0x16, // AsynchronousExternalAbort 9413499Sgiacomo.travaglini@arm.com 0x18, // AsynchPtyErrOnMemoryAccess 9510037SARM gem5 Developers 0xff, // AddressSizeL0 (INVALID) 9613114Sgiacomo.travaglini@arm.com 0xff, // AddressSizeL1 (INVALID) 9710037SARM gem5 Developers 0xff, // AddressSizeL2 (INVALID) 9810037SARM gem5 Developers 0xff, // AddressSizeL3 (INVALID) 9913531Sjairo.balart@metempsy.com 0x40, // PrefetchTLBMiss 10013531Sjairo.balart@metempsy.com 0x80 // PrefetchUncacheable 10113531Sjairo.balart@metempsy.com}; 10213531Sjairo.balart@metempsy.com 10313531Sjairo.balart@metempsy.comstatic_assert(sizeof(ArmFault::shortDescFaultSources) == 10413531Sjairo.balart@metempsy.com ArmFault::NumFaultSources, 10513531Sjairo.balart@metempsy.com "Invalid size of ArmFault::shortDescFaultSources[]"); 10612477SCurtis.Dunham@arm.com 10710037SARM gem5 Developersuint8_t ArmFault::longDescFaultSources[] = { 10810037SARM gem5 Developers 0x21, // AlignmentFault 1099384SAndreas.Sandberg@arm.com 0xff, // InstructionCacheMaintenance (INVALID) 1109384SAndreas.Sandberg@arm.com 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 1119384SAndreas.Sandberg@arm.com 0x15, // SynchExtAbtOnTranslTableWalkL1 11212479SCurtis.Dunham@arm.com 0x16, // SynchExtAbtOnTranslTableWalkL2 11312479SCurtis.Dunham@arm.com 0x17, // SynchExtAbtOnTranslTableWalkL3 1149384SAndreas.Sandberg@arm.com 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 1159384SAndreas.Sandberg@arm.com 0x1d, // SynchPtyErrOnTranslTableWalkL1 1169384SAndreas.Sandberg@arm.com 0x1e, // SynchPtyErrOnTranslTableWalkL2 1179384SAndreas.Sandberg@arm.com 0x1f, // SynchPtyErrOnTranslTableWalkL3 1189384SAndreas.Sandberg@arm.com 0xff, // TranslationL0 (INVALID) 1199384SAndreas.Sandberg@arm.com 0x05, // TranslationL1 1207427Sgblack@eecs.umich.edu 0x06, // TranslationL2 1217427Sgblack@eecs.umich.edu 0x07, // TranslationL3 1227427Sgblack@eecs.umich.edu 0xff, // AccessFlagL0 (INVALID) 1239385SAndreas.Sandberg@arm.com 0x09, // AccessFlagL1 1249385SAndreas.Sandberg@arm.com 0x0a, // AccessFlagL2 1257427Sgblack@eecs.umich.edu 0x0b, // AccessFlagL3 1267427Sgblack@eecs.umich.edu 0xff, // DomainL0 (INVALID) 12710037SARM gem5 Developers 0x3d, // DomainL1 12813114Sgiacomo.travaglini@arm.com 0x3e, // DomainL2 12910037SARM gem5 Developers 0xff, // DomainL3 (RESERVED) 13013114Sgiacomo.travaglini@arm.com 0xff, // PermissionL0 (INVALID) 13113114Sgiacomo.travaglini@arm.com 0x0d, // PermissionL1 13213114Sgiacomo.travaglini@arm.com 0x0e, // PermissionL2 13313114Sgiacomo.travaglini@arm.com 0x0f, // PermissionL3 13413114Sgiacomo.travaglini@arm.com 0x22, // DebugEvent 13512690Sgiacomo.travaglini@arm.com 0x10, // SynchronousExternalAbort 13610037SARM gem5 Developers 0x30, // TLBConflictAbort 1377427Sgblack@eecs.umich.edu 0x18, // SynchPtyErrOnMemoryAccess 1387427Sgblack@eecs.umich.edu 0x11, // AsynchronousExternalAbort 13910037SARM gem5 Developers 0x19, // AsynchPtyErrOnMemoryAccess 1407427Sgblack@eecs.umich.edu 0xff, // AddressSizeL0 (INVALID) 1417427Sgblack@eecs.umich.edu 0xff, // AddressSizeL1 (INVALID) 1427427Sgblack@eecs.umich.edu 0xff, // AddressSizeL2 (INVALID) 1437427Sgblack@eecs.umich.edu 0xff, // AddressSizeL3 (INVALID) 1447427Sgblack@eecs.umich.edu 0x40, // PrefetchTLBMiss 1457427Sgblack@eecs.umich.edu 0x80 // PrefetchUncacheable 1467427Sgblack@eecs.umich.edu}; 1477427Sgblack@eecs.umich.edu 1487427Sgblack@eecs.umich.edustatic_assert(sizeof(ArmFault::longDescFaultSources) == 1497427Sgblack@eecs.umich.edu ArmFault::NumFaultSources, 1507427Sgblack@eecs.umich.edu "Invalid size of ArmFault::longDescFaultSources[]"); 1517427Sgblack@eecs.umich.edu 1527427Sgblack@eecs.umich.eduuint8_t ArmFault::aarch64FaultSources[] = { 1537427Sgblack@eecs.umich.edu 0x21, // AlignmentFault 1547427Sgblack@eecs.umich.edu 0xff, // InstructionCacheMaintenance (INVALID) 1557427Sgblack@eecs.umich.edu 0x14, // SynchExtAbtOnTranslTableWalkL0 1567427Sgblack@eecs.umich.edu 0x15, // SynchExtAbtOnTranslTableWalkL1 1577427Sgblack@eecs.umich.edu 0x16, // SynchExtAbtOnTranslTableWalkL2 1587427Sgblack@eecs.umich.edu 0x17, // SynchExtAbtOnTranslTableWalkL3 1597427Sgblack@eecs.umich.edu 0x1c, // SynchPtyErrOnTranslTableWalkL0 1607427Sgblack@eecs.umich.edu 0x1d, // SynchPtyErrOnTranslTableWalkL1 1617427Sgblack@eecs.umich.edu 0x1e, // SynchPtyErrOnTranslTableWalkL2 1627427Sgblack@eecs.umich.edu 0x1f, // SynchPtyErrOnTranslTableWalkL3 1637436Sdam.sunwoo@arm.com 0x04, // TranslationL0 1647436Sdam.sunwoo@arm.com 0x05, // TranslationL1 16510037SARM gem5 Developers 0x06, // TranslationL2 16610037SARM gem5 Developers 0x07, // TranslationL3 1677436Sdam.sunwoo@arm.com 0x08, // AccessFlagL0 1687436Sdam.sunwoo@arm.com 0x09, // AccessFlagL1 1697436Sdam.sunwoo@arm.com 0x0a, // AccessFlagL2 1707436Sdam.sunwoo@arm.com 0x0b, // AccessFlagL3 1717436Sdam.sunwoo@arm.com // @todo: Section & Page Domain Fault in AArch64? 1727436Sdam.sunwoo@arm.com 0xff, // DomainL0 (INVALID) 1737436Sdam.sunwoo@arm.com 0xff, // DomainL1 (INVALID) 1747436Sdam.sunwoo@arm.com 0xff, // DomainL2 (INVALID) 1757436Sdam.sunwoo@arm.com 0xff, // DomainL3 (INVALID) 1767436Sdam.sunwoo@arm.com 0x0c, // PermissionL0 1777436Sdam.sunwoo@arm.com 0x0d, // PermissionL1 1787436Sdam.sunwoo@arm.com 0x0e, // PermissionL2 17913393Sgiacomo.travaglini@arm.com 0x0f, // PermissionL3 18010037SARM gem5 Developers 0xff, // DebugEvent (INVALID) 1817436Sdam.sunwoo@arm.com 0x10, // SynchronousExternalAbort 1827436Sdam.sunwoo@arm.com 0x30, // TLBConflictAbort 1837436Sdam.sunwoo@arm.com 0x18, // SynchPtyErrOnMemoryAccess 1847436Sdam.sunwoo@arm.com 0xff, // AsynchronousExternalAbort (INVALID) 1857436Sdam.sunwoo@arm.com 0xff, // AsynchPtyErrOnMemoryAccess (INVALID) 1867436Sdam.sunwoo@arm.com 0x00, // AddressSizeL0 1877436Sdam.sunwoo@arm.com 0x01, // AddressSizeL1 1887436Sdam.sunwoo@arm.com 0x02, // AddressSizeL2 1897436Sdam.sunwoo@arm.com 0x03, // AddressSizeL3 1907436Sdam.sunwoo@arm.com 0x40, // PrefetchTLBMiss 1917436Sdam.sunwoo@arm.com 0x80 // PrefetchUncacheable 1927436Sdam.sunwoo@arm.com}; 1937436Sdam.sunwoo@arm.com 1947436Sdam.sunwoo@arm.comstatic_assert(sizeof(ArmFault::aarch64FaultSources) == 1957436Sdam.sunwoo@arm.com ArmFault::NumFaultSources, 1967436Sdam.sunwoo@arm.com "Invalid size of ArmFault::aarch64FaultSources[]"); 19713393Sgiacomo.travaglini@arm.com 19813393Sgiacomo.travaglini@arm.com// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode, 19913393Sgiacomo.travaglini@arm.com// {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap, 20013393Sgiacomo.travaglini@arm.com// {A, F} disable, class, stat 20113393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = { 20213393Sgiacomo.travaglini@arm.com // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED 20313393Sgiacomo.travaglini@arm.com // location in AArch64) 20413393Sgiacomo.travaglini@arm.com "Reset", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 20513393Sgiacomo.travaglini@arm.com 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 20613393Sgiacomo.travaglini@arm.com}; 20713393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = { 20813393Sgiacomo.travaglini@arm.com "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED, 20913393Sgiacomo.travaglini@arm.com 4, 2, 0, 0, true, false, false, EC_UNKNOWN, FaultStat() 21013393Sgiacomo.travaglini@arm.com}; 21113393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = { 21213393Sgiacomo.travaglini@arm.com "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 21313396Sgiacomo.travaglini@arm.com 4, 2, 4, 2, true, false, false, EC_SVC_TO_HYP, FaultStat() 21413396Sgiacomo.travaglini@arm.com}; 21513396Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals = { 21613396Sgiacomo.travaglini@arm.com "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON, 21713393Sgiacomo.travaglini@arm.com 4, 4, 4, 4, false, true, true, EC_SMC_TO_HYP, FaultStat() 21813393Sgiacomo.travaglini@arm.com}; 21913393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals = { 22013393Sgiacomo.travaglini@arm.com "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 22113393Sgiacomo.travaglini@arm.com 4, 4, 4, 4, true, false, false, EC_HVC, FaultStat() 22213393Sgiacomo.travaglini@arm.com}; 22313393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = { 22413393Sgiacomo.travaglini@arm.com "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22513393Sgiacomo.travaglini@arm.com 4, 4, 0, 0, true, true, false, EC_PREFETCH_ABORT_TO_HYP, FaultStat() 22613393Sgiacomo.travaglini@arm.com}; 22713393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = { 22813393Sgiacomo.travaglini@arm.com "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22913393Sgiacomo.travaglini@arm.com 8, 8, 0, 0, true, true, false, EC_DATA_ABORT_TO_HYP, FaultStat() 23013393Sgiacomo.travaglini@arm.com}; 23113393Sgiacomo.travaglini@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals = { 23213393Sgiacomo.travaglini@arm.com "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 23313393Sgiacomo.travaglini@arm.com 8, 8, 0, 0, true, true, false, EC_INVALID, FaultStat() 23413393Sgiacomo.travaglini@arm.com}; 2357644Sali.saidi@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals = { 2368147SAli.Saidi@ARM.com // @todo: double check these values 2379385SAndreas.Sandberg@arm.com "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 2389385SAndreas.Sandberg@arm.com 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 23910037SARM gem5 Developers}; 24010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = { 24110037SARM gem5 Developers "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 24210037SARM gem5 Developers 4, 4, 0, 0, false, true, false, EC_UNKNOWN, FaultStat() 24310037SARM gem5 Developers}; 24410037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals = { 24510037SARM gem5 Developers "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 24610037SARM gem5 Developers 4, 4, 0, 0, false, true, false, EC_INVALID, FaultStat() 24710037SARM gem5 Developers}; 24810037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = { 24910037SARM gem5 Developers "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25010037SARM gem5 Developers 4, 4, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 25110037SARM gem5 Developers}; 25210037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals = { 25310037SARM gem5 Developers "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25410037SARM gem5 Developers 4, 4, 0, 0, false, true, true, EC_INVALID, FaultStat() 2558147SAli.Saidi@ARM.com}; 2567427Sgblack@eecs.umich.edutemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals = { 2577427Sgblack@eecs.umich.edu // Some dummy values (SupervisorTrap is AArch64-only) 2587427Sgblack@eecs.umich.edu "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 25910037SARM gem5 Developers 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 26010037SARM gem5 Developers}; 26110037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals = { 26210037SARM gem5 Developers // Some dummy values (SecureMonitorTrap is AArch64-only) 26313396Sgiacomo.travaglini@arm.com "Secure Monitor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_MON, 26410037SARM gem5 Developers 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 26510037SARM gem5 Developers}; 26610037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals = { 26710037SARM gem5 Developers // Some dummy values (PCAlignmentFault is AArch64-only) 26810037SARM gem5 Developers "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 26910037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_PC_ALIGNMENT, FaultStat() 27010037SARM gem5 Developers}; 27110037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals = { 27210037SARM gem5 Developers // Some dummy values (SPAlignmentFault is AArch64-only) 27310037SARM gem5 Developers "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 27410037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_STACK_PTR_ALIGNMENT, FaultStat() 27510037SARM gem5 Developers}; 27610037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals = { 27710037SARM gem5 Developers // Some dummy values (SError is AArch64-only) 27810037SARM gem5 Developers "SError", 0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC, 27910037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_SERROR, FaultStat() 28010037SARM gem5 Developers}; 28110037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = { 28210037SARM gem5 Developers // Some dummy values 28310037SARM gem5 Developers "Pipe Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 28410037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 28510037SARM gem5 Developers}; 28610037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = { 28710037SARM gem5 Developers // Some dummy values 28810037SARM gem5 Developers "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 28910037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 29010037SARM gem5 Developers}; 29110037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<IllegalInstSetStateFault>::vals = { 29210037SARM gem5 Developers // Some dummy values (SPAlignmentFault is AArch64-only) 29310037SARM gem5 Developers "Illegal Inst Set State Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 29410037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_ILLEGAL_INST, FaultStat() 29511770SCurtis.Dunham@arm.com}; 29610037SARM gem5 Developers 29711574SCurtis.Dunham@arm.comAddr 29811770SCurtis.Dunham@arm.comArmFault::getVector(ThreadContext *tc) 29911770SCurtis.Dunham@arm.com{ 30010037SARM gem5 Developers Addr base; 30111770SCurtis.Dunham@arm.com 30211770SCurtis.Dunham@arm.com // ARM ARM issue C B1.8.1 30310037SARM gem5 Developers bool haveSecurity = ArmSystem::haveSecurity(tc); 30410037SARM gem5 Developers 30510037SARM gem5 Developers // panic if SCTLR.VE because I have no idea what to do with vectored 30613114Sgiacomo.travaglini@arm.com // interrupts 30710037SARM gem5 Developers SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 30813114Sgiacomo.travaglini@arm.com assert(!sctlr.ve); 30913114Sgiacomo.travaglini@arm.com // Check for invalid modes 31013114Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 31113114Sgiacomo.travaglini@arm.com assert(haveSecurity || cpsr.mode != MODE_MON); 31213114Sgiacomo.travaglini@arm.com assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP); 31313114Sgiacomo.travaglini@arm.com 31413114Sgiacomo.travaglini@arm.com switch (cpsr.mode) 31513114Sgiacomo.travaglini@arm.com { 31613114Sgiacomo.travaglini@arm.com case MODE_MON: 31713114Sgiacomo.travaglini@arm.com base = tc->readMiscReg(MISCREG_MVBAR); 31813114Sgiacomo.travaglini@arm.com break; 31913114Sgiacomo.travaglini@arm.com case MODE_HYP: 32013114Sgiacomo.travaglini@arm.com base = tc->readMiscReg(MISCREG_HVBAR); 32113114Sgiacomo.travaglini@arm.com break; 32213114Sgiacomo.travaglini@arm.com default: 32313114Sgiacomo.travaglini@arm.com if (sctlr.v) { 32413114Sgiacomo.travaglini@arm.com base = HighVecs; 32513114Sgiacomo.travaglini@arm.com } else { 32613114Sgiacomo.travaglini@arm.com base = haveSecurity ? tc->readMiscReg(MISCREG_VBAR) : 0; 32713499Sgiacomo.travaglini@arm.com } 32813499Sgiacomo.travaglini@arm.com break; 32913499Sgiacomo.travaglini@arm.com } 33013499Sgiacomo.travaglini@arm.com return base + offset(tc); 33113114Sgiacomo.travaglini@arm.com} 33213114Sgiacomo.travaglini@arm.com 33313114Sgiacomo.travaglini@arm.comAddr 33413114Sgiacomo.travaglini@arm.comArmFault::getVector64(ThreadContext *tc) 33513114Sgiacomo.travaglini@arm.com{ 33610037SARM gem5 Developers Addr vbar; 33710037SARM gem5 Developers switch (toEL) { 33810037SARM gem5 Developers case EL3: 33910461SAndreas.Sandberg@ARM.com assert(ArmSystem::haveSecurity(tc)); 34010461SAndreas.Sandberg@ARM.com vbar = tc->readMiscReg(MISCREG_VBAR_EL3); 34110461SAndreas.Sandberg@ARM.com break; 34210461SAndreas.Sandberg@ARM.com case EL2: 34310037SARM gem5 Developers assert(ArmSystem::haveVirtualization(tc)); 34410037SARM gem5 Developers vbar = tc->readMiscReg(MISCREG_VBAR_EL2); 34510037SARM gem5 Developers break; 34610037SARM gem5 Developers case EL1: 34710037SARM gem5 Developers vbar = tc->readMiscReg(MISCREG_VBAR_EL1); 34813116Sgiacomo.travaglini@arm.com break; 34910037SARM gem5 Developers default: 35010461SAndreas.Sandberg@ARM.com panic("Invalid target exception level"); 35110461SAndreas.Sandberg@ARM.com break; 35210461SAndreas.Sandberg@ARM.com } 35310461SAndreas.Sandberg@ARM.com return vbar + offset64(); 35410461SAndreas.Sandberg@ARM.com} 35510037SARM gem5 Developers 35610037SARM gem5 DevelopersMiscRegIndex 35710037SARM gem5 DevelopersArmFault::getSyndromeReg64() const 35810037SARM gem5 Developers{ 35910037SARM gem5 Developers switch (toEL) { 36011574SCurtis.Dunham@arm.com case EL1: 36110037SARM gem5 Developers return MISCREG_ESR_EL1; 36210037SARM gem5 Developers case EL2: 36310037SARM gem5 Developers return MISCREG_ESR_EL2; 36411574SCurtis.Dunham@arm.com case EL3: 36510037SARM gem5 Developers return MISCREG_ESR_EL3; 36610037SARM gem5 Developers default: 36710037SARM gem5 Developers panic("Invalid exception level"); 36810037SARM gem5 Developers break; 36910037SARM gem5 Developers } 37010037SARM gem5 Developers} 37110037SARM gem5 Developers 37213114Sgiacomo.travaglini@arm.comMiscRegIndex 37313173Sgiacomo.travaglini@arm.comArmFault::getFaultAddrReg64() const 37413173Sgiacomo.travaglini@arm.com{ 37513173Sgiacomo.travaglini@arm.com switch (toEL) { 37613173Sgiacomo.travaglini@arm.com case EL1: 37710037SARM gem5 Developers return MISCREG_FAR_EL1; 37810037SARM gem5 Developers case EL2: 37912972Sandreas.sandberg@arm.com return MISCREG_FAR_EL2; 38012972Sandreas.sandberg@arm.com case EL3: 38112972Sandreas.sandberg@arm.com return MISCREG_FAR_EL3; 38212972Sandreas.sandberg@arm.com default: 38312972Sandreas.sandberg@arm.com panic("Invalid exception level"); 38413531Sjairo.balart@metempsy.com break; 38513531Sjairo.balart@metempsy.com } 38613531Sjairo.balart@metempsy.com} 38713531Sjairo.balart@metempsy.com 38813531Sjairo.balart@metempsy.comvoid 38913531Sjairo.balart@metempsy.comArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) 39013531Sjairo.balart@metempsy.com{ 39112972Sandreas.sandberg@arm.com uint32_t value; 39212972Sandreas.sandberg@arm.com uint32_t exc_class = (uint32_t) ec(tc); 39312972Sandreas.sandberg@arm.com uint32_t issVal = iss(); 39413581Sgabeblack@google.com assert(!from64 || ArmSystem::highestELIs64(tc)); 39510035Sandreas.hansson@arm.com 3967405SAli.Saidi@ARM.com value = exc_class << 26; 3977405SAli.Saidi@ARM.com 3987614Sminkyu.jeong@arm.com // HSR.IL not valid for Prefetch Aborts (0x20, 0x21) and Data Aborts (0x24, 39912478SCurtis.Dunham@arm.com // 0x25) for which the ISS information is not valid (ARMv7). 40012478SCurtis.Dunham@arm.com // @todo: ARMv8 revises AArch32 functionality: when HSR.IL is not 40112478SCurtis.Dunham@arm.com // valid it is treated as RES1. 40212478SCurtis.Dunham@arm.com if (to64) { 40312478SCurtis.Dunham@arm.com value |= 1 << 25; 40412478SCurtis.Dunham@arm.com } else if ((bits(exc_class, 5, 3) != 4) || 40512478SCurtis.Dunham@arm.com (bits(exc_class, 2) && bits(issVal, 24))) { 40612478SCurtis.Dunham@arm.com if (!machInst.thumb || machInst.bigThumb) 40712478SCurtis.Dunham@arm.com value |= 1 << 25; 40812478SCurtis.Dunham@arm.com } 40912478SCurtis.Dunham@arm.com // Condition code valid for EC[5:4] nonzero 41012478SCurtis.Dunham@arm.com if (!from64 && ((bits(exc_class, 5, 4) == 0) && 41112478SCurtis.Dunham@arm.com (bits(exc_class, 3, 0) != 0))) { 41212478SCurtis.Dunham@arm.com if (!machInst.thumb) { 41312478SCurtis.Dunham@arm.com uint32_t cond; 41412478SCurtis.Dunham@arm.com ConditionCode condCode = (ConditionCode) (uint32_t) machInst.condCode; 4157405SAli.Saidi@ARM.com // If its on unconditional instruction report with a cond code of 4167405SAli.Saidi@ARM.com // 0xE, ie the unconditional code 4177405SAli.Saidi@ARM.com cond = (condCode == COND_UC) ? COND_AL : condCode; 41813581Sgabeblack@google.com value |= cond << 20; 4197405SAli.Saidi@ARM.com value |= 1 << 24; 4207405SAli.Saidi@ARM.com } 42110037SARM gem5 Developers value |= bits(issVal, 19, 0); 42210037SARM gem5 Developers } else { 42310037SARM gem5 Developers value |= issVal; 4249050Schander.sudanthi@arm.com } 4257405SAli.Saidi@ARM.com tc->setMiscReg(syndrome_reg, value); 42610037SARM gem5 Developers} 42710037SARM gem5 Developers 4287720Sgblack@eecs.umich.eduvoid 4297720Sgblack@eecs.umich.eduArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 4307405SAli.Saidi@ARM.com{ 4317405SAli.Saidi@ARM.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 4327757SAli.Saidi@ARM.com 43310037SARM gem5 Developers if (ArmSystem::highestELIs64(tc)) { // ARMv8 43410037SARM gem5 Developers // Determine source exception level and mode 43510037SARM gem5 Developers fromMode = (OperatingMode) (uint8_t) cpsr.mode; 43610037SARM gem5 Developers fromEL = opModeToEL(fromMode); 43710037SARM gem5 Developers if (opModeIs64(fromMode)) 43810037SARM gem5 Developers from64 = true; 43910037SARM gem5 Developers 44010037SARM gem5 Developers // Determine target exception level 44110037SARM gem5 Developers if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) 44210037SARM gem5 Developers toEL = EL3; 44310037SARM gem5 Developers else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) 44410037SARM gem5 Developers toEL = EL2; 44510037SARM gem5 Developers else 44610037SARM gem5 Developers toEL = opModeToEL(nextMode()); 44710037SARM gem5 Developers if (fromEL > toEL) 44810037SARM gem5 Developers toEL = fromEL; 44910037SARM gem5 Developers 45010037SARM gem5 Developers if (toEL == ArmSystem::highestEL(tc) || ELIs64(tc, toEL)) { 45110037SARM gem5 Developers // Invoke exception handler in AArch64 state 45210037SARM gem5 Developers to64 = true; 45310037SARM gem5 Developers invoke64(tc, inst); 45410037SARM gem5 Developers return; 45510037SARM gem5 Developers } 45610037SARM gem5 Developers } 45710037SARM gem5 Developers 45810037SARM gem5 Developers // ARMv7 (ARM ARM issue C B1.9) 45910037SARM gem5 Developers 46010037SARM gem5 Developers bool have_security = ArmSystem::haveSecurity(tc); 46110037SARM gem5 Developers bool have_virtualization = ArmSystem::haveVirtualization(tc); 46210037SARM gem5 Developers 46310037SARM gem5 Developers FaultBase::invoke(tc); 46410037SARM gem5 Developers if (!FullSystem) 46510037SARM gem5 Developers return; 46612667Schuan.zhu@arm.com countStat()++; 46710037SARM gem5 Developers 46810037SARM gem5 Developers SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 46910037SARM gem5 Developers SCR scr = tc->readMiscReg(MISCREG_SCR); 47010037SARM gem5 Developers CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR); 47110037SARM gem5 Developers saved_cpsr.nz = tc->readCCReg(CCREG_NZ); 47210037SARM gem5 Developers saved_cpsr.c = tc->readCCReg(CCREG_C); 47313581Sgabeblack@google.com saved_cpsr.v = tc->readCCReg(CCREG_V); 47410037SARM gem5 Developers saved_cpsr.ge = tc->readCCReg(CCREG_GE); 47510037SARM gem5 Developers 47610037SARM gem5 Developers Addr curPc M5_VAR_USED = tc->pcState().pc(); 47710037SARM gem5 Developers ITSTATE it = tc->pcState().itstate(); 47810037SARM gem5 Developers saved_cpsr.it2 = it.top6; 4798284SAli.Saidi@ARM.com saved_cpsr.it1 = it.bottom2; 48010037SARM gem5 Developers 48113550Sgiacomo.travaglini@arm.com // if we have a valid instruction then use it to annotate this fault with 48210037SARM gem5 Developers // extra information. This is used to generate the correct fault syndrome 48313550Sgiacomo.travaglini@arm.com // information 48410037SARM gem5 Developers if (inst) { 48510037SARM gem5 Developers ArmStaticInst *armInst = reinterpret_cast<ArmStaticInst *>(inst.get()); 48610037SARM gem5 Developers armInst->annotateFault(this); 48710037SARM gem5 Developers } 48810037SARM gem5 Developers 48910037SARM gem5 Developers if (have_security && routeToMonitor(tc)) 49010037SARM gem5 Developers cpsr.mode = MODE_MON; 49110037SARM gem5 Developers else if (have_virtualization && routeToHyp(tc)) 49210037SARM gem5 Developers cpsr.mode = MODE_HYP; 49310037SARM gem5 Developers else 49410037SARM gem5 Developers cpsr.mode = nextMode(); 4959050Schander.sudanthi@arm.com 4968284SAli.Saidi@ARM.com // Ensure Secure state if initially in Monitor mode 49710037SARM gem5 Developers if (have_security && saved_cpsr.mode == MODE_MON) { 49810037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 49910037SARM gem5 Developers if (scr.ns) { 50010037SARM gem5 Developers scr.ns = 0; 50110037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_SCR, scr); 50210037SARM gem5 Developers } 50310037SARM gem5 Developers } 5047405SAli.Saidi@ARM.com 5057731SAli.Saidi@ARM.com // some bits are set differently if we have been routed to hyp mode 5068468Swade.walker@arm.com if (cpsr.mode == MODE_HYP) { 5078468Swade.walker@arm.com SCTLR hsctlr = tc->readMiscReg(MISCREG_HSCTLR); 5088468Swade.walker@arm.com cpsr.t = hsctlr.te; 5097405SAli.Saidi@ARM.com cpsr.e = hsctlr.ee; 5107731SAli.Saidi@ARM.com if (!scr.ea) {cpsr.a = 1;} 5117405SAli.Saidi@ARM.com if (!scr.fiq) {cpsr.f = 1;} 5127405SAli.Saidi@ARM.com if (!scr.irq) {cpsr.i = 1;} 51311809Sbaz21@cam.ac.uk } else if (cpsr.mode == MODE_MON) { 51411809Sbaz21@cam.ac.uk // Special case handling when entering monitor mode 5159130Satgutier@umich.edu cpsr.t = sctlr.te; 5169130Satgutier@umich.edu cpsr.e = sctlr.ee; 5179130Satgutier@umich.edu cpsr.a = 1; 5189130Satgutier@umich.edu cpsr.f = 1; 5199814Sandreas.hansson@arm.com cpsr.i = 1; 5209130Satgutier@umich.edu } else { 5219130Satgutier@umich.edu cpsr.t = sctlr.te; 5229130Satgutier@umich.edu cpsr.e = sctlr.ee; 5239130Satgutier@umich.edu 5249130Satgutier@umich.edu // The *Disable functions are virtual and different per fault 5259130Satgutier@umich.edu cpsr.a = cpsr.a | abortDisable(tc); 5269130Satgutier@umich.edu cpsr.f = cpsr.f | fiqDisable(tc); 5279130Satgutier@umich.edu cpsr.i = 1; 5289130Satgutier@umich.edu } 5299130Satgutier@umich.edu cpsr.it1 = cpsr.it2 = 0; 5309130Satgutier@umich.edu cpsr.j = 0; 5319130Satgutier@umich.edu tc->setMiscReg(MISCREG_CPSR, cpsr); 5329130Satgutier@umich.edu 5339130Satgutier@umich.edu // Make sure mailbox sets to one always 5349130Satgutier@umich.edu tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 5359130Satgutier@umich.edu 5369130Satgutier@umich.edu // Clear the exclusive monitor 5379130Satgutier@umich.edu tc->setMiscReg(MISCREG_LOCKFLAG, 0); 5389130Satgutier@umich.edu 5399130Satgutier@umich.edu if (cpsr.mode == MODE_HYP) { 5409130Satgutier@umich.edu tc->setMiscReg(MISCREG_ELR_HYP, curPc + 5419130Satgutier@umich.edu (saved_cpsr.t ? thumbPcOffset(true) : armPcOffset(true))); 5427583SAli.Saidi@arm.com } else { 5437583SAli.Saidi@arm.com tc->setIntReg(INTREG_LR, curPc + 5447583SAli.Saidi@arm.com (saved_cpsr.t ? thumbPcOffset(false) : armPcOffset(false))); 54510461SAndreas.Sandberg@ARM.com } 54610461SAndreas.Sandberg@ARM.com 54710461SAndreas.Sandberg@ARM.com switch (cpsr.mode) { 54810461SAndreas.Sandberg@ARM.com case MODE_FIQ: 54910461SAndreas.Sandberg@ARM.com tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 55010461SAndreas.Sandberg@ARM.com break; 55110461SAndreas.Sandberg@ARM.com case MODE_IRQ: 5528302SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 5538302SAli.Saidi@ARM.com break; 5547783SGiacomo.Gabrielli@arm.com case MODE_SVC: 5557783SGiacomo.Gabrielli@arm.com tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 5567783SGiacomo.Gabrielli@arm.com break; 5577783SGiacomo.Gabrielli@arm.com case MODE_MON: 55810037SARM gem5 Developers assert(have_security); 55910037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_MON, saved_cpsr); 56010037SARM gem5 Developers break; 56110037SARM gem5 Developers case MODE_ABORT: 56210037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 56310037SARM gem5 Developers break; 56410037SARM gem5 Developers case MODE_UNDEFINED: 56510037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 56610037SARM gem5 Developers if (ec(tc) != EC_UNKNOWN) 56710037SARM gem5 Developers setSyndrome(tc, MISCREG_HSR); 56810037SARM gem5 Developers break; 56910037SARM gem5 Developers case MODE_HYP: 57010037SARM gem5 Developers assert(have_virtualization); 57110037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr); 57210037SARM gem5 Developers setSyndrome(tc, MISCREG_HSR); 57310037SARM gem5 Developers break; 57410037SARM gem5 Developers default: 57510037SARM gem5 Developers panic("unknown Mode\n"); 57610037SARM gem5 Developers } 57710037SARM gem5 Developers 57810037SARM gem5 Developers Addr newPc = getVector(tc); 57910037SARM gem5 Developers DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n", 58010037SARM gem5 Developers name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc); 58110037SARM gem5 Developers PCState pc(newPc); 58210037SARM gem5 Developers pc.thumb(cpsr.t); 58310037SARM gem5 Developers pc.nextThumb(pc.thumb()); 58410037SARM gem5 Developers pc.jazelle(cpsr.j); 58510037SARM gem5 Developers pc.nextJazelle(pc.jazelle()); 58610037SARM gem5 Developers pc.aarch64(!cpsr.width); 58710037SARM gem5 Developers pc.nextAArch64(!cpsr.width); 58810037SARM gem5 Developers tc->pcState(pc); 58910037SARM gem5 Developers} 59010338SCurtis.Dunham@arm.com 59110338SCurtis.Dunham@arm.comvoid 59210338SCurtis.Dunham@arm.comArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst) 59310037SARM gem5 Developers{ 59410037SARM gem5 Developers // Determine actual misc. register indices for ELR_ELx and SPSR_ELx 59510037SARM gem5 Developers MiscRegIndex elr_idx, spsr_idx; 59610037SARM gem5 Developers switch (toEL) { 59710037SARM gem5 Developers case EL1: 59810037SARM gem5 Developers elr_idx = MISCREG_ELR_EL1; 59910037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL1; 60010037SARM gem5 Developers break; 60110037SARM gem5 Developers case EL2: 60210037SARM gem5 Developers assert(ArmSystem::haveVirtualization(tc)); 60310037SARM gem5 Developers elr_idx = MISCREG_ELR_EL2; 60410037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL2; 60510037SARM gem5 Developers break; 60610037SARM gem5 Developers case EL3: 60710037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 60810037SARM gem5 Developers elr_idx = MISCREG_ELR_EL3; 60910037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL3; 61010037SARM gem5 Developers break; 61110037SARM gem5 Developers default: 61210037SARM gem5 Developers panic("Invalid target exception level"); 61310037SARM gem5 Developers break; 61410037SARM gem5 Developers } 61510037SARM gem5 Developers 61610037SARM gem5 Developers // Save process state into SPSR_ELx 61710037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 61810037SARM gem5 Developers CPSR spsr = cpsr; 61910037SARM gem5 Developers spsr.nz = tc->readCCReg(CCREG_NZ); 62010037SARM gem5 Developers spsr.c = tc->readCCReg(CCREG_C); 6218549Sdaniel.johnson@arm.com spsr.v = tc->readCCReg(CCREG_V); 6228868SMatt.Horsnell@arm.com if (from64) { 6238868SMatt.Horsnell@arm.com // Force some bitfields to 0 6248868SMatt.Horsnell@arm.com spsr.q = 0; 6258868SMatt.Horsnell@arm.com spsr.it1 = 0; 6268868SMatt.Horsnell@arm.com spsr.j = 0; 6278868SMatt.Horsnell@arm.com spsr.res0_23_22 = 0; 6288868SMatt.Horsnell@arm.com spsr.ge = 0; 6298868SMatt.Horsnell@arm.com spsr.it2 = 0; 6308868SMatt.Horsnell@arm.com spsr.t = 0; 63110461SAndreas.Sandberg@ARM.com } else { 6328868SMatt.Horsnell@arm.com spsr.ge = tc->readCCReg(CCREG_GE); 63310461SAndreas.Sandberg@ARM.com ITSTATE it = tc->pcState().itstate(); 63410037SARM gem5 Developers spsr.it2 = it.top6; 6358868SMatt.Horsnell@arm.com spsr.it1 = it.bottom2; 63610037SARM gem5 Developers // Force some bitfields to 0 63711150Smitch.hayenga@arm.com spsr.res0_23_22 = 0; 63810037SARM gem5 Developers spsr.ss = 0; 63910037SARM gem5 Developers } 64010037SARM gem5 Developers tc->setMiscReg(spsr_idx, spsr); 64110037SARM gem5 Developers 64211150Smitch.hayenga@arm.com // Save preferred return address into ELR_ELx 64310037SARM gem5 Developers Addr curr_pc = tc->pcState().pc(); 64410037SARM gem5 Developers Addr ret_addr = curr_pc; 64510037SARM gem5 Developers if (from64) 64610037SARM gem5 Developers ret_addr += armPcElrOffset(); 64710037SARM gem5 Developers else 64810037SARM gem5 Developers ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset(); 64910037SARM gem5 Developers tc->setMiscReg(elr_idx, ret_addr); 65013581Sgabeblack@google.com 65110037SARM gem5 Developers // Update process state 65210037SARM gem5 Developers OperatingMode64 mode = 0; 65310037SARM gem5 Developers mode.spX = 1; 65410037SARM gem5 Developers mode.el = toEL; 65510037SARM gem5 Developers mode.width = 0; 65610037SARM gem5 Developers cpsr.mode = mode; 65710037SARM gem5 Developers cpsr.daif = 0xf; 65810037SARM gem5 Developers cpsr.il = 0; 65913581Sgabeblack@google.com cpsr.ss = 0; 66010037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 66110037SARM gem5 Developers 66210037SARM gem5 Developers // Set PC to start of exception handler 66310037SARM gem5 Developers Addr new_pc = purifyTaggedAddr(getVector64(tc), tc, toEL); 66410037SARM gem5 Developers DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x " 66510037SARM gem5 Developers "elr:%#x newVec: %#x\n", name(), cpsr, curr_pc, ret_addr, new_pc); 66610037SARM gem5 Developers PCState pc(new_pc); 66710037SARM gem5 Developers pc.aarch64(!cpsr.width); 66810037SARM gem5 Developers pc.nextAArch64(!cpsr.width); 66910037SARM gem5 Developers tc->pcState(pc); 67010844Sandreas.sandberg@arm.com 67111772SCurtis.Dunham@arm.com // If we have a valid instruction then use it to annotate this fault with 67211772SCurtis.Dunham@arm.com // extra information. This is used to generate the correct fault syndrome 67311772SCurtis.Dunham@arm.com // information 67411772SCurtis.Dunham@arm.com if (inst) 67511774SCurtis.Dunham@arm.com reinterpret_cast<ArmStaticInst *>(inst.get())->annotateFault(this); 67611774SCurtis.Dunham@arm.com // Save exception syndrome 67711774SCurtis.Dunham@arm.com if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ)) 67811774SCurtis.Dunham@arm.com setSyndrome(tc, getSyndromeReg64()); 67911774SCurtis.Dunham@arm.com} 68011774SCurtis.Dunham@arm.com 68111774SCurtis.Dunham@arm.comvoid 68211773SCurtis.Dunham@arm.comReset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 68313531Sjairo.balart@metempsy.com{ 68413531Sjairo.balart@metempsy.com if (FullSystem) { 68513531Sjairo.balart@metempsy.com tc->getCpuPtr()->clearInterrupts(tc->threadId()); 68613531Sjairo.balart@metempsy.com tc->clearArchRegs(); 68713531Sjairo.balart@metempsy.com } 68811773SCurtis.Dunham@arm.com if (!ArmSystem::highestELIs64(tc)) { 68911773SCurtis.Dunham@arm.com ArmFault::invoke(tc, inst); 69011772SCurtis.Dunham@arm.com tc->setMiscReg(MISCREG_VMPIDR, 69110037SARM gem5 Developers getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc)); 69212816Sgiacomo.travaglini@arm.com 69312816Sgiacomo.travaglini@arm.com // Unless we have SMC code to get us there, boot in HYP! 69412816Sgiacomo.travaglini@arm.com if (ArmSystem::haveVirtualization(tc) && 69510844Sandreas.sandberg@arm.com !ArmSystem::haveSecurity(tc)) { 69610844Sandreas.sandberg@arm.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 69710844Sandreas.sandberg@arm.com cpsr.mode = MODE_HYP; 69810844Sandreas.sandberg@arm.com tc->setMiscReg(MISCREG_CPSR, cpsr); 69910844Sandreas.sandberg@arm.com } 70010844Sandreas.sandberg@arm.com } else { 70113531Sjairo.balart@metempsy.com // Advance the PC to the IMPLEMENTATION DEFINED reset value 70213531Sjairo.balart@metempsy.com PCState pc = ArmSystem::resetAddr64(tc); 70313531Sjairo.balart@metempsy.com pc.aarch64(true); 70413531Sjairo.balart@metempsy.com pc.nextAArch64(true); 70510188Sgeoffrey.blake@arm.com tc->pcState(pc); 70610037SARM gem5 Developers } 70710037SARM gem5 Developers} 7087405SAli.Saidi@ARM.com 7097405SAli.Saidi@ARM.comvoid 7107405SAli.Saidi@ARM.comUndefinedInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst) 7117405SAli.Saidi@ARM.com{ 7127405SAli.Saidi@ARM.com if (FullSystem) { 71313582Sgabeblack@google.com ArmFault::invoke(tc, inst); 7147405SAli.Saidi@ARM.com return; 7157405SAli.Saidi@ARM.com } 7167614Sminkyu.jeong@arm.com 71712478SCurtis.Dunham@arm.com // If the mnemonic isn't defined this has to be an unknown instruction. 71812478SCurtis.Dunham@arm.com assert(unknown || mnemonic != NULL); 71912478SCurtis.Dunham@arm.com if (disabled) { 72012478SCurtis.Dunham@arm.com panic("Attempted to execute disabled instruction " 72112478SCurtis.Dunham@arm.com "'%s' (inst 0x%08x)", mnemonic, machInst); 72211771SCurtis.Dunham@arm.com } else if (unknown) { 72312478SCurtis.Dunham@arm.com panic("Attempted to execute unknown instruction (inst 0x%08x)", 72412478SCurtis.Dunham@arm.com machInst); 72510037SARM gem5 Developers } else { 72612478SCurtis.Dunham@arm.com panic("Attempted to execute unimplemented instruction " 72710037SARM gem5 Developers "'%s' (inst 0x%08x)", mnemonic, machInst); 72812478SCurtis.Dunham@arm.com } 72910037SARM gem5 Developers} 73012478SCurtis.Dunham@arm.com 73110037SARM gem5 Developersbool 7327405SAli.Saidi@ARM.comUndefinedInstruction::routeToHyp(ThreadContext *tc) const 7337405SAli.Saidi@ARM.com{ 7347405SAli.Saidi@ARM.com bool toHyp; 73513582Sgabeblack@google.com 7367405SAli.Saidi@ARM.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 7377749SAli.Saidi@ARM.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 73813581Sgabeblack@google.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 73910037SARM gem5 Developers 74010037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 7418284SAli.Saidi@ARM.com toHyp = scr.ns && (cpsr.mode == MODE_HYP); 7427405SAli.Saidi@ARM.com // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 7437405SAli.Saidi@ARM.com toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 7447749SAli.Saidi@ARM.com return toHyp; 7457749SAli.Saidi@ARM.com} 7467749SAli.Saidi@ARM.com 7477749SAli.Saidi@ARM.comuint32_t 7487405SAli.Saidi@ARM.comUndefinedInstruction::iss() const 74912510Sgiacomo.travaglini@arm.com{ 75012406Sgabeblack@google.com if (overrideEc == EC_INVALID) 75112406Sgabeblack@google.com return issRaw; 7527749SAli.Saidi@ARM.com 7537749SAli.Saidi@ARM.com uint32_t new_iss = 0; 7547614Sminkyu.jeong@arm.com uint32_t op0, op1, op2, CRn, CRm, Rt, dir; 7557614Sminkyu.jeong@arm.com 7567720Sgblack@eecs.umich.edu dir = bits(machInst, 21, 21); 7577720Sgblack@eecs.umich.edu op0 = bits(machInst, 20, 19); 7587720Sgblack@eecs.umich.edu op1 = bits(machInst, 18, 16); 75912763Sgiacomo.travaglini@arm.com CRn = bits(machInst, 15, 12); 7608887Sgeoffrey.blake@arm.com CRm = bits(machInst, 11, 8); 7618887Sgeoffrey.blake@arm.com op2 = bits(machInst, 7, 5); 7628887Sgeoffrey.blake@arm.com Rt = bits(machInst, 4, 0); 7638887Sgeoffrey.blake@arm.com 7648887Sgeoffrey.blake@arm.com new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 | 7658887Sgeoffrey.blake@arm.com Rt << 5 | CRm << 1 | dir; 7668887Sgeoffrey.blake@arm.com 7678887Sgeoffrey.blake@arm.com return new_iss; 7688887Sgeoffrey.blake@arm.com} 7697408Sgblack@eecs.umich.edu 77010037SARM gem5 Developersvoid 77110037SARM gem5 DevelopersSupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 77210037SARM gem5 Developers{ 77310037SARM gem5 Developers if (FullSystem) { 77410037SARM gem5 Developers ArmFault::invoke(tc, inst); 77510037SARM gem5 Developers return; 77610037SARM gem5 Developers } 77710037SARM gem5 Developers 77810037SARM gem5 Developers // As of now, there isn't a 32 bit thumb version of this instruction. 77910037SARM gem5 Developers assert(!machInst.bigThumb); 78010037SARM gem5 Developers uint32_t callNum; 7817408Sgblack@eecs.umich.edu CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 7827408Sgblack@eecs.umich.edu OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode; 7838206SWilliam.Wang@arm.com if (opModeIs64(mode)) 7848206SWilliam.Wang@arm.com callNum = tc->readIntReg(INTREG_X8); 7858206SWilliam.Wang@arm.com else 7868206SWilliam.Wang@arm.com callNum = tc->readIntReg(INTREG_R7); 7878206SWilliam.Wang@arm.com Fault fault; 7888206SWilliam.Wang@arm.com tc->syscall(callNum, &fault); 7898206SWilliam.Wang@arm.com 7908206SWilliam.Wang@arm.com // Advance the PC since that won't happen automatically. 79110037SARM gem5 Developers PCState pc = tc->pcState(); 79210037SARM gem5 Developers assert(inst); 79310037SARM gem5 Developers inst->advancePC(pc); 79410037SARM gem5 Developers tc->pcState(pc); 79510037SARM gem5 Developers} 79612667Schuan.zhu@arm.com 79710037SARM gem5 Developersbool 79810037SARM gem5 DevelopersSupervisorCall::routeToHyp(ThreadContext *tc) const 79910037SARM gem5 Developers{ 80010037SARM gem5 Developers bool toHyp; 80110037SARM gem5 Developers 80210037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 80310037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 80413581Sgabeblack@google.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 8058206SWilliam.Wang@arm.com 80610037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 80710037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 80810037SARM gem5 Developers // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 80910037SARM gem5 Developers toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 81010037SARM gem5 Developers return toHyp; 81110037SARM gem5 Developers} 81210037SARM gem5 Developers 81310037SARM gem5 DevelopersExceptionClass 81410037SARM gem5 DevelopersSupervisorCall::ec(ThreadContext *tc) const 81510037SARM gem5 Developers{ 81610037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : 81710037SARM gem5 Developers (from64 ? EC_SVC_64 : vals.ec); 81810037SARM gem5 Developers} 81910037SARM gem5 Developers 82010037SARM gem5 Developersuint32_t 82110037SARM gem5 DevelopersSupervisorCall::iss() const 82210037SARM gem5 Developers{ 82310037SARM gem5 Developers // Even if we have a 24 bit imm from an arm32 instruction then we only use 82410037SARM gem5 Developers // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC). 82510037SARM gem5 Developers return issRaw & 0xFFFF; 82610037SARM gem5 Developers} 82710037SARM gem5 Developers 82810037SARM gem5 Developersuint32_t 82910037SARM gem5 DevelopersSecureMonitorCall::iss() const 83010037SARM gem5 Developers{ 83110037SARM gem5 Developers if (from64) 83210037SARM gem5 Developers return bits(machInst, 20, 5); 83310037SARM gem5 Developers return 0; 83410037SARM gem5 Developers} 8358206SWilliam.Wang@arm.com 8368206SWilliam.Wang@arm.comExceptionClass 8377408Sgblack@eecs.umich.eduUndefinedInstruction::ec(ThreadContext *tc) const 8387408Sgblack@eecs.umich.edu{ 8397408Sgblack@eecs.umich.edu return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 8407731SAli.Saidi@ARM.com} 8418206SWilliam.Wang@arm.com 84210037SARM gem5 Developers 84310037SARM gem5 DevelopersHypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) : 84410037SARM gem5 Developers ArmFaultVals<HypervisorCall>(_machInst, _imm) 84510037SARM gem5 Developers{} 84610037SARM gem5 Developers 8477408Sgblack@eecs.umich.eduExceptionClass 8487408Sgblack@eecs.umich.eduHypervisorCall::ec(ThreadContext *tc) const 8497408Sgblack@eecs.umich.edu{ 8507408Sgblack@eecs.umich.edu return from64 ? EC_HVC_64 : vals.ec; 8517408Sgblack@eecs.umich.edu} 8527408Sgblack@eecs.umich.edu 8537408Sgblack@eecs.umich.eduExceptionClass 8547408Sgblack@eecs.umich.eduHypervisorTrap::ec(ThreadContext *tc) const 8557408Sgblack@eecs.umich.edu{ 8567408Sgblack@eecs.umich.edu return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 85710037SARM gem5 Developers} 85810037SARM gem5 Developers 85910037SARM gem5 Developerstemplate<class T> 86010037SARM gem5 DevelopersFaultOffset 86110037SARM gem5 DevelopersArmFaultVals<T>::offset(ThreadContext *tc) 86210037SARM gem5 Developers{ 8637408Sgblack@eecs.umich.edu bool isHypTrap = false; 8647408Sgblack@eecs.umich.edu 8657408Sgblack@eecs.umich.edu // Normally we just use the exception vector from the table at the top if 8667408Sgblack@eecs.umich.edu // this file, however if this exception has caused a transition to hype 8677408Sgblack@eecs.umich.edu // mode, and its an exception type that would only do this if it has been 8687408Sgblack@eecs.umich.edu // trapped then we use the hyp trap vector instead of the normal vector 8697408Sgblack@eecs.umich.edu if (vals.hypTrappable) { 8707408Sgblack@eecs.umich.edu CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 8717408Sgblack@eecs.umich.edu if (cpsr.mode == MODE_HYP) { 8727408Sgblack@eecs.umich.edu CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 8737408Sgblack@eecs.umich.edu isHypTrap = spsr.mode != MODE_HYP; 8747408Sgblack@eecs.umich.edu } 87510037SARM gem5 Developers } 87610037SARM gem5 Developers return isHypTrap ? 0x14 : vals.offset; 8779377Sgblack@eecs.umich.edu} 8787408Sgblack@eecs.umich.edu 8797408Sgblack@eecs.umich.edu// void 88010037SARM gem5 Developers// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx) 88110037SARM gem5 Developers// { 88210037SARM gem5 Developers// ESR esr = 0; 88310037SARM gem5 Developers// esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32; 88410037SARM gem5 Developers// esr.il = !machInst.thumb; 88510037SARM gem5 Developers// if (machInst.aarch64) 88610037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 20, 5); 88710037SARM gem5 Developers// else if (machInst.thumb) 88810037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 7, 0); 88910037SARM gem5 Developers// else 89010037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 15, 0); 89110037SARM gem5 Developers// tc->setMiscReg(esr_idx, esr); 89210037SARM gem5 Developers// } 89310037SARM gem5 Developers 89410037SARM gem5 Developersvoid 89510037SARM gem5 DevelopersSecureMonitorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 89610037SARM gem5 Developers{ 89710037SARM gem5 Developers if (FullSystem) { 89810037SARM gem5 Developers ArmFault::invoke(tc, inst); 89910037SARM gem5 Developers return; 90010037SARM gem5 Developers } 90110037SARM gem5 Developers} 90210037SARM gem5 Developers 90310037SARM gem5 DevelopersExceptionClass 90410037SARM gem5 DevelopersSecureMonitorCall::ec(ThreadContext *tc) const 90510037SARM gem5 Developers{ 90610037SARM gem5 Developers return (from64 ? EC_SMC_64 : vals.ec); 90710037SARM gem5 Developers} 90810037SARM gem5 Developers 90910037SARM gem5 DevelopersExceptionClass 91010037SARM gem5 DevelopersSupervisorTrap::ec(ThreadContext *tc) const 91110037SARM gem5 Developers{ 91210037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 91310037SARM gem5 Developers} 91410037SARM gem5 Developers 91510037SARM gem5 DevelopersExceptionClass 91610037SARM gem5 DevelopersSecureMonitorTrap::ec(ThreadContext *tc) const 9178302SAli.Saidi@ARM.com{ 9188302SAli.Saidi@ARM.com return (overrideEc != EC_INVALID) ? overrideEc : 9198302SAli.Saidi@ARM.com (from64 ? EC_SMC_64 : vals.ec); 92010037SARM gem5 Developers} 9218302SAli.Saidi@ARM.com 9228302SAli.Saidi@ARM.comtemplate<class T> 9238302SAli.Saidi@ARM.comvoid 9247783SGiacomo.Gabrielli@arm.comAbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst) 9257783SGiacomo.Gabrielli@arm.com{ 92610037SARM gem5 Developers if (tranMethod == ArmFault::UnknownTran) { 92710037SARM gem5 Developers tranMethod = longDescFormatInUse(tc) ? ArmFault::LpaeTran 9287783SGiacomo.Gabrielli@arm.com : ArmFault::VmsaTran; 9297783SGiacomo.Gabrielli@arm.com 9307783SGiacomo.Gabrielli@arm.com if ((tranMethod == ArmFault::VmsaTran) && this->routeToMonitor(tc)) { 9317783SGiacomo.Gabrielli@arm.com // See ARM ARM B3-1416 9327783SGiacomo.Gabrielli@arm.com bool override_LPAE = false; 93310037SARM gem5 Developers TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S); 93410037SARM gem5 Developers TTBCR M5_VAR_USED ttbcr_ns = tc->readMiscReg(MISCREG_TTBCR_NS); 9357783SGiacomo.Gabrielli@arm.com if (ttbcr_s.eae) { 9367783SGiacomo.Gabrielli@arm.com override_LPAE = true; 9377783SGiacomo.Gabrielli@arm.com } else { 9387408Sgblack@eecs.umich.edu // Unimplemented code option, not seen in testing. May need 9397408Sgblack@eecs.umich.edu // extension according to the manual exceprt above. 9408206SWilliam.Wang@arm.com DPRINTF(Faults, "Warning: Incomplete translation method " 9418206SWilliam.Wang@arm.com "override detected.\n"); 9427408Sgblack@eecs.umich.edu } 9437408Sgblack@eecs.umich.edu if (override_LPAE) 94410037SARM gem5 Developers tranMethod = ArmFault::LpaeTran; 9457408Sgblack@eecs.umich.edu } 9467408Sgblack@eecs.umich.edu } 94710037SARM gem5 Developers 94810037SARM gem5 Developers if (source == ArmFault::AsynchronousExternalAbort) { 94910037SARM gem5 Developers tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 95010037SARM gem5 Developers } 95110037SARM gem5 Developers // Get effective fault source encoding 95210037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 95310037SARM gem5 Developers FSR fsr = getFsr(tc); 95410037SARM gem5 Developers 95510037SARM gem5 Developers // source must be determined BEFORE invoking generic routines which will 95610037SARM gem5 Developers // try to set hsr etc. and are based upon source! 95710037SARM gem5 Developers ArmFaultVals<T>::invoke(tc, inst); 95810037SARM gem5 Developers 95910037SARM gem5 Developers if (!this->to64) { // AArch32 96010037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 96110037SARM gem5 Developers tc->setMiscReg(T::HFarIndex, faultAddr); 96210037SARM gem5 Developers } else if (stage2) { 96310037SARM gem5 Developers tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf); 96410037SARM gem5 Developers tc->setMiscReg(T::HFarIndex, OVAddr); 96510037SARM gem5 Developers } else { 96610037SARM gem5 Developers tc->setMiscReg(T::FsrIndex, fsr); 96710037SARM gem5 Developers tc->setMiscReg(T::FarIndex, faultAddr); 96810037SARM gem5 Developers } 96910037SARM gem5 Developers DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x "\ 97010037SARM gem5 Developers "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod); 97110037SARM gem5 Developers } else { // AArch64 97210037SARM gem5 Developers // Set the FAR register. Nothing else to do if we are in AArch64 state 97310037SARM gem5 Developers // because the syndrome register has already been set inside invoke64() 97410037SARM gem5 Developers if (stage2) { 97510037SARM gem5 Developers // stage 2 fault, set HPFAR_EL2 to the faulting IPA 97610037SARM gem5 Developers // and FAR_EL2 to the Original VA 97710037SARM gem5 Developers tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), OVAddr); 97810037SARM gem5 Developers tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4); 97912406Sgabeblack@google.com 98012406Sgabeblack@google.com DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n", 98110037SARM gem5 Developers OVAddr, faultAddr); 9827408Sgblack@eecs.umich.edu } else { 9837408Sgblack@eecs.umich.edu tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr); 9847408Sgblack@eecs.umich.edu } 98510037SARM gem5 Developers } 98612639Sgiacomo.travaglini@arm.com} 98712639Sgiacomo.travaglini@arm.com 98812639Sgiacomo.travaglini@arm.comtemplate<class T> 98912639Sgiacomo.travaglini@arm.comFSR 99012639Sgiacomo.travaglini@arm.comAbortFault<T>::getFsr(ThreadContext *tc) 99112639Sgiacomo.travaglini@arm.com{ 99212639Sgiacomo.travaglini@arm.com FSR fsr = 0; 99312639Sgiacomo.travaglini@arm.com 99410037SARM gem5 Developers if (((CPSR) tc->readMiscRegNoEffect(MISCREG_CPSR)).width) { 9957408Sgblack@eecs.umich.edu // AArch32 99610037SARM gem5 Developers assert(tranMethod != ArmFault::UnknownTran); 99713581Sgabeblack@google.com if (tranMethod == ArmFault::LpaeTran) { 99812406Sgabeblack@google.com srcEncoded = ArmFault::longDescFaultSources[source]; 99912406Sgabeblack@google.com fsr.status = srcEncoded; 10007408Sgblack@eecs.umich.edu fsr.lpae = 1; 10019385SAndreas.Sandberg@arm.com } else { 10029385SAndreas.Sandberg@arm.com srcEncoded = ArmFault::shortDescFaultSources[source]; 10039385SAndreas.Sandberg@arm.com fsr.fsLow = bits(srcEncoded, 3, 0); 100410461SAndreas.Sandberg@ARM.com fsr.fsHigh = bits(srcEncoded, 4); 10059385SAndreas.Sandberg@arm.com fsr.domain = static_cast<uint8_t>(domain); 10069385SAndreas.Sandberg@arm.com } 10079385SAndreas.Sandberg@arm.com fsr.wnr = (write ? 1 : 0); 10089385SAndreas.Sandberg@arm.com fsr.ext = 0; 10099385SAndreas.Sandberg@arm.com } else { 10109385SAndreas.Sandberg@arm.com // AArch64 10119385SAndreas.Sandberg@arm.com srcEncoded = ArmFault::aarch64FaultSources[source]; 10129385SAndreas.Sandberg@arm.com } 10139385SAndreas.Sandberg@arm.com if (srcEncoded == ArmFault::FaultSourceInvalid) { 10149385SAndreas.Sandberg@arm.com panic("Invalid fault source\n"); 10159385SAndreas.Sandberg@arm.com } 10169385SAndreas.Sandberg@arm.com return fsr; 10179385SAndreas.Sandberg@arm.com} 10187408Sgblack@eecs.umich.edu 10197408Sgblack@eecs.umich.edutemplate<class T> 10207408Sgblack@eecs.umich.edubool 102110037SARM gem5 DevelopersAbortFault<T>::abortDisable(ThreadContext *tc) 102210037SARM gem5 Developers{ 102310037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 102410037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 102510037SARM gem5 Developers return (!scr.ns || scr.aw); 102610037SARM gem5 Developers } 102710037SARM gem5 Developers return true; 102810037SARM gem5 Developers} 102910037SARM gem5 Developers 103013116Sgiacomo.travaglini@arm.comtemplate<class T> 103110037SARM gem5 Developersvoid 103210037SARM gem5 DevelopersAbortFault<T>::annotate(ArmFault::AnnotationIDs id, uint64_t val) 10339385SAndreas.Sandberg@arm.com{ 10347408Sgblack@eecs.umich.edu switch (id) 10359385SAndreas.Sandberg@arm.com { 103612605Sgiacomo.travaglini@arm.com case ArmFault::S1PTW: 103712605Sgiacomo.travaglini@arm.com s1ptw = val; 103812605Sgiacomo.travaglini@arm.com break; 103912605Sgiacomo.travaglini@arm.com case ArmFault::OVA: 104012605Sgiacomo.travaglini@arm.com OVAddr = val; 104112605Sgiacomo.travaglini@arm.com break; 104212605Sgiacomo.travaglini@arm.com 104312605Sgiacomo.travaglini@arm.com // Just ignore unknown ID's 104412605Sgiacomo.travaglini@arm.com default: 104512605Sgiacomo.travaglini@arm.com break; 104612605Sgiacomo.travaglini@arm.com } 10477408Sgblack@eecs.umich.edu} 104812605Sgiacomo.travaglini@arm.com 104912605Sgiacomo.travaglini@arm.comtemplate<class T> 105012605Sgiacomo.travaglini@arm.comuint32_t 105112605Sgiacomo.travaglini@arm.comAbortFault<T>::iss() const 105212605Sgiacomo.travaglini@arm.com{ 105312605Sgiacomo.travaglini@arm.com uint32_t val; 105412605Sgiacomo.travaglini@arm.com 105512605Sgiacomo.travaglini@arm.com val = srcEncoded & 0x3F; 105612605Sgiacomo.travaglini@arm.com val |= write << 6; 10577408Sgblack@eecs.umich.edu val |= s1ptw << 7; 105812605Sgiacomo.travaglini@arm.com return (val); 105912605Sgiacomo.travaglini@arm.com} 106012605Sgiacomo.travaglini@arm.com 106112605Sgiacomo.travaglini@arm.comtemplate<class T> 106212605Sgiacomo.travaglini@arm.combool 106312605Sgiacomo.travaglini@arm.comAbortFault<T>::isMMUFault() const 106412605Sgiacomo.travaglini@arm.com{ 106512605Sgiacomo.travaglini@arm.com // NOTE: Not relying on LL information being aligned to lowest bits here 106612605Sgiacomo.travaglini@arm.com return 10677408Sgblack@eecs.umich.edu (source == ArmFault::AlignmentFault) || 106812605Sgiacomo.travaglini@arm.com ((source >= ArmFault::TranslationLL) && 106912605Sgiacomo.travaglini@arm.com (source < ArmFault::TranslationLL + 4)) || 107012605Sgiacomo.travaglini@arm.com ((source >= ArmFault::AccessFlagLL) && 107112605Sgiacomo.travaglini@arm.com (source < ArmFault::AccessFlagLL + 4)) || 107212605Sgiacomo.travaglini@arm.com ((source >= ArmFault::DomainLL) && 107312605Sgiacomo.travaglini@arm.com (source < ArmFault::DomainLL + 4)) || 107412605Sgiacomo.travaglini@arm.com ((source >= ArmFault::PermissionLL) && 107512605Sgiacomo.travaglini@arm.com (source < ArmFault::PermissionLL + 4)); 107612605Sgiacomo.travaglini@arm.com} 107712605Sgiacomo.travaglini@arm.com 107812605Sgiacomo.travaglini@arm.comExceptionClass 107912605Sgiacomo.travaglini@arm.comPrefetchAbort::ec(ThreadContext *tc) const 108012605Sgiacomo.travaglini@arm.com{ 108112576Sgiacomo.travaglini@arm.com if (to64) { 108212605Sgiacomo.travaglini@arm.com // AArch64 108312605Sgiacomo.travaglini@arm.com if (toEL == fromEL) 108412605Sgiacomo.travaglini@arm.com return EC_PREFETCH_ABORT_CURR_EL; 108512605Sgiacomo.travaglini@arm.com else 108612605Sgiacomo.travaglini@arm.com return EC_PREFETCH_ABORT_LOWER_EL; 108712605Sgiacomo.travaglini@arm.com } else { 108812605Sgiacomo.travaglini@arm.com // AArch32 108912605Sgiacomo.travaglini@arm.com // Abort faults have different EC codes depending on whether 109012605Sgiacomo.travaglini@arm.com // the fault originated within HYP mode, or not. So override 109112605Sgiacomo.travaglini@arm.com // the method and add the extra adjustment of the EC value. 109212605Sgiacomo.travaglini@arm.com 109312605Sgiacomo.travaglini@arm.com ExceptionClass ec = ArmFaultVals<PrefetchAbort>::vals.ec; 109412605Sgiacomo.travaglini@arm.com 109512605Sgiacomo.travaglini@arm.com CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 109612576Sgiacomo.travaglini@arm.com if (spsr.mode == MODE_HYP) { 109712605Sgiacomo.travaglini@arm.com ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 109812605Sgiacomo.travaglini@arm.com } 109912605Sgiacomo.travaglini@arm.com return ec; 110012605Sgiacomo.travaglini@arm.com } 110112605Sgiacomo.travaglini@arm.com} 110212605Sgiacomo.travaglini@arm.com 110312605Sgiacomo.travaglini@arm.combool 110412605Sgiacomo.travaglini@arm.comPrefetchAbort::routeToMonitor(ThreadContext *tc) const 110512605Sgiacomo.travaglini@arm.com{ 110612605Sgiacomo.travaglini@arm.com SCR scr = 0; 110712605Sgiacomo.travaglini@arm.com if (from64) 110812605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 110912605Sgiacomo.travaglini@arm.com else 111012605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 111112605Sgiacomo.travaglini@arm.com 111212605Sgiacomo.travaglini@arm.com return scr.ea && !isMMUFault(); 111312605Sgiacomo.travaglini@arm.com} 111412605Sgiacomo.travaglini@arm.com 111512605Sgiacomo.travaglini@arm.combool 111612605Sgiacomo.travaglini@arm.comPrefetchAbort::routeToHyp(ThreadContext *tc) const 111712605Sgiacomo.travaglini@arm.com{ 111812605Sgiacomo.travaglini@arm.com bool toHyp; 111912605Sgiacomo.travaglini@arm.com 112012605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 112112605Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 112212605Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 11237408Sgblack@eecs.umich.edu HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 112412605Sgiacomo.travaglini@arm.com 112512605Sgiacomo.travaglini@arm.com // if in Hyp mode then stay in Hyp mode 112612605Sgiacomo.travaglini@arm.com toHyp = scr.ns && (cpsr.mode == MODE_HYP); 112712605Sgiacomo.travaglini@arm.com // otherwise, check whether to take to Hyp mode through Hyp Trap vector 112812605Sgiacomo.travaglini@arm.com toHyp |= (stage2 || 112912605Sgiacomo.travaglini@arm.com ( (source == DebugEvent) && hdcr.tde && (cpsr.mode != MODE_HYP)) || 113012605Sgiacomo.travaglini@arm.com ( (source == SynchronousExternalAbort) && hcr.tge && (cpsr.mode == MODE_USER)) 113112605Sgiacomo.travaglini@arm.com ) && !inSecureState(tc); 113212605Sgiacomo.travaglini@arm.com return toHyp; 113312605Sgiacomo.travaglini@arm.com} 113412605Sgiacomo.travaglini@arm.com 113512605Sgiacomo.travaglini@arm.comExceptionClass 113612605Sgiacomo.travaglini@arm.comDataAbort::ec(ThreadContext *tc) const 113712605Sgiacomo.travaglini@arm.com{ 113812605Sgiacomo.travaglini@arm.com if (to64) { 113912605Sgiacomo.travaglini@arm.com // AArch64 114012576Sgiacomo.travaglini@arm.com if (source == ArmFault::AsynchronousExternalAbort) { 114112605Sgiacomo.travaglini@arm.com panic("Asynchronous External Abort should be handled with " 114212605Sgiacomo.travaglini@arm.com "SystemErrors (SErrors)!"); 114312605Sgiacomo.travaglini@arm.com } 114412605Sgiacomo.travaglini@arm.com if (toEL == fromEL) 114512605Sgiacomo.travaglini@arm.com return EC_DATA_ABORT_CURR_EL; 114612605Sgiacomo.travaglini@arm.com else 114712605Sgiacomo.travaglini@arm.com return EC_DATA_ABORT_LOWER_EL; 114812605Sgiacomo.travaglini@arm.com } else { 114912605Sgiacomo.travaglini@arm.com // AArch32 115012605Sgiacomo.travaglini@arm.com // Abort faults have different EC codes depending on whether 115112605Sgiacomo.travaglini@arm.com // the fault originated within HYP mode, or not. So override 115212605Sgiacomo.travaglini@arm.com // the method and add the extra adjustment of the EC value. 115312576Sgiacomo.travaglini@arm.com 115412605Sgiacomo.travaglini@arm.com ExceptionClass ec = ArmFaultVals<DataAbort>::vals.ec; 115512605Sgiacomo.travaglini@arm.com 115612605Sgiacomo.travaglini@arm.com CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 115712605Sgiacomo.travaglini@arm.com if (spsr.mode == MODE_HYP) { 115812605Sgiacomo.travaglini@arm.com ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 115912605Sgiacomo.travaglini@arm.com } 116012605Sgiacomo.travaglini@arm.com return ec; 116112605Sgiacomo.travaglini@arm.com } 116212605Sgiacomo.travaglini@arm.com} 116312605Sgiacomo.travaglini@arm.com 116412605Sgiacomo.travaglini@arm.combool 116512605Sgiacomo.travaglini@arm.comDataAbort::routeToMonitor(ThreadContext *tc) const 116612605Sgiacomo.travaglini@arm.com{ 116712605Sgiacomo.travaglini@arm.com SCR scr = 0; 116812605Sgiacomo.travaglini@arm.com if (from64) 116912576Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 117012605Sgiacomo.travaglini@arm.com else 117112605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 117212605Sgiacomo.travaglini@arm.com 117312605Sgiacomo.travaglini@arm.com return scr.ea && !isMMUFault(); 117412605Sgiacomo.travaglini@arm.com} 117512605Sgiacomo.travaglini@arm.com 117612605Sgiacomo.travaglini@arm.combool 117712605Sgiacomo.travaglini@arm.comDataAbort::routeToHyp(ThreadContext *tc) const 117812605Sgiacomo.travaglini@arm.com{ 117912605Sgiacomo.travaglini@arm.com bool toHyp; 118012605Sgiacomo.travaglini@arm.com 118112605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 118212576Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 118312605Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 118412605Sgiacomo.travaglini@arm.com HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 118512605Sgiacomo.travaglini@arm.com 118612605Sgiacomo.travaglini@arm.com // if in Hyp mode then stay in Hyp mode 118712605Sgiacomo.travaglini@arm.com toHyp = scr.ns && (cpsr.mode == MODE_HYP); 118812605Sgiacomo.travaglini@arm.com // otherwise, check whether to take to Hyp mode through Hyp Trap vector 118912605Sgiacomo.travaglini@arm.com toHyp |= (stage2 || 119012605Sgiacomo.travaglini@arm.com ( (cpsr.mode != MODE_HYP) && ( ((source == AsynchronousExternalAbort) && hcr.amo) || 119112605Sgiacomo.travaglini@arm.com ((source == DebugEvent) && hdcr.tde) ) 119212605Sgiacomo.travaglini@arm.com ) || 119312605Sgiacomo.travaglini@arm.com ( (cpsr.mode == MODE_USER) && hcr.tge && 119412605Sgiacomo.travaglini@arm.com ((source == AlignmentFault) || 119512605Sgiacomo.travaglini@arm.com (source == SynchronousExternalAbort)) 119612605Sgiacomo.travaglini@arm.com ) 119712605Sgiacomo.travaglini@arm.com ) && !inSecureState(tc); 119812577Sgiacomo.travaglini@arm.com return toHyp; 119912605Sgiacomo.travaglini@arm.com} 120012605Sgiacomo.travaglini@arm.com 120112605Sgiacomo.travaglini@arm.comuint32_t 120212605Sgiacomo.travaglini@arm.comDataAbort::iss() const 120312605Sgiacomo.travaglini@arm.com{ 120412605Sgiacomo.travaglini@arm.com uint32_t val; 120512605Sgiacomo.travaglini@arm.com 120612605Sgiacomo.travaglini@arm.com // Add on the data abort specific fields to the generic abort ISS value 120712605Sgiacomo.travaglini@arm.com val = AbortFault<DataAbort>::iss(); 120812605Sgiacomo.travaglini@arm.com // ISS is valid if not caused by a stage 1 page table walk, and when taken 120912605Sgiacomo.travaglini@arm.com // to AArch64 only when directed to EL2 121012605Sgiacomo.travaglini@arm.com if (!s1ptw && (!to64 || toEL == EL2)) { 121112605Sgiacomo.travaglini@arm.com val |= isv << 24; 121212605Sgiacomo.travaglini@arm.com if (isv) { 121312577Sgiacomo.travaglini@arm.com val |= sas << 22; 121412605Sgiacomo.travaglini@arm.com val |= sse << 21; 121512605Sgiacomo.travaglini@arm.com val |= srt << 16; 121612605Sgiacomo.travaglini@arm.com // AArch64 only. These assignments are safe on AArch32 as well 121712605Sgiacomo.travaglini@arm.com // because these vars are initialized to false 121812605Sgiacomo.travaglini@arm.com val |= sf << 15; 121912605Sgiacomo.travaglini@arm.com val |= ar << 14; 122012605Sgiacomo.travaglini@arm.com } 122112605Sgiacomo.travaglini@arm.com } 122212605Sgiacomo.travaglini@arm.com return (val); 122312605Sgiacomo.travaglini@arm.com} 122412605Sgiacomo.travaglini@arm.com 122512605Sgiacomo.travaglini@arm.comvoid 122610037SARM gem5 DevelopersDataAbort::annotate(AnnotationIDs id, uint64_t val) 122712605Sgiacomo.travaglini@arm.com{ 122812605Sgiacomo.travaglini@arm.com AbortFault<DataAbort>::annotate(id, val); 122912605Sgiacomo.travaglini@arm.com switch (id) 123012605Sgiacomo.travaglini@arm.com { 123112605Sgiacomo.travaglini@arm.com case SAS: 123212605Sgiacomo.travaglini@arm.com isv = true; 123312605Sgiacomo.travaglini@arm.com sas = val; 123412605Sgiacomo.travaglini@arm.com break; 123512605Sgiacomo.travaglini@arm.com case SSE: 123612605Sgiacomo.travaglini@arm.com isv = true; 123712605Sgiacomo.travaglini@arm.com sse = val; 123812605Sgiacomo.travaglini@arm.com break; 123912605Sgiacomo.travaglini@arm.com case SRT: 124010037SARM gem5 Developers isv = true; 124112605Sgiacomo.travaglini@arm.com srt = val; 124212605Sgiacomo.travaglini@arm.com break; 124312605Sgiacomo.travaglini@arm.com case SF: 124412605Sgiacomo.travaglini@arm.com isv = true; 124512605Sgiacomo.travaglini@arm.com sf = val; 124612605Sgiacomo.travaglini@arm.com break; 124712605Sgiacomo.travaglini@arm.com case AR: 124812605Sgiacomo.travaglini@arm.com isv = true; 124912605Sgiacomo.travaglini@arm.com ar = val; 125012605Sgiacomo.travaglini@arm.com break; 125112605Sgiacomo.travaglini@arm.com // Just ignore unknown ID's 125212605Sgiacomo.travaglini@arm.com default: 125312605Sgiacomo.travaglini@arm.com break; 125410037SARM gem5 Developers } 125512605Sgiacomo.travaglini@arm.com} 125612605Sgiacomo.travaglini@arm.com 125712605Sgiacomo.travaglini@arm.comvoid 125812605Sgiacomo.travaglini@arm.comVirtualDataAbort::invoke(ThreadContext *tc, const StaticInstPtr &inst) 125912605Sgiacomo.travaglini@arm.com{ 126012605Sgiacomo.travaglini@arm.com AbortFault<VirtualDataAbort>::invoke(tc, inst); 126112605Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 126212605Sgiacomo.travaglini@arm.com hcr.va = 0; 126312605Sgiacomo.travaglini@arm.com tc->setMiscRegNoEffect(MISCREG_HCR, hcr); 126412605Sgiacomo.travaglini@arm.com} 126512605Sgiacomo.travaglini@arm.com 126612605Sgiacomo.travaglini@arm.combool 126710037SARM gem5 DevelopersInterrupt::routeToMonitor(ThreadContext *tc) const 126812605Sgiacomo.travaglini@arm.com{ 126912605Sgiacomo.travaglini@arm.com assert(ArmSystem::haveSecurity(tc)); 127012605Sgiacomo.travaglini@arm.com SCR scr = 0; 127112605Sgiacomo.travaglini@arm.com if (from64) 127212605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 127312605Sgiacomo.travaglini@arm.com else 127412605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 127512605Sgiacomo.travaglini@arm.com return scr.irq; 127612605Sgiacomo.travaglini@arm.com} 127712605Sgiacomo.travaglini@arm.com 127812605Sgiacomo.travaglini@arm.combool 127912605Sgiacomo.travaglini@arm.comInterrupt::routeToHyp(ThreadContext *tc) const 128010037SARM gem5 Developers{ 128112605Sgiacomo.travaglini@arm.com bool toHyp; 128212605Sgiacomo.travaglini@arm.com 128312605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 128412605Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 128512605Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 128612605Sgiacomo.travaglini@arm.com // Determine whether IRQs are routed to Hyp mode. 128712605Sgiacomo.travaglini@arm.com toHyp = (!scr.irq && hcr.imo && !inSecureState(tc)) || 128812605Sgiacomo.travaglini@arm.com (cpsr.mode == MODE_HYP); 128910037SARM gem5 Developers return toHyp; 129012605Sgiacomo.travaglini@arm.com} 129112605Sgiacomo.travaglini@arm.com 129212605Sgiacomo.travaglini@arm.combool 129312605Sgiacomo.travaglini@arm.comInterrupt::abortDisable(ThreadContext *tc) 129412605Sgiacomo.travaglini@arm.com{ 129512605Sgiacomo.travaglini@arm.com if (ArmSystem::haveSecurity(tc)) { 129612605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 129712605Sgiacomo.travaglini@arm.com return (!scr.ns || scr.aw); 129810037SARM gem5 Developers } 129912605Sgiacomo.travaglini@arm.com return true; 130012605Sgiacomo.travaglini@arm.com} 130112605Sgiacomo.travaglini@arm.com 130212605Sgiacomo.travaglini@arm.comVirtualInterrupt::VirtualInterrupt() 130312605Sgiacomo.travaglini@arm.com{} 130412605Sgiacomo.travaglini@arm.com 130512605Sgiacomo.travaglini@arm.combool 130612605Sgiacomo.travaglini@arm.comFastInterrupt::routeToMonitor(ThreadContext *tc) const 130710037SARM gem5 Developers{ 130812605Sgiacomo.travaglini@arm.com assert(ArmSystem::haveSecurity(tc)); 130912605Sgiacomo.travaglini@arm.com SCR scr = 0; 131012605Sgiacomo.travaglini@arm.com if (from64) 131112605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 131212605Sgiacomo.travaglini@arm.com else 131312605Sgiacomo.travaglini@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 131412605Sgiacomo.travaglini@arm.com return scr.fiq; 131512605Sgiacomo.travaglini@arm.com} 131612605Sgiacomo.travaglini@arm.com 131712605Sgiacomo.travaglini@arm.combool 131812605Sgiacomo.travaglini@arm.comFastInterrupt::routeToHyp(ThreadContext *tc) const 131912605Sgiacomo.travaglini@arm.com{ 132012605Sgiacomo.travaglini@arm.com bool toHyp; 132112605Sgiacomo.travaglini@arm.com 132212605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 132312605Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 132412605Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 132510037SARM gem5 Developers // Determine whether IRQs are routed to Hyp mode. 132612605Sgiacomo.travaglini@arm.com toHyp = (!scr.fiq && hcr.fmo && !inSecureState(tc)) || 132712605Sgiacomo.travaglini@arm.com (cpsr.mode == MODE_HYP); 132812605Sgiacomo.travaglini@arm.com return toHyp; 132912605Sgiacomo.travaglini@arm.com} 133012605Sgiacomo.travaglini@arm.com 133112605Sgiacomo.travaglini@arm.combool 133212605Sgiacomo.travaglini@arm.comFastInterrupt::abortDisable(ThreadContext *tc) 133313549Sanouk.vanlaer@arm.com{ 133413549Sanouk.vanlaer@arm.com if (ArmSystem::haveSecurity(tc)) { 133513549Sanouk.vanlaer@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 133613549Sanouk.vanlaer@arm.com return (!scr.ns || scr.aw); 133713549Sanouk.vanlaer@arm.com } 133813549Sanouk.vanlaer@arm.com return true; 133913549Sanouk.vanlaer@arm.com} 134013549Sanouk.vanlaer@arm.com 134113549Sanouk.vanlaer@arm.combool 134213549Sanouk.vanlaer@arm.comFastInterrupt::fiqDisable(ThreadContext *tc) 134313549Sanouk.vanlaer@arm.com{ 134412605Sgiacomo.travaglini@arm.com if (ArmSystem::haveVirtualization(tc)) { 134510037SARM gem5 Developers return true; 134610037SARM gem5 Developers } else if (ArmSystem::haveSecurity(tc)) { 134710037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 134810037SARM gem5 Developers return (!scr.ns || scr.fw); 134912605Sgiacomo.travaglini@arm.com } 135012605Sgiacomo.travaglini@arm.com return true; 135112605Sgiacomo.travaglini@arm.com} 135212605Sgiacomo.travaglini@arm.com 135312605Sgiacomo.travaglini@arm.comVirtualFastInterrupt::VirtualFastInterrupt() 135412605Sgiacomo.travaglini@arm.com{} 135512605Sgiacomo.travaglini@arm.com 135612605Sgiacomo.travaglini@arm.comvoid 135712605Sgiacomo.travaglini@arm.comPCAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 135812605Sgiacomo.travaglini@arm.com{ 135912605Sgiacomo.travaglini@arm.com ArmFaultVals<PCAlignmentFault>::invoke(tc, inst); 136012605Sgiacomo.travaglini@arm.com assert(from64); 136112605Sgiacomo.travaglini@arm.com // Set the FAR 136212605Sgiacomo.travaglini@arm.com tc->setMiscReg(getFaultAddrReg64(), faultPC); 136312605Sgiacomo.travaglini@arm.com} 136412605Sgiacomo.travaglini@arm.com 136512605Sgiacomo.travaglini@arm.comSPAlignmentFault::SPAlignmentFault() 136612605Sgiacomo.travaglini@arm.com{} 136712605Sgiacomo.travaglini@arm.com 136812605Sgiacomo.travaglini@arm.comSystemError::SystemError() 136912605Sgiacomo.travaglini@arm.com{} 137012605Sgiacomo.travaglini@arm.com 137112605Sgiacomo.travaglini@arm.comvoid 137210037SARM gem5 DevelopersSystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst) 137310037SARM gem5 Developers{ 137412605Sgiacomo.travaglini@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 137512605Sgiacomo.travaglini@arm.com ArmFault::invoke(tc, inst); 137612605Sgiacomo.travaglini@arm.com} 137712605Sgiacomo.travaglini@arm.com 137812605Sgiacomo.travaglini@arm.combool 137912605Sgiacomo.travaglini@arm.comSystemError::routeToMonitor(ThreadContext *tc) const 138012605Sgiacomo.travaglini@arm.com{ 138112605Sgiacomo.travaglini@arm.com assert(ArmSystem::haveSecurity(tc)); 138212605Sgiacomo.travaglini@arm.com assert(from64); 138312605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 138412605Sgiacomo.travaglini@arm.com return scr.ea; 138512605Sgiacomo.travaglini@arm.com} 138612605Sgiacomo.travaglini@arm.com 138710037SARM gem5 Developersbool 138810037SARM gem5 DevelopersSystemError::routeToHyp(ThreadContext *tc) const 138912605Sgiacomo.travaglini@arm.com{ 139012605Sgiacomo.travaglini@arm.com bool toHyp; 139112605Sgiacomo.travaglini@arm.com assert(from64); 139212605Sgiacomo.travaglini@arm.com 139312605Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 139412605Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 139512605Sgiacomo.travaglini@arm.com 139612605Sgiacomo.travaglini@arm.com toHyp = (!scr.ea && hcr.amo && !inSecureState(tc)) || 139712605Sgiacomo.travaglini@arm.com (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(tc)); 139812605Sgiacomo.travaglini@arm.com return toHyp; 139912605Sgiacomo.travaglini@arm.com} 140012605Sgiacomo.travaglini@arm.com 140112605Sgiacomo.travaglini@arm.comvoid 140212605Sgiacomo.travaglini@arm.comFlushPipe::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 140312605Sgiacomo.travaglini@arm.com DPRINTF(Faults, "Invoking FlushPipe Fault\n"); 140412605Sgiacomo.travaglini@arm.com 140512605Sgiacomo.travaglini@arm.com // Set the PC to the next instruction of the faulting instruction. 140612605Sgiacomo.travaglini@arm.com // Net effect is simply squashing all instructions behind and 140712605Sgiacomo.travaglini@arm.com // start refetching from the next instruction. 140812605Sgiacomo.travaglini@arm.com PCState pc = tc->pcState(); 140912605Sgiacomo.travaglini@arm.com assert(inst); 141012605Sgiacomo.travaglini@arm.com inst->advancePC(pc); 141112605Sgiacomo.travaglini@arm.com tc->pcState(pc); 141212605Sgiacomo.travaglini@arm.com} 141310037SARM gem5 Developers 141410037SARM gem5 Developersvoid 141512605Sgiacomo.travaglini@arm.comArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 141612605Sgiacomo.travaglini@arm.com DPRINTF(Faults, "Invoking ArmSev Fault\n"); 141712605Sgiacomo.travaglini@arm.com if (!FullSystem) 141812605Sgiacomo.travaglini@arm.com return; 141912605Sgiacomo.travaglini@arm.com 142012605Sgiacomo.travaglini@arm.com // Set sev_mailbox to 1, clear the pending interrupt from remote 142112605Sgiacomo.travaglini@arm.com // SEV execution and let pipeline continue as pcState is still 142212605Sgiacomo.travaglini@arm.com // valid. 142312605Sgiacomo.travaglini@arm.com tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 142412605Sgiacomo.travaglini@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0); 142512605Sgiacomo.travaglini@arm.com} 142612605Sgiacomo.travaglini@arm.com 142712605Sgiacomo.travaglini@arm.com// Instantiate all the templates to make the linker happy 142812605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<Reset>; 142912605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<UndefinedInstruction>; 143012605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<SupervisorCall>; 143112605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<SecureMonitorCall>; 143212605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<HypervisorCall>; 143312605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<PrefetchAbort>; 143412605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<DataAbort>; 143512605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<VirtualDataAbort>; 143612605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<HypervisorTrap>; 143712605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<Interrupt>; 143812605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<VirtualInterrupt>; 143912605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<FastInterrupt>; 144012605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<VirtualFastInterrupt>; 144112605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<SupervisorTrap>; 144212605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<SecureMonitorTrap>; 144310037SARM gem5 Developerstemplate class ArmFaultVals<PCAlignmentFault>; 144410037SARM gem5 Developerstemplate class ArmFaultVals<SPAlignmentFault>; 144512605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<SystemError>; 144612605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<FlushPipe>; 144712605Sgiacomo.travaglini@arm.comtemplate class ArmFaultVals<ArmSev>; 144812605Sgiacomo.travaglini@arm.comtemplate class AbortFault<PrefetchAbort>; 144912605Sgiacomo.travaglini@arm.comtemplate class AbortFault<DataAbort>; 145012605Sgiacomo.travaglini@arm.comtemplate class AbortFault<VirtualDataAbort>; 145112605Sgiacomo.travaglini@arm.com 145212605Sgiacomo.travaglini@arm.com 145312605Sgiacomo.travaglini@arm.comIllegalInstSetStateFault::IllegalInstSetStateFault() 145412605Sgiacomo.travaglini@arm.com{} 145512605Sgiacomo.travaglini@arm.com 145612605Sgiacomo.travaglini@arm.com 145712605Sgiacomo.travaglini@arm.com} // namespace ArmISA 145812605Sgiacomo.travaglini@arm.com