utility.cc revision 14020
16757SAli.Saidi@ARM.com/* 214001Sgiacomo.travaglini@arm.com * Copyright (c) 2009-2014, 2016-2019 ARM Limited 36757SAli.Saidi@ARM.com * All rights reserved. 46757SAli.Saidi@ARM.com * 57111Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67111Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77111Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87111Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97111Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107111Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117111Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127111Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137111Sgblack@eecs.umich.edu * 146757SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 156757SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 166757SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 176757SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 186757SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 196757SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 206757SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 216757SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 226757SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 236757SAli.Saidi@ARM.com * this software without specific prior written permission. 246757SAli.Saidi@ARM.com * 256757SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266757SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276757SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286757SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296757SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306757SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316757SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326757SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336757SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346757SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356757SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366757SAli.Saidi@ARM.com * 376757SAli.Saidi@ARM.com * Authors: Ali Saidi 386757SAli.Saidi@ARM.com */ 396735Sgblack@eecs.umich.edu 4011793Sbrandon.potter@amd.com#include "arch/arm/utility.hh" 4111793Sbrandon.potter@amd.com 4210474Sandreas.hansson@arm.com#include <memory> 436757SAli.Saidi@ARM.com 446757SAli.Saidi@ARM.com#include "arch/arm/faults.hh" 457707Sgblack@eecs.umich.edu#include "arch/arm/isa_traits.hh" 4610037SARM gem5 Developers#include "arch/arm/system.hh" 478782Sgblack@eecs.umich.edu#include "arch/arm/tlb.hh" 488782Sgblack@eecs.umich.edu#include "arch/arm/vtophys.hh" 4911793Sbrandon.potter@amd.com#include "cpu/base.hh" 508887Sgeoffrey.blake@arm.com#include "cpu/checker/cpu.hh" 516757SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 528706Sandreas.hansson@arm.com#include "mem/fs_translating_port_proxy.hh" 538782Sgblack@eecs.umich.edu#include "sim/full_system.hh" 547749SAli.Saidi@ARM.com 556735Sgblack@eecs.umich.edunamespace ArmISA { 566735Sgblack@eecs.umich.edu 576735Sgblack@eecs.umich.eduvoid 586735Sgblack@eecs.umich.eduinitCPU(ThreadContext *tc, int cpuId) 596735Sgblack@eecs.umich.edu{ 606735Sgblack@eecs.umich.edu // Reset CP15?? What does that mean -- ali 619058Satgutier@umich.edu 626735Sgblack@eecs.umich.edu // FPEXC.EN = 0 638886SAli.Saidi@ARM.com 6410474Sandreas.hansson@arm.com static Fault reset = std::make_shared<Reset>(); 658286SAli.Saidi@ARM.com reset->invoke(tc); 666735Sgblack@eecs.umich.edu} 676735Sgblack@eecs.umich.edu 687707Sgblack@eecs.umich.eduuint64_t 697707Sgblack@eecs.umich.edugetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 707707Sgblack@eecs.umich.edu{ 718806Sgblack@eecs.umich.edu if (!FullSystem) { 728806Sgblack@eecs.umich.edu panic("getArgument() only implemented for full system mode.\n"); 738806Sgblack@eecs.umich.edu M5_DUMMY_RETURN 748806Sgblack@eecs.umich.edu } 758706Sandreas.hansson@arm.com 767693SAli.Saidi@ARM.com if (fp) 777693SAli.Saidi@ARM.com panic("getArgument(): Floating point arguments not implemented\n"); 787693SAli.Saidi@ARM.com 7910037SARM gem5 Developers if (inAArch64(tc)) { 8010037SARM gem5 Developers if (size == (uint16_t)(-1)) 8110037SARM gem5 Developers size = sizeof(uint64_t); 8210037SARM gem5 Developers 8310037SARM gem5 Developers if (number < 8 /*NumArgumentRegs64*/) { 8410037SARM gem5 Developers return tc->readIntReg(number); 857693SAli.Saidi@ARM.com } else { 8610037SARM gem5 Developers panic("getArgument(): No support reading stack args for AArch64\n"); 877693SAli.Saidi@ARM.com } 887693SAli.Saidi@ARM.com } else { 8910037SARM gem5 Developers if (size == (uint16_t)(-1)) 9010318Sandreas.hansson@arm.com // todo: should this not be sizeof(uint32_t) rather? 9110037SARM gem5 Developers size = ArmISA::MachineBytes; 9210037SARM gem5 Developers 9310037SARM gem5 Developers if (number < NumArgumentRegs) { 9410037SARM gem5 Developers // If the argument is 64 bits, it must be in an even regiser 9510037SARM gem5 Developers // number. Increment the number here if it isn't even. 9610037SARM gem5 Developers if (size == sizeof(uint64_t)) { 9710037SARM gem5 Developers if ((number % 2) != 0) 9810037SARM gem5 Developers number++; 9910037SARM gem5 Developers // Read the two halves of the data. Number is inc here to 10010037SARM gem5 Developers // get the second half of the 64 bit reg. 10110037SARM gem5 Developers uint64_t tmp; 10210037SARM gem5 Developers tmp = tc->readIntReg(number++); 10310037SARM gem5 Developers tmp |= tc->readIntReg(number) << 32; 10410037SARM gem5 Developers return tmp; 10510037SARM gem5 Developers } else { 10610037SARM gem5 Developers return tc->readIntReg(number); 10710037SARM gem5 Developers } 10810037SARM gem5 Developers } else { 10910037SARM gem5 Developers Addr sp = tc->readIntReg(StackPointerReg); 11014020Sgabeblack@google.com PortProxy &vp = tc->getVirtProxy(); 11110037SARM gem5 Developers uint64_t arg; 11210037SARM gem5 Developers if (size == sizeof(uint64_t)) { 11310037SARM gem5 Developers // If the argument is even it must be aligned 11410037SARM gem5 Developers if ((number % 2) != 0) 11510037SARM gem5 Developers number++; 11610037SARM gem5 Developers arg = vp.read<uint64_t>(sp + 11710037SARM gem5 Developers (number-NumArgumentRegs) * sizeof(uint32_t)); 11810037SARM gem5 Developers // since two 32 bit args == 1 64 bit arg, increment number 1197693SAli.Saidi@ARM.com number++; 12010037SARM gem5 Developers } else { 12110037SARM gem5 Developers arg = vp.read<uint32_t>(sp + 12210037SARM gem5 Developers (number-NumArgumentRegs) * sizeof(uint32_t)); 12310037SARM gem5 Developers } 12410037SARM gem5 Developers return arg; 1257693SAli.Saidi@ARM.com } 1267650SAli.Saidi@ARM.com } 12710037SARM gem5 Developers panic("getArgument() should always return\n"); 1286757SAli.Saidi@ARM.com} 1296757SAli.Saidi@ARM.com 1307693SAli.Saidi@ARM.comvoid 1317693SAli.Saidi@ARM.comskipFunction(ThreadContext *tc) 1327693SAli.Saidi@ARM.com{ 1339920Syasuko.eckert@amd.com PCState newPC = tc->pcState(); 13410037SARM gem5 Developers if (inAArch64(tc)) { 13510037SARM gem5 Developers newPC.set(tc->readIntReg(INTREG_X30)); 13610037SARM gem5 Developers } else { 13710037SARM gem5 Developers newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1)); 13810037SARM gem5 Developers } 1398887Sgeoffrey.blake@arm.com 1408887Sgeoffrey.blake@arm.com CheckerCPU *checker = tc->getCheckerCpuPtr(); 1418887Sgeoffrey.blake@arm.com if (checker) { 1428887Sgeoffrey.blake@arm.com tc->pcStateNoRecord(newPC); 1438887Sgeoffrey.blake@arm.com } else { 1448887Sgeoffrey.blake@arm.com tc->pcState(newPC); 1458887Sgeoffrey.blake@arm.com } 1467693SAli.Saidi@ARM.com} 1477693SAli.Saidi@ARM.com 14813601Sgiacomo.travaglini@arm.comstatic void 14913601Sgiacomo.travaglini@arm.comcopyVecRegs(ThreadContext *src, ThreadContext *dest) 15013601Sgiacomo.travaglini@arm.com{ 15113601Sgiacomo.travaglini@arm.com auto src_mode = RenameMode<ArmISA::ISA>::mode(src->pcState()); 15213601Sgiacomo.travaglini@arm.com 15313601Sgiacomo.travaglini@arm.com // The way vector registers are copied (VecReg vs VecElem) is relevant 15413601Sgiacomo.travaglini@arm.com // in the O3 model only. 15513601Sgiacomo.travaglini@arm.com if (src_mode == Enums::Full) { 15613601Sgiacomo.travaglini@arm.com for (auto idx = 0; idx < NumVecRegs; idx++) 15713601Sgiacomo.travaglini@arm.com dest->setVecRegFlat(idx, src->readVecRegFlat(idx)); 15813601Sgiacomo.travaglini@arm.com } else { 15913601Sgiacomo.travaglini@arm.com for (auto idx = 0; idx < NumVecRegs; idx++) 16013601Sgiacomo.travaglini@arm.com for (auto elem_idx = 0; elem_idx < NumVecElemPerVecReg; elem_idx++) 16113601Sgiacomo.travaglini@arm.com dest->setVecElemFlat( 16213601Sgiacomo.travaglini@arm.com idx, elem_idx, src->readVecElemFlat(idx, elem_idx)); 16313601Sgiacomo.travaglini@arm.com } 16413601Sgiacomo.travaglini@arm.com} 16513601Sgiacomo.travaglini@arm.com 1667748SAli.Saidi@ARM.comvoid 1677748SAli.Saidi@ARM.comcopyRegs(ThreadContext *src, ThreadContext *dest) 1687748SAli.Saidi@ARM.com{ 1699920Syasuko.eckert@amd.com for (int i = 0; i < NumIntRegs; i++) 1709431SAndreas.Sandberg@ARM.com dest->setIntRegFlat(i, src->readIntRegFlat(i)); 1718208SAli.Saidi@ARM.com 1729920Syasuko.eckert@amd.com for (int i = 0; i < NumFloatRegs; i++) 17313611Sgabeblack@google.com dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 1748208SAli.Saidi@ARM.com 17510338SCurtis.Dunham@arm.com for (int i = 0; i < NumCCRegs; i++) 17610338SCurtis.Dunham@arm.com dest->setCCReg(i, src->readCCReg(i)); 1779920Syasuko.eckert@amd.com 1789920Syasuko.eckert@amd.com for (int i = 0; i < NumMiscRegs; i++) 1797748SAli.Saidi@ARM.com dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 1806759SAli.Saidi@ARM.com 18113601Sgiacomo.travaglini@arm.com copyVecRegs(src, dest); 18213601Sgiacomo.travaglini@arm.com 1837748SAli.Saidi@ARM.com // setMiscReg "with effect" will set the misc register mapping correctly. 1847748SAli.Saidi@ARM.com // e.g. updateRegMap(val) 1857748SAli.Saidi@ARM.com dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR)); 1867748SAli.Saidi@ARM.com 1877749SAli.Saidi@ARM.com // Copy over the PC State 1887748SAli.Saidi@ARM.com dest->pcState(src->pcState()); 1897749SAli.Saidi@ARM.com 1907749SAli.Saidi@ARM.com // Invalidate the tlb misc register cache 19112406Sgabeblack@google.com dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg(); 19212406Sgabeblack@google.com dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg(); 1936759SAli.Saidi@ARM.com} 1947752SWilliam.Wang@arm.com 19510037SARM gem5 Developersbool 19610037SARM gem5 DevelopersinSecureState(ThreadContext *tc) 19710037SARM gem5 Developers{ 19810037SARM gem5 Developers SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) : 19910037SARM gem5 Developers tc->readMiscReg(MISCREG_SCR); 20010037SARM gem5 Developers return ArmSystem::haveSecurity(tc) && inSecureState( 20110037SARM gem5 Developers scr, tc->readMiscReg(MISCREG_CPSR)); 20210037SARM gem5 Developers} 20310037SARM gem5 Developers 20412495Sgiacomo.travaglini@arm.cominline bool 20512495Sgiacomo.travaglini@arm.comisSecureBelowEL3(ThreadContext *tc) 20612495Sgiacomo.travaglini@arm.com{ 20712495Sgiacomo.travaglini@arm.com SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 20812495Sgiacomo.travaglini@arm.com return ArmSystem::haveEL(tc, EL3) && scr.ns == 0; 20912495Sgiacomo.travaglini@arm.com} 21012495Sgiacomo.travaglini@arm.com 21110037SARM gem5 Developersbool 21210037SARM gem5 DevelopersinAArch64(ThreadContext *tc) 21310037SARM gem5 Developers{ 21410037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 21510037SARM gem5 Developers return opModeIs64((OperatingMode) (uint8_t) cpsr.mode); 21610037SARM gem5 Developers} 21710037SARM gem5 Developers 21810037SARM gem5 Developersbool 21910037SARM gem5 DeveloperslongDescFormatInUse(ThreadContext *tc) 22010037SARM gem5 Developers{ 22110037SARM gem5 Developers TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR); 22210037SARM gem5 Developers return ArmSystem::haveLPAE(tc) && ttbcr.eae; 22310037SARM gem5 Developers} 22410037SARM gem5 Developers 22513585Sgabeblack@google.comRegVal 22613550Sgiacomo.travaglini@arm.comreadMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 22713550Sgiacomo.travaglini@arm.com{ 22813550Sgiacomo.travaglini@arm.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 22913550Sgiacomo.travaglini@arm.com const ExceptionLevel current_el = 23013550Sgiacomo.travaglini@arm.com opModeToEL((OperatingMode) (uint8_t) cpsr.mode); 23113550Sgiacomo.travaglini@arm.com 23213550Sgiacomo.travaglini@arm.com const bool is_secure = isSecureBelowEL3(tc); 23313550Sgiacomo.travaglini@arm.com 23413550Sgiacomo.travaglini@arm.com switch (current_el) { 23513550Sgiacomo.travaglini@arm.com case EL0: 23613550Sgiacomo.travaglini@arm.com // Note: in MsrMrs instruction we read the register value before 23713550Sgiacomo.travaglini@arm.com // checking access permissions. This means that EL0 entry must 23813550Sgiacomo.travaglini@arm.com // be part of the table even if MPIDR is not accessible in user 23913550Sgiacomo.travaglini@arm.com // mode. 24013550Sgiacomo.travaglini@arm.com warn_once("Trying to read MPIDR at EL0\n"); 24113550Sgiacomo.travaglini@arm.com M5_FALLTHROUGH; 24213550Sgiacomo.travaglini@arm.com case EL1: 24313550Sgiacomo.travaglini@arm.com if (ArmSystem::haveEL(tc, EL2) && !is_secure) 24413550Sgiacomo.travaglini@arm.com return tc->readMiscReg(MISCREG_VMPIDR_EL2); 24513550Sgiacomo.travaglini@arm.com else 24613550Sgiacomo.travaglini@arm.com return getMPIDR(arm_sys, tc); 24713550Sgiacomo.travaglini@arm.com case EL2: 24813550Sgiacomo.travaglini@arm.com case EL3: 24913550Sgiacomo.travaglini@arm.com return getMPIDR(arm_sys, tc); 25013550Sgiacomo.travaglini@arm.com default: 25113550Sgiacomo.travaglini@arm.com panic("Invalid EL for reading MPIDR register\n"); 25213550Sgiacomo.travaglini@arm.com } 25313550Sgiacomo.travaglini@arm.com} 25413550Sgiacomo.travaglini@arm.com 25513585Sgabeblack@google.comRegVal 25610037SARM gem5 DevelopersgetMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 25710037SARM gem5 Developers{ 25810190Sakash.bagdia@arm.com // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical 25910190Sakash.bagdia@arm.com // Reference Manual 26010190Sakash.bagdia@arm.com // 26110190Sakash.bagdia@arm.com // bit 31 - Multi-processor extensions available 26210190Sakash.bagdia@arm.com // bit 30 - Uni-processor system 26310190Sakash.bagdia@arm.com // bit 24 - Multi-threaded cores 26410190Sakash.bagdia@arm.com // bit 11-8 - Cluster ID 26510190Sakash.bagdia@arm.com // bit 1-0 - CPU ID 26610190Sakash.bagdia@arm.com // 26710190Sakash.bagdia@arm.com // We deliberately extend both the Cluster ID and CPU ID fields to allow 26810190Sakash.bagdia@arm.com // for simulation of larger systems 26910190Sakash.bagdia@arm.com assert((0 <= tc->cpuId()) && (tc->cpuId() < 256)); 27011294Sandreas.hansson@arm.com assert(tc->socketId() < 65536); 27111149Smitch.hayenga@arm.com if (arm_sys->multiThread) { 27211149Smitch.hayenga@arm.com return 0x80000000 | // multiprocessor extensions available 27312712Sgiacomo.travaglini@arm.com 0x01000000 | // multi-threaded cores 27411149Smitch.hayenga@arm.com tc->contextId(); 27511149Smitch.hayenga@arm.com } else if (arm_sys->multiProc) { 27610037SARM gem5 Developers return 0x80000000 | // multiprocessor extensions available 27710190Sakash.bagdia@arm.com tc->cpuId() | tc->socketId() << 8; 27810037SARM gem5 Developers } else { 27910037SARM gem5 Developers return 0x80000000 | // multiprocessor extensions available 28010037SARM gem5 Developers 0x40000000 | // in up system 28110190Sakash.bagdia@arm.com tc->cpuId() | tc->socketId() << 8; 28210037SARM gem5 Developers } 28310037SARM gem5 Developers} 28410037SARM gem5 Developers 28510037SARM gem5 Developersbool 28610037SARM gem5 DevelopersELIs64(ThreadContext *tc, ExceptionLevel el) 28710037SARM gem5 Developers{ 28812494Schuan.zhu@arm.com return !ELIs32(tc, el); 28912494Schuan.zhu@arm.com} 29010037SARM gem5 Developers 29112494Schuan.zhu@arm.combool 29212494Schuan.zhu@arm.comELIs32(ThreadContext *tc, ExceptionLevel el) 29312494Schuan.zhu@arm.com{ 29412496Sgiacomo.travaglini@arm.com bool known, aarch32; 29512496Sgiacomo.travaglini@arm.com std::tie(known, aarch32) = ELUsingAArch32K(tc, el); 29612496Sgiacomo.travaglini@arm.com panic_if(!known, "EL state is UNKNOWN"); 29712496Sgiacomo.travaglini@arm.com return aarch32; 29812496Sgiacomo.travaglini@arm.com} 29912496Sgiacomo.travaglini@arm.com 30013759Sgiacomo.gabrielli@arm.combool 30113759Sgiacomo.gabrielli@arm.comELIsInHost(ThreadContext *tc, ExceptionLevel el) 30213759Sgiacomo.gabrielli@arm.com{ 30313759Sgiacomo.gabrielli@arm.com if (!ArmSystem::haveVirtualization(tc)) { 30413759Sgiacomo.gabrielli@arm.com return false; 30513759Sgiacomo.gabrielli@arm.com } 30613759Sgiacomo.gabrielli@arm.com HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 30713759Sgiacomo.gabrielli@arm.com return (!isSecureBelowEL3(tc) && !ELIs32(tc, EL2) && hcr.e2h == 1 && 30813759Sgiacomo.gabrielli@arm.com (el == EL2 || (el == EL0 && hcr.tge == 1))); 30913759Sgiacomo.gabrielli@arm.com} 31013759Sgiacomo.gabrielli@arm.com 31112496Sgiacomo.travaglini@arm.comstd::pair<bool, bool> 31212496Sgiacomo.travaglini@arm.comELUsingAArch32K(ThreadContext *tc, ExceptionLevel el) 31312496Sgiacomo.travaglini@arm.com{ 31412494Schuan.zhu@arm.com // Return true if the specified EL is in aarch32 state. 31512494Schuan.zhu@arm.com const bool have_el3 = ArmSystem::haveSecurity(tc); 31612494Schuan.zhu@arm.com const bool have_el2 = ArmSystem::haveVirtualization(tc); 31712494Schuan.zhu@arm.com 31812494Schuan.zhu@arm.com panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist"); 31912494Schuan.zhu@arm.com panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist"); 32012494Schuan.zhu@arm.com 32112496Sgiacomo.travaglini@arm.com bool known, aarch32; 32212496Sgiacomo.travaglini@arm.com known = aarch32 = false; 32312496Sgiacomo.travaglini@arm.com if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) { 32412496Sgiacomo.travaglini@arm.com // Target EL is the highest one in a system where 32512496Sgiacomo.travaglini@arm.com // the highest is using AArch64. 32612496Sgiacomo.travaglini@arm.com known = true; aarch32 = false; 32712494Schuan.zhu@arm.com } else if (!ArmSystem::highestELIs64(tc)) { 32812496Sgiacomo.travaglini@arm.com // All ELs are using AArch32: 32912496Sgiacomo.travaglini@arm.com known = true; aarch32 = true; 33012494Schuan.zhu@arm.com } else { 33112494Schuan.zhu@arm.com SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 33212494Schuan.zhu@arm.com bool aarch32_below_el3 = (have_el3 && scr.rw == 0); 33312494Schuan.zhu@arm.com 33412494Schuan.zhu@arm.com HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 33512494Schuan.zhu@arm.com bool aarch32_at_el1 = (aarch32_below_el3 33612495Sgiacomo.travaglini@arm.com || (have_el2 33712495Sgiacomo.travaglini@arm.com && !isSecureBelowEL3(tc) && hcr.rw == 0)); 33812494Schuan.zhu@arm.com 33912494Schuan.zhu@arm.com // Only know if EL0 using AArch32 from PSTATE 34012494Schuan.zhu@arm.com if (el == EL0 && !aarch32_at_el1) { 34112496Sgiacomo.travaglini@arm.com // EL0 controlled by PSTATE 34212494Schuan.zhu@arm.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 34312496Sgiacomo.travaglini@arm.com 34412496Sgiacomo.travaglini@arm.com known = (cpsr.el == EL0); 34512496Sgiacomo.travaglini@arm.com aarch32 = (cpsr.width == 1); 34612494Schuan.zhu@arm.com } else { 34712496Sgiacomo.travaglini@arm.com known = true; 34812496Sgiacomo.travaglini@arm.com aarch32 = (aarch32_below_el3 && el != EL3) 34912496Sgiacomo.travaglini@arm.com || (aarch32_at_el1 && (el == EL0 || el == EL1) ); 35010037SARM gem5 Developers } 35110037SARM gem5 Developers } 35212496Sgiacomo.travaglini@arm.com 35312496Sgiacomo.travaglini@arm.com return std::make_pair(known, aarch32); 35410037SARM gem5 Developers} 35510037SARM gem5 Developers 35610037SARM gem5 Developersbool 35710037SARM gem5 DevelopersisBigEndian64(ThreadContext *tc) 35810037SARM gem5 Developers{ 35910037SARM gem5 Developers switch (opModeToEL(currOpMode(tc))) { 36010037SARM gem5 Developers case EL3: 36110037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee; 36210037SARM gem5 Developers case EL2: 36310037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee; 36410037SARM gem5 Developers case EL1: 36510037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee; 36610037SARM gem5 Developers case EL0: 36710037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e; 36810037SARM gem5 Developers default: 36910037SARM gem5 Developers panic("Invalid exception level"); 37010037SARM gem5 Developers break; 37110037SARM gem5 Developers } 37210037SARM gem5 Developers} 37310037SARM gem5 Developers 37412788Sgiacomo.travaglini@arm.combool 37512788Sgiacomo.travaglini@arm.combadMode32(ThreadContext *tc, OperatingMode mode) 37612788Sgiacomo.travaglini@arm.com{ 37712788Sgiacomo.travaglini@arm.com return unknownMode32(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode)); 37812788Sgiacomo.travaglini@arm.com} 37912788Sgiacomo.travaglini@arm.com 38012788Sgiacomo.travaglini@arm.combool 38112788Sgiacomo.travaglini@arm.combadMode(ThreadContext *tc, OperatingMode mode) 38212788Sgiacomo.travaglini@arm.com{ 38312788Sgiacomo.travaglini@arm.com return unknownMode(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode)); 38412788Sgiacomo.travaglini@arm.com} 38512788Sgiacomo.travaglini@arm.com 38610037SARM gem5 DevelopersAddr 38710854SNathanael.Premillieu@arm.compurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, 38810854SNathanael.Premillieu@arm.com TTBCR tcr) 38910854SNathanael.Premillieu@arm.com{ 39010854SNathanael.Premillieu@arm.com switch (el) { 39110854SNathanael.Premillieu@arm.com case EL0: 39210854SNathanael.Premillieu@arm.com case EL1: 39310854SNathanael.Premillieu@arm.com if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 39410854SNathanael.Premillieu@arm.com return addr | mask(63, 55); 39510854SNathanael.Premillieu@arm.com else if (!bits(addr, 55, 48) && tcr.tbi0) 39610854SNathanael.Premillieu@arm.com return bits(addr,55, 0); 39710854SNathanael.Premillieu@arm.com break; 39811574SCurtis.Dunham@arm.com case EL2: 39911574SCurtis.Dunham@arm.com assert(ArmSystem::haveVirtualization(tc)); 40011574SCurtis.Dunham@arm.com tcr = tc->readMiscReg(MISCREG_TCR_EL2); 40111574SCurtis.Dunham@arm.com if (tcr.tbi) 40211574SCurtis.Dunham@arm.com return addr & mask(56); 40311574SCurtis.Dunham@arm.com break; 40410854SNathanael.Premillieu@arm.com case EL3: 40510854SNathanael.Premillieu@arm.com assert(ArmSystem::haveSecurity(tc)); 40610854SNathanael.Premillieu@arm.com if (tcr.tbi) 40710854SNathanael.Premillieu@arm.com return addr & mask(56); 40810854SNathanael.Premillieu@arm.com break; 40910854SNathanael.Premillieu@arm.com default: 41010854SNathanael.Premillieu@arm.com panic("Invalid exception level"); 41110854SNathanael.Premillieu@arm.com break; 41210854SNathanael.Premillieu@arm.com } 41310854SNathanael.Premillieu@arm.com 41410854SNathanael.Premillieu@arm.com return addr; // Nothing to do if this is not a tagged address 41510854SNathanael.Premillieu@arm.com} 41610854SNathanael.Premillieu@arm.com 41710854SNathanael.Premillieu@arm.comAddr 41810037SARM gem5 DeveloperspurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el) 41910037SARM gem5 Developers{ 42010037SARM gem5 Developers TTBCR tcr; 42110037SARM gem5 Developers 42210037SARM gem5 Developers switch (el) { 42310037SARM gem5 Developers case EL0: 42410037SARM gem5 Developers case EL1: 42510037SARM gem5 Developers tcr = tc->readMiscReg(MISCREG_TCR_EL1); 42610037SARM gem5 Developers if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 42710037SARM gem5 Developers return addr | mask(63, 55); 42810037SARM gem5 Developers else if (!bits(addr, 55, 48) && tcr.tbi0) 42910037SARM gem5 Developers return bits(addr,55, 0); 43010037SARM gem5 Developers break; 43111574SCurtis.Dunham@arm.com case EL2: 43211574SCurtis.Dunham@arm.com assert(ArmSystem::haveVirtualization(tc)); 43311574SCurtis.Dunham@arm.com tcr = tc->readMiscReg(MISCREG_TCR_EL2); 43411574SCurtis.Dunham@arm.com if (tcr.tbi) 43511574SCurtis.Dunham@arm.com return addr & mask(56); 43611574SCurtis.Dunham@arm.com break; 43710037SARM gem5 Developers case EL3: 43810037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 43910037SARM gem5 Developers tcr = tc->readMiscReg(MISCREG_TCR_EL3); 44010037SARM gem5 Developers if (tcr.tbi) 44110037SARM gem5 Developers return addr & mask(56); 44210037SARM gem5 Developers break; 44310037SARM gem5 Developers default: 44410037SARM gem5 Developers panic("Invalid exception level"); 44510037SARM gem5 Developers break; 44610037SARM gem5 Developers } 44710037SARM gem5 Developers 44810037SARM gem5 Developers return addr; // Nothing to do if this is not a tagged address 44910037SARM gem5 Developers} 45010037SARM gem5 Developers 4517752SWilliam.Wang@arm.comAddr 4527752SWilliam.Wang@arm.comtruncPage(Addr addr) 4537752SWilliam.Wang@arm.com{ 4547752SWilliam.Wang@arm.com return addr & ~(PageBytes - 1); 4557748SAli.Saidi@ARM.com} 4567752SWilliam.Wang@arm.com 4577752SWilliam.Wang@arm.comAddr 4587752SWilliam.Wang@arm.comroundPage(Addr addr) 4597752SWilliam.Wang@arm.com{ 4607752SWilliam.Wang@arm.com return (addr + PageBytes - 1) & ~(PageBytes - 1); 4617752SWilliam.Wang@arm.com} 4627752SWilliam.Wang@arm.com 46310037SARM gem5 Developersbool 46413999Sgiacomo.travaglini@arm.commcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss) 46510037SARM gem5 Developers{ 46610037SARM gem5 Developers bool isRead; 46710037SARM gem5 Developers uint32_t crm; 46810037SARM gem5 Developers IntRegIndex rt; 46910037SARM gem5 Developers uint32_t crn; 47010037SARM gem5 Developers uint32_t opc1; 47110037SARM gem5 Developers uint32_t opc2; 47210037SARM gem5 Developers bool trapToHype = false; 47310037SARM gem5 Developers 47413999Sgiacomo.travaglini@arm.com const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 47513999Sgiacomo.travaglini@arm.com const HCR hcr = tc->readMiscReg(MISCREG_HCR); 47613999Sgiacomo.travaglini@arm.com const SCR scr = tc->readMiscReg(MISCREG_SCR); 47713999Sgiacomo.travaglini@arm.com const HDCR hdcr = tc->readMiscReg(MISCREG_HDCR); 47813999Sgiacomo.travaglini@arm.com const HSTR hstr = tc->readMiscReg(MISCREG_HSTR); 47913999Sgiacomo.travaglini@arm.com const HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR); 48010037SARM gem5 Developers 48110037SARM gem5 Developers if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 48210037SARM gem5 Developers mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 48310037SARM gem5 Developers trapToHype = ((uint32_t) hstr) & (1 << crn); 48410037SARM gem5 Developers trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12); 48510037SARM gem5 Developers trapToHype |= hcr.tidcp && ( 48610037SARM gem5 Developers ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) || 48710037SARM gem5 Developers ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) || 48810037SARM gem5 Developers ((crn == 11) && ((crm <= 8) || (crm == 15))) ); 48910037SARM gem5 Developers 49010037SARM gem5 Developers if (!trapToHype) { 49110037SARM gem5 Developers switch (unflattenMiscReg(miscReg)) { 49210037SARM gem5 Developers case MISCREG_CPACR: 49310037SARM gem5 Developers trapToHype = hcptr.tcpac; 49410037SARM gem5 Developers break; 49510037SARM gem5 Developers case MISCREG_REVIDR: 49610037SARM gem5 Developers case MISCREG_TCMTR: 49710037SARM gem5 Developers case MISCREG_TLBTR: 49810037SARM gem5 Developers case MISCREG_AIDR: 49910037SARM gem5 Developers trapToHype = hcr.tid1; 50010037SARM gem5 Developers break; 50110037SARM gem5 Developers case MISCREG_CTR: 50210037SARM gem5 Developers case MISCREG_CCSIDR: 50310037SARM gem5 Developers case MISCREG_CLIDR: 50410037SARM gem5 Developers case MISCREG_CSSELR: 50510037SARM gem5 Developers trapToHype = hcr.tid2; 50610037SARM gem5 Developers break; 50710037SARM gem5 Developers case MISCREG_ID_PFR0: 50810037SARM gem5 Developers case MISCREG_ID_PFR1: 50910037SARM gem5 Developers case MISCREG_ID_DFR0: 51010037SARM gem5 Developers case MISCREG_ID_AFR0: 51110037SARM gem5 Developers case MISCREG_ID_MMFR0: 51210037SARM gem5 Developers case MISCREG_ID_MMFR1: 51310037SARM gem5 Developers case MISCREG_ID_MMFR2: 51410037SARM gem5 Developers case MISCREG_ID_MMFR3: 51510037SARM gem5 Developers case MISCREG_ID_ISAR0: 51610037SARM gem5 Developers case MISCREG_ID_ISAR1: 51710037SARM gem5 Developers case MISCREG_ID_ISAR2: 51810037SARM gem5 Developers case MISCREG_ID_ISAR3: 51910037SARM gem5 Developers case MISCREG_ID_ISAR4: 52010037SARM gem5 Developers case MISCREG_ID_ISAR5: 52110037SARM gem5 Developers trapToHype = hcr.tid3; 52210037SARM gem5 Developers break; 52310037SARM gem5 Developers case MISCREG_DCISW: 52410037SARM gem5 Developers case MISCREG_DCCSW: 52510037SARM gem5 Developers case MISCREG_DCCISW: 52610037SARM gem5 Developers trapToHype = hcr.tsw; 52710037SARM gem5 Developers break; 52810037SARM gem5 Developers case MISCREG_DCIMVAC: 52910037SARM gem5 Developers case MISCREG_DCCIMVAC: 53010037SARM gem5 Developers case MISCREG_DCCMVAC: 53110037SARM gem5 Developers trapToHype = hcr.tpc; 53210037SARM gem5 Developers break; 53310037SARM gem5 Developers case MISCREG_ICIMVAU: 53410037SARM gem5 Developers case MISCREG_ICIALLU: 53510037SARM gem5 Developers case MISCREG_ICIALLUIS: 53610037SARM gem5 Developers case MISCREG_DCCMVAU: 53710037SARM gem5 Developers trapToHype = hcr.tpu; 53810037SARM gem5 Developers break; 53910037SARM gem5 Developers case MISCREG_TLBIALLIS: 54010037SARM gem5 Developers case MISCREG_TLBIMVAIS: 54110037SARM gem5 Developers case MISCREG_TLBIASIDIS: 54210037SARM gem5 Developers case MISCREG_TLBIMVAAIS: 54312576Sgiacomo.travaglini@arm.com case MISCREG_TLBIMVALIS: 54412576Sgiacomo.travaglini@arm.com case MISCREG_TLBIMVAALIS: 54510037SARM gem5 Developers case MISCREG_DTLBIALL: 54610037SARM gem5 Developers case MISCREG_ITLBIALL: 54710037SARM gem5 Developers case MISCREG_DTLBIMVA: 54810037SARM gem5 Developers case MISCREG_ITLBIMVA: 54910037SARM gem5 Developers case MISCREG_DTLBIASID: 55010037SARM gem5 Developers case MISCREG_ITLBIASID: 55110037SARM gem5 Developers case MISCREG_TLBIMVAA: 55210037SARM gem5 Developers case MISCREG_TLBIALL: 55310037SARM gem5 Developers case MISCREG_TLBIMVA: 55412576Sgiacomo.travaglini@arm.com case MISCREG_TLBIMVAL: 55512576Sgiacomo.travaglini@arm.com case MISCREG_TLBIMVAAL: 55610037SARM gem5 Developers case MISCREG_TLBIASID: 55710037SARM gem5 Developers trapToHype = hcr.ttlb; 55810037SARM gem5 Developers break; 55910037SARM gem5 Developers case MISCREG_ACTLR: 56010037SARM gem5 Developers trapToHype = hcr.tac; 56110037SARM gem5 Developers break; 56210037SARM gem5 Developers case MISCREG_SCTLR: 56310037SARM gem5 Developers case MISCREG_TTBR0: 56410037SARM gem5 Developers case MISCREG_TTBR1: 56510037SARM gem5 Developers case MISCREG_TTBCR: 56610037SARM gem5 Developers case MISCREG_DACR: 56710037SARM gem5 Developers case MISCREG_DFSR: 56810037SARM gem5 Developers case MISCREG_IFSR: 56910037SARM gem5 Developers case MISCREG_DFAR: 57010037SARM gem5 Developers case MISCREG_IFAR: 57110037SARM gem5 Developers case MISCREG_ADFSR: 57210037SARM gem5 Developers case MISCREG_AIFSR: 57310037SARM gem5 Developers case MISCREG_PRRR: 57410037SARM gem5 Developers case MISCREG_NMRR: 57510037SARM gem5 Developers case MISCREG_MAIR0: 57610037SARM gem5 Developers case MISCREG_MAIR1: 57710037SARM gem5 Developers case MISCREG_CONTEXTIDR: 57810037SARM gem5 Developers trapToHype = hcr.tvm & !isRead; 57910037SARM gem5 Developers break; 58010037SARM gem5 Developers case MISCREG_PMCR: 58110037SARM gem5 Developers trapToHype = hdcr.tpmcr; 58210037SARM gem5 Developers break; 58314001Sgiacomo.travaglini@arm.com // GICv3 regs 58414001Sgiacomo.travaglini@arm.com case MISCREG_ICC_SGI0R: 58514001Sgiacomo.travaglini@arm.com if (tc->getIsaPtr()->haveGICv3CpuIfc()) 58614001Sgiacomo.travaglini@arm.com trapToHype = hcr.fmo; 58714001Sgiacomo.travaglini@arm.com break; 58814001Sgiacomo.travaglini@arm.com case MISCREG_ICC_SGI1R: 58914001Sgiacomo.travaglini@arm.com case MISCREG_ICC_ASGI1R: 59014001Sgiacomo.travaglini@arm.com if (tc->getIsaPtr()->haveGICv3CpuIfc()) 59114001Sgiacomo.travaglini@arm.com trapToHype = hcr.imo; 59214001Sgiacomo.travaglini@arm.com break; 59310037SARM gem5 Developers // No default action needed 59410037SARM gem5 Developers default: 59510037SARM gem5 Developers break; 59610037SARM gem5 Developers } 59710037SARM gem5 Developers } 59810037SARM gem5 Developers } 59910037SARM gem5 Developers return trapToHype; 60010037SARM gem5 Developers} 60110037SARM gem5 Developers 60210037SARM gem5 Developers 60310037SARM gem5 Developersbool 60410037SARM gem5 DevelopersmcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 60510037SARM gem5 Developers HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 60610037SARM gem5 Developers{ 60710037SARM gem5 Developers bool isRead; 60810037SARM gem5 Developers uint32_t crm; 60910037SARM gem5 Developers IntRegIndex rt; 61010037SARM gem5 Developers uint32_t crn; 61110037SARM gem5 Developers uint32_t opc1; 61210037SARM gem5 Developers uint32_t opc2; 61310037SARM gem5 Developers bool trapToHype = false; 61410037SARM gem5 Developers 61510037SARM gem5 Developers if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 61610037SARM gem5 Developers mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 61710037SARM gem5 Developers inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n", 61810037SARM gem5 Developers crm, crn, opc1, opc2, hdcr, hcptr, hstr); 61910037SARM gem5 Developers trapToHype = hdcr.tda && (opc1 == 0); 62010037SARM gem5 Developers trapToHype |= hcptr.tta && (opc1 == 1); 62110037SARM gem5 Developers if (!trapToHype) { 62210037SARM gem5 Developers switch (unflattenMiscReg(miscReg)) { 62310037SARM gem5 Developers case MISCREG_DBGOSLSR: 62410037SARM gem5 Developers case MISCREG_DBGOSLAR: 62510037SARM gem5 Developers case MISCREG_DBGOSDLR: 62610037SARM gem5 Developers case MISCREG_DBGPRCR: 62710037SARM gem5 Developers trapToHype = hdcr.tdosa; 62810037SARM gem5 Developers break; 62910037SARM gem5 Developers case MISCREG_DBGDRAR: 63010037SARM gem5 Developers case MISCREG_DBGDSAR: 63110037SARM gem5 Developers trapToHype = hdcr.tdra; 63210037SARM gem5 Developers break; 63310037SARM gem5 Developers case MISCREG_JIDR: 63410037SARM gem5 Developers trapToHype = hcr.tid0; 63510037SARM gem5 Developers break; 63610037SARM gem5 Developers case MISCREG_JOSCR: 63710037SARM gem5 Developers case MISCREG_JMCR: 63810037SARM gem5 Developers trapToHype = hstr.tjdbx; 63910037SARM gem5 Developers break; 64010037SARM gem5 Developers case MISCREG_TEECR: 64110037SARM gem5 Developers case MISCREG_TEEHBR: 64210037SARM gem5 Developers trapToHype = hstr.ttee; 64310037SARM gem5 Developers break; 64410037SARM gem5 Developers // No default action needed 64510037SARM gem5 Developers default: 64610037SARM gem5 Developers break; 64710037SARM gem5 Developers } 64810037SARM gem5 Developers } 64910037SARM gem5 Developers } 65010037SARM gem5 Developers return trapToHype; 65110037SARM gem5 Developers} 65210037SARM gem5 Developers 65310037SARM gem5 Developersbool 65410037SARM gem5 DevelopersmcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, 65510037SARM gem5 Developers HCR hcr, uint32_t iss) 65610037SARM gem5 Developers{ 65710037SARM gem5 Developers uint32_t crm; 65810037SARM gem5 Developers IntRegIndex rt; 65910037SARM gem5 Developers uint32_t crn; 66010037SARM gem5 Developers uint32_t opc1; 66110037SARM gem5 Developers uint32_t opc2; 66210037SARM gem5 Developers bool isRead; 66310037SARM gem5 Developers bool trapToHype = false; 66410037SARM gem5 Developers 66510037SARM gem5 Developers if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 66610037SARM gem5 Developers // This is technically the wrong function, but we can re-use it for 66710037SARM gem5 Developers // the moment because we only need one field, which overlaps with the 66810037SARM gem5 Developers // mcrmrc layout 66910037SARM gem5 Developers mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 67010037SARM gem5 Developers trapToHype = ((uint32_t) hstr) & (1 << crm); 67110037SARM gem5 Developers 67210037SARM gem5 Developers if (!trapToHype) { 67310037SARM gem5 Developers switch (unflattenMiscReg(miscReg)) { 67410037SARM gem5 Developers case MISCREG_SCTLR: 67510037SARM gem5 Developers case MISCREG_TTBR0: 67610037SARM gem5 Developers case MISCREG_TTBR1: 67710037SARM gem5 Developers case MISCREG_TTBCR: 67810037SARM gem5 Developers case MISCREG_DACR: 67910037SARM gem5 Developers case MISCREG_DFSR: 68010037SARM gem5 Developers case MISCREG_IFSR: 68110037SARM gem5 Developers case MISCREG_DFAR: 68210037SARM gem5 Developers case MISCREG_IFAR: 68310037SARM gem5 Developers case MISCREG_ADFSR: 68410037SARM gem5 Developers case MISCREG_AIFSR: 68510037SARM gem5 Developers case MISCREG_PRRR: 68610037SARM gem5 Developers case MISCREG_NMRR: 68710037SARM gem5 Developers case MISCREG_MAIR0: 68810037SARM gem5 Developers case MISCREG_MAIR1: 68910037SARM gem5 Developers case MISCREG_CONTEXTIDR: 69010037SARM gem5 Developers trapToHype = hcr.tvm & !isRead; 69110037SARM gem5 Developers break; 69210037SARM gem5 Developers // No default action needed 69310037SARM gem5 Developers default: 69410037SARM gem5 Developers break; 69510037SARM gem5 Developers } 69610037SARM gem5 Developers } 69710037SARM gem5 Developers } 69810037SARM gem5 Developers return trapToHype; 69910037SARM gem5 Developers} 70010037SARM gem5 Developers 70110037SARM gem5 Developersbool 70210037SARM gem5 DevelopersdecodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, 70310037SARM gem5 Developers CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity) 70410037SARM gem5 Developers{ 70510103Sstephan.diestelhorst@arm.com OperatingMode mode = MODE_UNDEFINED; 70610037SARM gem5 Developers bool ok = true; 70710037SARM gem5 Developers 70810037SARM gem5 Developers // R mostly indicates if its a int register or a misc reg, we override 70910037SARM gem5 Developers // below if the few corner cases 71010037SARM gem5 Developers isIntReg = !r; 71110037SARM gem5 Developers // Loosely based on ARM ARM issue C section B9.3.10 71210037SARM gem5 Developers if (r) { 71310037SARM gem5 Developers switch (sysM) 71410037SARM gem5 Developers { 71510037SARM gem5 Developers case 0xE: 71610037SARM gem5 Developers regIdx = MISCREG_SPSR_FIQ; 71710037SARM gem5 Developers mode = MODE_FIQ; 71810037SARM gem5 Developers break; 71910037SARM gem5 Developers case 0x10: 72010037SARM gem5 Developers regIdx = MISCREG_SPSR_IRQ; 72110037SARM gem5 Developers mode = MODE_IRQ; 72210037SARM gem5 Developers break; 72310037SARM gem5 Developers case 0x12: 72410037SARM gem5 Developers regIdx = MISCREG_SPSR_SVC; 72510037SARM gem5 Developers mode = MODE_SVC; 72610037SARM gem5 Developers break; 72710037SARM gem5 Developers case 0x14: 72810037SARM gem5 Developers regIdx = MISCREG_SPSR_ABT; 72910037SARM gem5 Developers mode = MODE_ABORT; 73010037SARM gem5 Developers break; 73110037SARM gem5 Developers case 0x16: 73210037SARM gem5 Developers regIdx = MISCREG_SPSR_UND; 73310037SARM gem5 Developers mode = MODE_UNDEFINED; 73410037SARM gem5 Developers break; 73510037SARM gem5 Developers case 0x1C: 73610037SARM gem5 Developers regIdx = MISCREG_SPSR_MON; 73710037SARM gem5 Developers mode = MODE_MON; 73810037SARM gem5 Developers break; 73910037SARM gem5 Developers case 0x1E: 74010037SARM gem5 Developers regIdx = MISCREG_SPSR_HYP; 74110037SARM gem5 Developers mode = MODE_HYP; 74210037SARM gem5 Developers break; 74310037SARM gem5 Developers default: 74410037SARM gem5 Developers ok = false; 74510037SARM gem5 Developers break; 74610037SARM gem5 Developers } 74710037SARM gem5 Developers } else { 74810037SARM gem5 Developers int sysM4To3 = bits(sysM, 4, 3); 74910037SARM gem5 Developers 75010037SARM gem5 Developers if (sysM4To3 == 0) { 75110037SARM gem5 Developers mode = MODE_USER; 75210037SARM gem5 Developers regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 75310037SARM gem5 Developers } else if (sysM4To3 == 1) { 75410037SARM gem5 Developers mode = MODE_FIQ; 75510037SARM gem5 Developers regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 75610037SARM gem5 Developers } else if (sysM4To3 == 3) { 75710037SARM gem5 Developers if (bits(sysM, 1) == 0) { 75810037SARM gem5 Developers mode = MODE_MON; 75910037SARM gem5 Developers regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 76010037SARM gem5 Developers } else { 76110037SARM gem5 Developers mode = MODE_HYP; 76210037SARM gem5 Developers if (bits(sysM, 0) == 1) { 76310037SARM gem5 Developers regIdx = intRegInMode(mode, 13); // R13 in HYP 76410037SARM gem5 Developers } else { 76510037SARM gem5 Developers isIntReg = false; 76610037SARM gem5 Developers regIdx = MISCREG_ELR_HYP; 76710037SARM gem5 Developers } 76810037SARM gem5 Developers } 76910037SARM gem5 Developers } else { // Other Banked registers 77010037SARM gem5 Developers int sysM2 = bits(sysM, 2); 77110037SARM gem5 Developers int sysM1 = bits(sysM, 1); 77210037SARM gem5 Developers 77310037SARM gem5 Developers mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) | 77410037SARM gem5 Developers (1 << 1) | 77510037SARM gem5 Developers ((sysM2 && !sysM1) << 2) | 77610037SARM gem5 Developers ((sysM2 && sysM1) << 3) | 77710037SARM gem5 Developers (1 << 4) ); 77810037SARM gem5 Developers regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 77910037SARM gem5 Developers // Don't flatten the register here. This is going to go through 78010037SARM gem5 Developers // setIntReg() which will do the flattening 78110037SARM gem5 Developers ok &= mode != cpsr.mode; 78210037SARM gem5 Developers } 78310037SARM gem5 Developers } 78410037SARM gem5 Developers 78510037SARM gem5 Developers // Check that the requested register is accessable from the current mode 78610037SARM gem5 Developers if (ok && checkSecurity && mode != cpsr.mode) { 78710037SARM gem5 Developers switch (cpsr.mode) 78810037SARM gem5 Developers { 78910037SARM gem5 Developers case MODE_USER: 79010037SARM gem5 Developers ok = false; 79110037SARM gem5 Developers break; 79210037SARM gem5 Developers case MODE_FIQ: 79310037SARM gem5 Developers ok &= mode != MODE_HYP; 79410037SARM gem5 Developers ok &= (mode != MODE_MON) || !scr.ns; 79510037SARM gem5 Developers break; 79610037SARM gem5 Developers case MODE_HYP: 79710037SARM gem5 Developers ok &= mode != MODE_MON; 79810037SARM gem5 Developers ok &= (mode != MODE_FIQ) || !nsacr.rfr; 79910037SARM gem5 Developers break; 80010037SARM gem5 Developers case MODE_IRQ: 80110037SARM gem5 Developers case MODE_SVC: 80210037SARM gem5 Developers case MODE_ABORT: 80310037SARM gem5 Developers case MODE_UNDEFINED: 80410037SARM gem5 Developers case MODE_SYSTEM: 80510037SARM gem5 Developers ok &= mode != MODE_HYP; 80610037SARM gem5 Developers ok &= (mode != MODE_MON) || !scr.ns; 80710037SARM gem5 Developers ok &= (mode != MODE_FIQ) || !nsacr.rfr; 80810037SARM gem5 Developers break; 80910037SARM gem5 Developers // can access everything, no further checks required 81010037SARM gem5 Developers case MODE_MON: 81110037SARM gem5 Developers break; 81210037SARM gem5 Developers default: 81310037SARM gem5 Developers panic("unknown Mode 0x%x\n", cpsr.mode); 81410037SARM gem5 Developers break; 81510037SARM gem5 Developers } 81610037SARM gem5 Developers } 81710037SARM gem5 Developers return (ok); 81810037SARM gem5 Developers} 81910037SARM gem5 Developers 82010037SARM gem5 Developersbool 82110037SARM gem5 DevelopersSPAlignmentCheckEnabled(ThreadContext* tc) 82210037SARM gem5 Developers{ 82310037SARM gem5 Developers switch (opModeToEL(currOpMode(tc))) { 82410037SARM gem5 Developers case EL3: 82510037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa; 82610037SARM gem5 Developers case EL2: 82710037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa; 82810037SARM gem5 Developers case EL1: 82910037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa; 83010037SARM gem5 Developers case EL0: 83110037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0; 83210037SARM gem5 Developers default: 83310037SARM gem5 Developers panic("Invalid exception level"); 83410037SARM gem5 Developers break; 83510037SARM gem5 Developers } 83610037SARM gem5 Developers} 83710037SARM gem5 Developers 83810037SARM gem5 Developersint 83910037SARM gem5 DevelopersdecodePhysAddrRange64(uint8_t pa_enc) 84010037SARM gem5 Developers{ 84110037SARM gem5 Developers switch (pa_enc) { 84210037SARM gem5 Developers case 0x0: 84310037SARM gem5 Developers return 32; 84410037SARM gem5 Developers case 0x1: 84510037SARM gem5 Developers return 36; 84610037SARM gem5 Developers case 0x2: 84710037SARM gem5 Developers return 40; 84810037SARM gem5 Developers case 0x3: 84910037SARM gem5 Developers return 42; 85010037SARM gem5 Developers case 0x4: 85110037SARM gem5 Developers return 44; 85210037SARM gem5 Developers case 0x5: 85310037SARM gem5 Developers case 0x6: 85410037SARM gem5 Developers case 0x7: 85510037SARM gem5 Developers return 48; 85610037SARM gem5 Developers default: 85710037SARM gem5 Developers panic("Invalid phys. address range encoding"); 85810037SARM gem5 Developers } 85910037SARM gem5 Developers} 86010037SARM gem5 Developers 86110037SARM gem5 Developersuint8_t 86210037SARM gem5 DevelopersencodePhysAddrRange64(int pa_size) 86310037SARM gem5 Developers{ 86410037SARM gem5 Developers switch (pa_size) { 86510037SARM gem5 Developers case 32: 86610037SARM gem5 Developers return 0x0; 86710037SARM gem5 Developers case 36: 86810037SARM gem5 Developers return 0x1; 86910037SARM gem5 Developers case 40: 87010037SARM gem5 Developers return 0x2; 87110037SARM gem5 Developers case 42: 87210037SARM gem5 Developers return 0x3; 87310037SARM gem5 Developers case 44: 87410037SARM gem5 Developers return 0x4; 87510037SARM gem5 Developers case 48: 87610037SARM gem5 Developers return 0x5; 87710037SARM gem5 Developers default: 87810037SARM gem5 Developers panic("Invalid phys. address range"); 87910037SARM gem5 Developers } 88010037SARM gem5 Developers} 88110037SARM gem5 Developers 8827752SWilliam.Wang@arm.com} // namespace ArmISA 883