faults.cc revision 11793
1360SN/A/* 210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2010, 2012-2014, 2016 ARM Limited 310796Sbrandon.potter@amd.com * All rights reserved 410027SChris.Adeniyi-Jones@arm.com * 510027SChris.Adeniyi-Jones@arm.com * The license below extends only to copyright in the software and shall 610027SChris.Adeniyi-Jones@arm.com * not be construed as granting a license to any other intellectual 710027SChris.Adeniyi-Jones@arm.com * property including but not limited to intellectual property relating 810027SChris.Adeniyi-Jones@arm.com * to a hardware implementation of the functionality of the software 910027SChris.Adeniyi-Jones@arm.com * licensed hereunder. You may use the software subject to the license 1010027SChris.Adeniyi-Jones@arm.com * terms below provided that you ensure that this notice is replicated 1110027SChris.Adeniyi-Jones@arm.com * unmodified and in its entirety in all distributions of the software, 1210027SChris.Adeniyi-Jones@arm.com * modified or unmodified, in source code or in binary form. 1310027SChris.Adeniyi-Jones@arm.com * 1410027SChris.Adeniyi-Jones@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 151458SN/A * Copyright (c) 2007-2008 The Florida State University 16360SN/A * All rights reserved. 17360SN/A * 18360SN/A * Redistribution and use in source and binary forms, with or without 19360SN/A * modification, are permitted provided that the following conditions are 20360SN/A * met: redistributions of source code must retain the above copyright 21360SN/A * notice, this list of conditions and the following disclaimer; 22360SN/A * redistributions in binary form must reproduce the above copyright 23360SN/A * notice, this list of conditions and the following disclaimer in the 24360SN/A * documentation and/or other materials provided with the distribution; 25360SN/A * neither the name of the copyright holders nor the names of its 26360SN/A * contributors may be used to endorse or promote products derived from 27360SN/A * this software without specific prior written permission. 28360SN/A * 29360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 422665Ssaidi@eecs.umich.edu * Gabe Black 43360SN/A * Giacomo Gabrielli 44360SN/A * Thomas Grocutt 451354SN/A */ 461354SN/A 47360SN/A#include "arch/arm/faults.hh" 4812018Sandreas.sandberg@arm.com 4912018Sandreas.sandberg@arm.com#include "arch/arm/insts/static_inst.hh" 5012018Sandreas.sandberg@arm.com#include "arch/arm/system.hh" 5112018Sandreas.sandberg@arm.com#include "arch/arm/utility.hh" 5212018Sandreas.sandberg@arm.com#include "base/compiler.hh" 5312018Sandreas.sandberg@arm.com#include "base/trace.hh" 5412018Sandreas.sandberg@arm.com#include "cpu/base.hh" 552064SN/A#include "cpu/thread_context.hh" 5612018Sandreas.sandberg@arm.com#include "debug/Faults.hh" 5712018Sandreas.sandberg@arm.com#include "sim/full_system.hh" 5812018Sandreas.sandberg@arm.com 5912018Sandreas.sandberg@arm.comnamespace ArmISA 6012018Sandreas.sandberg@arm.com{ 6112018Sandreas.sandberg@arm.com 6211799Sbrandon.potter@amd.comuint8_t ArmFault::shortDescFaultSources[] = { 6312018Sandreas.sandberg@arm.com 0x01, // AlignmentFault 6412018Sandreas.sandberg@arm.com 0x04, // InstructionCacheMaintenance 6512018Sandreas.sandberg@arm.com 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 6612018Sandreas.sandberg@arm.com 0x0c, // SynchExtAbtOnTranslTableWalkL1 6712018Sandreas.sandberg@arm.com 0x0e, // SynchExtAbtOnTranslTableWalkL2 6812018Sandreas.sandberg@arm.com 0xff, // SynchExtAbtOnTranslTableWalkL3 (INVALID) 6911799Sbrandon.potter@amd.com 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 70360SN/A 0x1c, // SynchPtyErrOnTranslTableWalkL1 71360SN/A 0x1e, // SynchPtyErrOnTranslTableWalkL2 72360SN/A 0xff, // SynchPtyErrOnTranslTableWalkL3 (INVALID) 73360SN/A 0xff, // TranslationL0 (INVALID) 74360SN/A 0x05, // TranslationL1 75360SN/A 0x07, // TranslationL2 761809SN/A 0xff, // TranslationL3 (INVALID) 7711800Sbrandon.potter@amd.com 0xff, // AccessFlagL0 (INVALID) 7811392Sbrandon.potter@amd.com 0x03, // AccessFlagL1 791809SN/A 0x06, // AccessFlagL2 8011392Sbrandon.potter@amd.com 0xff, // AccessFlagL3 (INVALID) 8113570Sbrandon.potter@amd.com 0xff, // DomainL0 (INVALID) 8211383Sbrandon.potter@amd.com 0x09, // DomainL1 8313568Sbrandon.potter@amd.com 0x0b, // DomainL2 843113Sgblack@eecs.umich.edu 0xff, // DomainL3 (INVALID) 8511799Sbrandon.potter@amd.com 0xff, // PermissionL0 (INVALID) 8611759Sbrandon.potter@amd.com 0x0d, // PermissionL1 8711812Sbaz21@cam.ac.uk 0x0f, // PermissionL2 8811812Sbaz21@cam.ac.uk 0xff, // PermissionL3 (INVALID) 8911799Sbrandon.potter@amd.com 0x02, // DebugEvent 908229Snate@binkert.org 0x08, // SynchronousExternalAbort 9113570Sbrandon.potter@amd.com 0x10, // TLBConflictAbort 928229Snate@binkert.org 0x19, // SynchPtyErrOnMemoryAccess 9311594Santhony.gutierrez@amd.com 0x16, // AsynchronousExternalAbort 947075Snate@binkert.org 0x18, // AsynchPtyErrOnMemoryAccess 958229Snate@binkert.org 0xff, // AddressSizeL0 (INVALID) 9611856Sbrandon.potter@amd.com 0xff, // AddressSizeL1 (INVALID) 977075Snate@binkert.org 0xff, // AddressSizeL2 (INVALID) 98360SN/A 0xff, // AddressSizeL3 (INVALID) 9912461Sgabeblack@google.com 0x40, // PrefetchTLBMiss 10011886Sbrandon.potter@amd.com 0x80 // PrefetchUncacheable 10111800Sbrandon.potter@amd.com}; 10211392Sbrandon.potter@amd.com 10312334Sgabeblack@google.comstatic_assert(sizeof(ArmFault::shortDescFaultSources) == 1041354SN/A ArmFault::NumFaultSources, 1056216Snate@binkert.org "Invalid size of ArmFault::shortDescFaultSources[]"); 1066658Snate@binkert.org 1072474SN/Auint8_t ArmFault::longDescFaultSources[] = { 1082680Sktlim@umich.edu 0x21, // AlignmentFault 1098229Snate@binkert.org 0xff, // InstructionCacheMaintenance (INVALID) 11011886Sbrandon.potter@amd.com 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID) 11110496Ssteve.reinhardt@amd.com 0x15, // SynchExtAbtOnTranslTableWalkL1 11211911SBrandon.Potter@amd.com 0x16, // SynchExtAbtOnTranslTableWalkL2 1138229Snate@binkert.org 0x17, // SynchExtAbtOnTranslTableWalkL3 11411794Sbrandon.potter@amd.com 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID) 11511886Sbrandon.potter@amd.com 0x1d, // SynchPtyErrOnTranslTableWalkL1 11610497Ssteve.reinhardt@amd.com 0x1e, // SynchPtyErrOnTranslTableWalkL2 11711794Sbrandon.potter@amd.com 0x1f, // SynchPtyErrOnTranslTableWalkL3 118360SN/A 0xff, // TranslationL0 (INVALID) 11913629SAndrea.Mondelli@ucf.edu 0x05, // TranslationL1 12013629SAndrea.Mondelli@ucf.edu 0x06, // TranslationL2 12113629SAndrea.Mondelli@ucf.edu 0x07, // TranslationL3 12213629SAndrea.Mondelli@ucf.edu 0xff, // AccessFlagL0 (INVALID) 123360SN/A 0x09, // AccessFlagL1 124360SN/A 0x0a, // AccessFlagL2 125360SN/A 0x0b, // AccessFlagL3 126360SN/A 0xff, // DomainL0 (INVALID) 127360SN/A 0x3d, // DomainL1 128360SN/A 0x3e, // DomainL2 129360SN/A 0xff, // DomainL3 (RESERVED) 130360SN/A 0xff, // PermissionL0 (INVALID) 131360SN/A 0x0d, // PermissionL1 132378SN/A 0x0e, // PermissionL2 1331706SN/A 0x0f, // PermissionL3 13411851Sbrandon.potter@amd.com 0x22, // DebugEvent 135378SN/A 0x10, // SynchronousExternalAbort 136378SN/A 0x30, // TLBConflictAbort 137378SN/A 0x18, // SynchPtyErrOnMemoryAccess 138378SN/A 0x11, // AsynchronousExternalAbort 139378SN/A 0x19, // AsynchPtyErrOnMemoryAccess 1401706SN/A 0xff, // AddressSizeL0 (INVALID) 14111851Sbrandon.potter@amd.com 0xff, // AddressSizeL1 (INVALID) 142360SN/A 0xff, // AddressSizeL2 (INVALID) 14311760Sbrandon.potter@amd.com 0xff, // AddressSizeL3 (INVALID) 14411760Sbrandon.potter@amd.com 0x40, // PrefetchTLBMiss 14511851Sbrandon.potter@amd.com 0x80 // PrefetchUncacheable 14611760Sbrandon.potter@amd.com}; 1476109Ssanchezd@stanford.edu 1481706SN/Astatic_assert(sizeof(ArmFault::longDescFaultSources) == 14911851Sbrandon.potter@amd.com ArmFault::NumFaultSources, 150378SN/A "Invalid size of ArmFault::longDescFaultSources[]"); 1516109Ssanchezd@stanford.edu 1526109Ssanchezd@stanford.eduuint8_t ArmFault::aarch64FaultSources[] = { 15311851Sbrandon.potter@amd.com 0x21, // AlignmentFault 1546109Ssanchezd@stanford.edu 0xff, // InstructionCacheMaintenance (INVALID) 15511886Sbrandon.potter@amd.com 0x14, // SynchExtAbtOnTranslTableWalkL0 15611886Sbrandon.potter@amd.com 0x15, // SynchExtAbtOnTranslTableWalkL1 15711886Sbrandon.potter@amd.com 0x16, // SynchExtAbtOnTranslTableWalkL2 15811886Sbrandon.potter@amd.com 0x17, // SynchExtAbtOnTranslTableWalkL3 159378SN/A 0x1c, // SynchPtyErrOnTranslTableWalkL0 1601706SN/A 0x1d, // SynchPtyErrOnTranslTableWalkL1 16111851Sbrandon.potter@amd.com 0x1e, // SynchPtyErrOnTranslTableWalkL2 162378SN/A 0x1f, // SynchPtyErrOnTranslTableWalkL3 1635748SSteve.Reinhardt@amd.com 0x04, // TranslationL0 1645748SSteve.Reinhardt@amd.com 0x05, // TranslationL1 16511851Sbrandon.potter@amd.com 0x06, // TranslationL2 166378SN/A 0x07, // TranslationL3 167378SN/A 0x08, // AccessFlagL0 1681706SN/A 0x09, // AccessFlagL1 16911851Sbrandon.potter@amd.com 0x0a, // AccessFlagL2 170378SN/A 0x0b, // AccessFlagL3 171378SN/A // @todo: Section & Page Domain Fault in AArch64? 1721706SN/A 0xff, // DomainL0 (INVALID) 17311851Sbrandon.potter@amd.com 0xff, // DomainL1 (INVALID) 174378SN/A 0xff, // DomainL2 (INVALID) 1754118Sgblack@eecs.umich.edu 0xff, // DomainL3 (INVALID) 1764118Sgblack@eecs.umich.edu 0x0c, // PermissionL0 17711851Sbrandon.potter@amd.com 0x0d, // PermissionL1 1784118Sgblack@eecs.umich.edu 0x0e, // PermissionL2 179378SN/A 0x0f, // PermissionL3 1801706SN/A 0xff, // DebugEvent (INVALID) 18111851Sbrandon.potter@amd.com 0x10, // SynchronousExternalAbort 182378SN/A 0x30, // TLBConflictAbort 18313568Sbrandon.potter@amd.com 0x18, // SynchPtyErrOnMemoryAccess 18413568Sbrandon.potter@amd.com 0xff, // AsynchronousExternalAbort (INVALID) 18513568Sbrandon.potter@amd.com 0xff, // AsynchPtyErrOnMemoryAccess (INVALID) 18613568Sbrandon.potter@amd.com 0x00, // AddressSizeL0 187378SN/A 0x01, // AddressSizeL1 1881706SN/A 0x02, // AddressSizeL2 18911851Sbrandon.potter@amd.com 0x03, // AddressSizeL3 190360SN/A 0x40, // PrefetchTLBMiss 1915513SMichael.Adler@intel.com 0x80 // PrefetchUncacheable 1925513SMichael.Adler@intel.com}; 19311851Sbrandon.potter@amd.com 1945513SMichael.Adler@intel.comstatic_assert(sizeof(ArmFault::aarch64FaultSources) == 19510203SAli.Saidi@ARM.com ArmFault::NumFaultSources, 19610203SAli.Saidi@ARM.com "Invalid size of ArmFault::aarch64FaultSources[]"); 19711851Sbrandon.potter@amd.com 19810203SAli.Saidi@ARM.com// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode, 1995513SMichael.Adler@intel.com// {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap, 20011851Sbrandon.potter@amd.com// {A, F} disable, class, stat 2015513SMichael.Adler@intel.comtemplate<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = { 202511SN/A // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED 20310633Smichaelupton@gmail.com // location in AArch64) 20411851Sbrandon.potter@amd.com "Reset", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 20510633Smichaelupton@gmail.com 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 2061706SN/A}; 20711851Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = { 208511SN/A "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED, 20912795Smattdsinclair@gmail.com 4, 2, 0, 0, true, false, false, EC_UNKNOWN, FaultStat() 21012795Smattdsinclair@gmail.com}; 21112795Smattdsinclair@gmail.comtemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = { 21212795Smattdsinclair@gmail.com "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 21312796Smattdsinclair@gmail.com 4, 2, 4, 2, true, false, false, EC_SVC_TO_HYP, FaultStat() 21412796Smattdsinclair@gmail.com}; 21512796Smattdsinclair@gmail.comtemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals = { 21612796Smattdsinclair@gmail.com "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON, 2175513SMichael.Adler@intel.com 4, 4, 4, 4, false, true, true, EC_SMC_TO_HYP, FaultStat() 2185513SMichael.Adler@intel.com}; 21911851Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals = { 2205513SMichael.Adler@intel.com "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 22113031Sbrandon.potter@amd.com 4, 4, 4, 4, true, false, false, EC_HVC, FaultStat() 22213031Sbrandon.potter@amd.com}; 22313031Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = { 22413031Sbrandon.potter@amd.com "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22513031Sbrandon.potter@amd.com 4, 4, 0, 0, true, true, false, EC_PREFETCH_ABORT_TO_HYP, FaultStat() 22613031Sbrandon.potter@amd.com}; 22713031Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = { 22813031Sbrandon.potter@amd.com "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 22913031Sbrandon.potter@amd.com 8, 8, 0, 0, true, true, false, EC_DATA_ABORT_TO_HYP, FaultStat() 23013031Sbrandon.potter@amd.com}; 23113031Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals = { 23213031Sbrandon.potter@amd.com "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT, 233511SN/A 8, 8, 0, 0, true, true, false, EC_INVALID, FaultStat() 2341706SN/A}; 23511851Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals = { 2361706SN/A // @todo: double check these values 2371706SN/A "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP, 2381706SN/A 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 2391706SN/A}; 24011851Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = { 2411706SN/A "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 2421706SN/A 4, 4, 0, 0, false, true, false, EC_UNKNOWN, FaultStat() 2431706SN/A}; 2441706SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals = { 24511851Sbrandon.potter@amd.com "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ, 2461706SN/A 4, 4, 0, 0, false, true, false, EC_INVALID, FaultStat() 247511SN/A}; 2486703Svince@csl.cornell.edutemplate<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = { 2496703Svince@csl.cornell.edu "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25011851Sbrandon.potter@amd.com 4, 4, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 2516703Svince@csl.cornell.edu}; 2526685Stjones1@inf.ed.ac.uktemplate<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals = { 2536685Stjones1@inf.ed.ac.uk "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ, 25411851Sbrandon.potter@amd.com 4, 4, 0, 0, false, true, true, EC_INVALID, FaultStat() 2556685Stjones1@inf.ed.ac.uk}; 2566685Stjones1@inf.ed.ac.uktemplate<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals = { 2575513SMichael.Adler@intel.com // Some dummy values (SupervisorTrap is AArch64-only) 2585513SMichael.Adler@intel.com "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 25911851Sbrandon.potter@amd.com 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 2605513SMichael.Adler@intel.com}; 26111885Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals = { 26211885Sbrandon.potter@amd.com // Some dummy values (SecureMonitorTrap is AArch64-only) 26311885Sbrandon.potter@amd.com "Secure Monitor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_MON, 2645513SMichael.Adler@intel.com 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat() 2651999SN/A}; 2661999SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals = { 26711851Sbrandon.potter@amd.com // Some dummy values (PCAlignmentFault is AArch64-only) 2681999SN/A "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 26911885Sbrandon.potter@amd.com 0, 0, 0, 0, true, false, false, EC_PC_ALIGNMENT, FaultStat() 27011885Sbrandon.potter@amd.com}; 27111885Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals = { 2721999SN/A // Some dummy values (SPAlignmentFault is AArch64-only) 2731999SN/A "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 2741999SN/A 0, 0, 0, 0, true, false, false, EC_STACK_PTR_ALIGNMENT, FaultStat() 27511851Sbrandon.potter@amd.com}; 2761999SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals = { 2773079Sstever@eecs.umich.edu // Some dummy values (SError is AArch64-only) 2783079Sstever@eecs.umich.edu "SError", 0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC, 27911851Sbrandon.potter@amd.com 0, 0, 0, 0, false, true, true, EC_SERROR, FaultStat() 2803079Sstever@eecs.umich.edu}; 28111908SBrandon.Potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = { 28211908SBrandon.Potter@amd.com // Some dummy values 28311908SBrandon.Potter@amd.com "Pipe Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 28411908SBrandon.Potter@amd.com 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 28511875Sbrandon.potter@amd.com}; 2862093SN/Atemplate<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = { 28711851Sbrandon.potter@amd.com // Some dummy values 2882093SN/A "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, 2892687Sksewell@umich.edu 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat() 2902687Sksewell@umich.edu}; 29111851Sbrandon.potter@amd.comtemplate<> ArmFault::FaultVals ArmFaultVals<IllegalInstSetStateFault>::vals = { 2922687Sksewell@umich.edu // Some dummy values (SPAlignmentFault is AArch64-only) 2932238SN/A "Illegal Inst Set State Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 2942238SN/A 0, 0, 0, 0, true, false, false, EC_ILLEGAL_INST, FaultStat() 29511851Sbrandon.potter@amd.com}; 2962238SN/A 29711908SBrandon.Potter@amd.comAddr 29811908SBrandon.Potter@amd.comArmFault::getVector(ThreadContext *tc) 29911908SBrandon.Potter@amd.com{ 30011908SBrandon.Potter@amd.com Addr base; 30111908SBrandon.Potter@amd.com 30211908SBrandon.Potter@amd.com // ARM ARM issue C B1.8.1 30311908SBrandon.Potter@amd.com bool haveSecurity = ArmSystem::haveSecurity(tc); 30411908SBrandon.Potter@amd.com 3052238SN/A // panic if SCTLR.VE because I have no idea what to do with vectored 3062238SN/A // interrupts 30711851Sbrandon.potter@amd.com SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 3082238SN/A assert(!sctlr.ve); 30913571Sbrandon.potter@amd.com // Check for invalid modes 31013571Sbrandon.potter@amd.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 31113571Sbrandon.potter@amd.com assert(haveSecurity || cpsr.mode != MODE_MON); 31213571Sbrandon.potter@amd.com assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP); 31313568Sbrandon.potter@amd.com 31413568Sbrandon.potter@amd.com switch (cpsr.mode) 31513568Sbrandon.potter@amd.com { 31613568Sbrandon.potter@amd.com case MODE_MON: 31713568Sbrandon.potter@amd.com base = tc->readMiscReg(MISCREG_MVBAR); 31813568Sbrandon.potter@amd.com break; 31913568Sbrandon.potter@amd.com case MODE_HYP: 32013568Sbrandon.potter@amd.com base = tc->readMiscReg(MISCREG_HVBAR); 32113568Sbrandon.potter@amd.com break; 32213568Sbrandon.potter@amd.com default: 32313568Sbrandon.potter@amd.com if (sctlr.v) { 32413568Sbrandon.potter@amd.com base = HighVecs; 32513448Sciro.santilli@arm.com } else { 32613031Sbrandon.potter@amd.com base = haveSecurity ? tc->readMiscReg(MISCREG_VBAR) : 0; 32713031Sbrandon.potter@amd.com } 32813031Sbrandon.potter@amd.com break; 32913448Sciro.santilli@arm.com } 33013031Sbrandon.potter@amd.com return base + offset(tc); 33113539Sjavier.setoain@arm.com} 33213539Sjavier.setoain@arm.com 33313539Sjavier.setoain@arm.comAddr 33413539Sjavier.setoain@arm.comArmFault::getVector64(ThreadContext *tc) 33513539Sjavier.setoain@arm.com{ 33613539Sjavier.setoain@arm.com Addr vbar; 33713569Sbrandon.potter@amd.com switch (toEL) { 33813569Sbrandon.potter@amd.com case EL3: 33913569Sbrandon.potter@amd.com assert(ArmSystem::haveSecurity(tc)); 34013569Sbrandon.potter@amd.com vbar = tc->readMiscReg(MISCREG_VBAR_EL3); 34113569Sbrandon.potter@amd.com break; 34213569Sbrandon.potter@amd.com case EL2: 34313569Sbrandon.potter@amd.com assert(ArmSystem::haveVirtualization(tc)); 34413569Sbrandon.potter@amd.com vbar = tc->readMiscReg(MISCREG_VBAR_EL2); 34513569Sbrandon.potter@amd.com break; 34613569Sbrandon.potter@amd.com case EL1: 34713569Sbrandon.potter@amd.com vbar = tc->readMiscReg(MISCREG_VBAR_EL1); 34813569Sbrandon.potter@amd.com break; 34913569Sbrandon.potter@amd.com default: 35013569Sbrandon.potter@amd.com panic("Invalid target exception level"); 35113569Sbrandon.potter@amd.com break; 35213569Sbrandon.potter@amd.com } 35313031Sbrandon.potter@amd.com return vbar + offset64(); 3542238SN/A} 35511851Sbrandon.potter@amd.com 3562238SN/AMiscRegIndex 3572238SN/AArmFault::getSyndromeReg64() const 3582238SN/A{ 35911851Sbrandon.potter@amd.com switch (toEL) { 3602238SN/A case EL1: 3612238SN/A return MISCREG_ESR_EL1; 3622238SN/A case EL2: 36311851Sbrandon.potter@amd.com return MISCREG_ESR_EL2; 3642238SN/A case EL3: 3652238SN/A return MISCREG_ESR_EL3; 3662238SN/A default: 36711851Sbrandon.potter@amd.com panic("Invalid exception level"); 3682238SN/A break; 3692238SN/A } 3702238SN/A} 37111851Sbrandon.potter@amd.com 3722238SN/AMiscRegIndex 3739455Smitch.hayenga+gem5@gmail.comArmFault::getFaultAddrReg64() const 3749455Smitch.hayenga+gem5@gmail.com{ 37511851Sbrandon.potter@amd.com switch (toEL) { 37610203SAli.Saidi@ARM.com case EL1: 37711851Sbrandon.potter@amd.com return MISCREG_FAR_EL1; 37811851Sbrandon.potter@amd.com case EL2: 3799455Smitch.hayenga+gem5@gmail.com return MISCREG_FAR_EL2; 38013571Sbrandon.potter@amd.com case EL3: 38113571Sbrandon.potter@amd.com return MISCREG_FAR_EL3; 38213571Sbrandon.potter@amd.com default: 38313571Sbrandon.potter@amd.com panic("Invalid exception level"); 38413571Sbrandon.potter@amd.com break; 38513571Sbrandon.potter@amd.com } 38613571Sbrandon.potter@amd.com} 38713571Sbrandon.potter@amd.com 38813571Sbrandon.potter@amd.comvoid 38913571Sbrandon.potter@amd.comArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) 39013571Sbrandon.potter@amd.com{ 39113571Sbrandon.potter@amd.com uint32_t value; 3929112Smarc.orr@gmail.com uint32_t exc_class = (uint32_t) ec(tc); 39311906SBrandon.Potter@amd.com uint32_t issVal = iss(); 39411906SBrandon.Potter@amd.com assert(!from64 || ArmSystem::highestELIs64(tc)); 3959112Smarc.orr@gmail.com 3969112Smarc.orr@gmail.com value = exc_class << 26; 39711851Sbrandon.potter@amd.com 3989112Smarc.orr@gmail.com // HSR.IL not valid for Prefetch Aborts (0x20, 0x21) and Data Aborts (0x24, 3999112Smarc.orr@gmail.com // 0x25) for which the ISS information is not valid (ARMv7). 40011911SBrandon.Potter@amd.com // @todo: ARMv8 revises AArch32 functionality: when HSR.IL is not 4019112Smarc.orr@gmail.com // valid it is treated as RES1. 40211911SBrandon.Potter@amd.com if (to64) { 40311911SBrandon.Potter@amd.com value |= 1 << 25; 40411911SBrandon.Potter@amd.com } else if ((bits(exc_class, 5, 3) != 4) || 40511911SBrandon.Potter@amd.com (bits(exc_class, 2) && bits(issVal, 24))) { 40613642Sqtt2@cornell.edu if (!machInst.thumb || machInst.bigThumb) 40713642Sqtt2@cornell.edu value |= 1 << 25; 40813642Sqtt2@cornell.edu } 4099112Smarc.orr@gmail.com // Condition code valid for EC[5:4] nonzero 41011911SBrandon.Potter@amd.com if (!from64 && ((bits(exc_class, 5, 4) == 0) && 41111911SBrandon.Potter@amd.com (bits(exc_class, 3, 0) != 0))) { 41211911SBrandon.Potter@amd.com if (!machInst.thumb) { 41311911SBrandon.Potter@amd.com uint32_t cond; 4149238Slluc.alvarez@bsc.es ConditionCode condCode = (ConditionCode) (uint32_t) machInst.condCode; 41513642Sqtt2@cornell.edu // If its on unconditional instruction report with a cond code of 4169112Smarc.orr@gmail.com // 0xE, ie the unconditional code 41711911SBrandon.Potter@amd.com cond = (condCode == COND_UC) ? COND_AL : condCode; 4189112Smarc.orr@gmail.com value |= cond << 20; 41913642Sqtt2@cornell.edu value |= 1 << 24; 42011911SBrandon.Potter@amd.com } 42111911SBrandon.Potter@amd.com value |= bits(issVal, 19, 0); 42211911SBrandon.Potter@amd.com } else { 42311911SBrandon.Potter@amd.com value |= issVal; 4249112Smarc.orr@gmail.com } 42511911SBrandon.Potter@amd.com tc->setMiscReg(syndrome_reg, value); 42611911SBrandon.Potter@amd.com} 42711911SBrandon.Potter@amd.com 42811911SBrandon.Potter@amd.comvoid 42911911SBrandon.Potter@amd.comArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 43011911SBrandon.Potter@amd.com{ 4319112Smarc.orr@gmail.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 4329112Smarc.orr@gmail.com 43313642Sqtt2@cornell.edu if (ArmSystem::highestELIs64(tc)) { // ARMv8 43413642Sqtt2@cornell.edu // Determine source exception level and mode 43513642Sqtt2@cornell.edu fromMode = (OperatingMode) (uint8_t) cpsr.mode; 43613642Sqtt2@cornell.edu fromEL = opModeToEL(fromMode); 43713642Sqtt2@cornell.edu if (opModeIs64(fromMode)) 43811911SBrandon.Potter@amd.com from64 = true; 4399112Smarc.orr@gmail.com 44011911SBrandon.Potter@amd.com // Determine target exception level 44111911SBrandon.Potter@amd.com if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) 44213642Sqtt2@cornell.edu toEL = EL3; 44313642Sqtt2@cornell.edu else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) 44413650Smw828@cornell.edu toEL = EL2; 44513650Smw828@cornell.edu else 44613650Smw828@cornell.edu toEL = opModeToEL(nextMode()); 44713650Smw828@cornell.edu if (fromEL > toEL) 44813650Smw828@cornell.edu toEL = fromEL; 44913650Smw828@cornell.edu 45013650Smw828@cornell.edu if (toEL == ArmSystem::highestEL(tc) || ELIs64(tc, toEL)) { 45113650Smw828@cornell.edu // Invoke exception handler in AArch64 state 45213650Smw828@cornell.edu to64 = true; 45313650Smw828@cornell.edu invoke64(tc, inst); 45413650Smw828@cornell.edu return; 45513650Smw828@cornell.edu } 45613650Smw828@cornell.edu } 45713650Smw828@cornell.edu 45813651Smw828@cornell.edu // ARMv7 (ARM ARM issue C B1.9) 45913651Smw828@cornell.edu 46013651Smw828@cornell.edu bool have_security = ArmSystem::haveSecurity(tc); 46113651Smw828@cornell.edu bool have_virtualization = ArmSystem::haveVirtualization(tc); 46213651Smw828@cornell.edu 46313651Smw828@cornell.edu FaultBase::invoke(tc); 46413651Smw828@cornell.edu if (!FullSystem) 46513651Smw828@cornell.edu return; 46613651Smw828@cornell.edu countStat()++; 46713651Smw828@cornell.edu 46813651Smw828@cornell.edu SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); 46913651Smw828@cornell.edu SCR scr = tc->readMiscReg(MISCREG_SCR); 47013651Smw828@cornell.edu CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR); 47113651Smw828@cornell.edu saved_cpsr.nz = tc->readCCReg(CCREG_NZ); 47213651Smw828@cornell.edu saved_cpsr.c = tc->readCCReg(CCREG_C); 47313651Smw828@cornell.edu saved_cpsr.v = tc->readCCReg(CCREG_V); 47413651Smw828@cornell.edu saved_cpsr.ge = tc->readCCReg(CCREG_GE); 47513651Smw828@cornell.edu 47613651Smw828@cornell.edu Addr curPc M5_VAR_USED = tc->pcState().pc(); 47713651Smw828@cornell.edu ITSTATE it = tc->pcState().itstate(); 47813651Smw828@cornell.edu saved_cpsr.it2 = it.top6; 47913651Smw828@cornell.edu saved_cpsr.it1 = it.bottom2; 48013651Smw828@cornell.edu 48113651Smw828@cornell.edu // if we have a valid instruction then use it to annotate this fault with 48213651Smw828@cornell.edu // extra information. This is used to generate the correct fault syndrome 48313651Smw828@cornell.edu // information 48413651Smw828@cornell.edu if (inst) { 48513651Smw828@cornell.edu ArmStaticInst *armInst = reinterpret_cast<ArmStaticInst *>(inst.get()); 48613651Smw828@cornell.edu armInst->annotateFault(this); 48713651Smw828@cornell.edu } 48813651Smw828@cornell.edu 48913651Smw828@cornell.edu if (have_security && routeToMonitor(tc)) 49013651Smw828@cornell.edu cpsr.mode = MODE_MON; 49113651Smw828@cornell.edu else if (have_virtualization && routeToHyp(tc)) 49213651Smw828@cornell.edu cpsr.mode = MODE_HYP; 49313651Smw828@cornell.edu else 49413651Smw828@cornell.edu cpsr.mode = nextMode(); 49513651Smw828@cornell.edu 49613651Smw828@cornell.edu // Ensure Secure state if initially in Monitor mode 49713651Smw828@cornell.edu if (have_security && saved_cpsr.mode == MODE_MON) { 49813651Smw828@cornell.edu SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 49913651Smw828@cornell.edu if (scr.ns) { 50013651Smw828@cornell.edu scr.ns = 0; 50113651Smw828@cornell.edu tc->setMiscRegNoEffect(MISCREG_SCR, scr); 50213651Smw828@cornell.edu } 50313651Smw828@cornell.edu } 50413651Smw828@cornell.edu 50513651Smw828@cornell.edu // some bits are set differently if we have been routed to hyp mode 50613651Smw828@cornell.edu if (cpsr.mode == MODE_HYP) { 50713651Smw828@cornell.edu SCTLR hsctlr = tc->readMiscReg(MISCREG_HSCTLR); 50813651Smw828@cornell.edu cpsr.t = hsctlr.te; 50913651Smw828@cornell.edu cpsr.e = hsctlr.ee; 51013651Smw828@cornell.edu if (!scr.ea) {cpsr.a = 1;} 51113651Smw828@cornell.edu if (!scr.fiq) {cpsr.f = 1;} 51213651Smw828@cornell.edu if (!scr.irq) {cpsr.i = 1;} 51313651Smw828@cornell.edu } else if (cpsr.mode == MODE_MON) { 51413651Smw828@cornell.edu // Special case handling when entering monitor mode 51513651Smw828@cornell.edu cpsr.t = sctlr.te; 51613651Smw828@cornell.edu cpsr.e = sctlr.ee; 51713651Smw828@cornell.edu cpsr.a = 1; 51813651Smw828@cornell.edu cpsr.f = 1; 51913651Smw828@cornell.edu cpsr.i = 1; 52013651Smw828@cornell.edu } else { 52113651Smw828@cornell.edu cpsr.t = sctlr.te; 52213651Smw828@cornell.edu cpsr.e = sctlr.ee; 52313651Smw828@cornell.edu 52413651Smw828@cornell.edu // The *Disable functions are virtual and different per fault 52513651Smw828@cornell.edu cpsr.a = cpsr.a | abortDisable(tc); 52613651Smw828@cornell.edu cpsr.f = cpsr.f | fiqDisable(tc); 52713651Smw828@cornell.edu cpsr.i = 1; 52813651Smw828@cornell.edu } 5299112Smarc.orr@gmail.com cpsr.it1 = cpsr.it2 = 0; 53011911SBrandon.Potter@amd.com cpsr.j = 0; 53111911SBrandon.Potter@amd.com tc->setMiscReg(MISCREG_CPSR, cpsr); 5329112Smarc.orr@gmail.com 5339112Smarc.orr@gmail.com // Make sure mailbox sets to one always 5342238SN/A tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 5352238SN/A 5362238SN/A // Clear the exclusive monitor 5372238SN/A tc->setMiscReg(MISCREG_LOCKFLAG, 0); 53811851Sbrandon.potter@amd.com 5392238SN/A if (cpsr.mode == MODE_HYP) { 5402238SN/A tc->setMiscReg(MISCREG_ELR_HYP, curPc + 5412238SN/A (saved_cpsr.t ? thumbPcOffset(true) : armPcOffset(true))); 54211851Sbrandon.potter@amd.com } else { 5432238SN/A tc->setIntReg(INTREG_LR, curPc + 5442238SN/A (saved_cpsr.t ? thumbPcOffset(false) : armPcOffset(false))); 5452238SN/A } 54611851Sbrandon.potter@amd.com 5472238SN/A switch (cpsr.mode) { 5482238SN/A case MODE_FIQ: 5492238SN/A tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); 55011851Sbrandon.potter@amd.com break; 5512238SN/A case MODE_IRQ: 5522238SN/A tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); 5531354SN/A break; 5541354SN/A case MODE_SVC: 55510796Sbrandon.potter@amd.com tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); 55610796Sbrandon.potter@amd.com break; 5571354SN/A case MODE_MON: 5581354SN/A assert(have_security); 5591354SN/A tc->setMiscReg(MISCREG_SPSR_MON, saved_cpsr); 5601354SN/A break; 5611354SN/A case MODE_ABORT: 5621354SN/A tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); 5631354SN/A break; 5641354SN/A case MODE_UNDEFINED: 5651354SN/A tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); 5661354SN/A if (ec(tc) != EC_UNKNOWN) 56710796Sbrandon.potter@amd.com setSyndrome(tc, MISCREG_HSR); 5681354SN/A break; 56910796Sbrandon.potter@amd.com case MODE_HYP: 5701354SN/A assert(have_virtualization); 5711354SN/A tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr); 5721354SN/A setSyndrome(tc, MISCREG_HSR); 5731354SN/A break; 57410796Sbrandon.potter@amd.com default: 57510796Sbrandon.potter@amd.com panic("unknown Mode\n"); 57610796Sbrandon.potter@amd.com } 57710796Sbrandon.potter@amd.com 57810796Sbrandon.potter@amd.com Addr newPc = getVector(tc); 57910796Sbrandon.potter@amd.com DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n", 58010796Sbrandon.potter@amd.com name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc); 58110796Sbrandon.potter@amd.com PCState pc(newPc); 58210796Sbrandon.potter@amd.com pc.thumb(cpsr.t); 58310796Sbrandon.potter@amd.com pc.nextThumb(pc.thumb()); 58410796Sbrandon.potter@amd.com pc.jazelle(cpsr.j); 585360SN/A pc.nextJazelle(pc.jazelle()); 586360SN/A pc.aarch64(!cpsr.width); 587360SN/A pc.nextAArch64(!cpsr.width); 588360SN/A tc->pcState(pc); 589360SN/A} 590360SN/A 591360SN/Avoid 59211759Sbrandon.potter@amd.comArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst) 5933113Sgblack@eecs.umich.edu{ 5943113Sgblack@eecs.umich.edu // Determine actual misc. register indices for ELR_ELx and SPSR_ELx 5953113Sgblack@eecs.umich.edu MiscRegIndex elr_idx, spsr_idx; 5963113Sgblack@eecs.umich.edu switch (toEL) { 5973113Sgblack@eecs.umich.edu case EL1: 5983113Sgblack@eecs.umich.edu elr_idx = MISCREG_ELR_EL1; 5993113Sgblack@eecs.umich.edu spsr_idx = MISCREG_SPSR_EL1; 6003113Sgblack@eecs.umich.edu break; 6013113Sgblack@eecs.umich.edu case EL2: 6023113Sgblack@eecs.umich.edu assert(ArmSystem::haveVirtualization(tc)); 6033113Sgblack@eecs.umich.edu elr_idx = MISCREG_ELR_EL2; 6043113Sgblack@eecs.umich.edu spsr_idx = MISCREG_SPSR_EL2; 6053113Sgblack@eecs.umich.edu break; 60612032Sandreas.sandberg@arm.com case EL3: 6073113Sgblack@eecs.umich.edu assert(ArmSystem::haveSecurity(tc)); 6083113Sgblack@eecs.umich.edu elr_idx = MISCREG_ELR_EL3; 6094189Sgblack@eecs.umich.edu spsr_idx = MISCREG_SPSR_EL3; 6104189Sgblack@eecs.umich.edu break; 6113113Sgblack@eecs.umich.edu default: 6123113Sgblack@eecs.umich.edu panic("Invalid target exception level"); 6133113Sgblack@eecs.umich.edu break; 6143113Sgblack@eecs.umich.edu } 6158737Skoansin.tan@gmail.com 6163113Sgblack@eecs.umich.edu // Save process state into SPSR_ELx 6178737Skoansin.tan@gmail.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 6183277Sgblack@eecs.umich.edu CPSR spsr = cpsr; 6195515SMichael.Adler@intel.com spsr.nz = tc->readCCReg(CCREG_NZ); 6205515SMichael.Adler@intel.com spsr.c = tc->readCCReg(CCREG_C); 6215515SMichael.Adler@intel.com spsr.v = tc->readCCReg(CCREG_V); 6225515SMichael.Adler@intel.com if (from64) { 6235515SMichael.Adler@intel.com // Force some bitfields to 0 6248737Skoansin.tan@gmail.com spsr.q = 0; 6253277Sgblack@eecs.umich.edu spsr.it1 = 0; 6268737Skoansin.tan@gmail.com spsr.j = 0; 6273277Sgblack@eecs.umich.edu spsr.res0_23_22 = 0; 6288737Skoansin.tan@gmail.com spsr.ge = 0; 6293277Sgblack@eecs.umich.edu spsr.it2 = 0; 6308737Skoansin.tan@gmail.com spsr.t = 0; 6313113Sgblack@eecs.umich.edu } else { 6323113Sgblack@eecs.umich.edu spsr.ge = tc->readCCReg(CCREG_GE); 6333113Sgblack@eecs.umich.edu ITSTATE it = tc->pcState().itstate(); 6343113Sgblack@eecs.umich.edu spsr.it2 = it.top6; 6358737Skoansin.tan@gmail.com spsr.it1 = it.bottom2; 6363113Sgblack@eecs.umich.edu // Force some bitfields to 0 6378737Skoansin.tan@gmail.com spsr.res0_23_22 = 0; 6383114Sgblack@eecs.umich.edu spsr.ss = 0; 6398737Skoansin.tan@gmail.com } 6403114Sgblack@eecs.umich.edu tc->setMiscReg(spsr_idx, spsr); 6418737Skoansin.tan@gmail.com 6423114Sgblack@eecs.umich.edu // Save preferred return address into ELR_ELx 6438737Skoansin.tan@gmail.com Addr curr_pc = tc->pcState().pc(); 64411906SBrandon.Potter@amd.com Addr ret_addr = curr_pc; 6454061Sgblack@eecs.umich.edu if (from64) 6464061Sgblack@eecs.umich.edu ret_addr += armPcElrOffset(); 6478737Skoansin.tan@gmail.com else 6483113Sgblack@eecs.umich.edu ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset(); 6498737Skoansin.tan@gmail.com tc->setMiscReg(elr_idx, ret_addr); 6503113Sgblack@eecs.umich.edu 6513113Sgblack@eecs.umich.edu // Update process state 6523113Sgblack@eecs.umich.edu OperatingMode64 mode = 0; 6533113Sgblack@eecs.umich.edu mode.spX = 1; 6543113Sgblack@eecs.umich.edu mode.el = toEL; 65512032Sandreas.sandberg@arm.com mode.width = 0; 6563113Sgblack@eecs.umich.edu cpsr.mode = mode; 6573113Sgblack@eecs.umich.edu cpsr.daif = 0xf; 6584189Sgblack@eecs.umich.edu cpsr.il = 0; 6594189Sgblack@eecs.umich.edu cpsr.ss = 0; 6603113Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CPSR, cpsr); 6613113Sgblack@eecs.umich.edu 6623113Sgblack@eecs.umich.edu // Set PC to start of exception handler 6638737Skoansin.tan@gmail.com Addr new_pc = purifyTaggedAddr(getVector64(tc), tc, toEL); 6643113Sgblack@eecs.umich.edu DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x " 6658737Skoansin.tan@gmail.com "elr:%#x newVec: %#x\n", name(), cpsr, curr_pc, ret_addr, new_pc); 6663113Sgblack@eecs.umich.edu PCState pc(new_pc); 6678737Skoansin.tan@gmail.com pc.aarch64(!cpsr.width); 6683113Sgblack@eecs.umich.edu pc.nextAArch64(!cpsr.width); 6693113Sgblack@eecs.umich.edu tc->pcState(pc); 6703113Sgblack@eecs.umich.edu 6713113Sgblack@eecs.umich.edu // If we have a valid instruction then use it to annotate this fault with 6723113Sgblack@eecs.umich.edu // extra information. This is used to generate the correct fault syndrome 6733113Sgblack@eecs.umich.edu // information 6743113Sgblack@eecs.umich.edu if (inst) 67511906SBrandon.Potter@amd.com reinterpret_cast<ArmStaticInst *>(inst.get())->annotateFault(this); 6763113Sgblack@eecs.umich.edu // Save exception syndrome 67712032Sandreas.sandberg@arm.com if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ)) 6788852Sandreas.hansson@arm.com setSyndrome(tc, getSyndromeReg64()); 67911906SBrandon.Potter@amd.com} 6803113Sgblack@eecs.umich.edu 6813113Sgblack@eecs.umich.eduvoid 6823113Sgblack@eecs.umich.eduReset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 6833113Sgblack@eecs.umich.edu{ 6843113Sgblack@eecs.umich.edu if (FullSystem) { 6853113Sgblack@eecs.umich.edu tc->getCpuPtr()->clearInterrupts(tc->threadId()); 6863113Sgblack@eecs.umich.edu tc->clearArchRegs(); 6873113Sgblack@eecs.umich.edu } 68812032Sandreas.sandberg@arm.com if (!ArmSystem::highestELIs64(tc)) { 6898852Sandreas.hansson@arm.com ArmFault::invoke(tc, inst); 69011906SBrandon.Potter@amd.com tc->setMiscReg(MISCREG_VMPIDR, 6913113Sgblack@eecs.umich.edu getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc)); 6923113Sgblack@eecs.umich.edu 6933113Sgblack@eecs.umich.edu // Unless we have SMC code to get us there, boot in HYP! 6946686Stjones1@inf.ed.ac.uk if (ArmSystem::haveVirtualization(tc) && 6953113Sgblack@eecs.umich.edu !ArmSystem::haveSecurity(tc)) { 6963113Sgblack@eecs.umich.edu CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 6973113Sgblack@eecs.umich.edu cpsr.mode = MODE_HYP; 69811759Sbrandon.potter@amd.com tc->setMiscReg(MISCREG_CPSR, cpsr); 69912032Sandreas.sandberg@arm.com } 70011759Sbrandon.potter@amd.com } else { 70111759Sbrandon.potter@amd.com // Advance the PC to the IMPLEMENTATION DEFINED reset value 70211759Sbrandon.potter@amd.com PCState pc = ArmSystem::resetAddr64(tc); 70311759Sbrandon.potter@amd.com pc.aarch64(true); 70411759Sbrandon.potter@amd.com pc.nextAArch64(true); 70511812Sbaz21@cam.ac.uk tc->pcState(pc); 70611812Sbaz21@cam.ac.uk } 70711812Sbaz21@cam.ac.uk} 70811759Sbrandon.potter@amd.com 70911812Sbaz21@cam.ac.ukvoid 71011759Sbrandon.potter@amd.comUndefinedInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst) 71111759Sbrandon.potter@amd.com{ 71211759Sbrandon.potter@amd.com if (FullSystem) { 71311759Sbrandon.potter@amd.com ArmFault::invoke(tc, inst); 71411759Sbrandon.potter@amd.com return; 71511759Sbrandon.potter@amd.com } 71611759Sbrandon.potter@amd.com 71711812Sbaz21@cam.ac.uk // If the mnemonic isn't defined this has to be an unknown instruction. 71811812Sbaz21@cam.ac.uk assert(unknown || mnemonic != NULL); 71911812Sbaz21@cam.ac.uk if (disabled) { 72011812Sbaz21@cam.ac.uk panic("Attempted to execute disabled instruction " 72111812Sbaz21@cam.ac.uk "'%s' (inst 0x%08x)", mnemonic, machInst); 72211812Sbaz21@cam.ac.uk } else if (unknown) { 72311812Sbaz21@cam.ac.uk panic("Attempted to execute unknown instruction (inst 0x%08x)", 72411759Sbrandon.potter@amd.com machInst); 72511759Sbrandon.potter@amd.com } else { 72611812Sbaz21@cam.ac.uk panic("Attempted to execute unimplemented instruction " 72711812Sbaz21@cam.ac.uk "'%s' (inst 0x%08x)", mnemonic, machInst); 72811759Sbrandon.potter@amd.com } 72911812Sbaz21@cam.ac.uk} 73011812Sbaz21@cam.ac.uk 73111812Sbaz21@cam.ac.ukbool 73211812Sbaz21@cam.ac.ukUndefinedInstruction::routeToHyp(ThreadContext *tc) const 73311812Sbaz21@cam.ac.uk{ 73411812Sbaz21@cam.ac.uk bool toHyp; 73511812Sbaz21@cam.ac.uk 73611759Sbrandon.potter@amd.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 73711759Sbrandon.potter@amd.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 73811759Sbrandon.potter@amd.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 73911759Sbrandon.potter@amd.com 740378SN/A // if in Hyp mode then stay in Hyp mode 741378SN/A toHyp = scr.ns && (cpsr.mode == MODE_HYP); 7429141Smarc.orr@gmail.com // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 7439141Smarc.orr@gmail.com toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 744360SN/A return toHyp; 7451450SN/A} 74611856Sbrandon.potter@amd.com 747360SN/Auint32_t 7486701Sgblack@eecs.umich.eduUndefinedInstruction::iss() const 74911856Sbrandon.potter@amd.com{ 75011856Sbrandon.potter@amd.com if (overrideEc == EC_INVALID) 751360SN/A return issRaw; 75210930Sbrandon.potter@amd.com 753360SN/A uint32_t new_iss = 0; 75411856Sbrandon.potter@amd.com uint32_t op0, op1, op2, CRn, CRm, Rt, dir; 75511856Sbrandon.potter@amd.com 75610496Ssteve.reinhardt@amd.com dir = bits(machInst, 21, 21); 75711856Sbrandon.potter@amd.com op0 = bits(machInst, 20, 19); 75811856Sbrandon.potter@amd.com op1 = bits(machInst, 18, 16); 7591458SN/A CRn = bits(machInst, 15, 12); 760360SN/A CRm = bits(machInst, 11, 8); 76111856Sbrandon.potter@amd.com op2 = bits(machInst, 7, 5); 76211856Sbrandon.potter@amd.com Rt = bits(machInst, 4, 0); 76311856Sbrandon.potter@amd.com 76411856Sbrandon.potter@amd.com new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 | 76511856Sbrandon.potter@amd.com Rt << 5 | CRm << 1 | dir; 76611856Sbrandon.potter@amd.com 76711856Sbrandon.potter@amd.com return new_iss; 76811856Sbrandon.potter@amd.com} 76910496Ssteve.reinhardt@amd.com 77011856Sbrandon.potter@amd.comvoid 77111856Sbrandon.potter@amd.comSupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 77211856Sbrandon.potter@amd.com{ 77311856Sbrandon.potter@amd.com if (FullSystem) { 77411856Sbrandon.potter@amd.com ArmFault::invoke(tc, inst); 77510930Sbrandon.potter@amd.com return; 7769141Smarc.orr@gmail.com } 777360SN/A 778360SN/A // As of now, there isn't a 32 bit thumb version of this instruction. 779360SN/A assert(!machInst.bigThumb); 78011907SBrandon.Potter@amd.com uint32_t callNum; 78111907SBrandon.Potter@amd.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 78211907SBrandon.Potter@amd.com OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode; 783360SN/A if (opModeIs64(mode)) 78411907SBrandon.Potter@amd.com callNum = tc->readIntReg(INTREG_X8); 78511907SBrandon.Potter@amd.com else 78611907SBrandon.Potter@amd.com callNum = tc->readIntReg(INTREG_R7); 78711907SBrandon.Potter@amd.com tc->syscall(callNum); 78811907SBrandon.Potter@amd.com 78911907SBrandon.Potter@amd.com // Advance the PC since that won't happen automatically. 79011907SBrandon.Potter@amd.com PCState pc = tc->pcState(); 79111907SBrandon.Potter@amd.com assert(inst); 79211907SBrandon.Potter@amd.com inst->advancePC(pc); 79311907SBrandon.Potter@amd.com tc->pcState(pc); 79411907SBrandon.Potter@amd.com} 79511907SBrandon.Potter@amd.com 79611907SBrandon.Potter@amd.combool 79711907SBrandon.Potter@amd.comSupervisorCall::routeToHyp(ThreadContext *tc) const 798360SN/A{ 79911907SBrandon.Potter@amd.com bool toHyp; 8001458SN/A 801360SN/A SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 80211907SBrandon.Potter@amd.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 80311907SBrandon.Potter@amd.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 80411907SBrandon.Potter@amd.com 80511907SBrandon.Potter@amd.com // if in Hyp mode then stay in Hyp mode 80611907SBrandon.Potter@amd.com toHyp = scr.ns && (cpsr.mode == MODE_HYP); 80711907SBrandon.Potter@amd.com // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector 80811907SBrandon.Potter@amd.com toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER); 80911907SBrandon.Potter@amd.com return toHyp; 81011907SBrandon.Potter@amd.com} 81111907SBrandon.Potter@amd.com 812360SN/AExceptionClass 81311907SBrandon.Potter@amd.comSupervisorCall::ec(ThreadContext *tc) const 81411907SBrandon.Potter@amd.com{ 81511907SBrandon.Potter@amd.com return (overrideEc != EC_INVALID) ? overrideEc : 816360SN/A (from64 ? EC_SVC_64 : vals.ec); 817360SN/A} 81811907SBrandon.Potter@amd.com 81911907SBrandon.Potter@amd.comuint32_t 82011907SBrandon.Potter@amd.comSupervisorCall::iss() const 82111907SBrandon.Potter@amd.com{ 822360SN/A // Even if we have a 24 bit imm from an arm32 instruction then we only use 82311907SBrandon.Potter@amd.com // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC). 824360SN/A return issRaw & 0xFFFF; 825360SN/A} 82611907SBrandon.Potter@amd.com 8273669Sbinkertn@umich.eduuint32_t 82811907SBrandon.Potter@amd.comSecureMonitorCall::iss() const 82911907SBrandon.Potter@amd.com{ 83011907SBrandon.Potter@amd.com if (from64) 83111907SBrandon.Potter@amd.com return bits(machInst, 20, 5); 83211907SBrandon.Potter@amd.com return 0; 83311907SBrandon.Potter@amd.com} 83411907SBrandon.Potter@amd.com 83511907SBrandon.Potter@amd.comExceptionClass 83611907SBrandon.Potter@amd.comUndefinedInstruction::ec(ThreadContext *tc) const 83711907SBrandon.Potter@amd.com{ 83811907SBrandon.Potter@amd.com return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 83911907SBrandon.Potter@amd.com} 84011907SBrandon.Potter@amd.com 84111907SBrandon.Potter@amd.com 84211907SBrandon.Potter@amd.comHypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) : 84311907SBrandon.Potter@amd.com ArmFaultVals<HypervisorCall>(_machInst, _imm) 84411907SBrandon.Potter@amd.com{} 84511907SBrandon.Potter@amd.com 84611907SBrandon.Potter@amd.comExceptionClass 84713371Sciro.santilli@arm.comHypervisorCall::ec(ThreadContext *tc) const 84811907SBrandon.Potter@amd.com{ 8491706SN/A return from64 ? EC_HVC_64 : vals.ec; 85011907SBrandon.Potter@amd.com} 85111907SBrandon.Potter@amd.com 85211907SBrandon.Potter@amd.comExceptionClass 85311907SBrandon.Potter@amd.comHypervisorTrap::ec(ThreadContext *tc) const 85411907SBrandon.Potter@amd.com{ 85511907SBrandon.Potter@amd.com return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 85610496Ssteve.reinhardt@amd.com} 85710496Ssteve.reinhardt@amd.com 85811907SBrandon.Potter@amd.comtemplate<class T> 85911907SBrandon.Potter@amd.comFaultOffset 86011907SBrandon.Potter@amd.comArmFaultVals<T>::offset(ThreadContext *tc) 86111907SBrandon.Potter@amd.com{ 86211907SBrandon.Potter@amd.com bool isHypTrap = false; 86311907SBrandon.Potter@amd.com 86410496Ssteve.reinhardt@amd.com // Normally we just use the exception vector from the table at the top if 86511907SBrandon.Potter@amd.com // this file, however if this exception has caused a transition to hype 86611907SBrandon.Potter@amd.com // mode, and its an exception type that would only do this if it has been 86711907SBrandon.Potter@amd.com // trapped then we use the hyp trap vector instead of the normal vector 86811907SBrandon.Potter@amd.com if (vals.hypTrappable) { 86910496Ssteve.reinhardt@amd.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 87010496Ssteve.reinhardt@amd.com if (cpsr.mode == MODE_HYP) { 87111907SBrandon.Potter@amd.com CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 87211907SBrandon.Potter@amd.com isHypTrap = spsr.mode != MODE_HYP; 87311907SBrandon.Potter@amd.com } 87411907SBrandon.Potter@amd.com } 87511907SBrandon.Potter@amd.com return isHypTrap ? 0x14 : vals.offset; 87611907SBrandon.Potter@amd.com} 87711907SBrandon.Potter@amd.com 87811907SBrandon.Potter@amd.com// void 87911907SBrandon.Potter@amd.com// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx) 88011907SBrandon.Potter@amd.com// { 88111907SBrandon.Potter@amd.com// ESR esr = 0; 88211907SBrandon.Potter@amd.com// esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32; 88311907SBrandon.Potter@amd.com// esr.il = !machInst.thumb; 88411907SBrandon.Potter@amd.com// if (machInst.aarch64) 88511907SBrandon.Potter@amd.com// esr.imm16 = bits(machInst.instBits, 20, 5); 88611907SBrandon.Potter@amd.com// else if (machInst.thumb) 88711907SBrandon.Potter@amd.com// esr.imm16 = bits(machInst.instBits, 7, 0); 88811907SBrandon.Potter@amd.com// else 88911907SBrandon.Potter@amd.com// esr.imm16 = bits(machInst.instBits, 15, 0); 89011907SBrandon.Potter@amd.com// tc->setMiscReg(esr_idx, esr); 89111907SBrandon.Potter@amd.com// } 89211907SBrandon.Potter@amd.com 89311907SBrandon.Potter@amd.comvoid 89411907SBrandon.Potter@amd.comSecureMonitorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) 89511907SBrandon.Potter@amd.com{ 896360SN/A if (FullSystem) { 89711907SBrandon.Potter@amd.com ArmFault::invoke(tc, inst); 89811907SBrandon.Potter@amd.com return; 89911907SBrandon.Potter@amd.com } 90011907SBrandon.Potter@amd.com} 90111907SBrandon.Potter@amd.com 90211907SBrandon.Potter@amd.comExceptionClass 90311907SBrandon.Potter@amd.comSecureMonitorCall::ec(ThreadContext *tc) const 90411907SBrandon.Potter@amd.com{ 90511907SBrandon.Potter@amd.com return (from64 ? EC_SMC_64 : vals.ec); 90611907SBrandon.Potter@amd.com} 90711907SBrandon.Potter@amd.com 90811907SBrandon.Potter@amd.comExceptionClass 90911907SBrandon.Potter@amd.comSupervisorTrap::ec(ThreadContext *tc) const 910360SN/A{ 911360SN/A return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; 91210027SChris.Adeniyi-Jones@arm.com} 91310027SChris.Adeniyi-Jones@arm.com 91410027SChris.Adeniyi-Jones@arm.comExceptionClass 91511851Sbrandon.potter@amd.comSecureMonitorTrap::ec(ThreadContext *tc) const 91610027SChris.Adeniyi-Jones@arm.com{ 91710027SChris.Adeniyi-Jones@arm.com return (overrideEc != EC_INVALID) ? overrideEc : 91811907SBrandon.Potter@amd.com (from64 ? EC_SMC_64 : vals.ec); 91910027SChris.Adeniyi-Jones@arm.com} 92010027SChris.Adeniyi-Jones@arm.com 92110027SChris.Adeniyi-Jones@arm.comtemplate<class T> 92210027SChris.Adeniyi-Jones@arm.comvoid 92310027SChris.Adeniyi-Jones@arm.comAbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst) 92411851Sbrandon.potter@amd.com{ 92511851Sbrandon.potter@amd.com if (tranMethod == ArmFault::UnknownTran) { 92610027SChris.Adeniyi-Jones@arm.com tranMethod = longDescFormatInUse(tc) ? ArmFault::LpaeTran 92711907SBrandon.Potter@amd.com : ArmFault::VmsaTran; 92810027SChris.Adeniyi-Jones@arm.com 92910027SChris.Adeniyi-Jones@arm.com if ((tranMethod == ArmFault::VmsaTran) && this->routeToMonitor(tc)) { 93010633Smichaelupton@gmail.com // See ARM ARM B3-1416 93110633Smichaelupton@gmail.com bool override_LPAE = false; 93210633Smichaelupton@gmail.com TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S); 93311851Sbrandon.potter@amd.com TTBCR M5_VAR_USED ttbcr_ns = tc->readMiscReg(MISCREG_TTBCR_NS); 93410633Smichaelupton@gmail.com if (ttbcr_s.eae) { 93510633Smichaelupton@gmail.com override_LPAE = true; 93610633Smichaelupton@gmail.com } else { 93710633Smichaelupton@gmail.com // Unimplemented code option, not seen in testing. May need 93810633Smichaelupton@gmail.com // extension according to the manual exceprt above. 93910633Smichaelupton@gmail.com DPRINTF(Faults, "Warning: Incomplete translation method " 94010633Smichaelupton@gmail.com "override detected.\n"); 94110633Smichaelupton@gmail.com } 94210633Smichaelupton@gmail.com if (override_LPAE) 94310633Smichaelupton@gmail.com tranMethod = ArmFault::LpaeTran; 94410203SAli.Saidi@ARM.com } 94510203SAli.Saidi@ARM.com } 94610203SAli.Saidi@ARM.com 94711851Sbrandon.potter@amd.com if (source == ArmFault::AsynchronousExternalAbort) { 94811851Sbrandon.potter@amd.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 94910203SAli.Saidi@ARM.com } 95010203SAli.Saidi@ARM.com // Get effective fault source encoding 95110203SAli.Saidi@ARM.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 95210203SAli.Saidi@ARM.com FSR fsr = getFsr(tc); 95310203SAli.Saidi@ARM.com 95410203SAli.Saidi@ARM.com // source must be determined BEFORE invoking generic routines which will 95510203SAli.Saidi@ARM.com // try to set hsr etc. and are based upon source! 95610203SAli.Saidi@ARM.com ArmFaultVals<T>::invoke(tc, inst); 95710203SAli.Saidi@ARM.com 95810203SAli.Saidi@ARM.com if (!this->to64) { // AArch32 95910203SAli.Saidi@ARM.com if (cpsr.mode == MODE_HYP) { 96011851Sbrandon.potter@amd.com tc->setMiscReg(T::HFarIndex, faultAddr); 96111851Sbrandon.potter@amd.com } else if (stage2) { 96210203SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf); 96310203SAli.Saidi@ARM.com tc->setMiscReg(T::HFarIndex, OVAddr); 96410203SAli.Saidi@ARM.com } else { 96510203SAli.Saidi@ARM.com tc->setMiscReg(T::FsrIndex, fsr); 96610203SAli.Saidi@ARM.com tc->setMiscReg(T::FarIndex, faultAddr); 96710203SAli.Saidi@ARM.com } 96810203SAli.Saidi@ARM.com DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x "\ 96910203SAli.Saidi@ARM.com "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod); 97010850SGiacomo.Gabrielli@arm.com } else { // AArch64 97110850SGiacomo.Gabrielli@arm.com // Set the FAR register. Nothing else to do if we are in AArch64 state 97210850SGiacomo.Gabrielli@arm.com // because the syndrome register has already been set inside invoke64() 97311851Sbrandon.potter@amd.com if (stage2) { 97410850SGiacomo.Gabrielli@arm.com // stage 2 fault, set HPFAR_EL2 to the faulting IPA 97510850SGiacomo.Gabrielli@arm.com // and FAR_EL2 to the Original VA 97610850SGiacomo.Gabrielli@arm.com tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), OVAddr); 97710850SGiacomo.Gabrielli@arm.com tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4); 97810850SGiacomo.Gabrielli@arm.com 97910850SGiacomo.Gabrielli@arm.com DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n", 98010850SGiacomo.Gabrielli@arm.com OVAddr, faultAddr); 98110850SGiacomo.Gabrielli@arm.com } else { 98210850SGiacomo.Gabrielli@arm.com tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr); 98310850SGiacomo.Gabrielli@arm.com } 98410850SGiacomo.Gabrielli@arm.com } 98510850SGiacomo.Gabrielli@arm.com} 98610850SGiacomo.Gabrielli@arm.com 98710850SGiacomo.Gabrielli@arm.comtemplate<class T> 98810850SGiacomo.Gabrielli@arm.comFSR 98910850SGiacomo.Gabrielli@arm.comAbortFault<T>::getFsr(ThreadContext *tc) 99010850SGiacomo.Gabrielli@arm.com{ 99110850SGiacomo.Gabrielli@arm.com FSR fsr = 0; 99210850SGiacomo.Gabrielli@arm.com 99310850SGiacomo.Gabrielli@arm.com if (((CPSR) tc->readMiscRegNoEffect(MISCREG_CPSR)).width) { 99410850SGiacomo.Gabrielli@arm.com // AArch32 99510850SGiacomo.Gabrielli@arm.com assert(tranMethod != ArmFault::UnknownTran); 99610850SGiacomo.Gabrielli@arm.com if (tranMethod == ArmFault::LpaeTran) { 99710850SGiacomo.Gabrielli@arm.com srcEncoded = ArmFault::longDescFaultSources[source]; 99810850SGiacomo.Gabrielli@arm.com fsr.status = srcEncoded; 99910850SGiacomo.Gabrielli@arm.com fsr.lpae = 1; 100010850SGiacomo.Gabrielli@arm.com } else { 100110850SGiacomo.Gabrielli@arm.com srcEncoded = ArmFault::shortDescFaultSources[source]; 100210850SGiacomo.Gabrielli@arm.com fsr.fsLow = bits(srcEncoded, 3, 0); 100310850SGiacomo.Gabrielli@arm.com fsr.fsHigh = bits(srcEncoded, 4); 100410850SGiacomo.Gabrielli@arm.com fsr.domain = static_cast<uint8_t>(domain); 100510850SGiacomo.Gabrielli@arm.com } 10066640Svince@csl.cornell.edu fsr.wnr = (write ? 1 : 0); 10076640Svince@csl.cornell.edu fsr.ext = 0; 10086640Svince@csl.cornell.edu } else { 100911851Sbrandon.potter@amd.com // AArch64 101011851Sbrandon.potter@amd.com srcEncoded = ArmFault::aarch64FaultSources[source]; 10116640Svince@csl.cornell.edu } 10126640Svince@csl.cornell.edu if (srcEncoded == ArmFault::FaultSourceInvalid) { 10136701Sgblack@eecs.umich.edu panic("Invalid fault source\n"); 10146701Sgblack@eecs.umich.edu } 101510793Sbrandon.potter@amd.com return fsr; 10166640Svince@csl.cornell.edu} 101711758Sbrandon.potter@amd.com 101811758Sbrandon.potter@amd.comtemplate<class T> 101911758Sbrandon.potter@amd.combool 10206640Svince@csl.cornell.eduAbortFault<T>::abortDisable(ThreadContext *tc) 10218706Sandreas.hansson@arm.com{ 10226640Svince@csl.cornell.edu if (ArmSystem::haveSecurity(tc)) { 10236701Sgblack@eecs.umich.edu SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 10246640Svince@csl.cornell.edu return (!scr.ns || scr.aw); 1025360SN/A } 10261999SN/A return true; 10271999SN/A} 10281999SN/A 102911851Sbrandon.potter@amd.comtemplate<class T> 10302680Sktlim@umich.eduvoid 10311999SN/AAbortFault<T>::annotate(ArmFault::AnnotationIDs id, uint64_t val) 10321999SN/A{ 10331999SN/A switch (id) 10346701Sgblack@eecs.umich.edu { 10358852Sandreas.hansson@arm.com case ArmFault::S1PTW: 10366701Sgblack@eecs.umich.edu s1ptw = val; 10371999SN/A break; 10386701Sgblack@eecs.umich.edu case ArmFault::OVA: 10391999SN/A OVAddr = val; 10406701Sgblack@eecs.umich.edu break; 10411999SN/A 10421999SN/A // Just ignore unknown ID's 10431999SN/A default: 10441999SN/A break; 10451999SN/A } 10463669Sbinkertn@umich.edu} 10473669Sbinkertn@umich.edu 10483669Sbinkertn@umich.edutemplate<class T> 10491999SN/Auint32_t 10501999SN/AAbortFault<T>::iss() const 10511999SN/A{ 10522218SN/A uint32_t val; 10531999SN/A 10541999SN/A val = srcEncoded & 0x3F; 10551999SN/A val |= write << 6; 10561999SN/A val |= s1ptw << 7; 105713570Sbrandon.potter@amd.com return (val); 105813570Sbrandon.potter@amd.com} 105913570Sbrandon.potter@amd.com 106013570Sbrandon.potter@amd.comtemplate<class T> 106113570Sbrandon.potter@amd.combool 106213570Sbrandon.potter@amd.comAbortFault<T>::isMMUFault() const 106313570Sbrandon.potter@amd.com{ 106413570Sbrandon.potter@amd.com // NOTE: Not relying on LL information being aligned to lowest bits here 106513570Sbrandon.potter@amd.com return 106613570Sbrandon.potter@amd.com (source == ArmFault::AlignmentFault) || 106713570Sbrandon.potter@amd.com ((source >= ArmFault::TranslationLL) && 106813570Sbrandon.potter@amd.com (source < ArmFault::TranslationLL + 4)) || 106913570Sbrandon.potter@amd.com ((source >= ArmFault::AccessFlagLL) && 107013570Sbrandon.potter@amd.com (source < ArmFault::AccessFlagLL + 4)) || 107113570Sbrandon.potter@amd.com ((source >= ArmFault::DomainLL) && 107213570Sbrandon.potter@amd.com (source < ArmFault::DomainLL + 4)) || 107313570Sbrandon.potter@amd.com ((source >= ArmFault::PermissionLL) && 107413570Sbrandon.potter@amd.com (source < ArmFault::PermissionLL + 4)); 107513570Sbrandon.potter@amd.com} 107613570Sbrandon.potter@amd.com 107713570Sbrandon.potter@amd.comExceptionClass 107813570Sbrandon.potter@amd.comPrefetchAbort::ec(ThreadContext *tc) const 107913570Sbrandon.potter@amd.com{ 108013570Sbrandon.potter@amd.com if (to64) { 108113570Sbrandon.potter@amd.com // AArch64 108213570Sbrandon.potter@amd.com if (toEL == fromEL) 108313570Sbrandon.potter@amd.com return EC_PREFETCH_ABORT_CURR_EL; 108413570Sbrandon.potter@amd.com else 108513570Sbrandon.potter@amd.com return EC_PREFETCH_ABORT_LOWER_EL; 108613570Sbrandon.potter@amd.com } else { 108713570Sbrandon.potter@amd.com // AArch32 108813570Sbrandon.potter@amd.com // Abort faults have different EC codes depending on whether 108913570Sbrandon.potter@amd.com // the fault originated within HYP mode, or not. So override 109013570Sbrandon.potter@amd.com // the method and add the extra adjustment of the EC value. 109113570Sbrandon.potter@amd.com 109213570Sbrandon.potter@amd.com ExceptionClass ec = ArmFaultVals<PrefetchAbort>::vals.ec; 109313570Sbrandon.potter@amd.com 109413570Sbrandon.potter@amd.com CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 109513570Sbrandon.potter@amd.com if (spsr.mode == MODE_HYP) { 109613570Sbrandon.potter@amd.com ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 109713570Sbrandon.potter@amd.com } 109813570Sbrandon.potter@amd.com return ec; 109913570Sbrandon.potter@amd.com } 110013570Sbrandon.potter@amd.com} 110113570Sbrandon.potter@amd.com 110213570Sbrandon.potter@amd.combool 110313570Sbrandon.potter@amd.comPrefetchAbort::routeToMonitor(ThreadContext *tc) const 110413570Sbrandon.potter@amd.com{ 110513570Sbrandon.potter@amd.com SCR scr = 0; 110613570Sbrandon.potter@amd.com if (from64) 110713570Sbrandon.potter@amd.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 110813570Sbrandon.potter@amd.com else 110913570Sbrandon.potter@amd.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 111013570Sbrandon.potter@amd.com 111113570Sbrandon.potter@amd.com return scr.ea && !isMMUFault(); 111213570Sbrandon.potter@amd.com} 111313570Sbrandon.potter@amd.com 111413570Sbrandon.potter@amd.combool 111513570Sbrandon.potter@amd.comPrefetchAbort::routeToHyp(ThreadContext *tc) const 111613570Sbrandon.potter@amd.com{ 111713570Sbrandon.potter@amd.com bool toHyp; 111813570Sbrandon.potter@amd.com 111913570Sbrandon.potter@amd.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 112013570Sbrandon.potter@amd.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 112113570Sbrandon.potter@amd.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 112213570Sbrandon.potter@amd.com HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 112313570Sbrandon.potter@amd.com 112413570Sbrandon.potter@amd.com // if in Hyp mode then stay in Hyp mode 112513570Sbrandon.potter@amd.com toHyp = scr.ns && (cpsr.mode == MODE_HYP); 112613570Sbrandon.potter@amd.com // otherwise, check whether to take to Hyp mode through Hyp Trap vector 112713570Sbrandon.potter@amd.com toHyp |= (stage2 || 112813570Sbrandon.potter@amd.com ( (source == DebugEvent) && hdcr.tde && (cpsr.mode != MODE_HYP)) || 112913570Sbrandon.potter@amd.com ( (source == SynchronousExternalAbort) && hcr.tge && (cpsr.mode == MODE_USER)) 113013570Sbrandon.potter@amd.com ) && !inSecureState(tc); 11311999SN/A return toHyp; 11321999SN/A} 11331999SN/A 11341999SN/AExceptionClass 113511856Sbrandon.potter@amd.comDataAbort::ec(ThreadContext *tc) const 11361999SN/A{ 11376701Sgblack@eecs.umich.edu if (to64) { 113811856Sbrandon.potter@amd.com // AArch64 113911856Sbrandon.potter@amd.com if (source == ArmFault::AsynchronousExternalAbort) { 114010931Sbrandon.potter@amd.com panic("Asynchronous External Abort should be handled with " 114111856Sbrandon.potter@amd.com "SystemErrors (SErrors)!"); 114211856Sbrandon.potter@amd.com } 11431999SN/A if (toEL == fromEL) 114411856Sbrandon.potter@amd.com return EC_DATA_ABORT_CURR_EL; 11451999SN/A else 114611856Sbrandon.potter@amd.com return EC_DATA_ABORT_LOWER_EL; 11471999SN/A } else { 114811856Sbrandon.potter@amd.com // AArch32 11491999SN/A // Abort faults have different EC codes depending on whether 115011856Sbrandon.potter@amd.com // the fault originated within HYP mode, or not. So override 11511999SN/A // the method and add the extra adjustment of the EC value. 11521999SN/A 11535877Shsul@eecs.umich.edu ExceptionClass ec = ArmFaultVals<DataAbort>::vals.ec; 11545877Shsul@eecs.umich.edu 11555877Shsul@eecs.umich.edu CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP); 115611851Sbrandon.potter@amd.com if (spsr.mode == MODE_HYP) { 11575877Shsul@eecs.umich.edu ec = ((ExceptionClass) (((uint32_t) ec) + 1)); 11586701Sgblack@eecs.umich.edu } 11596701Sgblack@eecs.umich.edu return ec; 11606701Sgblack@eecs.umich.edu } 11616701Sgblack@eecs.umich.edu} 11626701Sgblack@eecs.umich.edu 116310027SChris.Adeniyi-Jones@arm.combool 116410027SChris.Adeniyi-Jones@arm.comDataAbort::routeToMonitor(ThreadContext *tc) const 116510027SChris.Adeniyi-Jones@arm.com{ 116610027SChris.Adeniyi-Jones@arm.com SCR scr = 0; 116710027SChris.Adeniyi-Jones@arm.com if (from64) 11685877Shsul@eecs.umich.edu scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 116910318Sandreas.hansson@arm.com else 117010318Sandreas.hansson@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 11715877Shsul@eecs.umich.edu 11725877Shsul@eecs.umich.edu return scr.ea && !isMMUFault(); 11735877Shsul@eecs.umich.edu} 11745877Shsul@eecs.umich.edu 117510486Stjablin@gmail.combool 117610486Stjablin@gmail.comDataAbort::routeToHyp(ThreadContext *tc) const 11775877Shsul@eecs.umich.edu{ 117811905SBrandon.Potter@amd.com bool toHyp; 117911905SBrandon.Potter@amd.com 118011905SBrandon.Potter@amd.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 118111905SBrandon.Potter@amd.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 118210027SChris.Adeniyi-Jones@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 118312206Srico.amslinger@informatik.uni-augsburg.de HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); 118412206Srico.amslinger@informatik.uni-augsburg.de 11855877Shsul@eecs.umich.edu // if in Hyp mode then stay in Hyp mode 118611905SBrandon.Potter@amd.com toHyp = scr.ns && (cpsr.mode == MODE_HYP); 118711905SBrandon.Potter@amd.com // otherwise, check whether to take to Hyp mode through Hyp Trap vector 11885877Shsul@eecs.umich.edu toHyp |= (stage2 || 11895877Shsul@eecs.umich.edu ( (cpsr.mode != MODE_HYP) && ( ((source == AsynchronousExternalAbort) && hcr.amo) || 119010027SChris.Adeniyi-Jones@arm.com ((source == DebugEvent) && hdcr.tde) ) 11915877Shsul@eecs.umich.edu ) || 11925877Shsul@eecs.umich.edu ( (cpsr.mode == MODE_USER) && hcr.tge && 11935877Shsul@eecs.umich.edu ((source == AlignmentFault) || 119412206Srico.amslinger@informatik.uni-augsburg.de (source == SynchronousExternalAbort)) 119512206Srico.amslinger@informatik.uni-augsburg.de ) 119612206Srico.amslinger@informatik.uni-augsburg.de ) && !inSecureState(tc); 119712206Srico.amslinger@informatik.uni-augsburg.de return toHyp; 119812206Srico.amslinger@informatik.uni-augsburg.de} 119912206Srico.amslinger@informatik.uni-augsburg.de 120012206Srico.amslinger@informatik.uni-augsburg.deuint32_t 120112206Srico.amslinger@informatik.uni-augsburg.deDataAbort::iss() const 120212206Srico.amslinger@informatik.uni-augsburg.de{ 120310027SChris.Adeniyi-Jones@arm.com uint32_t val; 120410027SChris.Adeniyi-Jones@arm.com 120510027SChris.Adeniyi-Jones@arm.com // Add on the data abort specific fields to the generic abort ISS value 120610027SChris.Adeniyi-Jones@arm.com val = AbortFault<DataAbort>::iss(); 12075877Shsul@eecs.umich.edu // ISS is valid if not caused by a stage 1 page table walk, and when taken 120810027SChris.Adeniyi-Jones@arm.com // to AArch64 only when directed to EL2 120910027SChris.Adeniyi-Jones@arm.com if (!s1ptw && (!to64 || toEL == EL2)) { 121010027SChris.Adeniyi-Jones@arm.com val |= isv << 24; 121110027SChris.Adeniyi-Jones@arm.com if (isv) { 121212206Srico.amslinger@informatik.uni-augsburg.de val |= sas << 22; 121312206Srico.amslinger@informatik.uni-augsburg.de val |= sse << 21; 121412206Srico.amslinger@informatik.uni-augsburg.de val |= srt << 16; 121512206Srico.amslinger@informatik.uni-augsburg.de // AArch64 only. These assignments are safe on AArch32 as well 121610027SChris.Adeniyi-Jones@arm.com // because these vars are initialized to false 121710027SChris.Adeniyi-Jones@arm.com val |= sf << 15; 121810027SChris.Adeniyi-Jones@arm.com val |= ar << 14; 121910027SChris.Adeniyi-Jones@arm.com } 122010027SChris.Adeniyi-Jones@arm.com } 122110027SChris.Adeniyi-Jones@arm.com return (val); 12225877Shsul@eecs.umich.edu} 12235877Shsul@eecs.umich.edu 12245877Shsul@eecs.umich.eduvoid 122510027SChris.Adeniyi-Jones@arm.comDataAbort::annotate(AnnotationIDs id, uint64_t val) 122610027SChris.Adeniyi-Jones@arm.com{ 12278601Ssteve.reinhardt@amd.com AbortFault<DataAbort>::annotate(id, val); 122810027SChris.Adeniyi-Jones@arm.com switch (id) 12295877Shsul@eecs.umich.edu { 12305877Shsul@eecs.umich.edu case SAS: 12311999SN/A isv = true; 1232378SN/A sas = val; 1233360SN/A break; 12341450SN/A case SSE: 123511851Sbrandon.potter@amd.com isv = true; 12362680Sktlim@umich.edu sse = val; 1237360SN/A break; 1238360SN/A case SRT: 1239360SN/A isv = true; 12406701Sgblack@eecs.umich.edu srt = val; 12418852Sandreas.hansson@arm.com break; 12426701Sgblack@eecs.umich.edu case SF: 12436701Sgblack@eecs.umich.edu isv = true; 12446701Sgblack@eecs.umich.edu sf = val; 12456701Sgblack@eecs.umich.edu break; 1246360SN/A case AR: 12473669Sbinkertn@umich.edu isv = true; 12483669Sbinkertn@umich.edu ar = val; 12493669Sbinkertn@umich.edu break; 1250360SN/A // Just ignore unknown ID's 1251360SN/A default: 1252360SN/A break; 1253360SN/A } 12542218SN/A} 1255360SN/A 12568706Sandreas.hansson@arm.comvoid 1257360SN/AVirtualDataAbort::invoke(ThreadContext *tc, const StaticInstPtr &inst) 12581458SN/A{ 1259360SN/A AbortFault<VirtualDataAbort>::invoke(tc, inst); 1260360SN/A HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 1261360SN/A hcr.va = 0; 12625074Ssaidi@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_HCR, hcr); 12635074Ssaidi@eecs.umich.edu} 12645074Ssaidi@eecs.umich.edu 126511851Sbrandon.potter@amd.combool 12665074Ssaidi@eecs.umich.eduInterrupt::routeToMonitor(ThreadContext *tc) const 12675074Ssaidi@eecs.umich.edu{ 12685074Ssaidi@eecs.umich.edu assert(ArmSystem::haveSecurity(tc)); 12695074Ssaidi@eecs.umich.edu SCR scr = 0; 12706701Sgblack@eecs.umich.edu if (from64) 12718852Sandreas.hansson@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 12726701Sgblack@eecs.umich.edu else 12735074Ssaidi@eecs.umich.edu scr = tc->readMiscRegNoEffect(MISCREG_SCR); 12746701Sgblack@eecs.umich.edu return scr.irq; 12755074Ssaidi@eecs.umich.edu} 12765074Ssaidi@eecs.umich.edu 12775074Ssaidi@eecs.umich.edubool 12785074Ssaidi@eecs.umich.eduInterrupt::routeToHyp(ThreadContext *tc) const 12795208Ssaidi@eecs.umich.edu{ 12805208Ssaidi@eecs.umich.edu bool toHyp; 12815208Ssaidi@eecs.umich.edu 12825208Ssaidi@eecs.umich.edu SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 12835074Ssaidi@eecs.umich.edu HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 12845074Ssaidi@eecs.umich.edu CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 12855208Ssaidi@eecs.umich.edu // Determine whether IRQs are routed to Hyp mode. 12865074Ssaidi@eecs.umich.edu toHyp = (!scr.irq && hcr.imo && !inSecureState(tc)) || 12875074Ssaidi@eecs.umich.edu (cpsr.mode == MODE_HYP); 12885074Ssaidi@eecs.umich.edu return toHyp; 12895074Ssaidi@eecs.umich.edu} 12908706Sandreas.hansson@arm.com 12915074Ssaidi@eecs.umich.edubool 12925074Ssaidi@eecs.umich.eduInterrupt::abortDisable(ThreadContext *tc) 12935074Ssaidi@eecs.umich.edu{ 12945074Ssaidi@eecs.umich.edu if (ArmSystem::haveSecurity(tc)) { 12955074Ssaidi@eecs.umich.edu SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 129610027SChris.Adeniyi-Jones@arm.com return (!scr.ns || scr.aw); 129710027SChris.Adeniyi-Jones@arm.com } 129810027SChris.Adeniyi-Jones@arm.com return true; 129911851Sbrandon.potter@amd.com} 130010027SChris.Adeniyi-Jones@arm.com 130110027SChris.Adeniyi-Jones@arm.comVirtualInterrupt::VirtualInterrupt() 130210027SChris.Adeniyi-Jones@arm.com{} 130310027SChris.Adeniyi-Jones@arm.com 130410027SChris.Adeniyi-Jones@arm.combool 130510793Sbrandon.potter@amd.comFastInterrupt::routeToMonitor(ThreadContext *tc) const 130610027SChris.Adeniyi-Jones@arm.com{ 130710027SChris.Adeniyi-Jones@arm.com assert(ArmSystem::haveSecurity(tc)); 130810027SChris.Adeniyi-Jones@arm.com SCR scr = 0; 130910027SChris.Adeniyi-Jones@arm.com if (from64) 131010027SChris.Adeniyi-Jones@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 131110027SChris.Adeniyi-Jones@arm.com else 131210027SChris.Adeniyi-Jones@arm.com scr = tc->readMiscRegNoEffect(MISCREG_SCR); 131310027SChris.Adeniyi-Jones@arm.com return scr.fiq; 131410027SChris.Adeniyi-Jones@arm.com} 131510027SChris.Adeniyi-Jones@arm.com 131610027SChris.Adeniyi-Jones@arm.combool 131710027SChris.Adeniyi-Jones@arm.comFastInterrupt::routeToHyp(ThreadContext *tc) const 131810027SChris.Adeniyi-Jones@arm.com{ 131910027SChris.Adeniyi-Jones@arm.com bool toHyp; 132010027SChris.Adeniyi-Jones@arm.com 132110027SChris.Adeniyi-Jones@arm.com SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 132210027SChris.Adeniyi-Jones@arm.com HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 132310027SChris.Adeniyi-Jones@arm.com CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR); 132410027SChris.Adeniyi-Jones@arm.com // Determine whether IRQs are routed to Hyp mode. 132510027SChris.Adeniyi-Jones@arm.com toHyp = (!scr.fiq && hcr.fmo && !inSecureState(tc)) || 132610027SChris.Adeniyi-Jones@arm.com (cpsr.mode == MODE_HYP); 132710027SChris.Adeniyi-Jones@arm.com return toHyp; 132810027SChris.Adeniyi-Jones@arm.com} 132910027SChris.Adeniyi-Jones@arm.com 133010027SChris.Adeniyi-Jones@arm.combool 133110027SChris.Adeniyi-Jones@arm.comFastInterrupt::abortDisable(ThreadContext *tc) 133210027SChris.Adeniyi-Jones@arm.com{ 13331999SN/A if (ArmSystem::haveSecurity(tc)) { 13341999SN/A SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 13351999SN/A return (!scr.ns || scr.aw); 133611856Sbrandon.potter@amd.com } 13371999SN/A return true; 13386701Sgblack@eecs.umich.edu} 133911856Sbrandon.potter@amd.com 134011856Sbrandon.potter@amd.combool 134110931Sbrandon.potter@amd.comFastInterrupt::fiqDisable(ThreadContext *tc) 134211856Sbrandon.potter@amd.com{ 134311856Sbrandon.potter@amd.com if (ArmSystem::haveVirtualization(tc)) { 13441999SN/A return true; 134511856Sbrandon.potter@amd.com } else if (ArmSystem::haveSecurity(tc)) { 13461999SN/A SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR); 13472764Sstever@eecs.umich.edu return (!scr.ns || scr.fw); 13482064SN/A } 134910931Sbrandon.potter@amd.com return true; 13502064SN/A} 13512064SN/A 135210931Sbrandon.potter@amd.comVirtualFastInterrupt::VirtualFastInterrupt() 13532064SN/A{} 13541999SN/A 13551999SN/Avoid 13562218SN/APCAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 13571999SN/A{ 135810931Sbrandon.potter@amd.com ArmFaultVals<PCAlignmentFault>::invoke(tc, inst); 13591999SN/A assert(from64); 13601999SN/A // Set the FAR 13611999SN/A tc->setMiscReg(getFaultAddrReg64(), faultPC); 13621999SN/A} 13631999SN/A 1364378SN/ASPAlignmentFault::SPAlignmentFault() 1365360SN/A{} 13661450SN/A 136711851Sbrandon.potter@amd.comSystemError::SystemError() 13682680Sktlim@umich.edu{} 1369360SN/A 1370360SN/Avoid 1371360SN/ASystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst) 13726701Sgblack@eecs.umich.edu{ 13738852Sandreas.hansson@arm.com tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 13746701Sgblack@eecs.umich.edu ArmFault::invoke(tc, inst); 13756701Sgblack@eecs.umich.edu} 13766701Sgblack@eecs.umich.edu 13776701Sgblack@eecs.umich.edubool 1378360SN/ASystemError::routeToMonitor(ThreadContext *tc) const 13793669Sbinkertn@umich.edu{ 13803669Sbinkertn@umich.edu assert(ArmSystem::haveSecurity(tc)); 13813669Sbinkertn@umich.edu assert(from64); 1382360SN/A SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 1383360SN/A return scr.ea; 1384360SN/A} 1385360SN/A 13861458SN/Abool 1387360SN/ASystemError::routeToHyp(ThreadContext *tc) const 13888706Sandreas.hansson@arm.com{ 1389360SN/A bool toHyp; 13901458SN/A assert(from64); 1391360SN/A 1392360SN/A SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3); 13931999SN/A HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR); 13941999SN/A 13951999SN/A toHyp = (!scr.ea && hcr.amo && !inSecureState(tc)) || 139611851Sbrandon.potter@amd.com (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(tc)); 13972680Sktlim@umich.edu return toHyp; 13981999SN/A} 13991999SN/A 14001999SN/Avoid 14016701Sgblack@eecs.umich.eduFlushPipe::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 14028852Sandreas.hansson@arm.com DPRINTF(Faults, "Invoking FlushPipe Fault\n"); 14036701Sgblack@eecs.umich.edu 14046701Sgblack@eecs.umich.edu // Set the PC to the next instruction of the faulting instruction. 14056701Sgblack@eecs.umich.edu // Net effect is simply squashing all instructions behind and 14066701Sgblack@eecs.umich.edu // start refetching from the next instruction. 14071999SN/A PCState pc = tc->pcState(); 14083669Sbinkertn@umich.edu assert(inst); 14093669Sbinkertn@umich.edu inst->advancePC(pc); 14103669Sbinkertn@umich.edu tc->pcState(pc); 14112764Sstever@eecs.umich.edu} 14122064SN/A 14132064SN/Avoid 14142064SN/AArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) { 14151999SN/A DPRINTF(Faults, "Invoking ArmSev Fault\n"); 14161999SN/A if (!FullSystem) 14172064SN/A return; 14181999SN/A 14191999SN/A // Set sev_mailbox to 1, clear the pending interrupt from remote 14201999SN/A // SEV execution and let pipeline continue as pcState is still 14211999SN/A // valid. 14228706Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 14231999SN/A tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0); 14241999SN/A} 14251999SN/A 14261999SN/A// Instantiate all the templates to make the linker happy 1427378SN/Atemplate class ArmFaultVals<Reset>; 1428360SN/Atemplate class ArmFaultVals<UndefinedInstruction>; 14291450SN/Atemplate class ArmFaultVals<SupervisorCall>; 143011856Sbrandon.potter@amd.comtemplate class ArmFaultVals<SecureMonitorCall>; 1431360SN/Atemplate class ArmFaultVals<HypervisorCall>; 14326701Sgblack@eecs.umich.edutemplate class ArmFaultVals<PrefetchAbort>; 143311856Sbrandon.potter@amd.comtemplate class ArmFaultVals<DataAbort>; 143411856Sbrandon.potter@amd.comtemplate class ArmFaultVals<VirtualDataAbort>; 1435360SN/Atemplate class ArmFaultVals<HypervisorTrap>; 143611380Salexandru.dutu@amd.comtemplate class ArmFaultVals<Interrupt>; 1437360SN/Atemplate class ArmFaultVals<VirtualInterrupt>; 143811856Sbrandon.potter@amd.comtemplate class ArmFaultVals<FastInterrupt>; 143911856Sbrandon.potter@amd.comtemplate class ArmFaultVals<VirtualFastInterrupt>; 14401458SN/Atemplate class ArmFaultVals<SupervisorTrap>; 144111856Sbrandon.potter@amd.comtemplate class ArmFaultVals<SecureMonitorTrap>; 1442360SN/Atemplate class ArmFaultVals<PCAlignmentFault>; 1443360SN/Atemplate class ArmFaultVals<SPAlignmentFault>; 144410931Sbrandon.potter@amd.comtemplate class ArmFaultVals<SystemError>; 1445360SN/Atemplate class ArmFaultVals<FlushPipe>; 1446360SN/Atemplate class ArmFaultVals<ArmSev>; 14471458SN/Atemplate class AbortFault<PrefetchAbort>; 1448360SN/Atemplate class AbortFault<DataAbort>; 144910931Sbrandon.potter@amd.comtemplate class AbortFault<VirtualDataAbort>; 14502021SN/A 14511458SN/A 1452360SN/AIllegalInstSetStateFault::IllegalInstSetStateFault() 1453360SN/A{} 14541706SN/A 14551706SN/A 14561706SN/A} // namespace ArmISA 145711851Sbrandon.potter@amd.com