faults.cc revision 14128
16019Shines@cs.fsu.edu/* 212509Schuan.zhu@arm.com * Copyright (c) 2010, 2012-2014, 2016-2019 ARM Limited 37093Sgblack@eecs.umich.edu * All rights reserved 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu * 146019Shines@cs.fsu.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 156019Shines@cs.fsu.edu * Copyright (c) 2007-2008 The Florida State University 166019Shines@cs.fsu.edu * All rights reserved. 176019Shines@cs.fsu.edu * 186019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 196019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 206019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 216019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 226019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 236019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 246019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 256019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 266019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 276019Shines@cs.fsu.edu * this software without specific prior written permission. 286019Shines@cs.fsu.edu * 296019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406019Shines@cs.fsu.edu * 416735Sgblack@eecs.umich.edu * Authors: Ali Saidi 426735Sgblack@eecs.umich.edu * Gabe Black 4310037SARM gem5 Developers * Giacomo Gabrielli 4410037SARM gem5 Developers * Thomas Grocutt 456019Shines@cs.fsu.edu */ 466019Shines@cs.fsu.edu 476019Shines@cs.fsu.edu#include "arch/arm/faults.hh" 4811793Sbrandon.potter@amd.com 4911793Sbrandon.potter@amd.com#include "arch/arm/insts/static_inst.hh" 5010037SARM gem5 Developers#include "arch/arm/system.hh" 5110037SARM gem5 Developers#include "arch/arm/utility.hh" 5210037SARM gem5 Developers#include "base/compiler.hh" 538229Snate@binkert.org#include "base/trace.hh" 548229Snate@binkert.org#include "cpu/base.hh" 556019Shines@cs.fsu.edu#include "cpu/thread_context.hh" 568232Snate@binkert.org#include "debug/Faults.hh" 578782Sgblack@eecs.umich.edu#include "sim/full_system.hh" 586019Shines@cs.fsu.edu 596019Shines@cs.fsu.edunamespace ArmISA 606019Shines@cs.fsu.edu{ 616019Shines@cs.fsu.edu 6210037SARM gem5 Developersuint8_t ArmFault::shortDescFaultSources[] = { 6310037SARM gem5 Developers 0x01, // AlignmentFault 6410037SARM gem5 Developers 0x04, // InstructionCacheMaintenance 6510037SARM gem5 Developers 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 6610037SARM gem5 Developers 0x0c, // SynchExtAbtOnTranslTableWalkL1 6710037SARM gem5 Developers 0x0e, // SynchExtAbtOnTranslTableWalkL2 6810037SARM gem5 Developers 0xff, // SynchExtAbtOnTranslTableWalkL3 (INVALID) 6910037SARM gem5 Developers 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 7010037SARM gem5 Developers 0x1c, // SynchPtyErrOnTranslTableWalkL1 7110037SARM gem5 Developers 0x1e, // SynchPtyErrOnTranslTableWalkL2 7210037SARM gem5 Developers 0xff, // SynchPtyErrOnTranslTableWalkL3 (INVALID) 7310037SARM gem5 Developers 0xff, // TranslationL0 (INVALID) 7410037SARM gem5 Developers 0x05, // TranslationL1 7510037SARM gem5 Developers 0x07, // TranslationL2 7610037SARM gem5 Developers 0xff, // TranslationL3 (INVALID) 7710037SARM gem5 Developers 0xff, // AccessFlagL0 (INVALID) 7810037SARM gem5 Developers 0x03, // AccessFlagL1 7910037SARM gem5 Developers 0x06, // AccessFlagL2 8010037SARM gem5 Developers 0xff, // AccessFlagL3 (INVALID) 8110037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 8210037SARM gem5 Developers 0x09, // DomainL1 8310037SARM gem5 Developers 0x0b, // DomainL2 8410037SARM gem5 Developers 0xff, // DomainL3 (INVALID) 8510037SARM gem5 Developers 0xff, // PermissionL0 (INVALID) 8610037SARM gem5 Developers 0x0d, // PermissionL1 8710037SARM gem5 Developers 0x0f, // PermissionL2 8810037SARM gem5 Developers 0xff, // PermissionL3 (INVALID) 8910037SARM gem5 Developers 0x02, // DebugEvent 9010037SARM gem5 Developers 0x08, // SynchronousExternalAbort 9110037SARM gem5 Developers 0x10, // TLBConflictAbort 9210037SARM gem5 Developers 0x19, // SynchPtyErrOnMemoryAccess 9310037SARM gem5 Developers 0x16, // AsynchronousExternalAbort 9410037SARM gem5 Developers 0x18, // AsynchPtyErrOnMemoryAccess 9510037SARM gem5 Developers 0xff, // AddressSizeL0 (INVALID) 9610037SARM gem5 Developers 0xff, // AddressSizeL1 (INVALID) 9710037SARM gem5 Developers 0xff, // AddressSizeL2 (INVALID) 9810037SARM gem5 Developers 0xff, // AddressSizeL3 (INVALID) 9910037SARM gem5 Developers 0x40, // PrefetchTLBMiss 10010037SARM gem5 Developers 0x80 // PrefetchUncacheable 10110037SARM gem5 Developers}; 1026019Shines@cs.fsu.edu 10310037SARM gem5 Developersstatic_assert(sizeof(ArmFault::shortDescFaultSources) == 10410037SARM gem5 Developers ArmFault::NumFaultSources, 10510037SARM gem5 Developers "Invalid size of ArmFault::shortDescFaultSources[]"); 1066019Shines@cs.fsu.edu 10710037SARM gem5 Developersuint8_t ArmFault::longDescFaultSources[] = { 10810037SARM gem5 Developers 0x21, // AlignmentFault 10910037SARM gem5 Developers 0xff, // InstructionCacheMaintenance (INVALID) 11010037SARM gem5 Developers 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 11110037SARM gem5 Developers 0x15, // SynchExtAbtOnTranslTableWalkL1 11210037SARM gem5 Developers 0x16, // SynchExtAbtOnTranslTableWalkL2 11310037SARM gem5 Developers 0x17, // SynchExtAbtOnTranslTableWalkL3 11410037SARM gem5 Developers 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 11510037SARM gem5 Developers 0x1d, // SynchPtyErrOnTranslTableWalkL1 11610037SARM gem5 Developers 0x1e, // SynchPtyErrOnTranslTableWalkL2 11710037SARM gem5 Developers 0x1f, // SynchPtyErrOnTranslTableWalkL3 11810037SARM gem5 Developers 0xff, // TranslationL0 (INVALID) 11910037SARM gem5 Developers 0x05, // TranslationL1 12010037SARM gem5 Developers 0x06, // TranslationL2 12110037SARM gem5 Developers 0x07, // TranslationL3 12210037SARM gem5 Developers 0xff, // AccessFlagL0 (INVALID) 12310037SARM gem5 Developers 0x09, // AccessFlagL1 12410037SARM gem5 Developers 0x0a, // AccessFlagL2 12510037SARM gem5 Developers 0x0b, // AccessFlagL3 12610037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 12710037SARM gem5 Developers 0x3d, // DomainL1 12810037SARM gem5 Developers 0x3e, // DomainL2 12910037SARM gem5 Developers 0xff, // DomainL3 (RESERVED) 13010037SARM gem5 Developers 0xff, // PermissionL0 (INVALID) 13110037SARM gem5 Developers 0x0d, // PermissionL1 13210037SARM gem5 Developers 0x0e, // PermissionL2 13310037SARM gem5 Developers 0x0f, // PermissionL3 13410037SARM gem5 Developers 0x22, // DebugEvent 13510037SARM gem5 Developers 0x10, // SynchronousExternalAbort 13610037SARM gem5 Developers 0x30, // TLBConflictAbort 13710037SARM gem5 Developers 0x18, // SynchPtyErrOnMemoryAccess 13810037SARM gem5 Developers 0x11, // AsynchronousExternalAbort 13910037SARM gem5 Developers 0x19, // AsynchPtyErrOnMemoryAccess 14010037SARM gem5 Developers 0xff, // AddressSizeL0 (INVALID) 14110037SARM gem5 Developers 0xff, // AddressSizeL1 (INVALID) 14210037SARM gem5 Developers 0xff, // AddressSizeL2 (INVALID) 14310037SARM gem5 Developers 0xff, // AddressSizeL3 (INVALID) 14410037SARM gem5 Developers 0x40, // PrefetchTLBMiss 14510037SARM gem5 Developers 0x80 // PrefetchUncacheable 14610037SARM gem5 Developers}; 1476019Shines@cs.fsu.edu 14810037SARM gem5 Developersstatic_assert(sizeof(ArmFault::longDescFaultSources) == 14910037SARM gem5 Developers ArmFault::NumFaultSources, 15010037SARM gem5 Developers "Invalid size of ArmFault::longDescFaultSources[]"); 1516019Shines@cs.fsu.edu 15210037SARM gem5 Developersuint8_t ArmFault::aarch64FaultSources[] = { 15310037SARM gem5 Developers 0x21, // AlignmentFault 15410037SARM gem5 Developers 0xff, // InstructionCacheMaintenance (INVALID) 15510037SARM gem5 Developers 0x14, // SynchExtAbtOnTranslTableWalkL0 15610037SARM gem5 Developers 0x15, // SynchExtAbtOnTranslTableWalkL1 15710037SARM gem5 Developers 0x16, // SynchExtAbtOnTranslTableWalkL2 15810037SARM gem5 Developers 0x17, // SynchExtAbtOnTranslTableWalkL3 15910037SARM gem5 Developers 0x1c, // SynchPtyErrOnTranslTableWalkL0 16010037SARM gem5 Developers 0x1d, // SynchPtyErrOnTranslTableWalkL1 16110037SARM gem5 Developers 0x1e, // SynchPtyErrOnTranslTableWalkL2 16210037SARM gem5 Developers 0x1f, // SynchPtyErrOnTranslTableWalkL3 16310037SARM gem5 Developers 0x04, // TranslationL0 16410037SARM gem5 Developers 0x05, // TranslationL1 16510037SARM gem5 Developers 0x06, // TranslationL2 16610037SARM gem5 Developers 0x07, // TranslationL3 16710037SARM gem5 Developers 0x08, // AccessFlagL0 16810037SARM gem5 Developers 0x09, // AccessFlagL1 16910037SARM gem5 Developers 0x0a, // AccessFlagL2 17010037SARM gem5 Developers 0x0b, // AccessFlagL3 17110037SARM gem5 Developers // @todo: Section & Page Domain Fault in AArch64? 17210037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 17310037SARM gem5 Developers 0xff, // DomainL1 (INVALID) 17410037SARM gem5 Developers 0xff, // DomainL2 (INVALID) 17510037SARM gem5 Developers 0xff, // DomainL3 (INVALID) 17610037SARM gem5 Developers 0x0c, // PermissionL0 17710037SARM gem5 Developers 0x0d, // PermissionL1 17810037SARM gem5 Developers 0x0e, // PermissionL2 17910037SARM gem5 Developers 0x0f, // PermissionL3 18010037SARM gem5 Developers 0x22, // DebugEvent 18110037SARM gem5 Developers 0x10, // SynchronousExternalAbort 18210037SARM gem5 Developers 0x30, // TLBConflictAbort 18310037SARM gem5 Developers 0x18, // SynchPtyErrOnMemoryAccess 18410037SARM gem5 Developers 0xff, // AsynchronousExternalAbort (INVALID) 18510037SARM gem5 Developers 0xff, // AsynchPtyErrOnMemoryAccess (INVALID) 18610037SARM gem5 Developers 0x00, // AddressSizeL0 18710037SARM gem5 Developers 0x01, // AddressSizeL1 18810037SARM gem5 Developers 0x02, // AddressSizeL2 18910037SARM gem5 Developers 0x03, // AddressSizeL3 19010037SARM gem5 Developers 0x40, // PrefetchTLBMiss 19110037SARM gem5 Developers 0x80 // PrefetchUncacheable 19210037SARM gem5 Developers}; 1936019Shines@cs.fsu.edu 19410037SARM gem5 Developersstatic_assert(sizeof(ArmFault::aarch64FaultSources) == 19510037SARM gem5 Developers ArmFault::NumFaultSources, 19610037SARM gem5 Developers "Invalid size of ArmFault::aarch64FaultSources[]"); 1976019Shines@cs.fsu.edu 19810037SARM gem5 Developers// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode, 19910037SARM gem5 Developers// {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap, 20010037SARM gem5 Developers// {A, F} disable, class, stat 20112517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals( 20210037SARM gem5 Developers // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED 20310037SARM gem5 Developers // location in AArch64) 20410037SARM gem5 Developers "Reset", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 20512517Srekai.gonzalezalberquilla@arm.com 0, 0, 0, 0, false, true, true, EC_UNKNOWN 20612517Srekai.gonzalezalberquilla@arm.com); 20712517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals( 20810037SARM gem5 Developers "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED, 20912517Srekai.gonzalezalberquilla@arm.com 4, 2, 0, 0, true, false, false, EC_UNKNOWN 21012517Srekai.gonzalezalberquilla@arm.com); 21112517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals( 21210037SARM gem5 Developers "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 21312517Srekai.gonzalezalberquilla@arm.com 4, 2, 4, 2, true, false, false, EC_SVC_TO_HYP 21412517Srekai.gonzalezalberquilla@arm.com); 21512517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals( 21610037SARM gem5 Developers "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON, 21712517Srekai.gonzalezalberquilla@arm.com 4, 4, 4, 4, false, true, true, EC_SMC_TO_HYP 21812517Srekai.gonzalezalberquilla@arm.com); 21912517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals( 22010037SARM gem5 Developers "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 22112517Srekai.gonzalezalberquilla@arm.com 4, 4, 4, 4, true, false, false, EC_HVC 22212517Srekai.gonzalezalberquilla@arm.com); 22312517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals( 22410037SARM gem5 Developers "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22512517Srekai.gonzalezalberquilla@arm.com 4, 4, 0, 0, true, true, false, EC_PREFETCH_ABORT_TO_HYP 22612517Srekai.gonzalezalberquilla@arm.com); 22712517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals( 22810037SARM gem5 Developers "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22912517Srekai.gonzalezalberquilla@arm.com 8, 8, 0, 0, true, true, false, EC_DATA_ABORT_TO_HYP 23012517Srekai.gonzalezalberquilla@arm.com); 23112517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals( 23210037SARM gem5 Developers "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 23312517Srekai.gonzalezalberquilla@arm.com 8, 8, 0, 0, true, true, false, EC_INVALID 23412517Srekai.gonzalezalberquilla@arm.com); 23512517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals( 23610037SARM gem5 Developers // @todo: double check these values 23710037SARM gem5 Developers "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 23812517Srekai.gonzalezalberquilla@arm.com 0, 0, 0, 0, false, false, false, EC_UNKNOWN 23912517Srekai.gonzalezalberquilla@arm.com); 24012517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals( 24112512Sgiacomo.travaglini@arm.com "Secure Monitor Trap", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_MON, 24212517Srekai.gonzalezalberquilla@arm.com 4, 2, 0, 0, false, false, false, EC_UNKNOWN 24312517Srekai.gonzalezalberquilla@arm.com); 24412517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals( 24510037SARM gem5 Developers "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 24612517Srekai.gonzalezalberquilla@arm.com 4, 4, 0, 0, false, true, false, EC_UNKNOWN 24712517Srekai.gonzalezalberquilla@arm.com); 24812517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals( 24910037SARM gem5 Developers "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 25012517Srekai.gonzalezalberquilla@arm.com 4, 4, 0, 0, false, true, false, EC_INVALID 25112517Srekai.gonzalezalberquilla@arm.com); 25212517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals( 25310037SARM gem5 Developers "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25412517Srekai.gonzalezalberquilla@arm.com 4, 4, 0, 0, false, true, true, EC_UNKNOWN 25512517Srekai.gonzalezalberquilla@arm.com); 25612517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals( 25710037SARM gem5 Developers "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25812517Srekai.gonzalezalberquilla@arm.com 4, 4, 0, 0, false, true, true, EC_INVALID 25912517Srekai.gonzalezalberquilla@arm.com); 26012517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<IllegalInstSetStateFault>::vals( 26110037SARM gem5 Developers "Illegal Inst Set State Fault", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED, 26210037SARM gem5 Developers 4, 2, 0, 0, true, false, false, EC_ILLEGAL_INST 26312517Srekai.gonzalezalberquilla@arm.com); 26412517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals( 26512517Srekai.gonzalezalberquilla@arm.com // Some dummy values (SupervisorTrap is AArch64-only) 26610037SARM gem5 Developers "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 26710037SARM gem5 Developers 0, 0, 0, 0, false, false, false, EC_UNKNOWN 26812517Srekai.gonzalezalberquilla@arm.com); 26912517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals( 27012517Srekai.gonzalezalberquilla@arm.com // Some dummy values (PCAlignmentFault is AArch64-only) 27110037SARM gem5 Developers "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 27210037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_PC_ALIGNMENT 27312517Srekai.gonzalezalberquilla@arm.com); 27412517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals( 27512517Srekai.gonzalezalberquilla@arm.com // Some dummy values (SPAlignmentFault is AArch64-only) 27610037SARM gem5 Developers "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 27710037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_STACK_PTR_ALIGNMENT 27812517Srekai.gonzalezalberquilla@arm.com); 27912517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals( 28012517Srekai.gonzalezalberquilla@arm.com // Some dummy values (SError is AArch64-only) 28112299Sandreas.sandberg@arm.com "SError", 0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC, 28212299Sandreas.sandberg@arm.com 0, 0, 0, 0, false, true, true, EC_SERROR 28312517Srekai.gonzalezalberquilla@arm.com); 28412517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals( 28512517Srekai.gonzalezalberquilla@arm.com // Some dummy values (SoftwareBreakpoint is AArch64-only) 28610037SARM gem5 Developers "Software Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 28710037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_SOFTWARE_BREAKPOINT 28812517Srekai.gonzalezalberquilla@arm.com); 28912517Srekai.gonzalezalberquilla@arm.comtemplate<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals( 29012517Srekai.gonzalezalberquilla@arm.com // Some dummy values 29110037SARM gem5 Developers "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 29210037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_UNKNOWN 29312517Srekai.gonzalezalberquilla@arm.com); 29412517Srekai.gonzalezalberquilla@arm.com 2956019Shines@cs.fsu.eduAddr 29610037SARM gem5 DevelopersArmFault::getVector(ThreadContext *tc) 2977362Sgblack@eecs.umich.edu{ 2986735Sgblack@eecs.umich.edu Addr base; 29910037SARM gem5 Developers 3006019Shines@cs.fsu.edu // Check for invalid modes 30110037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 30210037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc) || cpsr.mode != MODE_MON); 3037400SAli.Saidi@ARM.com assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP); 3046735Sgblack@eecs.umich.edu 3056735Sgblack@eecs.umich.edu switch (cpsr.mode) 30610037SARM gem5 Developers { 3076735Sgblack@eecs.umich.edu case MODE_MON: 30810037SARM gem5 Developers base = tc->readMiscReg(MISCREG_MVBAR); 30910037SARM gem5 Developers break; 31010037SARM gem5 Developers case MODE_HYP: 31110037SARM gem5 Developers base = tc->readMiscReg(MISCREG_HVBAR); 3127400SAli.Saidi@ARM.com break; 31310037SARM gem5 Developers default: 31410037SARM gem5 Developers SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 31510037SARM gem5 Developers if (sctlr.v) { 31610037SARM gem5 Developers base = HighVecs; 31710037SARM gem5 Developers } else { 31810037SARM gem5 Developers base = ArmSystem::haveSecurity(tc) ? 31910037SARM gem5 Developers tc->readMiscReg(MISCREG_VBAR) : 0; 32010037SARM gem5 Developers } 32110037SARM gem5 Developers break; 32210037SARM gem5 Developers } 32310037SARM gem5 Developers 32410037SARM gem5 Developers return base + offset(tc); 32510037SARM gem5 Developers} 32610037SARM gem5 Developers 32710037SARM gem5 DevelopersAddr 32810037SARM gem5 DevelopersArmFault::getVector64(ThreadContext *tc) 32910037SARM gem5 Developers{ 3306019Shines@cs.fsu.edu Addr vbar; 3316019Shines@cs.fsu.edu switch (toEL) { 33210037SARM gem5 Developers case EL3: 33310037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 33410037SARM gem5 Developers vbar = tc->readMiscReg(MISCREG_VBAR_EL3); 33510037SARM gem5 Developers break; 33610037SARM gem5 Developers case EL2: 33710037SARM gem5 Developers assert(ArmSystem::haveVirtualization(tc)); 33810037SARM gem5 Developers vbar = tc->readMiscReg(MISCREG_VBAR_EL2); 33910037SARM gem5 Developers break; 34010037SARM gem5 Developers case EL1: 34111574SCurtis.Dunham@arm.com vbar = tc->readMiscReg(MISCREG_VBAR_EL1); 34211574SCurtis.Dunham@arm.com break; 34311574SCurtis.Dunham@arm.com default: 34411574SCurtis.Dunham@arm.com panic("Invalid target exception level"); 34510037SARM gem5 Developers break; 34610037SARM gem5 Developers } 34710037SARM gem5 Developers return vbar + offset64(tc); 34810037SARM gem5 Developers} 34910037SARM gem5 Developers 35010037SARM gem5 DevelopersMiscRegIndex 35110037SARM gem5 DevelopersArmFault::getSyndromeReg64() const 35212511Schuan.zhu@arm.com{ 35310037SARM gem5 Developers switch (toEL) { 35410037SARM gem5 Developers case EL1: 35510037SARM gem5 Developers return MISCREG_ESR_EL1; 35610037SARM gem5 Developers case EL2: 35710037SARM gem5 Developers return MISCREG_ESR_EL2; 35810037SARM gem5 Developers case EL3: 35910037SARM gem5 Developers return MISCREG_ESR_EL3; 36010037SARM gem5 Developers default: 36110037SARM gem5 Developers panic("Invalid exception level"); 36210037SARM gem5 Developers break; 36310037SARM gem5 Developers } 36410037SARM gem5 Developers} 36510037SARM gem5 Developers 36610037SARM gem5 DevelopersMiscRegIndex 36710037SARM gem5 DevelopersArmFault::getFaultAddrReg64() const 36810037SARM gem5 Developers{ 36910037SARM gem5 Developers switch (toEL) { 37010037SARM gem5 Developers case EL1: 37110037SARM gem5 Developers return MISCREG_FAR_EL1; 37210037SARM gem5 Developers case EL2: 37310037SARM gem5 Developers return MISCREG_FAR_EL2; 37410037SARM gem5 Developers case EL3: 37510037SARM gem5 Developers return MISCREG_FAR_EL3; 37610037SARM gem5 Developers default: 37710037SARM gem5 Developers panic("Invalid exception level"); 37810037SARM gem5 Developers break; 37910037SARM gem5 Developers } 38010037SARM gem5 Developers} 38110037SARM gem5 Developers 38210037SARM gem5 Developersvoid 38310037SARM gem5 DevelopersArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) 38410037SARM gem5 Developers{ 38510037SARM gem5 Developers uint32_t value; 38610037SARM gem5 Developers uint32_t exc_class = (uint32_t) ec(tc); 38710037SARM gem5 Developers uint32_t issVal = iss(); 38810037SARM gem5 Developers 38910037SARM gem5 Developers assert(!from64 || ArmSystem::highestELIs64(tc)); 39010037SARM gem5 Developers 39110037SARM gem5 Developers value = exc_class << 26; 39210037SARM gem5 Developers 39312402Sgiacomo.travaglini@arm.com // HSR.IL not valid for Prefetch Aborts (0x20, 0x21) and Data Aborts (0x24, 39410037SARM gem5 Developers // 0x25) for which the ISS information is not valid (ARMv7). 39510037SARM gem5 Developers // @todo: ARMv8 revises AArch32 functionality: when HSR.IL is not 39610037SARM gem5 Developers // valid it is treated as RES1. 39710037SARM gem5 Developers if (to64) { 39810037SARM gem5 Developers value |= 1 << 25; 39910037SARM gem5 Developers } else if ((bits(exc_class, 5, 3) != 4) || 40010037SARM gem5 Developers (bits(exc_class, 2) && bits(issVal, 24))) { 40110037SARM gem5 Developers if (!machInst.thumb || machInst.bigThumb) 40210037SARM gem5 Developers value |= 1 << 25; 40310037SARM gem5 Developers } 40410037SARM gem5 Developers // Condition code valid for EC[5:4] nonzero 40510037SARM gem5 Developers if (!from64 && ((bits(exc_class, 5, 4) == 0) && 40610037SARM gem5 Developers (bits(exc_class, 3, 0) != 0))) { 40710037SARM gem5 Developers if (!machInst.thumb) { 40810037SARM gem5 Developers uint32_t cond; 40910037SARM gem5 Developers ConditionCode condCode = (ConditionCode) (uint32_t) machInst.condCode; 41010037SARM gem5 Developers // If its on unconditional instruction report with a cond code of 41110037SARM gem5 Developers // 0xE, ie the unconditional code 41210037SARM gem5 Developers cond = (condCode == COND_UC) ? COND_AL : condCode; 41310037SARM gem5 Developers value |= cond << 20; 41410037SARM gem5 Developers value |= 1 << 24; 41510037SARM gem5 Developers } 41610037SARM gem5 Developers value |= bits(issVal, 19, 0); 41710037SARM gem5 Developers } else { 41810037SARM gem5 Developers value |= issVal; 41910037SARM gem5 Developers } 42010037SARM gem5 Developers tc->setMiscReg(syndrome_reg, value); 42110037SARM gem5 Developers} 42210037SARM gem5 Developers 42310037SARM gem5 Developersvoid 42410037SARM gem5 DevelopersArmFault::update(ThreadContext *tc) 42510037SARM gem5 Developers{ 42610037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 42710037SARM gem5 Developers 42810037SARM gem5 Developers // Determine source exception level and mode 42912569Sgiacomo.travaglini@arm.com fromMode = (OperatingMode) (uint8_t) cpsr.mode; 4306019Shines@cs.fsu.edu fromEL = opModeToEL(fromMode); 43110037SARM gem5 Developers if (opModeIs64(fromMode)) 43210037SARM gem5 Developers from64 = true; 43312569Sgiacomo.travaglini@arm.com 43412569Sgiacomo.travaglini@arm.com // Determine target exception level (aarch64) or target execution 43512569Sgiacomo.travaglini@arm.com // mode (aarch32). 43612569Sgiacomo.travaglini@arm.com if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) { 43712569Sgiacomo.travaglini@arm.com toMode = MODE_MON; 43810037SARM gem5 Developers toEL = EL3; 43912569Sgiacomo.travaglini@arm.com } else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) { 44012569Sgiacomo.travaglini@arm.com toMode = MODE_HYP; 44112569Sgiacomo.travaglini@arm.com toEL = EL2; 44212569Sgiacomo.travaglini@arm.com hypRouted = true; 44312569Sgiacomo.travaglini@arm.com } else { 44412569Sgiacomo.travaglini@arm.com toMode = nextMode(); 44512569Sgiacomo.travaglini@arm.com toEL = opModeToEL(toMode); 44612569Sgiacomo.travaglini@arm.com } 44712569Sgiacomo.travaglini@arm.com 44812569Sgiacomo.travaglini@arm.com if (fromEL > toEL) 44912569Sgiacomo.travaglini@arm.com toEL = fromEL; 45012569Sgiacomo.travaglini@arm.com 45112569Sgiacomo.travaglini@arm.com // Check for Set Priviledge Access Never, if PAN is supported 45212402Sgiacomo.travaglini@arm.com AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1); 45312569Sgiacomo.travaglini@arm.com if (mmfr1.pan) { 45412569Sgiacomo.travaglini@arm.com if (toEL == EL1) { 45510037SARM gem5 Developers const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1); 45612569Sgiacomo.travaglini@arm.com span = !sctlr.span; 45712569Sgiacomo.travaglini@arm.com } 45812569Sgiacomo.travaglini@arm.com 45912569Sgiacomo.travaglini@arm.com const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2); 46012569Sgiacomo.travaglini@arm.com if (toEL == EL2 && hcr.e2h && hcr.tge) { 46112569Sgiacomo.travaglini@arm.com const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2); 46212569Sgiacomo.travaglini@arm.com span = !sctlr.span; 46312569Sgiacomo.travaglini@arm.com } 46412569Sgiacomo.travaglini@arm.com } 46512569Sgiacomo.travaglini@arm.com 46612569Sgiacomo.travaglini@arm.com to64 = ELIs64(tc, toEL); 46712569Sgiacomo.travaglini@arm.com 46812569Sgiacomo.travaglini@arm.com // The fault specific informations have been updated; it is 46912569Sgiacomo.travaglini@arm.com // now possible to use them inside the fault. 47012569Sgiacomo.travaglini@arm.com faultUpdated = true; 47112569Sgiacomo.travaglini@arm.com} 47212569Sgiacomo.travaglini@arm.com 47312569Sgiacomo.travaglini@arm.comvoid 47412569Sgiacomo.travaglini@arm.comArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 47512569Sgiacomo.travaglini@arm.com{ 47612569Sgiacomo.travaglini@arm.com 47710037SARM gem5 Developers // Update fault state informations, like the starting mode (aarch32) 47810037SARM gem5 Developers // or EL (aarch64) and the ending mode or EL. 47910037SARM gem5 Developers // From the update function we are also evaluating if the fault must 48010037SARM gem5 Developers // be handled in AArch64 mode (to64). 48110037SARM gem5 Developers update(tc); 48210037SARM gem5 Developers 48310037SARM gem5 Developers if (to64) { 4846735Sgblack@eecs.umich.edu // Invoke exception handler in AArch64 state 4858782Sgblack@eecs.umich.edu invoke64(tc, inst); 4868782Sgblack@eecs.umich.edu return; 4876735Sgblack@eecs.umich.edu } 4886019Shines@cs.fsu.edu 4896735Sgblack@eecs.umich.edu // ARMv7 (ARM ARM issue C B1.9) 49010037SARM gem5 Developers 4918303SAli.Saidi@ARM.com bool have_security = ArmSystem::haveSecurity(tc); 49210338SCurtis.Dunham@arm.com 49310338SCurtis.Dunham@arm.com FaultBase::invoke(tc); 49410338SCurtis.Dunham@arm.com if (!FullSystem) 49510338SCurtis.Dunham@arm.com return; 4968303SAli.Saidi@ARM.com countStat()++; 4977720Sgblack@eecs.umich.edu 4988205SAli.Saidi@ARM.com SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 4998205SAli.Saidi@ARM.com SCR scr = tc->readMiscReg(MISCREG_SCR); 5008205SAli.Saidi@ARM.com CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR); 5016735Sgblack@eecs.umich.edu saved_cpsr.nz = tc->readCCReg(CCREG_NZ); 50210037SARM gem5 Developers saved_cpsr.c = tc->readCCReg(CCREG_C); 50310037SARM gem5 Developers saved_cpsr.v = tc->readCCReg(CCREG_V); 50410037SARM gem5 Developers saved_cpsr.ge = tc->readCCReg(CCREG_GE); 50510037SARM gem5 Developers 50612398Sgiacomo.travaglini@arm.com Addr curPc M5_VAR_USED = tc->pcState().pc(); 50710037SARM gem5 Developers ITSTATE it = tc->pcState().itstate(); 50810037SARM gem5 Developers saved_cpsr.it2 = it.top6; 50910037SARM gem5 Developers saved_cpsr.it1 = it.bottom2; 51010037SARM gem5 Developers 51110037SARM gem5 Developers // if we have a valid instruction then use it to annotate this fault with 51210037SARM gem5 Developers // extra information. This is used to generate the correct fault syndrome 51310037SARM gem5 Developers // information 51410037SARM gem5 Developers ArmStaticInst *arm_inst M5_VAR_USED = instrAnnotate(inst); 51510037SARM gem5 Developers 51610037SARM gem5 Developers // Ensure Secure state if initially in Monitor mode 51710037SARM gem5 Developers if (have_security && saved_cpsr.mode == MODE_MON) { 51810037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 51912569Sgiacomo.travaglini@arm.com if (scr.ns) { 52012569Sgiacomo.travaglini@arm.com scr.ns = 0; 52112569Sgiacomo.travaglini@arm.com tc->setMiscRegNoEffect(MISCREG_SCR, scr); 52210037SARM gem5 Developers } 52310037SARM gem5 Developers } 52410037SARM gem5 Developers 52510037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 52610037SARM gem5 Developers cpsr.mode = toMode; 52710037SARM gem5 Developers 52810037SARM gem5 Developers // some bits are set differently if we have been routed to hyp mode 52910037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 53010037SARM gem5 Developers SCTLR hsctlr = tc->readMiscReg(MISCREG_HSCTLR); 53110037SARM gem5 Developers cpsr.t = hsctlr.te; 53210037SARM gem5 Developers cpsr.e = hsctlr.ee; 53310037SARM gem5 Developers if (!scr.ea) {cpsr.a = 1;} 53410037SARM gem5 Developers if (!scr.fiq) {cpsr.f = 1;} 53510037SARM gem5 Developers if (!scr.irq) {cpsr.i = 1;} 53610037SARM gem5 Developers } else if (cpsr.mode == MODE_MON) { 53710037SARM gem5 Developers // Special case handling when entering monitor mode 53810037SARM gem5 Developers cpsr.t = sctlr.te; 53910037SARM gem5 Developers cpsr.e = sctlr.ee; 54010037SARM gem5 Developers cpsr.a = 1; 54110037SARM gem5 Developers cpsr.f = 1; 54210037SARM gem5 Developers cpsr.i = 1; 54310037SARM gem5 Developers } else { 54410037SARM gem5 Developers cpsr.t = sctlr.te; 54510037SARM gem5 Developers cpsr.e = sctlr.ee; 5466735Sgblack@eecs.umich.edu 5476735Sgblack@eecs.umich.edu // The *Disable functions are virtual and different per fault 5486735Sgblack@eecs.umich.edu cpsr.a = cpsr.a | abortDisable(tc); 54910037SARM gem5 Developers cpsr.f = cpsr.f | fiqDisable(tc); 5508518Sgeoffrey.blake@arm.com cpsr.i = 1; 5518518Sgeoffrey.blake@arm.com } 5526735Sgblack@eecs.umich.edu cpsr.it1 = cpsr.it2 = 0; 55310037SARM gem5 Developers cpsr.j = 0; 55410037SARM gem5 Developers cpsr.pan = span ? 1 : saved_cpsr.pan; 55510037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 55610037SARM gem5 Developers 55710037SARM gem5 Developers // Make sure mailbox sets to one always 55810037SARM gem5 Developers tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 55910037SARM gem5 Developers 56010037SARM gem5 Developers // Clear the exclusive monitor 56110037SARM gem5 Developers tc->setMiscReg(MISCREG_LOCKFLAG, 0); 56210037SARM gem5 Developers 56310037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 56410037SARM gem5 Developers tc->setMiscReg(MISCREG_ELR_HYP, curPc + 5656735Sgblack@eecs.umich.edu (saved_cpsr.t ? thumbPcOffset(true) : armPcOffset(true))); 5666735Sgblack@eecs.umich.edu } else { 5676735Sgblack@eecs.umich.edu tc->setIntReg(INTREG_LR, curPc + 5686735Sgblack@eecs.umich.edu (saved_cpsr.t ? thumbPcOffset(false) : armPcOffset(false))); 5696735Sgblack@eecs.umich.edu } 5706735Sgblack@eecs.umich.edu 5716735Sgblack@eecs.umich.edu switch (cpsr.mode) { 5726735Sgblack@eecs.umich.edu case MODE_FIQ: 5736735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 57410037SARM gem5 Developers break; 57510037SARM gem5 Developers case MODE_IRQ: 57610037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 5776735Sgblack@eecs.umich.edu break; 5786735Sgblack@eecs.umich.edu case MODE_SVC: 5796735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 5806735Sgblack@eecs.umich.edu break; 58110037SARM gem5 Developers case MODE_MON: 58210037SARM gem5 Developers assert(have_security); 58310037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_MON, saved_cpsr); 58410037SARM gem5 Developers break; 58510037SARM gem5 Developers case MODE_ABORT: 58610037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 58710037SARM gem5 Developers break; 58810037SARM gem5 Developers case MODE_UNDEFINED: 58910037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 59010037SARM gem5 Developers if (ec(tc) != EC_UNKNOWN) 5916735Sgblack@eecs.umich.edu setSyndrome(tc, MISCREG_HSR); 5926735Sgblack@eecs.umich.edu break; 5937093Sgblack@eecs.umich.edu case MODE_HYP: 5947093Sgblack@eecs.umich.edu assert(ArmSystem::haveVirtualization(tc)); 5957720Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr); 5967585SAli.Saidi@arm.com setSyndrome(tc, MISCREG_HSR); 5977720Sgblack@eecs.umich.edu break; 5987720Sgblack@eecs.umich.edu default: 5997720Sgblack@eecs.umich.edu panic("unknown Mode\n"); 6007720Sgblack@eecs.umich.edu } 6017720Sgblack@eecs.umich.edu 6027720Sgblack@eecs.umich.edu Addr newPc = getVector(tc); 60310037SARM gem5 Developers DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x " 60410037SARM gem5 Developers "%s\n", name(), cpsr, curPc, tc->readIntReg(INTREG_LR), 6057720Sgblack@eecs.umich.edu newPc, arm_inst ? csprintf("inst: %#x", arm_inst->encoding()) : 6066019Shines@cs.fsu.edu std::string()); 6077189Sgblack@eecs.umich.edu PCState pc(newPc); 6087400SAli.Saidi@ARM.com pc.thumb(cpsr.t); 60910417Sandreas.hansson@arm.com pc.nextThumb(pc.thumb()); 61010037SARM gem5 Developers pc.jazelle(cpsr.j); 61110037SARM gem5 Developers pc.nextJazelle(pc.jazelle()); 61210037SARM gem5 Developers pc.aarch64(!cpsr.width); 61310037SARM gem5 Developers pc.nextAArch64(!cpsr.width); 61410037SARM gem5 Developers pc.illegalExec(false); 61510037SARM gem5 Developers tc->pcState(pc); 61610037SARM gem5 Developers} 61710037SARM gem5 Developers 61811574SCurtis.Dunham@arm.comvoid 61911574SCurtis.Dunham@arm.comArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst) 62011574SCurtis.Dunham@arm.com{ 62111574SCurtis.Dunham@arm.com // Determine actual misc. register indices for ELR_ELx and SPSR_ELx 62211574SCurtis.Dunham@arm.com MiscRegIndex elr_idx, spsr_idx; 62310037SARM gem5 Developers switch (toEL) { 62410037SARM gem5 Developers case EL1: 62510037SARM gem5 Developers elr_idx = MISCREG_ELR_EL1; 62610037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL1; 62710037SARM gem5 Developers break; 62810037SARM gem5 Developers case EL2: 62910037SARM gem5 Developers assert(ArmSystem::haveVirtualization(tc)); 63010037SARM gem5 Developers elr_idx = MISCREG_ELR_EL2; 63110037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL2; 63210037SARM gem5 Developers break; 63310037SARM gem5 Developers case EL3: 63410037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 63510037SARM gem5 Developers elr_idx = MISCREG_ELR_EL3; 63610338SCurtis.Dunham@arm.com spsr_idx = MISCREG_SPSR_EL3; 63710338SCurtis.Dunham@arm.com break; 63810338SCurtis.Dunham@arm.com default: 63910037SARM gem5 Developers panic("Invalid target exception level"); 64010037SARM gem5 Developers break; 64110037SARM gem5 Developers } 64210037SARM gem5 Developers 64310037SARM gem5 Developers // Save process state into SPSR_ELx 64410037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 64510037SARM gem5 Developers CPSR spsr = cpsr; 64610037SARM gem5 Developers spsr.nz = tc->readCCReg(CCREG_NZ); 64710037SARM gem5 Developers spsr.c = tc->readCCReg(CCREG_C); 64810037SARM gem5 Developers spsr.v = tc->readCCReg(CCREG_V); 64910338SCurtis.Dunham@arm.com if (from64) { 65010037SARM gem5 Developers // Force some bitfields to 0 65110037SARM gem5 Developers spsr.q = 0; 65210037SARM gem5 Developers spsr.it1 = 0; 65310037SARM gem5 Developers spsr.j = 0; 65410037SARM gem5 Developers spsr.ge = 0; 65510037SARM gem5 Developers spsr.it2 = 0; 65610037SARM gem5 Developers spsr.t = 0; 65710037SARM gem5 Developers } else { 65810037SARM gem5 Developers spsr.ge = tc->readCCReg(CCREG_GE); 65910037SARM gem5 Developers ITSTATE it = tc->pcState().itstate(); 66010037SARM gem5 Developers spsr.it2 = it.top6; 66110037SARM gem5 Developers spsr.it1 = it.bottom2; 66210037SARM gem5 Developers // Force some bitfields to 0 66310037SARM gem5 Developers spsr.ss = 0; 66410037SARM gem5 Developers } 66510037SARM gem5 Developers tc->setMiscReg(spsr_idx, spsr); 66610037SARM gem5 Developers 66710037SARM gem5 Developers // Save preferred return address into ELR_ELx 66812511Schuan.zhu@arm.com Addr curr_pc = tc->pcState().pc(); 66912511Schuan.zhu@arm.com Addr ret_addr = curr_pc; 67010037SARM gem5 Developers if (from64) 67110037SARM gem5 Developers ret_addr += armPcElrOffset(); 67210037SARM gem5 Developers else 67310037SARM gem5 Developers ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset(); 67410037SARM gem5 Developers tc->setMiscReg(elr_idx, ret_addr); 67510037SARM gem5 Developers 67610037SARM gem5 Developers Addr vec_address = getVector64(tc); 67710037SARM gem5 Developers 67810037SARM gem5 Developers // Update process state 67910037SARM gem5 Developers OperatingMode64 mode = 0; 68010037SARM gem5 Developers mode.spX = 1; 68110037SARM gem5 Developers mode.el = toEL; 68212511Schuan.zhu@arm.com mode.width = 0; 68310037SARM gem5 Developers cpsr.mode = mode; 68410037SARM gem5 Developers cpsr.daif = 0xf; 68510037SARM gem5 Developers cpsr.il = 0; 68610037SARM gem5 Developers cpsr.ss = 0; 68710037SARM gem5 Developers cpsr.pan = span ? 1 : spsr.pan; 68810037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 68910037SARM gem5 Developers 69010037SARM gem5 Developers // If we have a valid instruction then use it to annotate this fault with 69110037SARM gem5 Developers // extra information. This is used to generate the correct fault syndrome 69210037SARM gem5 Developers // information 69310037SARM gem5 Developers ArmStaticInst *arm_inst M5_VAR_USED = instrAnnotate(inst); 69412398Sgiacomo.travaglini@arm.com 69510037SARM gem5 Developers // Set PC to start of exception handler 69610037SARM gem5 Developers Addr new_pc = purifyTaggedAddr(vec_address, tc, toEL); 69710037SARM gem5 Developers DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x " 69810037SARM gem5 Developers "elr:%#x newVec: %#x %s\n", name(), cpsr, curr_pc, ret_addr, 69910037SARM gem5 Developers new_pc, arm_inst ? csprintf("inst: %#x", arm_inst->encoding()) : 70010037SARM gem5 Developers std::string()); 70110417Sandreas.hansson@arm.com PCState pc(new_pc); 7027400SAli.Saidi@ARM.com pc.aarch64(!cpsr.width); 7038782Sgblack@eecs.umich.edu pc.nextAArch64(!cpsr.width); 70411150Smitch.hayenga@arm.com pc.illegalExec(false); 7058782Sgblack@eecs.umich.edu tc->pcState(pc); 7068782Sgblack@eecs.umich.edu 70710037SARM gem5 Developers // Save exception syndrome 70810037SARM gem5 Developers if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ)) 70910037SARM gem5 Developers setSyndrome(tc, getSyndromeReg64()); 71010037SARM gem5 Developers} 71110037SARM gem5 Developers 71210037SARM gem5 DevelopersArmStaticInst * 71310037SARM gem5 DevelopersArmFault::instrAnnotate(const StaticInstPtr &inst) 71410037SARM gem5 Developers{ 71510037SARM gem5 Developers if (inst) { 71610037SARM gem5 Developers auto arm_inst = static_cast<ArmStaticInst *>(inst.get()); 71710037SARM gem5 Developers arm_inst->annotateFault(this); 71810037SARM gem5 Developers return arm_inst; 71910037SARM gem5 Developers } else { 72010037SARM gem5 Developers return nullptr; 72110037SARM gem5 Developers } 72210037SARM gem5 Developers} 72310037SARM gem5 Developers 72410037SARM gem5 DevelopersAddr 72510037SARM gem5 DevelopersReset::getVector(ThreadContext *tc) 7267400SAli.Saidi@ARM.com{ 7277400SAli.Saidi@ARM.com Addr base; 7287189Sgblack@eecs.umich.edu 72910417Sandreas.hansson@arm.com // Check for invalid modes 7307189Sgblack@eecs.umich.edu CPSR M5_VAR_USED cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 7318782Sgblack@eecs.umich.edu assert(ArmSystem::haveSecurity(tc) || cpsr.mode != MODE_MON); 7328782Sgblack@eecs.umich.edu assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP); 7338806Sgblack@eecs.umich.edu 7348806Sgblack@eecs.umich.edu // RVBAR is aliased (implemented as) MVBAR in gem5, since the two 7358806Sgblack@eecs.umich.edu // are mutually exclusive; there is no need to check here for 7368806Sgblack@eecs.umich.edu // which register to use since they hold the same value 7378806Sgblack@eecs.umich.edu base = tc->readMiscReg(MISCREG_MVBAR); 7388806Sgblack@eecs.umich.edu 7398806Sgblack@eecs.umich.edu return base + offset(tc); 7408806Sgblack@eecs.umich.edu} 7418806Sgblack@eecs.umich.edu 7428806Sgblack@eecs.umich.eduvoid 7438806Sgblack@eecs.umich.eduReset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 7447189Sgblack@eecs.umich.edu{ 7458806Sgblack@eecs.umich.edu if (FullSystem) { 7468806Sgblack@eecs.umich.edu tc->getCpuPtr()->clearInterrupts(tc->threadId()); 7477189Sgblack@eecs.umich.edu tc->clearArchRegs(); 7487189Sgblack@eecs.umich.edu } 7497189Sgblack@eecs.umich.edu if (!ArmSystem::highestELIs64(tc)) { 75010037SARM gem5 Developers ArmFault::invoke(tc, inst); 75110037SARM gem5 Developers tc->setMiscReg(MISCREG_VMPIDR, 75210037SARM gem5 Developers getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc)); 75310037SARM gem5 Developers 75410037SARM gem5 Developers // Unless we have SMC code to get us there, boot in HYP! 75510037SARM gem5 Developers if (ArmSystem::haveVirtualization(tc) && 75610037SARM gem5 Developers !ArmSystem::haveSecurity(tc)) { 75710037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 75810037SARM gem5 Developers cpsr.mode = MODE_HYP; 75910037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 76010037SARM gem5 Developers } 76110037SARM gem5 Developers } else { 76210037SARM gem5 Developers // Advance the PC to the IMPLEMENTATION DEFINED reset value 76310037SARM gem5 Developers PCState pc = ArmSystem::resetAddr(tc); 76410037SARM gem5 Developers pc.aarch64(true); 76510037SARM gem5 Developers pc.nextAArch64(true); 76610037SARM gem5 Developers tc->pcState(pc); 76710037SARM gem5 Developers } 76810037SARM gem5 Developers} 76912402Sgiacomo.travaglini@arm.com 77012402Sgiacomo.travaglini@arm.comvoid 77112402Sgiacomo.travaglini@arm.comUndefinedInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst) 77212402Sgiacomo.travaglini@arm.com{ 77312402Sgiacomo.travaglini@arm.com if (FullSystem) { 77412402Sgiacomo.travaglini@arm.com ArmFault::invoke(tc, inst); 77510037SARM gem5 Developers return; 77610037SARM gem5 Developers } 77710037SARM gem5 Developers 77810037SARM gem5 Developers // If the mnemonic isn't defined this has to be an unknown instruction. 77910037SARM gem5 Developers assert(unknown || mnemonic != NULL); 78010037SARM gem5 Developers auto arm_inst = static_cast<ArmStaticInst *>(inst.get()); 78110037SARM gem5 Developers if (disabled) { 78210037SARM gem5 Developers panic("Attempted to execute disabled instruction " 78310037SARM gem5 Developers "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding()); 78410037SARM gem5 Developers } else if (unknown) { 78510037SARM gem5 Developers panic("Attempted to execute unknown instruction (inst 0x%08x)", 78610037SARM gem5 Developers arm_inst->encoding()); 78710037SARM gem5 Developers } else { 78810037SARM gem5 Developers panic("Attempted to execute unimplemented instruction " 78910037SARM gem5 Developers "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding()); 79010037SARM gem5 Developers } 79110037SARM gem5 Developers} 79210037SARM gem5 Developers 79310037SARM gem5 Developersbool 79410037SARM gem5 DevelopersUndefinedInstruction::routeToHyp(ThreadContext *tc) const 7957197Sgblack@eecs.umich.edu{ 79610417Sandreas.hansson@arm.com bool toHyp; 7977197Sgblack@eecs.umich.edu 7988782Sgblack@eecs.umich.edu SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 7998782Sgblack@eecs.umich.edu HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 8008806Sgblack@eecs.umich.edu CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 8018806Sgblack@eecs.umich.edu 8027197Sgblack@eecs.umich.edu // if in Hyp mode then stay in Hyp mode 8038806Sgblack@eecs.umich.edu toHyp = scr.ns && (cpsr.mode == MODE_HYP); 8048806Sgblack@eecs.umich.edu // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 8058806Sgblack@eecs.umich.edu toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 80610037SARM gem5 Developers return toHyp; 80710037SARM gem5 Developers} 80810037SARM gem5 Developers 80910037SARM gem5 Developersuint32_t 81010037SARM gem5 DevelopersUndefinedInstruction::iss() const 81110037SARM gem5 Developers{ 81211877Sbrandon.potter@amd.com 81311877Sbrandon.potter@amd.com // If UndefinedInstruction is routed to hypervisor, iss field is 0. 8148806Sgblack@eecs.umich.edu if (hypRouted) { 8158806Sgblack@eecs.umich.edu return 0; 8168806Sgblack@eecs.umich.edu } 8178806Sgblack@eecs.umich.edu 8188806Sgblack@eecs.umich.edu if (overrideEc == EC_INVALID) 8198806Sgblack@eecs.umich.edu return issRaw; 8207197Sgblack@eecs.umich.edu 8217197Sgblack@eecs.umich.edu uint32_t new_iss = 0; 82210037SARM gem5 Developers uint32_t op0, op1, op2, CRn, CRm, Rt, dir; 82310037SARM gem5 Developers 82410037SARM gem5 Developers dir = bits(machInst, 21, 21); 82510037SARM gem5 Developers op0 = bits(machInst, 20, 19); 82610037SARM gem5 Developers op1 = bits(machInst, 18, 16); 82710037SARM gem5 Developers CRn = bits(machInst, 15, 12); 82810037SARM gem5 Developers CRm = bits(machInst, 11, 8); 82910037SARM gem5 Developers op2 = bits(machInst, 7, 5); 83010037SARM gem5 Developers Rt = bits(machInst, 4, 0); 83110037SARM gem5 Developers 83210037SARM gem5 Developers new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 | 83310037SARM gem5 Developers Rt << 5 | CRm << 1 | dir; 83410037SARM gem5 Developers 83510037SARM gem5 Developers return new_iss; 83610037SARM gem5 Developers} 83710037SARM gem5 Developers 83810037SARM gem5 Developersvoid 83910037SARM gem5 DevelopersSupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 84010037SARM gem5 Developers{ 84110037SARM gem5 Developers if (FullSystem) { 84210037SARM gem5 Developers ArmFault::invoke(tc, inst); 84310037SARM gem5 Developers return; 84410037SARM gem5 Developers } 84510037SARM gem5 Developers 84610037SARM gem5 Developers // As of now, there isn't a 32 bit thumb version of this instruction. 84710037SARM gem5 Developers assert(!machInst.bigThumb); 84810037SARM gem5 Developers uint32_t callNum; 84910037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 85010037SARM gem5 Developers OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode; 85110037SARM gem5 Developers if (opModeIs64(mode)) 85210037SARM gem5 Developers callNum = tc->readIntReg(INTREG_X8); 85310037SARM gem5 Developers else 85410037SARM gem5 Developers callNum = tc->readIntReg(INTREG_R7); 85510037SARM gem5 Developers Fault fault; 85610037SARM gem5 Developers tc->syscall(callNum, &fault); 85710037SARM gem5 Developers 85810037SARM gem5 Developers // Advance the PC since that won't happen automatically. 85910037SARM gem5 Developers PCState pc = tc->pcState(); 86010037SARM gem5 Developers assert(inst); 86110037SARM gem5 Developers inst->advancePC(pc); 86210037SARM gem5 Developers tc->pcState(pc); 86310037SARM gem5 Developers} 86412402Sgiacomo.travaglini@arm.com 86512402Sgiacomo.travaglini@arm.combool 86612402Sgiacomo.travaglini@arm.comSupervisorCall::routeToHyp(ThreadContext *tc) const 86712402Sgiacomo.travaglini@arm.com{ 86812402Sgiacomo.travaglini@arm.com bool toHyp; 86912402Sgiacomo.travaglini@arm.com 87010037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 87110037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 87210037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 87310037SARM gem5 Developers 87410037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 87510037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 87610037SARM gem5 Developers // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 87710037SARM gem5 Developers toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 87811576SDylan.Johnson@ARM.com return toHyp; 87911576SDylan.Johnson@ARM.com} 88011576SDylan.Johnson@ARM.com 88111576SDylan.Johnson@ARM.comExceptionClass 88211576SDylan.Johnson@ARM.comSupervisorCall::ec(ThreadContext *tc) const 88311576SDylan.Johnson@ARM.com{ 88410037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : 88510037SARM gem5 Developers (from64 ? EC_SVC_64 : vals.ec); 88610037SARM gem5 Developers} 88710037SARM gem5 Developers 88810037SARM gem5 Developersuint32_t 88910037SARM gem5 DevelopersSupervisorCall::iss() const 89010037SARM gem5 Developers{ 89110037SARM gem5 Developers // Even if we have a 24 bit imm from an arm32 instruction then we only use 89210037SARM gem5 Developers // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC). 89310037SARM gem5 Developers return issRaw & 0xFFFF; 89410037SARM gem5 Developers} 89510037SARM gem5 Developers 89610037SARM gem5 Developersuint32_t 89710037SARM gem5 DevelopersSecureMonitorCall::iss() const 89810037SARM gem5 Developers{ 89910037SARM gem5 Developers if (from64) 90010037SARM gem5 Developers return bits(machInst, 20, 5); 90110037SARM gem5 Developers return 0; 90210037SARM gem5 Developers} 90310037SARM gem5 Developers 90410037SARM gem5 DevelopersExceptionClass 90510037SARM gem5 DevelopersUndefinedInstruction::ec(ThreadContext *tc) const 90610037SARM gem5 Developers{ 90710037SARM gem5 Developers // If UndefinedInstruction is routed to hypervisor, 90810037SARM gem5 Developers // HSR.EC field is 0. 90912511Schuan.zhu@arm.com if (hypRouted) 91012511Schuan.zhu@arm.com return EC_UNKNOWN; 91112511Schuan.zhu@arm.com else 91212511Schuan.zhu@arm.com return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 91312511Schuan.zhu@arm.com} 91412511Schuan.zhu@arm.com 91512511Schuan.zhu@arm.com 91612511Schuan.zhu@arm.comHypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) : 91712511Schuan.zhu@arm.com ArmFaultVals<HypervisorCall>(_machInst, _imm) 91812511Schuan.zhu@arm.com{} 91912511Schuan.zhu@arm.com 92012511Schuan.zhu@arm.comExceptionClass 92112511Schuan.zhu@arm.comHypervisorCall::ec(ThreadContext *tc) const 92212511Schuan.zhu@arm.com{ 92312511Schuan.zhu@arm.com return from64 ? EC_HVC_64 : vals.ec; 92412511Schuan.zhu@arm.com} 92512511Schuan.zhu@arm.com 92612511Schuan.zhu@arm.comExceptionClass 92712511Schuan.zhu@arm.comHypervisorTrap::ec(ThreadContext *tc) const 92812511Schuan.zhu@arm.com{ 92912511Schuan.zhu@arm.com return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 93012511Schuan.zhu@arm.com} 93112511Schuan.zhu@arm.com 93212511Schuan.zhu@arm.comtemplate<class T> 93312511Schuan.zhu@arm.comFaultOffset 93410037SARM gem5 DevelopersArmFaultVals<T>::offset(ThreadContext *tc) 93510037SARM gem5 Developers{ 93610037SARM gem5 Developers bool isHypTrap = false; 93710037SARM gem5 Developers 93810037SARM gem5 Developers // Normally we just use the exception vector from the table at the top if 93910037SARM gem5 Developers // this file, however if this exception has caused a transition to hype 94010037SARM gem5 Developers // mode, and its an exception type that would only do this if it has been 94110037SARM gem5 Developers // trapped then we use the hyp trap vector instead of the normal vector 94210037SARM gem5 Developers if (vals.hypTrappable) { 94310037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 94410037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 94510037SARM gem5 Developers CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 94610037SARM gem5 Developers isHypTrap = spsr.mode != MODE_HYP; 94710037SARM gem5 Developers } 94810037SARM gem5 Developers } 94910037SARM gem5 Developers return isHypTrap ? 0x14 : vals.offset; 95010417Sandreas.hansson@arm.com} 95110037SARM gem5 Developers 95210037SARM gem5 Developerstemplate<class T> 95310037SARM gem5 DevelopersFaultOffset 95410037SARM gem5 DevelopersArmFaultVals<T>::offset64(ThreadContext *tc) 95510037SARM gem5 Developers{ 95610037SARM gem5 Developers if (toEL == fromEL) { 95710037SARM gem5 Developers if (opModeIsT(fromMode)) 95810037SARM gem5 Developers return vals.currELTOffset; 95910037SARM gem5 Developers return vals.currELHOffset; 96010037SARM gem5 Developers } else { 96110037SARM gem5 Developers bool lower_32 = false; 96210037SARM gem5 Developers if (toEL == EL3) { 96310037SARM gem5 Developers if (!inSecureState(tc) && ArmSystem::haveEL(tc, EL2)) 96412509Schuan.zhu@arm.com lower_32 = ELIs32(tc, EL2); 96512509Schuan.zhu@arm.com else 96612509Schuan.zhu@arm.com lower_32 = ELIs32(tc, EL1); 96712509Schuan.zhu@arm.com } else { 96812509Schuan.zhu@arm.com lower_32 = ELIs32(tc, static_cast<ExceptionLevel>(toEL - 1)); 96912509Schuan.zhu@arm.com } 97012509Schuan.zhu@arm.com 97112509Schuan.zhu@arm.com if (lower_32) 97212509Schuan.zhu@arm.com return vals.lowerEL32Offset; 97312509Schuan.zhu@arm.com return vals.lowerEL64Offset; 97412509Schuan.zhu@arm.com } 97512509Schuan.zhu@arm.com} 97612509Schuan.zhu@arm.com 97712509Schuan.zhu@arm.com// void 97812509Schuan.zhu@arm.com// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx) 97912509Schuan.zhu@arm.com// { 98012509Schuan.zhu@arm.com// ESR esr = 0; 98112509Schuan.zhu@arm.com// esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32; 98212509Schuan.zhu@arm.com// esr.il = !machInst.thumb; 98312509Schuan.zhu@arm.com// if (machInst.aarch64) 98412509Schuan.zhu@arm.com// esr.imm16 = bits(machInst.instBits, 20, 5); 98512509Schuan.zhu@arm.com// else if (machInst.thumb) 98612509Schuan.zhu@arm.com// esr.imm16 = bits(machInst.instBits, 7, 0); 98712509Schuan.zhu@arm.com// else 98810037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 15, 0); 98910037SARM gem5 Developers// tc->setMiscReg(esr_idx, esr); 99010037SARM gem5 Developers// } 99112509Schuan.zhu@arm.com 99212509Schuan.zhu@arm.comvoid 99312509Schuan.zhu@arm.comSecureMonitorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 99412509Schuan.zhu@arm.com{ 99510037SARM gem5 Developers if (FullSystem) { 99610037SARM gem5 Developers ArmFault::invoke(tc, inst); 99710037SARM gem5 Developers return; 99810037SARM gem5 Developers } 99910037SARM gem5 Developers} 100010037SARM gem5 Developers 100110037SARM gem5 DevelopersExceptionClass 100210037SARM gem5 DevelopersSecureMonitorCall::ec(ThreadContext *tc) const 100310037SARM gem5 Developers{ 10047362Sgblack@eecs.umich.edu return (from64 ? EC_SMC_64 : vals.ec); 10057362Sgblack@eecs.umich.edu} 100610417Sandreas.hansson@arm.com 10077362Sgblack@eecs.umich.edubool 100810037SARM gem5 DevelopersSupervisorTrap::routeToHyp(ThreadContext *tc) const 100910037SARM gem5 Developers{ 101010037SARM gem5 Developers bool toHyp = false; 101110037SARM gem5 Developers 101210037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 101310037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2); 101410037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 101510037SARM gem5 Developers 101610037SARM gem5 Developers // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 101710037SARM gem5 Developers toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.el == EL0); 101810037SARM gem5 Developers return toHyp; 101910037SARM gem5 Developers} 102010037SARM gem5 Developers 102110037SARM gem5 Developersuint32_t 102210037SARM gem5 DevelopersSupervisorTrap::iss() const 102310037SARM gem5 Developers{ 102410037SARM gem5 Developers // If SupervisorTrap is routed to hypervisor, iss field is 0. 102510037SARM gem5 Developers if (hypRouted) { 102610037SARM gem5 Developers return 0; 102710037SARM gem5 Developers } 102810037SARM gem5 Developers return issRaw; 102910037SARM gem5 Developers} 103010037SARM gem5 Developers 103111150Smitch.hayenga@arm.comExceptionClass 103210037SARM gem5 DevelopersSupervisorTrap::ec(ThreadContext *tc) const 103310037SARM gem5 Developers{ 103410037SARM gem5 Developers if (hypRouted) 103510037SARM gem5 Developers return EC_UNKNOWN; 103610037SARM gem5 Developers else 103710037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 10388205SAli.Saidi@ARM.com} 103910037SARM gem5 Developers 104011496Sandreas.sandberg@arm.comExceptionClass 104112570Sgiacomo.travaglini@arm.comSecureMonitorTrap::ec(ThreadContext *tc) const 104210037SARM gem5 Developers{ 104310037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : 104410037SARM gem5 Developers (from64 ? EC_SMC_64 : vals.ec); 104510037SARM gem5 Developers} 104610037SARM gem5 Developers 104710037SARM gem5 Developerstemplate<class T> 104810037SARM gem5 Developersvoid 104910037SARM gem5 DevelopersAbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst) 105010037SARM gem5 Developers{ 105110037SARM gem5 Developers if (tranMethod == ArmFault::UnknownTran) { 105210037SARM gem5 Developers tranMethod = longDescFormatInUse(tc) ? ArmFault::LpaeTran 105310037SARM gem5 Developers : ArmFault::VmsaTran; 105410037SARM gem5 Developers 105510037SARM gem5 Developers if ((tranMethod == ArmFault::VmsaTran) && this->routeToMonitor(tc)) { 105611585SDylan.Johnson@ARM.com // See ARM ARM B3-1416 105711585SDylan.Johnson@ARM.com bool override_LPAE = false; 105811585SDylan.Johnson@ARM.com TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S); 105911585SDylan.Johnson@ARM.com TTBCR M5_VAR_USED ttbcr_ns = tc->readMiscReg(MISCREG_TTBCR_NS); 106011585SDylan.Johnson@ARM.com if (ttbcr_s.eae) { 106111585SDylan.Johnson@ARM.com override_LPAE = true; 106211585SDylan.Johnson@ARM.com } else { 106311585SDylan.Johnson@ARM.com // Unimplemented code option, not seen in testing. May need 106411585SDylan.Johnson@ARM.com // extension according to the manual exceprt above. 106511585SDylan.Johnson@ARM.com DPRINTF(Faults, "Warning: Incomplete translation method " 106611585SDylan.Johnson@ARM.com "override detected.\n"); 106710037SARM gem5 Developers } 106810037SARM gem5 Developers if (override_LPAE) 106910037SARM gem5 Developers tranMethod = ArmFault::LpaeTran; 107010037SARM gem5 Developers } 107112570Sgiacomo.travaglini@arm.com } 107212570Sgiacomo.travaglini@arm.com 107312570Sgiacomo.travaglini@arm.com if (source == ArmFault::AsynchronousExternalAbort) { 107412570Sgiacomo.travaglini@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 107512570Sgiacomo.travaglini@arm.com } 107612570Sgiacomo.travaglini@arm.com // Get effective fault source encoding 107712570Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 107812570Sgiacomo.travaglini@arm.com 107912570Sgiacomo.travaglini@arm.com // source must be determined BEFORE invoking generic routines which will 108012570Sgiacomo.travaglini@arm.com // try to set hsr etc. and are based upon source! 108112570Sgiacomo.travaglini@arm.com ArmFaultVals<T>::invoke(tc, inst); 108212570Sgiacomo.travaglini@arm.com 108312570Sgiacomo.travaglini@arm.com if (!this->to64) { // AArch32 108412570Sgiacomo.travaglini@arm.com FSR fsr = getFsr(tc); 108512570Sgiacomo.travaglini@arm.com if (cpsr.mode == MODE_HYP) { 108612570Sgiacomo.travaglini@arm.com tc->setMiscReg(T::HFarIndex, faultAddr); 108712570Sgiacomo.travaglini@arm.com } else if (stage2) { 108812570Sgiacomo.travaglini@arm.com tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf); 108912570Sgiacomo.travaglini@arm.com tc->setMiscReg(T::HFarIndex, OVAddr); 109012570Sgiacomo.travaglini@arm.com } else { 109112570Sgiacomo.travaglini@arm.com tc->setMiscReg(T::FsrIndex, fsr); 109212570Sgiacomo.travaglini@arm.com tc->setMiscReg(T::FarIndex, faultAddr); 109312570Sgiacomo.travaglini@arm.com } 109412570Sgiacomo.travaglini@arm.com DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x "\ 109512570Sgiacomo.travaglini@arm.com "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod); 109612570Sgiacomo.travaglini@arm.com } else { // AArch64 109712570Sgiacomo.travaglini@arm.com // Set the FAR register. Nothing else to do if we are in AArch64 state 109812570Sgiacomo.travaglini@arm.com // because the syndrome register has already been set inside invoke64() 109912570Sgiacomo.travaglini@arm.com if (stage2) { 110012570Sgiacomo.travaglini@arm.com // stage 2 fault, set HPFAR_EL2 to the faulting IPA 110112570Sgiacomo.travaglini@arm.com // and FAR_EL2 to the Original VA 110212570Sgiacomo.travaglini@arm.com tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), OVAddr); 110312570Sgiacomo.travaglini@arm.com tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4); 110412570Sgiacomo.travaglini@arm.com 110512570Sgiacomo.travaglini@arm.com DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n", 110612570Sgiacomo.travaglini@arm.com OVAddr, faultAddr); 110712570Sgiacomo.travaglini@arm.com } else { 110810037SARM gem5 Developers tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr); 110912570Sgiacomo.travaglini@arm.com } 111010037SARM gem5 Developers } 11117362Sgblack@eecs.umich.edu} 11128314Sgeoffrey.blake@arm.com 111312570Sgiacomo.travaglini@arm.comtemplate<class T> 111412570Sgiacomo.travaglini@arm.comvoid 111512570Sgiacomo.travaglini@arm.comAbortFault<T>::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) 111612570Sgiacomo.travaglini@arm.com{ 111712570Sgiacomo.travaglini@arm.com srcEncoded = getFaultStatusCode(tc); 111812570Sgiacomo.travaglini@arm.com if (srcEncoded == ArmFault::FaultSourceInvalid) { 111912570Sgiacomo.travaglini@arm.com panic("Invalid fault source\n"); 112010037SARM gem5 Developers } 112112570Sgiacomo.travaglini@arm.com ArmFault::setSyndrome(tc, syndrome_reg); 112212570Sgiacomo.travaglini@arm.com} 112312570Sgiacomo.travaglini@arm.com 112410037SARM gem5 Developerstemplate<class T> 112512570Sgiacomo.travaglini@arm.comuint8_t 112612570Sgiacomo.travaglini@arm.comAbortFault<T>::getFaultStatusCode(ThreadContext *tc) const 112712570Sgiacomo.travaglini@arm.com{ 112812570Sgiacomo.travaglini@arm.com 112910037SARM gem5 Developers panic_if(!this->faultUpdated, 113010037SARM gem5 Developers "Trying to use un-updated ArmFault internal variables\n"); 113110037SARM gem5 Developers 113210037SARM gem5 Developers uint8_t fsc = 0; 113310037SARM gem5 Developers 113410037SARM gem5 Developers if (!this->to64) { 113510037SARM gem5 Developers // AArch32 113610037SARM gem5 Developers assert(tranMethod != ArmFault::UnknownTran); 113710037SARM gem5 Developers if (tranMethod == ArmFault::LpaeTran) { 113810037SARM gem5 Developers fsc = ArmFault::longDescFaultSources[source]; 113910037SARM gem5 Developers } else { 114010037SARM gem5 Developers fsc = ArmFault::shortDescFaultSources[source]; 114110037SARM gem5 Developers } 114210037SARM gem5 Developers } else { 114310037SARM gem5 Developers // AArch64 114410037SARM gem5 Developers fsc = ArmFault::aarch64FaultSources[source]; 114510037SARM gem5 Developers } 114610037SARM gem5 Developers 114710037SARM gem5 Developers return fsc; 114810037SARM gem5 Developers} 114910037SARM gem5 Developers 115010037SARM gem5 Developerstemplate<class T> 115110037SARM gem5 DevelopersFSR 115210037SARM gem5 DevelopersAbortFault<T>::getFsr(ThreadContext *tc) const 115310037SARM gem5 Developers{ 115410037SARM gem5 Developers FSR fsr = 0; 115510037SARM gem5 Developers 115610037SARM gem5 Developers auto fsc = getFaultStatusCode(tc); 115710037SARM gem5 Developers 115810037SARM gem5 Developers // AArch32 115910037SARM gem5 Developers assert(tranMethod != ArmFault::UnknownTran); 116010037SARM gem5 Developers if (tranMethod == ArmFault::LpaeTran) { 116110037SARM gem5 Developers fsr.status = fsc; 116210037SARM gem5 Developers fsr.lpae = 1; 116310037SARM gem5 Developers } else { 116410037SARM gem5 Developers fsr.fsLow = bits(fsc, 3, 0); 116510037SARM gem5 Developers fsr.fsHigh = bits(fsc, 4); 116610037SARM gem5 Developers fsr.domain = static_cast<uint8_t>(domain); 116710037SARM gem5 Developers } 116810037SARM gem5 Developers 116910037SARM gem5 Developers fsr.wnr = (write ? 1 : 0); 117010037SARM gem5 Developers fsr.ext = 0; 117110037SARM gem5 Developers 117210037SARM gem5 Developers return fsr; 117310037SARM gem5 Developers} 117410037SARM gem5 Developers 117510037SARM gem5 Developerstemplate<class T> 117610037SARM gem5 Developersbool 117710037SARM gem5 DevelopersAbortFault<T>::abortDisable(ThreadContext *tc) 117810037SARM gem5 Developers{ 117910037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 118010037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 118110037SARM gem5 Developers return (!scr.ns || scr.aw); 118210037SARM gem5 Developers } 118310037SARM gem5 Developers return true; 118410037SARM gem5 Developers} 118510037SARM gem5 Developers 118610037SARM gem5 Developerstemplate<class T> 118710037SARM gem5 Developersvoid 118810037SARM gem5 DevelopersAbortFault<T>::annotate(ArmFault::AnnotationIDs id, uint64_t val) 118910037SARM gem5 Developers{ 119010037SARM gem5 Developers switch (id) 119110037SARM gem5 Developers { 119210037SARM gem5 Developers case ArmFault::S1PTW: 119310037SARM gem5 Developers s1ptw = val; 119410037SARM gem5 Developers break; 119510037SARM gem5 Developers case ArmFault::OVA: 119610037SARM gem5 Developers OVAddr = val; 119710037SARM gem5 Developers break; 119810037SARM gem5 Developers 119910037SARM gem5 Developers // Just ignore unknown ID's 120010037SARM gem5 Developers default: 120110037SARM gem5 Developers break; 120210037SARM gem5 Developers } 120310037SARM gem5 Developers} 120410037SARM gem5 Developers 120510037SARM gem5 Developerstemplate<class T> 120610037SARM gem5 Developersuint32_t 120710037SARM gem5 DevelopersAbortFault<T>::iss() const 120810037SARM gem5 Developers{ 120910037SARM gem5 Developers uint32_t val; 121010037SARM gem5 Developers 121110037SARM gem5 Developers val = srcEncoded & 0x3F; 121210037SARM gem5 Developers val |= write << 6; 121310037SARM gem5 Developers val |= s1ptw << 7; 121410037SARM gem5 Developers return (val); 121510037SARM gem5 Developers} 121610037SARM gem5 Developers 121710037SARM gem5 Developerstemplate<class T> 121810037SARM gem5 Developersbool 121910037SARM gem5 DevelopersAbortFault<T>::isMMUFault() const 122010037SARM gem5 Developers{ 122110037SARM gem5 Developers // NOTE: Not relying on LL information being aligned to lowest bits here 122210037SARM gem5 Developers return 122310037SARM gem5 Developers (source == ArmFault::AlignmentFault) || 122410037SARM gem5 Developers ((source >= ArmFault::TranslationLL) && 122510037SARM gem5 Developers (source < ArmFault::TranslationLL + 4)) || 122610037SARM gem5 Developers ((source >= ArmFault::AccessFlagLL) && 122710037SARM gem5 Developers (source < ArmFault::AccessFlagLL + 4)) || 122810037SARM gem5 Developers ((source >= ArmFault::DomainLL) && 122910037SARM gem5 Developers (source < ArmFault::DomainLL + 4)) || 123010037SARM gem5 Developers ((source >= ArmFault::PermissionLL) && 123110037SARM gem5 Developers (source < ArmFault::PermissionLL + 4)); 123210037SARM gem5 Developers} 123310037SARM gem5 Developers 123410037SARM gem5 Developerstemplate<class T> 123510037SARM gem5 Developersbool 123610037SARM gem5 DevelopersAbortFault<T>::getFaultVAddr(Addr &va) const 123710037SARM gem5 Developers{ 123810037SARM gem5 Developers va = (stage2 ? OVAddr : faultAddr); 123910037SARM gem5 Developers return true; 124010037SARM gem5 Developers} 124110037SARM gem5 Developers 124210037SARM gem5 DevelopersExceptionClass 124310037SARM gem5 DevelopersPrefetchAbort::ec(ThreadContext *tc) const 124411581SDylan.Johnson@ARM.com{ 124510037SARM gem5 Developers if (to64) { 124610037SARM gem5 Developers // AArch64 124710037SARM gem5 Developers if (toEL == fromEL) 124810037SARM gem5 Developers return EC_PREFETCH_ABORT_CURR_EL; 124910037SARM gem5 Developers else 125010037SARM gem5 Developers return EC_PREFETCH_ABORT_LOWER_EL; 125110037SARM gem5 Developers } else { 125210037SARM gem5 Developers // AArch32 125310037SARM gem5 Developers // Abort faults have different EC codes depending on whether 125410367SAndrew.Bardsley@arm.com // the fault originated within HYP mode, or not. So override 125510367SAndrew.Bardsley@arm.com // the method and add the extra adjustment of the EC value. 125610037SARM gem5 Developers 125710037SARM gem5 Developers ExceptionClass ec = ArmFaultVals<PrefetchAbort>::vals.ec; 125810037SARM gem5 Developers 125910037SARM gem5 Developers CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 126010037SARM gem5 Developers if (spsr.mode == MODE_HYP) { 126110037SARM gem5 Developers ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 126210037SARM gem5 Developers } 126310037SARM gem5 Developers return ec; 126410037SARM gem5 Developers } 126510037SARM gem5 Developers} 126610037SARM gem5 Developers 126710037SARM gem5 Developersbool 126810037SARM gem5 DevelopersPrefetchAbort::routeToMonitor(ThreadContext *tc) const 126910037SARM gem5 Developers{ 127010037SARM gem5 Developers SCR scr = 0; 127110037SARM gem5 Developers if (from64) 127210037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 127310037SARM gem5 Developers else 127410037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 127510037SARM gem5 Developers 127610037SARM gem5 Developers return scr.ea && !isMMUFault(); 127710037SARM gem5 Developers} 127810037SARM gem5 Developers 127910037SARM gem5 Developersbool 128010037SARM gem5 DevelopersPrefetchAbort::routeToHyp(ThreadContext *tc) const 128110037SARM gem5 Developers{ 128210037SARM gem5 Developers bool toHyp; 128310037SARM gem5 Developers 128410037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 128510037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 128610037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 128710037SARM gem5 Developers HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 128810037SARM gem5 Developers 128910037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 129010037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 129110037SARM gem5 Developers // otherwise, check whether to take to Hyp mode through Hyp Trap vector 129210037SARM gem5 Developers toHyp |= (stage2 || 129310037SARM gem5 Developers ( (source == DebugEvent) && hdcr.tde && (cpsr.mode != MODE_HYP)) || 129410037SARM gem5 Developers ( (source == SynchronousExternalAbort) && hcr.tge && (cpsr.mode == MODE_USER)) 129510037SARM gem5 Developers ) && !inSecureState(tc); 129610037SARM gem5 Developers return toHyp; 129710037SARM gem5 Developers} 129810037SARM gem5 Developers 129910037SARM gem5 DevelopersExceptionClass 130010037SARM gem5 DevelopersDataAbort::ec(ThreadContext *tc) const 130110037SARM gem5 Developers{ 130210037SARM gem5 Developers if (to64) { 130310037SARM gem5 Developers // AArch64 130410037SARM gem5 Developers if (source == ArmFault::AsynchronousExternalAbort) { 130510037SARM gem5 Developers panic("Asynchronous External Abort should be handled with " 130610037SARM gem5 Developers "SystemErrors (SErrors)!"); 130710037SARM gem5 Developers } 130810037SARM gem5 Developers if (toEL == fromEL) 130910037SARM gem5 Developers return EC_DATA_ABORT_CURR_EL; 131011581SDylan.Johnson@ARM.com else 131110037SARM gem5 Developers return EC_DATA_ABORT_LOWER_EL; 131210037SARM gem5 Developers } else { 131310037SARM gem5 Developers // AArch32 131410037SARM gem5 Developers // Abort faults have different EC codes depending on whether 131510037SARM gem5 Developers // the fault originated within HYP mode, or not. So override 131610037SARM gem5 Developers // the method and add the extra adjustment of the EC value. 131710037SARM gem5 Developers 131810037SARM gem5 Developers ExceptionClass ec = ArmFaultVals<DataAbort>::vals.ec; 131910037SARM gem5 Developers 132010037SARM gem5 Developers CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 132110037SARM gem5 Developers if (spsr.mode == MODE_HYP) { 132210037SARM gem5 Developers ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 132310037SARM gem5 Developers } 132410037SARM gem5 Developers return ec; 132510037SARM gem5 Developers } 132610037SARM gem5 Developers} 132710037SARM gem5 Developers 132810037SARM gem5 Developersbool 132910037SARM gem5 DevelopersDataAbort::routeToMonitor(ThreadContext *tc) const 133010037SARM gem5 Developers{ 133110037SARM gem5 Developers SCR scr = 0; 133210037SARM gem5 Developers if (from64) 133310037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 133410037SARM gem5 Developers else 133510037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 133610037SARM gem5 Developers 133710037SARM gem5 Developers return scr.ea && !isMMUFault(); 133810037SARM gem5 Developers} 133910037SARM gem5 Developers 134010037SARM gem5 Developersbool 134110037SARM gem5 DevelopersDataAbort::routeToHyp(ThreadContext *tc) const 134210037SARM gem5 Developers{ 134310037SARM gem5 Developers bool toHyp; 134410037SARM gem5 Developers 134510037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 134610037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 134710037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 134810037SARM gem5 Developers HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 134910037SARM gem5 Developers 135010037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 135110037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 135210037SARM gem5 Developers // otherwise, check whether to take to Hyp mode through Hyp Trap vector 135310037SARM gem5 Developers toHyp |= (stage2 || 135410037SARM gem5 Developers ( (cpsr.mode != MODE_HYP) && ( ((source == AsynchronousExternalAbort) && hcr.amo) || 135510037SARM gem5 Developers ((source == DebugEvent) && hdcr.tde) ) 135610037SARM gem5 Developers ) || 135710037SARM gem5 Developers ( (cpsr.mode == MODE_USER) && hcr.tge && 135810037SARM gem5 Developers ((source == AlignmentFault) || 135910037SARM gem5 Developers (source == SynchronousExternalAbort)) 136010037SARM gem5 Developers ) 136110037SARM gem5 Developers ) && !inSecureState(tc); 136210037SARM gem5 Developers return toHyp; 136310037SARM gem5 Developers} 136410037SARM gem5 Developers 136510037SARM gem5 Developersuint32_t 136610037SARM gem5 DevelopersDataAbort::iss() const 136710037SARM gem5 Developers{ 136810037SARM gem5 Developers uint32_t val; 136910037SARM gem5 Developers 137010037SARM gem5 Developers // Add on the data abort specific fields to the generic abort ISS value 137110417Sandreas.hansson@arm.com val = AbortFault<DataAbort>::iss(); 137210037SARM gem5 Developers // ISS is valid if not caused by a stage 1 page table walk, and when taken 137310037SARM gem5 Developers // to AArch64 only when directed to EL2 137410037SARM gem5 Developers if (!s1ptw && (!to64 || toEL == EL2)) { 137510037SARM gem5 Developers val |= isv << 24; 137610037SARM gem5 Developers if (isv) { 137710037SARM gem5 Developers val |= sas << 22; 137810037SARM gem5 Developers val |= sse << 21; 137910037SARM gem5 Developers val |= srt << 16; 138010037SARM gem5 Developers // AArch64 only. These assignments are safe on AArch32 as well 138110037SARM gem5 Developers // because these vars are initialized to false 138210037SARM gem5 Developers val |= sf << 15; 138310037SARM gem5 Developers val |= ar << 14; 138410037SARM gem5 Developers } 138510037SARM gem5 Developers } 138610037SARM gem5 Developers return (val); 138710037SARM gem5 Developers} 138810037SARM gem5 Developers 138910037SARM gem5 Developersvoid 139010037SARM gem5 DevelopersDataAbort::annotate(AnnotationIDs id, uint64_t val) 139110037SARM gem5 Developers{ 139210037SARM gem5 Developers AbortFault<DataAbort>::annotate(id, val); 139310037SARM gem5 Developers switch (id) 139410037SARM gem5 Developers { 139510037SARM gem5 Developers case SAS: 139610037SARM gem5 Developers isv = true; 139710037SARM gem5 Developers sas = val; 139810037SARM gem5 Developers break; 139910037SARM gem5 Developers case SSE: 140011581SDylan.Johnson@ARM.com isv = true; 140110037SARM gem5 Developers sse = val; 140210037SARM gem5 Developers break; 140310037SARM gem5 Developers case SRT: 140410037SARM gem5 Developers isv = true; 140510037SARM gem5 Developers srt = val; 140610037SARM gem5 Developers break; 140710037SARM gem5 Developers case SF: 140810037SARM gem5 Developers isv = true; 140910037SARM gem5 Developers sf = val; 141010037SARM gem5 Developers break; 141110037SARM gem5 Developers case AR: 141210037SARM gem5 Developers isv = true; 141310037SARM gem5 Developers ar = val; 141410037SARM gem5 Developers break; 141510037SARM gem5 Developers // Just ignore unknown ID's 141610037SARM gem5 Developers default: 141710037SARM gem5 Developers break; 141810037SARM gem5 Developers } 141910037SARM gem5 Developers} 142010037SARM gem5 Developers 142110037SARM gem5 Developersvoid 142210037SARM gem5 DevelopersVirtualDataAbort::invoke(ThreadContext *tc, const StaticInstPtr &inst) 142310037SARM gem5 Developers{ 142410037SARM gem5 Developers AbortFault<VirtualDataAbort>::invoke(tc, inst); 142510037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 142610037SARM gem5 Developers hcr.va = 0; 142710037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_HCR, hcr); 142810037SARM gem5 Developers} 142910037SARM gem5 Developers 143010037SARM gem5 Developersbool 143110037SARM gem5 DevelopersInterrupt::routeToMonitor(ThreadContext *tc) const 143210037SARM gem5 Developers{ 143310037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 143410037SARM gem5 Developers SCR scr = 0; 143510037SARM gem5 Developers if (from64) 143610037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 143710037SARM gem5 Developers else 143810037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 143911581SDylan.Johnson@ARM.com return scr.irq; 144010037SARM gem5 Developers} 144110037SARM gem5 Developers 144210037SARM gem5 Developersbool 144310037SARM gem5 DevelopersInterrupt::routeToHyp(ThreadContext *tc) const 144410037SARM gem5 Developers{ 144510037SARM gem5 Developers bool toHyp; 144610037SARM gem5 Developers 144710037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 144810037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 144910037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 145010037SARM gem5 Developers // Determine whether IRQs are routed to Hyp mode. 145110037SARM gem5 Developers toHyp = (!scr.irq && hcr.imo && !inSecureState(tc)) || 145210037SARM gem5 Developers (cpsr.mode == MODE_HYP); 145310037SARM gem5 Developers return toHyp; 145410037SARM gem5 Developers} 145510037SARM gem5 Developers 145610037SARM gem5 Developersbool 145710037SARM gem5 DevelopersInterrupt::abortDisable(ThreadContext *tc) 145810037SARM gem5 Developers{ 145910037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 146010037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 146110037SARM gem5 Developers return (!scr.ns || scr.aw); 146210037SARM gem5 Developers } 146310037SARM gem5 Developers return true; 146410037SARM gem5 Developers} 146510037SARM gem5 Developers 146610037SARM gem5 DevelopersVirtualInterrupt::VirtualInterrupt() 146710037SARM gem5 Developers{} 146810037SARM gem5 Developers 146910037SARM gem5 Developersbool 147010417Sandreas.hansson@arm.comFastInterrupt::routeToMonitor(ThreadContext *tc) const 147110037SARM gem5 Developers{ 147210037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 147310037SARM gem5 Developers SCR scr = 0; 147410037SARM gem5 Developers if (from64) 147510037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 147610037SARM gem5 Developers else 147710037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 147812568Sgiacomo.travaglini@arm.com return scr.fiq; 147912568Sgiacomo.travaglini@arm.com} 148012568Sgiacomo.travaglini@arm.com 148112568Sgiacomo.travaglini@arm.combool 148212568Sgiacomo.travaglini@arm.comFastInterrupt::routeToHyp(ThreadContext *tc) const 148312568Sgiacomo.travaglini@arm.com{ 148412568Sgiacomo.travaglini@arm.com bool toHyp; 148512568Sgiacomo.travaglini@arm.com 148612568Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 148712568Sgiacomo.travaglini@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 148812568Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 148912568Sgiacomo.travaglini@arm.com // Determine whether IRQs are routed to Hyp mode. 149012568Sgiacomo.travaglini@arm.com toHyp = (!scr.fiq && hcr.fmo && !inSecureState(tc)) || 149112568Sgiacomo.travaglini@arm.com (cpsr.mode == MODE_HYP); 149210037SARM gem5 Developers return toHyp; 149310037SARM gem5 Developers} 149410037SARM gem5 Developers 149510037SARM gem5 Developersbool 149610037SARM gem5 DevelopersFastInterrupt::abortDisable(ThreadContext *tc) 149710037SARM gem5 Developers{ 149810037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 149910417Sandreas.hansson@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 150010037SARM gem5 Developers return (!scr.ns || scr.aw); 150111150Smitch.hayenga@arm.com } 150210037SARM gem5 Developers return true; 150310037SARM gem5 Developers} 150410037SARM gem5 Developers 150510037SARM gem5 Developersbool 150610037SARM gem5 DevelopersFastInterrupt::fiqDisable(ThreadContext *tc) 150710037SARM gem5 Developers{ 150810037SARM gem5 Developers if (ArmSystem::haveVirtualization(tc)) { 150910037SARM gem5 Developers return true; 151010037SARM gem5 Developers } else if (ArmSystem::haveSecurity(tc)) { 151110037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 151210037SARM gem5 Developers return (!scr.ns || scr.fw); 151310037SARM gem5 Developers } 151410037SARM gem5 Developers return true; 151510037SARM gem5 Developers} 151610037SARM gem5 Developers 151710037SARM gem5 DevelopersVirtualFastInterrupt::VirtualFastInterrupt() 151810037SARM gem5 Developers{} 151910037SARM gem5 Developers 152010037SARM gem5 Developersvoid 152110037SARM gem5 DevelopersPCAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 152210037SARM gem5 Developers{ 152311581SDylan.Johnson@ARM.com ArmFaultVals<PCAlignmentFault>::invoke(tc, inst); 152411581SDylan.Johnson@ARM.com assert(from64); 152510037SARM gem5 Developers // Set the FAR 15267362Sgblack@eecs.umich.edu tc->setMiscReg(getFaultAddrReg64(), faultPC); 15277362Sgblack@eecs.umich.edu} 152812299Sandreas.sandberg@arm.com 152912299Sandreas.sandberg@arm.combool 153012299Sandreas.sandberg@arm.comPCAlignmentFault::routeToHyp(ThreadContext *tc) const 153112299Sandreas.sandberg@arm.com{ 153212299Sandreas.sandberg@arm.com bool toHyp = false; 153312299Sandreas.sandberg@arm.com 153412299Sandreas.sandberg@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 153512299Sandreas.sandberg@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2); 153612299Sandreas.sandberg@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 153712299Sandreas.sandberg@arm.com 153812299Sandreas.sandberg@arm.com // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 153912299Sandreas.sandberg@arm.com toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.el == EL0); 154012299Sandreas.sandberg@arm.com return toHyp; 154112299Sandreas.sandberg@arm.com} 154212299Sandreas.sandberg@arm.com 154312299Sandreas.sandberg@arm.comSPAlignmentFault::SPAlignmentFault() 154412299Sandreas.sandberg@arm.com{} 154512299Sandreas.sandberg@arm.com 154612299Sandreas.sandberg@arm.comSystemError::SystemError() 15477652Sminkyu.jeong@arm.com{} 154810417Sandreas.hansson@arm.com 15498518Sgeoffrey.blake@arm.comvoid 15508806Sgblack@eecs.umich.eduSystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst) 15518806Sgblack@eecs.umich.edu{ 15528806Sgblack@eecs.umich.edu tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 15538806Sgblack@eecs.umich.edu ArmFault::invoke(tc, inst); 15548806Sgblack@eecs.umich.edu} 15558806Sgblack@eecs.umich.edu 15568806Sgblack@eecs.umich.edubool 155711150Smitch.hayenga@arm.comSystemError::routeToMonitor(ThreadContext *tc) const 15588518Sgeoffrey.blake@arm.com{ 15598518Sgeoffrey.blake@arm.com assert(ArmSystem::haveSecurity(tc)); 156010037SARM gem5 Developers assert(from64); 156110037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 156210037SARM gem5 Developers return scr.ea; 156310037SARM gem5 Developers} 156410037SARM gem5 Developers 156510037SARM gem5 Developersbool 156610037SARM gem5 DevelopersSystemError::routeToHyp(ThreadContext *tc) const 156710037SARM gem5 Developers{ 156810037SARM gem5 Developers bool toHyp; 156910037SARM gem5 Developers assert(from64); 157010037SARM gem5 Developers 157110037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 157210037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 157310037SARM gem5 Developers 157410037SARM gem5 Developers toHyp = (!scr.ea && hcr.amo && !inSecureState(tc)) || 157510037SARM gem5 Developers (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(tc)); 157610037SARM gem5 Developers return toHyp; 157710037SARM gem5 Developers} 157810037SARM gem5 Developers 157912299Sandreas.sandberg@arm.com 158010037SARM gem5 DevelopersSoftwareBreakpoint::SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss) 158110037SARM gem5 Developers : ArmFaultVals<SoftwareBreakpoint>(_mach_inst, _iss) 158210037SARM gem5 Developers{} 158310037SARM gem5 Developers 158410037SARM gem5 Developersbool 158510037SARM gem5 DevelopersSoftwareBreakpoint::routeToHyp(ThreadContext *tc) const 158610037SARM gem5 Developers{ 158710037SARM gem5 Developers const bool have_el2 = ArmSystem::haveVirtualization(tc); 158810037SARM gem5 Developers 15896019Shines@cs.fsu.edu const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2); 15906019Shines@cs.fsu.edu const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2); 1591 1592 return have_el2 && !inSecureState(tc) && fromEL <= EL1 && 1593 (hcr.tge || mdcr.tde); 1594} 1595 1596ExceptionClass 1597SoftwareBreakpoint::ec(ThreadContext *tc) const 1598{ 1599 return from64 ? EC_SOFTWARE_BREAKPOINT_64 : vals.ec; 1600} 1601 1602void 1603ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 1604 DPRINTF(Faults, "Invoking ArmSev Fault\n"); 1605 if (!FullSystem) 1606 return; 1607 1608 // Set sev_mailbox to 1, clear the pending interrupt from remote 1609 // SEV execution and let pipeline continue as pcState is still 1610 // valid. 1611 tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 1612 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0); 1613} 1614 1615// Instantiate all the templates to make the linker happy 1616template class ArmFaultVals<Reset>; 1617template class ArmFaultVals<UndefinedInstruction>; 1618template class ArmFaultVals<SupervisorCall>; 1619template class ArmFaultVals<SecureMonitorCall>; 1620template class ArmFaultVals<HypervisorCall>; 1621template class ArmFaultVals<PrefetchAbort>; 1622template class ArmFaultVals<DataAbort>; 1623template class ArmFaultVals<VirtualDataAbort>; 1624template class ArmFaultVals<HypervisorTrap>; 1625template class ArmFaultVals<Interrupt>; 1626template class ArmFaultVals<VirtualInterrupt>; 1627template class ArmFaultVals<FastInterrupt>; 1628template class ArmFaultVals<VirtualFastInterrupt>; 1629template class ArmFaultVals<SupervisorTrap>; 1630template class ArmFaultVals<SecureMonitorTrap>; 1631template class ArmFaultVals<PCAlignmentFault>; 1632template class ArmFaultVals<SPAlignmentFault>; 1633template class ArmFaultVals<SystemError>; 1634template class ArmFaultVals<SoftwareBreakpoint>; 1635template class ArmFaultVals<ArmSev>; 1636template class AbortFault<PrefetchAbort>; 1637template class AbortFault<DataAbort>; 1638template class AbortFault<VirtualDataAbort>; 1639 1640 1641IllegalInstSetStateFault::IllegalInstSetStateFault() 1642{} 1643 1644bool 1645getFaultVAddr(Fault fault, Addr &va) 1646{ 1647 auto arm_fault = dynamic_cast<ArmFault *>(fault.get()); 1648 1649 if (arm_fault) { 1650 return arm_fault->getFaultVAddr(va); 1651 } else { 1652 auto pgt_fault = dynamic_cast<GenericPageTableFault *>(fault.get()); 1653 if (pgt_fault) { 1654 va = pgt_fault->getFaultVAddr(); 1655 return true; 1656 } 1657 1658 auto align_fault = dynamic_cast<GenericAlignmentFault *>(fault.get()); 1659 if (align_fault) { 1660 va = align_fault->getFaultVAddr(); 1661 return true; 1662 } 1663 1664 // Return false since it's not an address triggered exception 1665 return false; 1666 } 1667} 1668 1669} // namespace ArmISA 1670