faults.cc revision 11578
16019Shines@cs.fsu.edu/* 211496Sandreas.sandberg@arm.com * Copyright (c) 2010, 2012-2014, 2016 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" 4810037SARM gem5 Developers#include "arch/arm/system.hh" 4910037SARM gem5 Developers#include "arch/arm/utility.hh" 5010037SARM gem5 Developers#include "arch/arm/insts/static_inst.hh" 5110037SARM gem5 Developers#include "base/compiler.hh" 528229Snate@binkert.org#include "base/trace.hh" 538229Snate@binkert.org#include "cpu/base.hh" 546019Shines@cs.fsu.edu#include "cpu/thread_context.hh" 558232Snate@binkert.org#include "debug/Faults.hh" 568782Sgblack@eecs.umich.edu#include "sim/full_system.hh" 576019Shines@cs.fsu.edu 586019Shines@cs.fsu.edunamespace ArmISA 596019Shines@cs.fsu.edu{ 606019Shines@cs.fsu.edu 6110037SARM gem5 Developersuint8_t ArmFault::shortDescFaultSources[] = { 6210037SARM gem5 Developers 0x01, // AlignmentFault 6310037SARM gem5 Developers 0x04, // InstructionCacheMaintenance 6410037SARM gem5 Developers 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 6510037SARM gem5 Developers 0x0c, // SynchExtAbtOnTranslTableWalkL1 6610037SARM gem5 Developers 0x0e, // SynchExtAbtOnTranslTableWalkL2 6710037SARM gem5 Developers 0xff, // SynchExtAbtOnTranslTableWalkL3 (INVALID) 6810037SARM gem5 Developers 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 6910037SARM gem5 Developers 0x1c, // SynchPtyErrOnTranslTableWalkL1 7010037SARM gem5 Developers 0x1e, // SynchPtyErrOnTranslTableWalkL2 7110037SARM gem5 Developers 0xff, // SynchPtyErrOnTranslTableWalkL3 (INVALID) 7210037SARM gem5 Developers 0xff, // TranslationL0 (INVALID) 7310037SARM gem5 Developers 0x05, // TranslationL1 7410037SARM gem5 Developers 0x07, // TranslationL2 7510037SARM gem5 Developers 0xff, // TranslationL3 (INVALID) 7610037SARM gem5 Developers 0xff, // AccessFlagL0 (INVALID) 7710037SARM gem5 Developers 0x03, // AccessFlagL1 7810037SARM gem5 Developers 0x06, // AccessFlagL2 7910037SARM gem5 Developers 0xff, // AccessFlagL3 (INVALID) 8010037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 8110037SARM gem5 Developers 0x09, // DomainL1 8210037SARM gem5 Developers 0x0b, // DomainL2 8310037SARM gem5 Developers 0xff, // DomainL3 (INVALID) 8410037SARM gem5 Developers 0xff, // PermissionL0 (INVALID) 8510037SARM gem5 Developers 0x0d, // PermissionL1 8610037SARM gem5 Developers 0x0f, // PermissionL2 8710037SARM gem5 Developers 0xff, // PermissionL3 (INVALID) 8810037SARM gem5 Developers 0x02, // DebugEvent 8910037SARM gem5 Developers 0x08, // SynchronousExternalAbort 9010037SARM gem5 Developers 0x10, // TLBConflictAbort 9110037SARM gem5 Developers 0x19, // SynchPtyErrOnMemoryAccess 9210037SARM gem5 Developers 0x16, // AsynchronousExternalAbort 9310037SARM gem5 Developers 0x18, // AsynchPtyErrOnMemoryAccess 9410037SARM gem5 Developers 0xff, // AddressSizeL0 (INVALID) 9510037SARM gem5 Developers 0xff, // AddressSizeL1 (INVALID) 9610037SARM gem5 Developers 0xff, // AddressSizeL2 (INVALID) 9710037SARM gem5 Developers 0xff, // AddressSizeL3 (INVALID) 9810037SARM gem5 Developers 0x40, // PrefetchTLBMiss 9910037SARM gem5 Developers 0x80 // PrefetchUncacheable 10010037SARM gem5 Developers}; 1016019Shines@cs.fsu.edu 10210037SARM gem5 Developersstatic_assert(sizeof(ArmFault::shortDescFaultSources) == 10310037SARM gem5 Developers ArmFault::NumFaultSources, 10410037SARM gem5 Developers "Invalid size of ArmFault::shortDescFaultSources[]"); 1056019Shines@cs.fsu.edu 10610037SARM gem5 Developersuint8_t ArmFault::longDescFaultSources[] = { 10710037SARM gem5 Developers 0x21, // AlignmentFault 10810037SARM gem5 Developers 0xff, // InstructionCacheMaintenance (INVALID) 10910037SARM gem5 Developers 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 11010037SARM gem5 Developers 0x15, // SynchExtAbtOnTranslTableWalkL1 11110037SARM gem5 Developers 0x16, // SynchExtAbtOnTranslTableWalkL2 11210037SARM gem5 Developers 0x17, // SynchExtAbtOnTranslTableWalkL3 11310037SARM gem5 Developers 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 11410037SARM gem5 Developers 0x1d, // SynchPtyErrOnTranslTableWalkL1 11510037SARM gem5 Developers 0x1e, // SynchPtyErrOnTranslTableWalkL2 11610037SARM gem5 Developers 0x1f, // SynchPtyErrOnTranslTableWalkL3 11710037SARM gem5 Developers 0xff, // TranslationL0 (INVALID) 11810037SARM gem5 Developers 0x05, // TranslationL1 11910037SARM gem5 Developers 0x06, // TranslationL2 12010037SARM gem5 Developers 0x07, // TranslationL3 12110037SARM gem5 Developers 0xff, // AccessFlagL0 (INVALID) 12210037SARM gem5 Developers 0x09, // AccessFlagL1 12310037SARM gem5 Developers 0x0a, // AccessFlagL2 12410037SARM gem5 Developers 0x0b, // AccessFlagL3 12510037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 12610037SARM gem5 Developers 0x3d, // DomainL1 12710037SARM gem5 Developers 0x3e, // DomainL2 12810037SARM gem5 Developers 0xff, // DomainL3 (RESERVED) 12910037SARM gem5 Developers 0xff, // PermissionL0 (INVALID) 13010037SARM gem5 Developers 0x0d, // PermissionL1 13110037SARM gem5 Developers 0x0e, // PermissionL2 13210037SARM gem5 Developers 0x0f, // PermissionL3 13310037SARM gem5 Developers 0x22, // DebugEvent 13410037SARM gem5 Developers 0x10, // SynchronousExternalAbort 13510037SARM gem5 Developers 0x30, // TLBConflictAbort 13610037SARM gem5 Developers 0x18, // SynchPtyErrOnMemoryAccess 13710037SARM gem5 Developers 0x11, // AsynchronousExternalAbort 13810037SARM gem5 Developers 0x19, // AsynchPtyErrOnMemoryAccess 13910037SARM gem5 Developers 0xff, // AddressSizeL0 (INVALID) 14010037SARM gem5 Developers 0xff, // AddressSizeL1 (INVALID) 14110037SARM gem5 Developers 0xff, // AddressSizeL2 (INVALID) 14210037SARM gem5 Developers 0xff, // AddressSizeL3 (INVALID) 14310037SARM gem5 Developers 0x40, // PrefetchTLBMiss 14410037SARM gem5 Developers 0x80 // PrefetchUncacheable 14510037SARM gem5 Developers}; 1466019Shines@cs.fsu.edu 14710037SARM gem5 Developersstatic_assert(sizeof(ArmFault::longDescFaultSources) == 14810037SARM gem5 Developers ArmFault::NumFaultSources, 14910037SARM gem5 Developers "Invalid size of ArmFault::longDescFaultSources[]"); 1506019Shines@cs.fsu.edu 15110037SARM gem5 Developersuint8_t ArmFault::aarch64FaultSources[] = { 15210037SARM gem5 Developers 0x21, // AlignmentFault 15310037SARM gem5 Developers 0xff, // InstructionCacheMaintenance (INVALID) 15410037SARM gem5 Developers 0x14, // SynchExtAbtOnTranslTableWalkL0 15510037SARM gem5 Developers 0x15, // SynchExtAbtOnTranslTableWalkL1 15610037SARM gem5 Developers 0x16, // SynchExtAbtOnTranslTableWalkL2 15710037SARM gem5 Developers 0x17, // SynchExtAbtOnTranslTableWalkL3 15810037SARM gem5 Developers 0x1c, // SynchPtyErrOnTranslTableWalkL0 15910037SARM gem5 Developers 0x1d, // SynchPtyErrOnTranslTableWalkL1 16010037SARM gem5 Developers 0x1e, // SynchPtyErrOnTranslTableWalkL2 16110037SARM gem5 Developers 0x1f, // SynchPtyErrOnTranslTableWalkL3 16210037SARM gem5 Developers 0x04, // TranslationL0 16310037SARM gem5 Developers 0x05, // TranslationL1 16410037SARM gem5 Developers 0x06, // TranslationL2 16510037SARM gem5 Developers 0x07, // TranslationL3 16610037SARM gem5 Developers 0x08, // AccessFlagL0 16710037SARM gem5 Developers 0x09, // AccessFlagL1 16810037SARM gem5 Developers 0x0a, // AccessFlagL2 16910037SARM gem5 Developers 0x0b, // AccessFlagL3 17010037SARM gem5 Developers // @todo: Section & Page Domain Fault in AArch64? 17110037SARM gem5 Developers 0xff, // DomainL0 (INVALID) 17210037SARM gem5 Developers 0xff, // DomainL1 (INVALID) 17310037SARM gem5 Developers 0xff, // DomainL2 (INVALID) 17410037SARM gem5 Developers 0xff, // DomainL3 (INVALID) 17510037SARM gem5 Developers 0x0c, // PermissionL0 17610037SARM gem5 Developers 0x0d, // PermissionL1 17710037SARM gem5 Developers 0x0e, // PermissionL2 17810037SARM gem5 Developers 0x0f, // PermissionL3 17910037SARM gem5 Developers 0xff, // DebugEvent (INVALID) 18010037SARM gem5 Developers 0x10, // SynchronousExternalAbort 18110037SARM gem5 Developers 0x30, // TLBConflictAbort 18210037SARM gem5 Developers 0x18, // SynchPtyErrOnMemoryAccess 18310037SARM gem5 Developers 0xff, // AsynchronousExternalAbort (INVALID) 18410037SARM gem5 Developers 0xff, // AsynchPtyErrOnMemoryAccess (INVALID) 18510037SARM gem5 Developers 0x00, // AddressSizeL0 18610037SARM gem5 Developers 0x01, // AddressSizeL1 18710037SARM gem5 Developers 0x02, // AddressSizeL2 18810037SARM gem5 Developers 0x03, // AddressSizeL3 18910037SARM gem5 Developers 0x40, // PrefetchTLBMiss 19010037SARM gem5 Developers 0x80 // PrefetchUncacheable 19110037SARM gem5 Developers}; 1926019Shines@cs.fsu.edu 19310037SARM gem5 Developersstatic_assert(sizeof(ArmFault::aarch64FaultSources) == 19410037SARM gem5 Developers ArmFault::NumFaultSources, 19510037SARM gem5 Developers "Invalid size of ArmFault::aarch64FaultSources[]"); 1966019Shines@cs.fsu.edu 19710037SARM gem5 Developers// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode, 19810037SARM gem5 Developers// {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap, 19910037SARM gem5 Developers// {A, F} disable, class, stat 20010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = { 20110037SARM gem5 Developers // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED 20210037SARM gem5 Developers // location in AArch64) 20310037SARM gem5 Developers "Reset", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 20410037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 20510037SARM gem5 Developers}; 20610037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = { 20710037SARM gem5 Developers "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED, 20810037SARM gem5 Developers 4, 2, 0, 0, true, false, false, EC_UNKNOWN, FaultStat() 20910037SARM gem5 Developers}; 21010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = { 21110037SARM gem5 Developers "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 21210037SARM gem5 Developers 4, 2, 4, 2, true, false, false, EC_SVC_TO_HYP, FaultStat() 21310037SARM gem5 Developers}; 21410037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals = { 21510037SARM gem5 Developers "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON, 21610037SARM gem5 Developers 4, 4, 4, 4, false, true, true, EC_SMC_TO_HYP, FaultStat() 21710037SARM gem5 Developers}; 21810037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals = { 21910037SARM gem5 Developers "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 22010037SARM gem5 Developers 4, 4, 4, 4, true, false, false, EC_HVC, FaultStat() 22110037SARM gem5 Developers}; 22210037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = { 22310037SARM gem5 Developers "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22410037SARM gem5 Developers 4, 4, 0, 0, true, true, false, EC_PREFETCH_ABORT_TO_HYP, FaultStat() 22510037SARM gem5 Developers}; 22610037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = { 22710037SARM gem5 Developers "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22810037SARM gem5 Developers 8, 8, 0, 0, true, true, false, EC_DATA_ABORT_TO_HYP, FaultStat() 22910037SARM gem5 Developers}; 23010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals = { 23110037SARM gem5 Developers "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 23210037SARM gem5 Developers 8, 8, 0, 0, true, true, false, EC_INVALID, FaultStat() 23310037SARM gem5 Developers}; 23410037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals = { 23510037SARM gem5 Developers // @todo: double check these values 23610037SARM gem5 Developers "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 23710037SARM gem5 Developers 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 23810037SARM gem5 Developers}; 23910037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = { 24010037SARM gem5 Developers "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 24110037SARM gem5 Developers 4, 4, 0, 0, false, true, false, EC_UNKNOWN, FaultStat() 24210037SARM gem5 Developers}; 24310037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals = { 24410037SARM gem5 Developers "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 24510037SARM gem5 Developers 4, 4, 0, 0, false, true, false, EC_INVALID, FaultStat() 24610037SARM gem5 Developers}; 24710037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = { 24810037SARM gem5 Developers "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 24910037SARM gem5 Developers 4, 4, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 25010037SARM gem5 Developers}; 25110037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals = { 25210037SARM gem5 Developers "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25310037SARM gem5 Developers 4, 4, 0, 0, false, true, true, EC_INVALID, FaultStat() 25410037SARM gem5 Developers}; 25510037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals = { 25610037SARM gem5 Developers // Some dummy values (SupervisorTrap is AArch64-only) 25710037SARM gem5 Developers "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 25810037SARM gem5 Developers 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 25910037SARM gem5 Developers}; 26010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals = { 26110037SARM gem5 Developers // Some dummy values (SecureMonitorTrap is AArch64-only) 26210037SARM gem5 Developers "Secure Monitor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_MON, 26310037SARM gem5 Developers 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 26410037SARM gem5 Developers}; 26510037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals = { 26610037SARM gem5 Developers // Some dummy values (PCAlignmentFault is AArch64-only) 26710037SARM gem5 Developers "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 26810037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_PC_ALIGNMENT, FaultStat() 26910037SARM gem5 Developers}; 27010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals = { 27110037SARM gem5 Developers // Some dummy values (SPAlignmentFault is AArch64-only) 27210037SARM gem5 Developers "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 27310037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_STACK_PTR_ALIGNMENT, FaultStat() 27410037SARM gem5 Developers}; 27510037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals = { 27610037SARM gem5 Developers // Some dummy values (SError is AArch64-only) 27710037SARM gem5 Developers "SError", 0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC, 27810037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_SERROR, FaultStat() 27910037SARM gem5 Developers}; 28010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = { 28110037SARM gem5 Developers // Some dummy values 28210037SARM gem5 Developers "Pipe Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 28310037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 28410037SARM gem5 Developers}; 28510037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = { 28610037SARM gem5 Developers // Some dummy values 28710037SARM gem5 Developers "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 28810037SARM gem5 Developers 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 28910037SARM gem5 Developers}; 29010037SARM gem5 Developerstemplate<> ArmFault::FaultVals ArmFaultVals<IllegalInstSetStateFault>::vals = { 29110037SARM gem5 Developers // Some dummy values (SPAlignmentFault is AArch64-only) 29210037SARM gem5 Developers "Illegal Inst Set State Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 29310037SARM gem5 Developers 0, 0, 0, 0, true, false, false, EC_ILLEGAL_INST, FaultStat() 29410037SARM gem5 Developers}; 2956019Shines@cs.fsu.edu 29610037SARM gem5 DevelopersAddr 2977362Sgblack@eecs.umich.eduArmFault::getVector(ThreadContext *tc) 2986735Sgblack@eecs.umich.edu{ 29910037SARM gem5 Developers Addr base; 3006019Shines@cs.fsu.edu 30110037SARM gem5 Developers // ARM ARM issue C B1.8.1 30210037SARM gem5 Developers bool haveSecurity = ArmSystem::haveSecurity(tc); 3037400SAli.Saidi@ARM.com 3046735Sgblack@eecs.umich.edu // panic if SCTLR.VE because I have no idea what to do with vectored 3056735Sgblack@eecs.umich.edu // interrupts 30610037SARM gem5 Developers SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 3076735Sgblack@eecs.umich.edu assert(!sctlr.ve); 30810037SARM gem5 Developers // Check for invalid modes 30910037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 31010037SARM gem5 Developers assert(haveSecurity || cpsr.mode != MODE_MON); 31110037SARM gem5 Developers assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP); 3127400SAli.Saidi@ARM.com 31310037SARM gem5 Developers switch (cpsr.mode) 31410037SARM gem5 Developers { 31510037SARM gem5 Developers case MODE_MON: 31610037SARM gem5 Developers base = tc->readMiscReg(MISCREG_MVBAR); 31710037SARM gem5 Developers break; 31810037SARM gem5 Developers case MODE_HYP: 31910037SARM gem5 Developers base = tc->readMiscReg(MISCREG_HVBAR); 32010037SARM gem5 Developers break; 32110037SARM gem5 Developers default: 32210037SARM gem5 Developers if (sctlr.v) { 32310037SARM gem5 Developers base = HighVecs; 32410037SARM gem5 Developers } else { 32510037SARM gem5 Developers base = haveSecurity ? tc->readMiscReg(MISCREG_VBAR) : 0; 32610037SARM gem5 Developers } 32710037SARM gem5 Developers break; 32810037SARM gem5 Developers } 32910037SARM gem5 Developers return base + offset(tc); 3306019Shines@cs.fsu.edu} 3316019Shines@cs.fsu.edu 33210037SARM gem5 DevelopersAddr 33310037SARM gem5 DevelopersArmFault::getVector64(ThreadContext *tc) 33410037SARM gem5 Developers{ 33510037SARM gem5 Developers Addr vbar; 33610037SARM gem5 Developers switch (toEL) { 33710037SARM gem5 Developers case EL3: 33810037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 33910037SARM gem5 Developers vbar = tc->readMiscReg(MISCREG_VBAR_EL3); 34010037SARM gem5 Developers break; 34111574SCurtis.Dunham@arm.com case EL2: 34211574SCurtis.Dunham@arm.com assert(ArmSystem::haveVirtualization(tc)); 34311574SCurtis.Dunham@arm.com vbar = tc->readMiscReg(MISCREG_VBAR_EL2); 34411574SCurtis.Dunham@arm.com break; 34510037SARM gem5 Developers case EL1: 34610037SARM gem5 Developers vbar = tc->readMiscReg(MISCREG_VBAR_EL1); 34710037SARM gem5 Developers break; 34810037SARM gem5 Developers default: 34910037SARM gem5 Developers panic("Invalid target exception level"); 35010037SARM gem5 Developers break; 35110037SARM gem5 Developers } 35210037SARM gem5 Developers return vbar + offset64(); 35310037SARM gem5 Developers} 35410037SARM gem5 Developers 35510037SARM gem5 DevelopersMiscRegIndex 35610037SARM gem5 DevelopersArmFault::getSyndromeReg64() const 35710037SARM gem5 Developers{ 35810037SARM gem5 Developers switch (toEL) { 35910037SARM gem5 Developers case EL1: 36010037SARM gem5 Developers return MISCREG_ESR_EL1; 36110037SARM gem5 Developers case EL2: 36210037SARM gem5 Developers return MISCREG_ESR_EL2; 36310037SARM gem5 Developers case EL3: 36410037SARM gem5 Developers return MISCREG_ESR_EL3; 36510037SARM gem5 Developers default: 36610037SARM gem5 Developers panic("Invalid exception level"); 36710037SARM gem5 Developers break; 36810037SARM gem5 Developers } 36910037SARM gem5 Developers} 37010037SARM gem5 Developers 37110037SARM gem5 DevelopersMiscRegIndex 37210037SARM gem5 DevelopersArmFault::getFaultAddrReg64() const 37310037SARM gem5 Developers{ 37410037SARM gem5 Developers switch (toEL) { 37510037SARM gem5 Developers case EL1: 37610037SARM gem5 Developers return MISCREG_FAR_EL1; 37710037SARM gem5 Developers case EL2: 37810037SARM gem5 Developers return MISCREG_FAR_EL2; 37910037SARM gem5 Developers case EL3: 38010037SARM gem5 Developers return MISCREG_FAR_EL3; 38110037SARM gem5 Developers default: 38210037SARM gem5 Developers panic("Invalid exception level"); 38310037SARM gem5 Developers break; 38410037SARM gem5 Developers } 38510037SARM gem5 Developers} 38610037SARM gem5 Developers 38710037SARM gem5 Developersvoid 38810037SARM gem5 DevelopersArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) 38910037SARM gem5 Developers{ 39010037SARM gem5 Developers uint32_t value; 39110037SARM gem5 Developers uint32_t exc_class = (uint32_t) ec(tc); 39210037SARM gem5 Developers uint32_t issVal = iss(); 39310037SARM gem5 Developers assert(!from64 || ArmSystem::highestELIs64(tc)); 39410037SARM gem5 Developers 39510037SARM gem5 Developers value = exc_class << 26; 39610037SARM gem5 Developers 39710037SARM gem5 Developers // HSR.IL not valid for Prefetch Aborts (0x20, 0x21) and Data Aborts (0x24, 39810037SARM gem5 Developers // 0x25) for which the ISS information is not valid (ARMv7). 39910037SARM gem5 Developers // @todo: ARMv8 revises AArch32 functionality: when HSR.IL is not 40010037SARM gem5 Developers // valid it is treated as RES1. 40110037SARM gem5 Developers if (to64) { 40210037SARM gem5 Developers value |= 1 << 25; 40310037SARM gem5 Developers } else if ((bits(exc_class, 5, 3) != 4) || 40410037SARM gem5 Developers (bits(exc_class, 2) && bits(issVal, 24))) { 40510037SARM gem5 Developers if (!machInst.thumb || machInst.bigThumb) 40610037SARM gem5 Developers value |= 1 << 25; 40710037SARM gem5 Developers } 40810037SARM gem5 Developers // Condition code valid for EC[5:4] nonzero 40910037SARM gem5 Developers if (!from64 && ((bits(exc_class, 5, 4) == 0) && 41010037SARM gem5 Developers (bits(exc_class, 3, 0) != 0))) { 41110037SARM gem5 Developers if (!machInst.thumb) { 41210037SARM gem5 Developers uint32_t cond; 41310037SARM gem5 Developers ConditionCode condCode = (ConditionCode) (uint32_t) machInst.condCode; 41410037SARM gem5 Developers // If its on unconditional instruction report with a cond code of 41510037SARM gem5 Developers // 0xE, ie the unconditional code 41610037SARM gem5 Developers cond = (condCode == COND_UC) ? COND_AL : condCode; 41710037SARM gem5 Developers value |= cond << 20; 41810037SARM gem5 Developers value |= 1 << 24; 41910037SARM gem5 Developers } 42010037SARM gem5 Developers value |= bits(issVal, 19, 0); 42110037SARM gem5 Developers } else { 42210037SARM gem5 Developers value |= issVal; 42310037SARM gem5 Developers } 42410037SARM gem5 Developers tc->setMiscReg(syndrome_reg, value); 42510037SARM gem5 Developers} 42610037SARM gem5 Developers 42710037SARM gem5 Developersvoid 42810417Sandreas.hansson@arm.comArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 4296019Shines@cs.fsu.edu{ 43010037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 43110037SARM gem5 Developers 43210037SARM gem5 Developers if (ArmSystem::highestELIs64(tc)) { // ARMv8 43310037SARM gem5 Developers // Determine source exception level and mode 43410037SARM gem5 Developers fromMode = (OperatingMode) (uint8_t) cpsr.mode; 43510037SARM gem5 Developers fromEL = opModeToEL(fromMode); 43610037SARM gem5 Developers if (opModeIs64(fromMode)) 43710037SARM gem5 Developers from64 = true; 43810037SARM gem5 Developers 43910037SARM gem5 Developers // Determine target exception level 44010037SARM gem5 Developers if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) 44110037SARM gem5 Developers toEL = EL3; 44211578SDylan.Johnson@ARM.com else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) 44311578SDylan.Johnson@ARM.com toEL = EL2; 44410037SARM gem5 Developers else 44510037SARM gem5 Developers toEL = opModeToEL(nextMode()); 44610037SARM gem5 Developers if (fromEL > toEL) 44710037SARM gem5 Developers toEL = fromEL; 44810037SARM gem5 Developers 44910037SARM gem5 Developers if (toEL == ArmSystem::highestEL(tc) || ELIs64(tc, toEL)) { 45010037SARM gem5 Developers // Invoke exception handler in AArch64 state 45110037SARM gem5 Developers to64 = true; 45210037SARM gem5 Developers invoke64(tc, inst); 45310037SARM gem5 Developers return; 45410037SARM gem5 Developers } 45510037SARM gem5 Developers } 45610037SARM gem5 Developers 45710037SARM gem5 Developers // ARMv7 (ARM ARM issue C B1.9) 45810037SARM gem5 Developers 45910037SARM gem5 Developers bool have_security = ArmSystem::haveSecurity(tc); 46010037SARM gem5 Developers bool have_virtualization = ArmSystem::haveVirtualization(tc); 46110037SARM gem5 Developers 4626735Sgblack@eecs.umich.edu FaultBase::invoke(tc); 4638782Sgblack@eecs.umich.edu if (!FullSystem) 4648782Sgblack@eecs.umich.edu return; 4656735Sgblack@eecs.umich.edu countStat()++; 4666019Shines@cs.fsu.edu 4676735Sgblack@eecs.umich.edu SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 46810037SARM gem5 Developers SCR scr = tc->readMiscReg(MISCREG_SCR); 4698303SAli.Saidi@ARM.com CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR); 47010338SCurtis.Dunham@arm.com saved_cpsr.nz = tc->readCCReg(CCREG_NZ); 47110338SCurtis.Dunham@arm.com saved_cpsr.c = tc->readCCReg(CCREG_C); 47210338SCurtis.Dunham@arm.com saved_cpsr.v = tc->readCCReg(CCREG_V); 47310338SCurtis.Dunham@arm.com saved_cpsr.ge = tc->readCCReg(CCREG_GE); 4748303SAli.Saidi@ARM.com 4757720Sgblack@eecs.umich.edu Addr curPc M5_VAR_USED = tc->pcState().pc(); 4768205SAli.Saidi@ARM.com ITSTATE it = tc->pcState().itstate(); 4778205SAli.Saidi@ARM.com saved_cpsr.it2 = it.top6; 4788205SAli.Saidi@ARM.com saved_cpsr.it1 = it.bottom2; 4796735Sgblack@eecs.umich.edu 48010037SARM gem5 Developers // if we have a valid instruction then use it to annotate this fault with 48110037SARM gem5 Developers // extra information. This is used to generate the correct fault syndrome 48210037SARM gem5 Developers // information 48310037SARM gem5 Developers if (inst) { 48410037SARM gem5 Developers ArmStaticInst *armInst = reinterpret_cast<ArmStaticInst *>(inst.get()); 48510037SARM gem5 Developers armInst->annotateFault(this); 48610037SARM gem5 Developers } 48710037SARM gem5 Developers 48810037SARM gem5 Developers if (have_security && routeToMonitor(tc)) 48910037SARM gem5 Developers cpsr.mode = MODE_MON; 49010037SARM gem5 Developers else if (have_virtualization && routeToHyp(tc)) 49110037SARM gem5 Developers cpsr.mode = MODE_HYP; 49210037SARM gem5 Developers else 49310037SARM gem5 Developers cpsr.mode = nextMode(); 49410037SARM gem5 Developers 49510037SARM gem5 Developers // Ensure Secure state if initially in Monitor mode 49610037SARM gem5 Developers if (have_security && saved_cpsr.mode == MODE_MON) { 49710037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 49810037SARM gem5 Developers if (scr.ns) { 49910037SARM gem5 Developers scr.ns = 0; 50010037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_SCR, scr); 50110037SARM gem5 Developers } 50210037SARM gem5 Developers } 50310037SARM gem5 Developers 50410037SARM gem5 Developers // some bits are set differently if we have been routed to hyp mode 50510037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 50610037SARM gem5 Developers SCTLR hsctlr = tc->readMiscReg(MISCREG_HSCTLR); 50710037SARM gem5 Developers cpsr.t = hsctlr.te; 50810037SARM gem5 Developers cpsr.e = hsctlr.ee; 50910037SARM gem5 Developers if (!scr.ea) {cpsr.a = 1;} 51010037SARM gem5 Developers if (!scr.fiq) {cpsr.f = 1;} 51110037SARM gem5 Developers if (!scr.irq) {cpsr.i = 1;} 51210037SARM gem5 Developers } else if (cpsr.mode == MODE_MON) { 51310037SARM gem5 Developers // Special case handling when entering monitor mode 51410037SARM gem5 Developers cpsr.t = sctlr.te; 51510037SARM gem5 Developers cpsr.e = sctlr.ee; 51610037SARM gem5 Developers cpsr.a = 1; 51710037SARM gem5 Developers cpsr.f = 1; 51810037SARM gem5 Developers cpsr.i = 1; 51910037SARM gem5 Developers } else { 52010037SARM gem5 Developers cpsr.t = sctlr.te; 52110037SARM gem5 Developers cpsr.e = sctlr.ee; 52210037SARM gem5 Developers 52310037SARM gem5 Developers // The *Disable functions are virtual and different per fault 52410037SARM gem5 Developers cpsr.a = cpsr.a | abortDisable(tc); 52510037SARM gem5 Developers cpsr.f = cpsr.f | fiqDisable(tc); 52610037SARM gem5 Developers cpsr.i = 1; 52710037SARM gem5 Developers } 5286735Sgblack@eecs.umich.edu cpsr.it1 = cpsr.it2 = 0; 5296735Sgblack@eecs.umich.edu cpsr.j = 0; 5306735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CPSR, cpsr); 53110037SARM gem5 Developers 5328518Sgeoffrey.blake@arm.com // Make sure mailbox sets to one always 5338518Sgeoffrey.blake@arm.com tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 5346735Sgblack@eecs.umich.edu 53510037SARM gem5 Developers // Clear the exclusive monitor 53610037SARM gem5 Developers tc->setMiscReg(MISCREG_LOCKFLAG, 0); 53710037SARM gem5 Developers 53810037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 53910037SARM gem5 Developers tc->setMiscReg(MISCREG_ELR_HYP, curPc + 54010037SARM gem5 Developers (saved_cpsr.t ? thumbPcOffset(true) : armPcOffset(true))); 54110037SARM gem5 Developers } else { 54210037SARM gem5 Developers tc->setIntReg(INTREG_LR, curPc + 54310037SARM gem5 Developers (saved_cpsr.t ? thumbPcOffset(false) : armPcOffset(false))); 54410037SARM gem5 Developers } 54510037SARM gem5 Developers 54610037SARM gem5 Developers switch (cpsr.mode) { 5476735Sgblack@eecs.umich.edu case MODE_FIQ: 5486735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 5496735Sgblack@eecs.umich.edu break; 5506735Sgblack@eecs.umich.edu case MODE_IRQ: 5516735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 5526735Sgblack@eecs.umich.edu break; 5536735Sgblack@eecs.umich.edu case MODE_SVC: 5546735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 5556735Sgblack@eecs.umich.edu break; 55610037SARM gem5 Developers case MODE_MON: 55710037SARM gem5 Developers assert(have_security); 55810037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_MON, saved_cpsr); 5596735Sgblack@eecs.umich.edu break; 5606735Sgblack@eecs.umich.edu case MODE_ABORT: 5616735Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 5626735Sgblack@eecs.umich.edu break; 56310037SARM gem5 Developers case MODE_UNDEFINED: 56410037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 56510037SARM gem5 Developers if (ec(tc) != EC_UNKNOWN) 56610037SARM gem5 Developers setSyndrome(tc, MISCREG_HSR); 56710037SARM gem5 Developers break; 56810037SARM gem5 Developers case MODE_HYP: 56910037SARM gem5 Developers assert(have_virtualization); 57010037SARM gem5 Developers tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr); 57110037SARM gem5 Developers setSyndrome(tc, MISCREG_HSR); 57210037SARM gem5 Developers break; 5736735Sgblack@eecs.umich.edu default: 5746735Sgblack@eecs.umich.edu panic("unknown Mode\n"); 5757093Sgblack@eecs.umich.edu } 5767093Sgblack@eecs.umich.edu 5777720Sgblack@eecs.umich.edu Addr newPc = getVector(tc); 5787585SAli.Saidi@arm.com DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n", 5797720Sgblack@eecs.umich.edu name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc); 5807720Sgblack@eecs.umich.edu PCState pc(newPc); 5817720Sgblack@eecs.umich.edu pc.thumb(cpsr.t); 5827720Sgblack@eecs.umich.edu pc.nextThumb(pc.thumb()); 5837720Sgblack@eecs.umich.edu pc.jazelle(cpsr.j); 5847720Sgblack@eecs.umich.edu pc.nextJazelle(pc.jazelle()); 58510037SARM gem5 Developers pc.aarch64(!cpsr.width); 58610037SARM gem5 Developers pc.nextAArch64(!cpsr.width); 5877720Sgblack@eecs.umich.edu tc->pcState(pc); 5886019Shines@cs.fsu.edu} 5897189Sgblack@eecs.umich.edu 5907400SAli.Saidi@ARM.comvoid 59110417Sandreas.hansson@arm.comArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst) 59210037SARM gem5 Developers{ 59310037SARM gem5 Developers // Determine actual misc. register indices for ELR_ELx and SPSR_ELx 59410037SARM gem5 Developers MiscRegIndex elr_idx, spsr_idx; 59510037SARM gem5 Developers switch (toEL) { 59610037SARM gem5 Developers case EL1: 59710037SARM gem5 Developers elr_idx = MISCREG_ELR_EL1; 59810037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL1; 59910037SARM gem5 Developers break; 60011574SCurtis.Dunham@arm.com case EL2: 60111574SCurtis.Dunham@arm.com assert(ArmSystem::haveVirtualization(tc)); 60211574SCurtis.Dunham@arm.com elr_idx = MISCREG_ELR_EL2; 60311574SCurtis.Dunham@arm.com spsr_idx = MISCREG_SPSR_EL2; 60411574SCurtis.Dunham@arm.com break; 60510037SARM gem5 Developers case EL3: 60610037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 60710037SARM gem5 Developers elr_idx = MISCREG_ELR_EL3; 60810037SARM gem5 Developers spsr_idx = MISCREG_SPSR_EL3; 60910037SARM gem5 Developers break; 61010037SARM gem5 Developers default: 61110037SARM gem5 Developers panic("Invalid target exception level"); 61210037SARM gem5 Developers break; 61310037SARM gem5 Developers } 61410037SARM gem5 Developers 61510037SARM gem5 Developers // Save process state into SPSR_ELx 61610037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 61710037SARM gem5 Developers CPSR spsr = cpsr; 61810338SCurtis.Dunham@arm.com spsr.nz = tc->readCCReg(CCREG_NZ); 61910338SCurtis.Dunham@arm.com spsr.c = tc->readCCReg(CCREG_C); 62010338SCurtis.Dunham@arm.com spsr.v = tc->readCCReg(CCREG_V); 62110037SARM gem5 Developers if (from64) { 62210037SARM gem5 Developers // Force some bitfields to 0 62310037SARM gem5 Developers spsr.q = 0; 62410037SARM gem5 Developers spsr.it1 = 0; 62510037SARM gem5 Developers spsr.j = 0; 62610037SARM gem5 Developers spsr.res0_23_22 = 0; 62710037SARM gem5 Developers spsr.ge = 0; 62810037SARM gem5 Developers spsr.it2 = 0; 62910037SARM gem5 Developers spsr.t = 0; 63010037SARM gem5 Developers } else { 63110338SCurtis.Dunham@arm.com spsr.ge = tc->readCCReg(CCREG_GE); 63210037SARM gem5 Developers ITSTATE it = tc->pcState().itstate(); 63310037SARM gem5 Developers spsr.it2 = it.top6; 63410037SARM gem5 Developers spsr.it1 = it.bottom2; 63510037SARM gem5 Developers // Force some bitfields to 0 63610037SARM gem5 Developers spsr.res0_23_22 = 0; 63710037SARM gem5 Developers spsr.ss = 0; 63810037SARM gem5 Developers } 63910037SARM gem5 Developers tc->setMiscReg(spsr_idx, spsr); 64010037SARM gem5 Developers 64110037SARM gem5 Developers // Save preferred return address into ELR_ELx 64210037SARM gem5 Developers Addr curr_pc = tc->pcState().pc(); 64310037SARM gem5 Developers Addr ret_addr = curr_pc; 64410037SARM gem5 Developers if (from64) 64510037SARM gem5 Developers ret_addr += armPcElrOffset(); 64610037SARM gem5 Developers else 64710037SARM gem5 Developers ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset(); 64810037SARM gem5 Developers tc->setMiscReg(elr_idx, ret_addr); 64910037SARM gem5 Developers 65010037SARM gem5 Developers // Update process state 65110037SARM gem5 Developers OperatingMode64 mode = 0; 65210037SARM gem5 Developers mode.spX = 1; 65310037SARM gem5 Developers mode.el = toEL; 65410037SARM gem5 Developers mode.width = 0; 65510037SARM gem5 Developers cpsr.mode = mode; 65610037SARM gem5 Developers cpsr.daif = 0xf; 65710037SARM gem5 Developers cpsr.il = 0; 65810037SARM gem5 Developers cpsr.ss = 0; 65910037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 66010037SARM gem5 Developers 66110037SARM gem5 Developers // Set PC to start of exception handler 66210037SARM gem5 Developers Addr new_pc = purifyTaggedAddr(getVector64(tc), tc, toEL); 66310037SARM gem5 Developers DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x " 66410037SARM gem5 Developers "elr:%#x newVec: %#x\n", name(), cpsr, curr_pc, ret_addr, new_pc); 66510037SARM gem5 Developers PCState pc(new_pc); 66610037SARM gem5 Developers pc.aarch64(!cpsr.width); 66710037SARM gem5 Developers pc.nextAArch64(!cpsr.width); 66810037SARM gem5 Developers tc->pcState(pc); 66910037SARM gem5 Developers 67010037SARM gem5 Developers // If we have a valid instruction then use it to annotate this fault with 67110037SARM gem5 Developers // extra information. This is used to generate the correct fault syndrome 67210037SARM gem5 Developers // information 67310037SARM gem5 Developers if (inst) 67410037SARM gem5 Developers reinterpret_cast<ArmStaticInst *>(inst.get())->annotateFault(this); 67510037SARM gem5 Developers // Save exception syndrome 67610037SARM gem5 Developers if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ)) 67710037SARM gem5 Developers setSyndrome(tc, getSyndromeReg64()); 67810037SARM gem5 Developers} 67910037SARM gem5 Developers 68010037SARM gem5 Developersvoid 68110417Sandreas.hansson@arm.comReset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 6827400SAli.Saidi@ARM.com{ 6838782Sgblack@eecs.umich.edu if (FullSystem) { 68411150Smitch.hayenga@arm.com tc->getCpuPtr()->clearInterrupts(tc->threadId()); 6858782Sgblack@eecs.umich.edu tc->clearArchRegs(); 6868782Sgblack@eecs.umich.edu } 68710037SARM gem5 Developers if (!ArmSystem::highestELIs64(tc)) { 68810037SARM gem5 Developers ArmFault::invoke(tc, inst); 68910037SARM gem5 Developers tc->setMiscReg(MISCREG_VMPIDR, 69010037SARM gem5 Developers getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc)); 69110037SARM gem5 Developers 69210037SARM gem5 Developers // Unless we have SMC code to get us there, boot in HYP! 69310037SARM gem5 Developers if (ArmSystem::haveVirtualization(tc) && 69410037SARM gem5 Developers !ArmSystem::haveSecurity(tc)) { 69510037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 69610037SARM gem5 Developers cpsr.mode = MODE_HYP; 69710037SARM gem5 Developers tc->setMiscReg(MISCREG_CPSR, cpsr); 69810037SARM gem5 Developers } 69910037SARM gem5 Developers } else { 70010037SARM gem5 Developers // Advance the PC to the IMPLEMENTATION DEFINED reset value 70110037SARM gem5 Developers PCState pc = ArmSystem::resetAddr64(tc); 70210037SARM gem5 Developers pc.aarch64(true); 70310037SARM gem5 Developers pc.nextAArch64(true); 70410037SARM gem5 Developers tc->pcState(pc); 70510037SARM gem5 Developers } 7067400SAli.Saidi@ARM.com} 7077400SAli.Saidi@ARM.com 7087189Sgblack@eecs.umich.eduvoid 70910417Sandreas.hansson@arm.comUndefinedInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst) 7107189Sgblack@eecs.umich.edu{ 7118782Sgblack@eecs.umich.edu if (FullSystem) { 7128782Sgblack@eecs.umich.edu ArmFault::invoke(tc, inst); 7138806Sgblack@eecs.umich.edu return; 7148806Sgblack@eecs.umich.edu } 7158806Sgblack@eecs.umich.edu 7168806Sgblack@eecs.umich.edu // If the mnemonic isn't defined this has to be an unknown instruction. 7178806Sgblack@eecs.umich.edu assert(unknown || mnemonic != NULL); 7188806Sgblack@eecs.umich.edu if (disabled) { 7198806Sgblack@eecs.umich.edu panic("Attempted to execute disabled instruction " 7208806Sgblack@eecs.umich.edu "'%s' (inst 0x%08x)", mnemonic, machInst); 7218806Sgblack@eecs.umich.edu } else if (unknown) { 7228806Sgblack@eecs.umich.edu panic("Attempted to execute unknown instruction (inst 0x%08x)", 7238806Sgblack@eecs.umich.edu machInst); 7247189Sgblack@eecs.umich.edu } else { 7258806Sgblack@eecs.umich.edu panic("Attempted to execute unimplemented instruction " 7268806Sgblack@eecs.umich.edu "'%s' (inst 0x%08x)", mnemonic, machInst); 7277189Sgblack@eecs.umich.edu } 7287189Sgblack@eecs.umich.edu} 7297189Sgblack@eecs.umich.edu 73010037SARM gem5 Developersbool 73110037SARM gem5 DevelopersUndefinedInstruction::routeToHyp(ThreadContext *tc) const 73210037SARM gem5 Developers{ 73310037SARM gem5 Developers bool toHyp; 73410037SARM gem5 Developers 73510037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 73610037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 73710037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 73810037SARM gem5 Developers 73910037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 74010037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 74110037SARM gem5 Developers // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 74210037SARM gem5 Developers toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 74310037SARM gem5 Developers return toHyp; 74410037SARM gem5 Developers} 74510037SARM gem5 Developers 74610037SARM gem5 Developersuint32_t 74710037SARM gem5 DevelopersUndefinedInstruction::iss() const 74810037SARM gem5 Developers{ 74910037SARM gem5 Developers if (overrideEc == EC_INVALID) 75010037SARM gem5 Developers return issRaw; 75110037SARM gem5 Developers 75210037SARM gem5 Developers uint32_t new_iss = 0; 75310037SARM gem5 Developers uint32_t op0, op1, op2, CRn, CRm, Rt, dir; 75410037SARM gem5 Developers 75510037SARM gem5 Developers dir = bits(machInst, 21, 21); 75610037SARM gem5 Developers op0 = bits(machInst, 20, 19); 75710037SARM gem5 Developers op1 = bits(machInst, 18, 16); 75810037SARM gem5 Developers CRn = bits(machInst, 15, 12); 75910037SARM gem5 Developers CRm = bits(machInst, 11, 8); 76010037SARM gem5 Developers op2 = bits(machInst, 7, 5); 76110037SARM gem5 Developers Rt = bits(machInst, 4, 0); 76210037SARM gem5 Developers 76310037SARM gem5 Developers new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 | 76410037SARM gem5 Developers Rt << 5 | CRm << 1 | dir; 76510037SARM gem5 Developers 76610037SARM gem5 Developers return new_iss; 76710037SARM gem5 Developers} 76810037SARM gem5 Developers 7697197Sgblack@eecs.umich.eduvoid 77010417Sandreas.hansson@arm.comSupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 7717197Sgblack@eecs.umich.edu{ 7728782Sgblack@eecs.umich.edu if (FullSystem) { 7738782Sgblack@eecs.umich.edu ArmFault::invoke(tc, inst); 7748806Sgblack@eecs.umich.edu return; 7758806Sgblack@eecs.umich.edu } 7767197Sgblack@eecs.umich.edu 7778806Sgblack@eecs.umich.edu // As of now, there isn't a 32 bit thumb version of this instruction. 7788806Sgblack@eecs.umich.edu assert(!machInst.bigThumb); 7798806Sgblack@eecs.umich.edu uint32_t callNum; 78010037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 78110037SARM gem5 Developers OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode; 78210037SARM gem5 Developers if (opModeIs64(mode)) 78310037SARM gem5 Developers callNum = tc->readIntReg(INTREG_X8); 78410037SARM gem5 Developers else 78510037SARM gem5 Developers callNum = tc->readIntReg(INTREG_R7); 7868806Sgblack@eecs.umich.edu tc->syscall(callNum); 7878806Sgblack@eecs.umich.edu 7888806Sgblack@eecs.umich.edu // Advance the PC since that won't happen automatically. 7898806Sgblack@eecs.umich.edu PCState pc = tc->pcState(); 7908806Sgblack@eecs.umich.edu assert(inst); 7918806Sgblack@eecs.umich.edu inst->advancePC(pc); 7928806Sgblack@eecs.umich.edu tc->pcState(pc); 7937197Sgblack@eecs.umich.edu} 7947197Sgblack@eecs.umich.edu 79510037SARM gem5 Developersbool 79610037SARM gem5 DevelopersSupervisorCall::routeToHyp(ThreadContext *tc) const 79710037SARM gem5 Developers{ 79810037SARM gem5 Developers bool toHyp; 79910037SARM gem5 Developers 80010037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 80110037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 80210037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 80310037SARM gem5 Developers 80410037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 80510037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 80610037SARM gem5 Developers // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 80710037SARM gem5 Developers toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 80810037SARM gem5 Developers return toHyp; 80910037SARM gem5 Developers} 81010037SARM gem5 Developers 81110037SARM gem5 DevelopersExceptionClass 81210037SARM gem5 DevelopersSupervisorCall::ec(ThreadContext *tc) const 81310037SARM gem5 Developers{ 81410037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : 81510037SARM gem5 Developers (from64 ? EC_SVC_64 : vals.ec); 81610037SARM gem5 Developers} 81710037SARM gem5 Developers 81810037SARM gem5 Developersuint32_t 81910037SARM gem5 DevelopersSupervisorCall::iss() const 82010037SARM gem5 Developers{ 82110037SARM gem5 Developers // Even if we have a 24 bit imm from an arm32 instruction then we only use 82210037SARM gem5 Developers // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC). 82310037SARM gem5 Developers return issRaw & 0xFFFF; 82410037SARM gem5 Developers} 82510037SARM gem5 Developers 82610037SARM gem5 Developersuint32_t 82710037SARM gem5 DevelopersSecureMonitorCall::iss() const 82810037SARM gem5 Developers{ 82910037SARM gem5 Developers if (from64) 83010037SARM gem5 Developers return bits(machInst, 20, 5); 83110037SARM gem5 Developers return 0; 83210037SARM gem5 Developers} 83310037SARM gem5 Developers 83410037SARM gem5 DevelopersExceptionClass 83510037SARM gem5 DevelopersUndefinedInstruction::ec(ThreadContext *tc) const 83610037SARM gem5 Developers{ 83710037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 83810037SARM gem5 Developers} 83910037SARM gem5 Developers 84010037SARM gem5 Developers 84110037SARM gem5 DevelopersHypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) : 84210037SARM gem5 Developers ArmFaultVals<HypervisorCall>(_machInst, _imm) 84310037SARM gem5 Developers{} 84410037SARM gem5 Developers 84510037SARM gem5 DevelopersExceptionClass 84611576SDylan.Johnson@ARM.comHypervisorCall::ec(ThreadContext *tc) const 84711576SDylan.Johnson@ARM.com{ 84811576SDylan.Johnson@ARM.com return from64 ? EC_HVC_64 : vals.ec; 84911576SDylan.Johnson@ARM.com} 85011576SDylan.Johnson@ARM.com 85111576SDylan.Johnson@ARM.comExceptionClass 85210037SARM gem5 DevelopersHypervisorTrap::ec(ThreadContext *tc) const 85310037SARM gem5 Developers{ 85410037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 85510037SARM gem5 Developers} 85610037SARM gem5 Developers 85710037SARM gem5 Developerstemplate<class T> 85810037SARM gem5 DevelopersFaultOffset 85910037SARM gem5 DevelopersArmFaultVals<T>::offset(ThreadContext *tc) 86010037SARM gem5 Developers{ 86110037SARM gem5 Developers bool isHypTrap = false; 86210037SARM gem5 Developers 86310037SARM gem5 Developers // Normally we just use the exception vector from the table at the top if 86410037SARM gem5 Developers // this file, however if this exception has caused a transition to hype 86510037SARM gem5 Developers // mode, and its an exception type that would only do this if it has been 86610037SARM gem5 Developers // trapped then we use the hyp trap vector instead of the normal vector 86710037SARM gem5 Developers if (vals.hypTrappable) { 86810037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 86910037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 87010037SARM gem5 Developers CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 87110037SARM gem5 Developers isHypTrap = spsr.mode != MODE_HYP; 87210037SARM gem5 Developers } 87310037SARM gem5 Developers } 87410037SARM gem5 Developers return isHypTrap ? 0x14 : vals.offset; 87510037SARM gem5 Developers} 87610037SARM gem5 Developers 87710037SARM gem5 Developers// void 87810037SARM gem5 Developers// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx) 87910037SARM gem5 Developers// { 88010037SARM gem5 Developers// ESR esr = 0; 88110037SARM gem5 Developers// esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32; 88210037SARM gem5 Developers// esr.il = !machInst.thumb; 88310037SARM gem5 Developers// if (machInst.aarch64) 88410037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 20, 5); 88510037SARM gem5 Developers// else if (machInst.thumb) 88610037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 7, 0); 88710037SARM gem5 Developers// else 88810037SARM gem5 Developers// esr.imm16 = bits(machInst.instBits, 15, 0); 88910037SARM gem5 Developers// tc->setMiscReg(esr_idx, esr); 89010037SARM gem5 Developers// } 89110037SARM gem5 Developers 89210037SARM gem5 Developersvoid 89310417Sandreas.hansson@arm.comSecureMonitorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 89410037SARM gem5 Developers{ 89510037SARM gem5 Developers if (FullSystem) { 89610037SARM gem5 Developers ArmFault::invoke(tc, inst); 89710037SARM gem5 Developers return; 89810037SARM gem5 Developers } 89910037SARM gem5 Developers} 90010037SARM gem5 Developers 90110037SARM gem5 DevelopersExceptionClass 90210037SARM gem5 DevelopersSecureMonitorCall::ec(ThreadContext *tc) const 90310037SARM gem5 Developers{ 90410037SARM gem5 Developers return (from64 ? EC_SMC_64 : vals.ec); 90510037SARM gem5 Developers} 90610037SARM gem5 Developers 90710037SARM gem5 DevelopersExceptionClass 90810037SARM gem5 DevelopersSupervisorTrap::ec(ThreadContext *tc) const 90910037SARM gem5 Developers{ 91010037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 91110037SARM gem5 Developers} 91210037SARM gem5 Developers 91310037SARM gem5 DevelopersExceptionClass 91410037SARM gem5 DevelopersSecureMonitorTrap::ec(ThreadContext *tc) const 91510037SARM gem5 Developers{ 91610037SARM gem5 Developers return (overrideEc != EC_INVALID) ? overrideEc : 91710037SARM gem5 Developers (from64 ? EC_SMC_64 : vals.ec); 91810037SARM gem5 Developers} 91910037SARM gem5 Developers 9207362Sgblack@eecs.umich.edutemplate<class T> 9217362Sgblack@eecs.umich.eduvoid 92210417Sandreas.hansson@arm.comAbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst) 9237362Sgblack@eecs.umich.edu{ 92410037SARM gem5 Developers if (tranMethod == ArmFault::UnknownTran) { 92510037SARM gem5 Developers tranMethod = longDescFormatInUse(tc) ? ArmFault::LpaeTran 92610037SARM gem5 Developers : ArmFault::VmsaTran; 92710037SARM gem5 Developers 92810037SARM gem5 Developers if ((tranMethod == ArmFault::VmsaTran) && this->routeToMonitor(tc)) { 92910037SARM gem5 Developers // See ARM ARM B3-1416 93010037SARM gem5 Developers bool override_LPAE = false; 93110037SARM gem5 Developers TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S); 93210037SARM gem5 Developers TTBCR M5_VAR_USED ttbcr_ns = tc->readMiscReg(MISCREG_TTBCR_NS); 93310037SARM gem5 Developers if (ttbcr_s.eae) { 93410037SARM gem5 Developers override_LPAE = true; 93510037SARM gem5 Developers } else { 93610037SARM gem5 Developers // Unimplemented code option, not seen in testing. May need 93710037SARM gem5 Developers // extension according to the manual exceprt above. 93810037SARM gem5 Developers DPRINTF(Faults, "Warning: Incomplete translation method " 93910037SARM gem5 Developers "override detected.\n"); 94010037SARM gem5 Developers } 94110037SARM gem5 Developers if (override_LPAE) 94210037SARM gem5 Developers tranMethod = ArmFault::LpaeTran; 94310037SARM gem5 Developers } 94410037SARM gem5 Developers } 94510037SARM gem5 Developers 94610037SARM gem5 Developers if (source == ArmFault::AsynchronousExternalAbort) { 94711150Smitch.hayenga@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 94810037SARM gem5 Developers } 94910037SARM gem5 Developers // Get effective fault source encoding 95010037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 95110037SARM gem5 Developers FSR fsr = getFsr(tc); 95210037SARM gem5 Developers 95310037SARM gem5 Developers // source must be determined BEFORE invoking generic routines which will 95410037SARM gem5 Developers // try to set hsr etc. and are based upon source! 9558205SAli.Saidi@ARM.com ArmFaultVals<T>::invoke(tc, inst); 95610037SARM gem5 Developers 95711496Sandreas.sandberg@arm.com if (!this->to64) { // AArch32 95810037SARM gem5 Developers if (cpsr.mode == MODE_HYP) { 95910037SARM gem5 Developers tc->setMiscReg(T::HFarIndex, faultAddr); 96010037SARM gem5 Developers } else if (stage2) { 96110037SARM gem5 Developers tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf); 96210037SARM gem5 Developers tc->setMiscReg(T::HFarIndex, OVAddr); 96310037SARM gem5 Developers } else { 96410037SARM gem5 Developers tc->setMiscReg(T::FsrIndex, fsr); 96510037SARM gem5 Developers tc->setMiscReg(T::FarIndex, faultAddr); 96610037SARM gem5 Developers } 96710037SARM gem5 Developers DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x "\ 96810037SARM gem5 Developers "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod); 96910037SARM gem5 Developers } else { // AArch64 97010037SARM gem5 Developers // Set the FAR register. Nothing else to do if we are in AArch64 state 97110037SARM gem5 Developers // because the syndrome register has already been set inside invoke64() 97210037SARM gem5 Developers tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr); 97310037SARM gem5 Developers } 97410037SARM gem5 Developers} 97510037SARM gem5 Developers 97610037SARM gem5 Developerstemplate<class T> 97710037SARM gem5 DevelopersFSR 97810037SARM gem5 DevelopersAbortFault<T>::getFsr(ThreadContext *tc) 97910037SARM gem5 Developers{ 9807362Sgblack@eecs.umich.edu FSR fsr = 0; 9818314Sgeoffrey.blake@arm.com 98210037SARM gem5 Developers if (((CPSR) tc->readMiscRegNoEffect(MISCREG_CPSR)).width) { 98310037SARM gem5 Developers // AArch32 98410037SARM gem5 Developers assert(tranMethod != ArmFault::UnknownTran); 98510037SARM gem5 Developers if (tranMethod == ArmFault::LpaeTran) { 98610037SARM gem5 Developers srcEncoded = ArmFault::longDescFaultSources[source]; 98710037SARM gem5 Developers fsr.status = srcEncoded; 98810037SARM gem5 Developers fsr.lpae = 1; 98910037SARM gem5 Developers } else { 99010037SARM gem5 Developers srcEncoded = ArmFault::shortDescFaultSources[source]; 99110037SARM gem5 Developers fsr.fsLow = bits(srcEncoded, 3, 0); 99210037SARM gem5 Developers fsr.fsHigh = bits(srcEncoded, 4); 99310037SARM gem5 Developers fsr.domain = static_cast<uint8_t>(domain); 99410037SARM gem5 Developers } 99510037SARM gem5 Developers fsr.wnr = (write ? 1 : 0); 99610037SARM gem5 Developers fsr.ext = 0; 99710037SARM gem5 Developers } else { 99810037SARM gem5 Developers // AArch64 99910037SARM gem5 Developers srcEncoded = ArmFault::aarch64FaultSources[source]; 100010037SARM gem5 Developers } 100110037SARM gem5 Developers if (srcEncoded == ArmFault::FaultSourceInvalid) { 100210037SARM gem5 Developers panic("Invalid fault source\n"); 100310037SARM gem5 Developers } 100410037SARM gem5 Developers return fsr; 100510037SARM gem5 Developers} 100610037SARM gem5 Developers 100710037SARM gem5 Developerstemplate<class T> 100810037SARM gem5 Developersbool 100910037SARM gem5 DevelopersAbortFault<T>::abortDisable(ThreadContext *tc) 101010037SARM gem5 Developers{ 101110037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 101210037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 101310037SARM gem5 Developers return (!scr.ns || scr.aw); 101410037SARM gem5 Developers } 101510037SARM gem5 Developers return true; 101610037SARM gem5 Developers} 101710037SARM gem5 Developers 101810037SARM gem5 Developerstemplate<class T> 101910037SARM gem5 Developersvoid 102010037SARM gem5 DevelopersAbortFault<T>::annotate(ArmFault::AnnotationIDs id, uint64_t val) 102110037SARM gem5 Developers{ 102210037SARM gem5 Developers switch (id) 102310037SARM gem5 Developers { 102410037SARM gem5 Developers case ArmFault::S1PTW: 102510037SARM gem5 Developers s1ptw = val; 102610037SARM gem5 Developers break; 102710037SARM gem5 Developers case ArmFault::OVA: 102810037SARM gem5 Developers OVAddr = val; 102910037SARM gem5 Developers break; 103010037SARM gem5 Developers 103110037SARM gem5 Developers // Just ignore unknown ID's 103210037SARM gem5 Developers default: 103310037SARM gem5 Developers break; 103410037SARM gem5 Developers } 103510037SARM gem5 Developers} 103610037SARM gem5 Developers 103710037SARM gem5 Developerstemplate<class T> 103810037SARM gem5 Developersuint32_t 103910037SARM gem5 DevelopersAbortFault<T>::iss() const 104010037SARM gem5 Developers{ 104110037SARM gem5 Developers uint32_t val; 104210037SARM gem5 Developers 104310037SARM gem5 Developers val = srcEncoded & 0x3F; 104410037SARM gem5 Developers val |= write << 6; 104510037SARM gem5 Developers val |= s1ptw << 7; 104610037SARM gem5 Developers return (val); 104710037SARM gem5 Developers} 104810037SARM gem5 Developers 104910037SARM gem5 Developerstemplate<class T> 105010037SARM gem5 Developersbool 105110037SARM gem5 DevelopersAbortFault<T>::isMMUFault() const 105210037SARM gem5 Developers{ 105310037SARM gem5 Developers // NOTE: Not relying on LL information being aligned to lowest bits here 105410037SARM gem5 Developers return 105510037SARM gem5 Developers (source == ArmFault::AlignmentFault) || 105610037SARM gem5 Developers ((source >= ArmFault::TranslationLL) && 105710037SARM gem5 Developers (source < ArmFault::TranslationLL + 4)) || 105810037SARM gem5 Developers ((source >= ArmFault::AccessFlagLL) && 105910037SARM gem5 Developers (source < ArmFault::AccessFlagLL + 4)) || 106010037SARM gem5 Developers ((source >= ArmFault::DomainLL) && 106110037SARM gem5 Developers (source < ArmFault::DomainLL + 4)) || 106210037SARM gem5 Developers ((source >= ArmFault::PermissionLL) && 106310037SARM gem5 Developers (source < ArmFault::PermissionLL + 4)); 106410037SARM gem5 Developers} 106510037SARM gem5 Developers 106610037SARM gem5 DevelopersExceptionClass 106710037SARM gem5 DevelopersPrefetchAbort::ec(ThreadContext *tc) const 106810037SARM gem5 Developers{ 106910037SARM gem5 Developers if (to64) { 107010037SARM gem5 Developers // AArch64 107110037SARM gem5 Developers if (toEL == fromEL) 107210037SARM gem5 Developers return EC_PREFETCH_ABORT_CURR_EL; 107310037SARM gem5 Developers else 107410037SARM gem5 Developers return EC_PREFETCH_ABORT_LOWER_EL; 107510037SARM gem5 Developers } else { 107610037SARM gem5 Developers // AArch32 107710037SARM gem5 Developers // Abort faults have different EC codes depending on whether 107810037SARM gem5 Developers // the fault originated within HYP mode, or not. So override 107910037SARM gem5 Developers // the method and add the extra adjustment of the EC value. 108010037SARM gem5 Developers 108110037SARM gem5 Developers ExceptionClass ec = ArmFaultVals<PrefetchAbort>::vals.ec; 108210037SARM gem5 Developers 108310037SARM gem5 Developers CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 108410037SARM gem5 Developers if (spsr.mode == MODE_HYP) { 108510037SARM gem5 Developers ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 108610037SARM gem5 Developers } 108710037SARM gem5 Developers return ec; 108810037SARM gem5 Developers } 108910037SARM gem5 Developers} 109010037SARM gem5 Developers 109110037SARM gem5 Developersbool 109210037SARM gem5 DevelopersPrefetchAbort::routeToMonitor(ThreadContext *tc) const 109310037SARM gem5 Developers{ 109410037SARM gem5 Developers SCR scr = 0; 109510037SARM gem5 Developers if (from64) 109610037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 109710037SARM gem5 Developers else 109810037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 109910037SARM gem5 Developers 110010037SARM gem5 Developers return scr.ea && !isMMUFault(); 110110037SARM gem5 Developers} 110210037SARM gem5 Developers 110310037SARM gem5 Developersbool 110410037SARM gem5 DevelopersPrefetchAbort::routeToHyp(ThreadContext *tc) const 110510037SARM gem5 Developers{ 110610037SARM gem5 Developers bool toHyp; 110710037SARM gem5 Developers 110810037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 110910037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 111010037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 111110037SARM gem5 Developers HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 111210037SARM gem5 Developers 111310037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 111410037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 111510037SARM gem5 Developers // otherwise, check whether to take to Hyp mode through Hyp Trap vector 111610037SARM gem5 Developers toHyp |= (stage2 || 111710037SARM gem5 Developers ( (source == DebugEvent) && hdcr.tde && (cpsr.mode != MODE_HYP)) || 111810037SARM gem5 Developers ( (source == SynchronousExternalAbort) && hcr.tge && (cpsr.mode == MODE_USER)) 111910037SARM gem5 Developers ) && !inSecureState(scr, cpsr); 112010037SARM gem5 Developers return toHyp; 112110037SARM gem5 Developers} 112210037SARM gem5 Developers 112310037SARM gem5 DevelopersExceptionClass 112410037SARM gem5 DevelopersDataAbort::ec(ThreadContext *tc) const 112510037SARM gem5 Developers{ 112610037SARM gem5 Developers if (to64) { 112710037SARM gem5 Developers // AArch64 112810037SARM gem5 Developers if (source == ArmFault::AsynchronousExternalAbort) { 112910367SAndrew.Bardsley@arm.com panic("Asynchronous External Abort should be handled with " 113010367SAndrew.Bardsley@arm.com "SystemErrors (SErrors)!"); 113110037SARM gem5 Developers } 113210037SARM gem5 Developers if (toEL == fromEL) 113310037SARM gem5 Developers return EC_DATA_ABORT_CURR_EL; 113410037SARM gem5 Developers else 113510037SARM gem5 Developers return EC_DATA_ABORT_LOWER_EL; 113610037SARM gem5 Developers } else { 113710037SARM gem5 Developers // AArch32 113810037SARM gem5 Developers // Abort faults have different EC codes depending on whether 113910037SARM gem5 Developers // the fault originated within HYP mode, or not. So override 114010037SARM gem5 Developers // the method and add the extra adjustment of the EC value. 114110037SARM gem5 Developers 114210037SARM gem5 Developers ExceptionClass ec = ArmFaultVals<DataAbort>::vals.ec; 114310037SARM gem5 Developers 114410037SARM gem5 Developers CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 114510037SARM gem5 Developers if (spsr.mode == MODE_HYP) { 114610037SARM gem5 Developers ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 114710037SARM gem5 Developers } 114810037SARM gem5 Developers return ec; 114910037SARM gem5 Developers } 115010037SARM gem5 Developers} 115110037SARM gem5 Developers 115210037SARM gem5 Developersbool 115310037SARM gem5 DevelopersDataAbort::routeToMonitor(ThreadContext *tc) const 115410037SARM gem5 Developers{ 115510037SARM gem5 Developers SCR scr = 0; 115610037SARM gem5 Developers if (from64) 115710037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 115810037SARM gem5 Developers else 115910037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 116010037SARM gem5 Developers 116110037SARM gem5 Developers return scr.ea && !isMMUFault(); 116210037SARM gem5 Developers} 116310037SARM gem5 Developers 116410037SARM gem5 Developersbool 116510037SARM gem5 DevelopersDataAbort::routeToHyp(ThreadContext *tc) const 116610037SARM gem5 Developers{ 116710037SARM gem5 Developers bool toHyp; 116810037SARM gem5 Developers 116910037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 117010037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 117110037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 117210037SARM gem5 Developers HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 117310037SARM gem5 Developers 117410037SARM gem5 Developers // if in Hyp mode then stay in Hyp mode 117510037SARM gem5 Developers toHyp = scr.ns && (cpsr.mode == MODE_HYP); 117610037SARM gem5 Developers // otherwise, check whether to take to Hyp mode through Hyp Trap vector 117710037SARM gem5 Developers toHyp |= (stage2 || 117810037SARM gem5 Developers ( (cpsr.mode != MODE_HYP) && ( ((source == AsynchronousExternalAbort) && hcr.amo) || 117910037SARM gem5 Developers ((source == DebugEvent) && hdcr.tde) ) 118010037SARM gem5 Developers ) || 118110037SARM gem5 Developers ( (cpsr.mode == MODE_USER) && hcr.tge && 118210037SARM gem5 Developers ((source == AlignmentFault) || 118310037SARM gem5 Developers (source == SynchronousExternalAbort)) 118410037SARM gem5 Developers ) 118510037SARM gem5 Developers ) && !inSecureState(scr, cpsr); 118610037SARM gem5 Developers return toHyp; 118710037SARM gem5 Developers} 118810037SARM gem5 Developers 118910037SARM gem5 Developersuint32_t 119010037SARM gem5 DevelopersDataAbort::iss() const 119110037SARM gem5 Developers{ 119210037SARM gem5 Developers uint32_t val; 119310037SARM gem5 Developers 119410037SARM gem5 Developers // Add on the data abort specific fields to the generic abort ISS value 119510037SARM gem5 Developers val = AbortFault<DataAbort>::iss(); 119610037SARM gem5 Developers // ISS is valid if not caused by a stage 1 page table walk, and when taken 119710037SARM gem5 Developers // to AArch64 only when directed to EL2 119810037SARM gem5 Developers if (!s1ptw && (!to64 || toEL == EL2)) { 119910037SARM gem5 Developers val |= isv << 24; 120010037SARM gem5 Developers if (isv) { 120110037SARM gem5 Developers val |= sas << 22; 120210037SARM gem5 Developers val |= sse << 21; 120310037SARM gem5 Developers val |= srt << 16; 120410037SARM gem5 Developers // AArch64 only. These assignments are safe on AArch32 as well 120510037SARM gem5 Developers // because these vars are initialized to false 120610037SARM gem5 Developers val |= sf << 15; 120710037SARM gem5 Developers val |= ar << 14; 120810037SARM gem5 Developers } 120910037SARM gem5 Developers } 121010037SARM gem5 Developers return (val); 121110037SARM gem5 Developers} 121210037SARM gem5 Developers 121310037SARM gem5 Developersvoid 121410037SARM gem5 DevelopersDataAbort::annotate(AnnotationIDs id, uint64_t val) 121510037SARM gem5 Developers{ 121610037SARM gem5 Developers AbortFault<DataAbort>::annotate(id, val); 121710037SARM gem5 Developers switch (id) 121810037SARM gem5 Developers { 121910037SARM gem5 Developers case SAS: 122010037SARM gem5 Developers isv = true; 122110037SARM gem5 Developers sas = val; 122210037SARM gem5 Developers break; 122310037SARM gem5 Developers case SSE: 122410037SARM gem5 Developers isv = true; 122510037SARM gem5 Developers sse = val; 122610037SARM gem5 Developers break; 122710037SARM gem5 Developers case SRT: 122810037SARM gem5 Developers isv = true; 122910037SARM gem5 Developers srt = val; 123010037SARM gem5 Developers break; 123110037SARM gem5 Developers case SF: 123210037SARM gem5 Developers isv = true; 123310037SARM gem5 Developers sf = val; 123410037SARM gem5 Developers break; 123510037SARM gem5 Developers case AR: 123610037SARM gem5 Developers isv = true; 123710037SARM gem5 Developers ar = val; 123810037SARM gem5 Developers break; 123910037SARM gem5 Developers // Just ignore unknown ID's 124010037SARM gem5 Developers default: 124110037SARM gem5 Developers break; 124210037SARM gem5 Developers } 124310037SARM gem5 Developers} 124410037SARM gem5 Developers 124510037SARM gem5 Developersvoid 124610417Sandreas.hansson@arm.comVirtualDataAbort::invoke(ThreadContext *tc, const StaticInstPtr &inst) 124710037SARM gem5 Developers{ 124810037SARM gem5 Developers AbortFault<VirtualDataAbort>::invoke(tc, inst); 124910037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 125010037SARM gem5 Developers hcr.va = 0; 125110037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_HCR, hcr); 125210037SARM gem5 Developers} 125310037SARM gem5 Developers 125410037SARM gem5 Developersbool 125510037SARM gem5 DevelopersInterrupt::routeToMonitor(ThreadContext *tc) const 125610037SARM gem5 Developers{ 125710037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 125810037SARM gem5 Developers SCR scr = 0; 125910037SARM gem5 Developers if (from64) 126010037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 126110037SARM gem5 Developers else 126210037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 126310037SARM gem5 Developers return scr.irq; 126410037SARM gem5 Developers} 126510037SARM gem5 Developers 126610037SARM gem5 Developersbool 126710037SARM gem5 DevelopersInterrupt::routeToHyp(ThreadContext *tc) const 126810037SARM gem5 Developers{ 126910037SARM gem5 Developers bool toHyp; 127010037SARM gem5 Developers 127110037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 127210037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 127310037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 127410037SARM gem5 Developers // Determine whether IRQs are routed to Hyp mode. 127510037SARM gem5 Developers toHyp = (!scr.irq && hcr.imo && !inSecureState(scr, cpsr)) || 127610037SARM gem5 Developers (cpsr.mode == MODE_HYP); 127710037SARM gem5 Developers return toHyp; 127810037SARM gem5 Developers} 127910037SARM gem5 Developers 128010037SARM gem5 Developersbool 128110037SARM gem5 DevelopersInterrupt::abortDisable(ThreadContext *tc) 128210037SARM gem5 Developers{ 128310037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 128410037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 128510037SARM gem5 Developers return (!scr.ns || scr.aw); 128610037SARM gem5 Developers } 128710037SARM gem5 Developers return true; 128810037SARM gem5 Developers} 128910037SARM gem5 Developers 129010037SARM gem5 DevelopersVirtualInterrupt::VirtualInterrupt() 129110037SARM gem5 Developers{} 129210037SARM gem5 Developers 129310037SARM gem5 Developersbool 129410037SARM gem5 DevelopersFastInterrupt::routeToMonitor(ThreadContext *tc) const 129510037SARM gem5 Developers{ 129610037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 129710037SARM gem5 Developers SCR scr = 0; 129810037SARM gem5 Developers if (from64) 129910037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 130010037SARM gem5 Developers else 130110037SARM gem5 Developers scr = tc->readMiscRegNoEffect(MISCREG_SCR); 130210037SARM gem5 Developers return scr.fiq; 130310037SARM gem5 Developers} 130410037SARM gem5 Developers 130510037SARM gem5 Developersbool 130610037SARM gem5 DevelopersFastInterrupt::routeToHyp(ThreadContext *tc) const 130710037SARM gem5 Developers{ 130810037SARM gem5 Developers bool toHyp; 130910037SARM gem5 Developers 131010037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 131110037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 131210037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 131310037SARM gem5 Developers // Determine whether IRQs are routed to Hyp mode. 131410037SARM gem5 Developers toHyp = (!scr.fiq && hcr.fmo && !inSecureState(scr, cpsr)) || 131510037SARM gem5 Developers (cpsr.mode == MODE_HYP); 131610037SARM gem5 Developers return toHyp; 131710037SARM gem5 Developers} 131810037SARM gem5 Developers 131910037SARM gem5 Developersbool 132010037SARM gem5 DevelopersFastInterrupt::abortDisable(ThreadContext *tc) 132110037SARM gem5 Developers{ 132210037SARM gem5 Developers if (ArmSystem::haveSecurity(tc)) { 132310037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 132410037SARM gem5 Developers return (!scr.ns || scr.aw); 132510037SARM gem5 Developers } 132610037SARM gem5 Developers return true; 132710037SARM gem5 Developers} 132810037SARM gem5 Developers 132910037SARM gem5 Developersbool 133010037SARM gem5 DevelopersFastInterrupt::fiqDisable(ThreadContext *tc) 133110037SARM gem5 Developers{ 133210037SARM gem5 Developers if (ArmSystem::haveVirtualization(tc)) { 133310037SARM gem5 Developers return true; 133410037SARM gem5 Developers } else if (ArmSystem::haveSecurity(tc)) { 133510037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 133610037SARM gem5 Developers return (!scr.ns || scr.fw); 133710037SARM gem5 Developers } 133810037SARM gem5 Developers return true; 133910037SARM gem5 Developers} 134010037SARM gem5 Developers 134110037SARM gem5 DevelopersVirtualFastInterrupt::VirtualFastInterrupt() 134210037SARM gem5 Developers{} 134310037SARM gem5 Developers 134410037SARM gem5 Developersvoid 134510417Sandreas.hansson@arm.comPCAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 134610037SARM gem5 Developers{ 134710037SARM gem5 Developers ArmFaultVals<PCAlignmentFault>::invoke(tc, inst); 134810037SARM gem5 Developers assert(from64); 134910037SARM gem5 Developers // Set the FAR 135010037SARM gem5 Developers tc->setMiscReg(getFaultAddrReg64(), faultPC); 135110037SARM gem5 Developers} 135210037SARM gem5 Developers 135310037SARM gem5 DevelopersSPAlignmentFault::SPAlignmentFault() 135410037SARM gem5 Developers{} 135510037SARM gem5 Developers 135610037SARM gem5 DevelopersSystemError::SystemError() 135710037SARM gem5 Developers{} 135810037SARM gem5 Developers 135910037SARM gem5 Developersvoid 136010417Sandreas.hansson@arm.comSystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst) 136110037SARM gem5 Developers{ 136211150Smitch.hayenga@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 136310037SARM gem5 Developers ArmFault::invoke(tc, inst); 136410037SARM gem5 Developers} 136510037SARM gem5 Developers 136610037SARM gem5 Developersbool 136710037SARM gem5 DevelopersSystemError::routeToMonitor(ThreadContext *tc) const 136810037SARM gem5 Developers{ 136910037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 137010037SARM gem5 Developers assert(from64); 137110037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 137210037SARM gem5 Developers return scr.ea; 137310037SARM gem5 Developers} 137410037SARM gem5 Developers 137510037SARM gem5 Developersbool 137610037SARM gem5 DevelopersSystemError::routeToHyp(ThreadContext *tc) const 137710037SARM gem5 Developers{ 137810037SARM gem5 Developers bool toHyp; 137910037SARM gem5 Developers assert(from64); 138010037SARM gem5 Developers 138110037SARM gem5 Developers SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 138210037SARM gem5 Developers HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 138310037SARM gem5 Developers CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 138410037SARM gem5 Developers 138510037SARM gem5 Developers toHyp = (!scr.ea && hcr.amo && !inSecureState(scr, cpsr)) || 138610037SARM gem5 Developers (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(scr,cpsr)); 138710037SARM gem5 Developers return toHyp; 13887362Sgblack@eecs.umich.edu} 13897362Sgblack@eecs.umich.edu 13907652Sminkyu.jeong@arm.comvoid 139110417Sandreas.hansson@arm.comFlushPipe::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 13927652Sminkyu.jeong@arm.com DPRINTF(Faults, "Invoking FlushPipe Fault\n"); 13937652Sminkyu.jeong@arm.com 13947652Sminkyu.jeong@arm.com // Set the PC to the next instruction of the faulting instruction. 13957652Sminkyu.jeong@arm.com // Net effect is simply squashing all instructions behind and 13967652Sminkyu.jeong@arm.com // start refetching from the next instruction. 13977720Sgblack@eecs.umich.edu PCState pc = tc->pcState(); 13987720Sgblack@eecs.umich.edu assert(inst); 13997720Sgblack@eecs.umich.edu inst->advancePC(pc); 14007720Sgblack@eecs.umich.edu tc->pcState(pc); 14017652Sminkyu.jeong@arm.com} 14027652Sminkyu.jeong@arm.com 14038518Sgeoffrey.blake@arm.comvoid 140410417Sandreas.hansson@arm.comArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 14058518Sgeoffrey.blake@arm.com DPRINTF(Faults, "Invoking ArmSev Fault\n"); 14068806Sgblack@eecs.umich.edu if (!FullSystem) 14078806Sgblack@eecs.umich.edu return; 14088806Sgblack@eecs.umich.edu 14098806Sgblack@eecs.umich.edu // Set sev_mailbox to 1, clear the pending interrupt from remote 14108806Sgblack@eecs.umich.edu // SEV execution and let pipeline continue as pcState is still 14118806Sgblack@eecs.umich.edu // valid. 14128806Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 141311150Smitch.hayenga@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0); 14148518Sgeoffrey.blake@arm.com} 14158518Sgeoffrey.blake@arm.com 141610037SARM gem5 Developers// Instantiate all the templates to make the linker happy 141710037SARM gem5 Developerstemplate class ArmFaultVals<Reset>; 141810037SARM gem5 Developerstemplate class ArmFaultVals<UndefinedInstruction>; 141910037SARM gem5 Developerstemplate class ArmFaultVals<SupervisorCall>; 142010037SARM gem5 Developerstemplate class ArmFaultVals<SecureMonitorCall>; 142110037SARM gem5 Developerstemplate class ArmFaultVals<HypervisorCall>; 142210037SARM gem5 Developerstemplate class ArmFaultVals<PrefetchAbort>; 142310037SARM gem5 Developerstemplate class ArmFaultVals<DataAbort>; 142410037SARM gem5 Developerstemplate class ArmFaultVals<VirtualDataAbort>; 142510037SARM gem5 Developerstemplate class ArmFaultVals<HypervisorTrap>; 142610037SARM gem5 Developerstemplate class ArmFaultVals<Interrupt>; 142710037SARM gem5 Developerstemplate class ArmFaultVals<VirtualInterrupt>; 142810037SARM gem5 Developerstemplate class ArmFaultVals<FastInterrupt>; 142910037SARM gem5 Developerstemplate class ArmFaultVals<VirtualFastInterrupt>; 143010037SARM gem5 Developerstemplate class ArmFaultVals<SupervisorTrap>; 143110037SARM gem5 Developerstemplate class ArmFaultVals<SecureMonitorTrap>; 143210037SARM gem5 Developerstemplate class ArmFaultVals<PCAlignmentFault>; 143310037SARM gem5 Developerstemplate class ArmFaultVals<SPAlignmentFault>; 143410037SARM gem5 Developerstemplate class ArmFaultVals<SystemError>; 143510037SARM gem5 Developerstemplate class ArmFaultVals<FlushPipe>; 143610037SARM gem5 Developerstemplate class ArmFaultVals<ArmSev>; 143710037SARM gem5 Developerstemplate class AbortFault<PrefetchAbort>; 143810037SARM gem5 Developerstemplate class AbortFault<DataAbort>; 143910037SARM gem5 Developerstemplate class AbortFault<VirtualDataAbort>; 144010037SARM gem5 Developers 144110037SARM gem5 Developers 144210037SARM gem5 DevelopersIllegalInstSetStateFault::IllegalInstSetStateFault() 144310037SARM gem5 Developers{} 144410037SARM gem5 Developers 14456019Shines@cs.fsu.edu 14466019Shines@cs.fsu.edu} // namespace ArmISA 1447