utility.cc revision 10338
16757SAli.Saidi@ARM.com/* 210338SCurtis.Dunham@arm.com * Copyright (c) 2009-2014 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 406757SAli.Saidi@ARM.com 416757SAli.Saidi@ARM.com#include "arch/arm/faults.hh" 427707Sgblack@eecs.umich.edu#include "arch/arm/isa_traits.hh" 4310037SARM gem5 Developers#include "arch/arm/system.hh" 448782Sgblack@eecs.umich.edu#include "arch/arm/tlb.hh" 456757SAli.Saidi@ARM.com#include "arch/arm/utility.hh" 468782Sgblack@eecs.umich.edu#include "arch/arm/vtophys.hh" 478887Sgeoffrey.blake@arm.com#include "cpu/checker/cpu.hh" 488886SAli.Saidi@ARM.com#include "cpu/base.hh" 496757SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 508706Sandreas.hansson@arm.com#include "mem/fs_translating_port_proxy.hh" 518782Sgblack@eecs.umich.edu#include "sim/full_system.hh" 527749SAli.Saidi@ARM.com 536735Sgblack@eecs.umich.edunamespace ArmISA { 546735Sgblack@eecs.umich.edu 556735Sgblack@eecs.umich.eduvoid 566735Sgblack@eecs.umich.eduinitCPU(ThreadContext *tc, int cpuId) 576735Sgblack@eecs.umich.edu{ 586735Sgblack@eecs.umich.edu // Reset CP15?? What does that mean -- ali 599058Satgutier@umich.edu 606735Sgblack@eecs.umich.edu // FPEXC.EN = 0 618886SAli.Saidi@ARM.com 626757SAli.Saidi@ARM.com static Fault reset = new Reset; 638286SAli.Saidi@ARM.com reset->invoke(tc); 646735Sgblack@eecs.umich.edu} 656735Sgblack@eecs.umich.edu 667707Sgblack@eecs.umich.eduuint64_t 677707Sgblack@eecs.umich.edugetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 687707Sgblack@eecs.umich.edu{ 698806Sgblack@eecs.umich.edu if (!FullSystem) { 708806Sgblack@eecs.umich.edu panic("getArgument() only implemented for full system mode.\n"); 718806Sgblack@eecs.umich.edu M5_DUMMY_RETURN 728806Sgblack@eecs.umich.edu } 738706Sandreas.hansson@arm.com 747693SAli.Saidi@ARM.com if (fp) 757693SAli.Saidi@ARM.com panic("getArgument(): Floating point arguments not implemented\n"); 767693SAli.Saidi@ARM.com 7710037SARM gem5 Developers if (inAArch64(tc)) { 7810037SARM gem5 Developers if (size == (uint16_t)(-1)) 7910037SARM gem5 Developers size = sizeof(uint64_t); 8010037SARM gem5 Developers 8110037SARM gem5 Developers if (number < 8 /*NumArgumentRegs64*/) { 8210037SARM gem5 Developers return tc->readIntReg(number); 837693SAli.Saidi@ARM.com } else { 8410037SARM gem5 Developers panic("getArgument(): No support reading stack args for AArch64\n"); 857693SAli.Saidi@ARM.com } 867693SAli.Saidi@ARM.com } else { 8710037SARM gem5 Developers if (size == (uint16_t)(-1)) 8810318Sandreas.hansson@arm.com // todo: should this not be sizeof(uint32_t) rather? 8910037SARM gem5 Developers size = ArmISA::MachineBytes; 9010037SARM gem5 Developers 9110037SARM gem5 Developers if (number < NumArgumentRegs) { 9210037SARM gem5 Developers // If the argument is 64 bits, it must be in an even regiser 9310037SARM gem5 Developers // number. Increment the number here if it isn't even. 9410037SARM gem5 Developers if (size == sizeof(uint64_t)) { 9510037SARM gem5 Developers if ((number % 2) != 0) 9610037SARM gem5 Developers number++; 9710037SARM gem5 Developers // Read the two halves of the data. Number is inc here to 9810037SARM gem5 Developers // get the second half of the 64 bit reg. 9910037SARM gem5 Developers uint64_t tmp; 10010037SARM gem5 Developers tmp = tc->readIntReg(number++); 10110037SARM gem5 Developers tmp |= tc->readIntReg(number) << 32; 10210037SARM gem5 Developers return tmp; 10310037SARM gem5 Developers } else { 10410037SARM gem5 Developers return tc->readIntReg(number); 10510037SARM gem5 Developers } 10610037SARM gem5 Developers } else { 10710037SARM gem5 Developers Addr sp = tc->readIntReg(StackPointerReg); 10810037SARM gem5 Developers FSTranslatingPortProxy &vp = tc->getVirtProxy(); 10910037SARM gem5 Developers uint64_t arg; 11010037SARM gem5 Developers if (size == sizeof(uint64_t)) { 11110037SARM gem5 Developers // If the argument is even it must be aligned 11210037SARM gem5 Developers if ((number % 2) != 0) 11310037SARM gem5 Developers number++; 11410037SARM gem5 Developers arg = vp.read<uint64_t>(sp + 11510037SARM gem5 Developers (number-NumArgumentRegs) * sizeof(uint32_t)); 11610037SARM gem5 Developers // since two 32 bit args == 1 64 bit arg, increment number 1177693SAli.Saidi@ARM.com number++; 11810037SARM gem5 Developers } else { 11910037SARM gem5 Developers arg = vp.read<uint32_t>(sp + 12010037SARM gem5 Developers (number-NumArgumentRegs) * sizeof(uint32_t)); 12110037SARM gem5 Developers } 12210037SARM gem5 Developers return arg; 1237693SAli.Saidi@ARM.com } 1247650SAli.Saidi@ARM.com } 12510037SARM gem5 Developers panic("getArgument() should always return\n"); 1266757SAli.Saidi@ARM.com} 1276757SAli.Saidi@ARM.com 1287693SAli.Saidi@ARM.comvoid 1297693SAli.Saidi@ARM.comskipFunction(ThreadContext *tc) 1307693SAli.Saidi@ARM.com{ 1319920Syasuko.eckert@amd.com PCState newPC = tc->pcState(); 13210037SARM gem5 Developers if (inAArch64(tc)) { 13310037SARM gem5 Developers newPC.set(tc->readIntReg(INTREG_X30)); 13410037SARM gem5 Developers } else { 13510037SARM gem5 Developers newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1)); 13610037SARM gem5 Developers } 1378887Sgeoffrey.blake@arm.com 1388887Sgeoffrey.blake@arm.com CheckerCPU *checker = tc->getCheckerCpuPtr(); 1398887Sgeoffrey.blake@arm.com if (checker) { 1408887Sgeoffrey.blake@arm.com tc->pcStateNoRecord(newPC); 1418887Sgeoffrey.blake@arm.com } else { 1428887Sgeoffrey.blake@arm.com tc->pcState(newPC); 1438887Sgeoffrey.blake@arm.com } 1447693SAli.Saidi@ARM.com} 1457693SAli.Saidi@ARM.com 1467748SAli.Saidi@ARM.comvoid 1477748SAli.Saidi@ARM.comcopyRegs(ThreadContext *src, ThreadContext *dest) 1487748SAli.Saidi@ARM.com{ 1499920Syasuko.eckert@amd.com for (int i = 0; i < NumIntRegs; i++) 1509431SAndreas.Sandberg@ARM.com dest->setIntRegFlat(i, src->readIntRegFlat(i)); 1518208SAli.Saidi@ARM.com 1529920Syasuko.eckert@amd.com for (int i = 0; i < NumFloatRegs; i++) 1539431SAndreas.Sandberg@ARM.com dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 1548208SAli.Saidi@ARM.com 15510338SCurtis.Dunham@arm.com for (int i = 0; i < NumCCRegs; i++) 15610338SCurtis.Dunham@arm.com dest->setCCReg(i, src->readCCReg(i)); 1579920Syasuko.eckert@amd.com 1589920Syasuko.eckert@amd.com for (int i = 0; i < NumMiscRegs; i++) 1597748SAli.Saidi@ARM.com dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 1606759SAli.Saidi@ARM.com 1617748SAli.Saidi@ARM.com // setMiscReg "with effect" will set the misc register mapping correctly. 1627748SAli.Saidi@ARM.com // e.g. updateRegMap(val) 1637748SAli.Saidi@ARM.com dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR)); 1647748SAli.Saidi@ARM.com 1657749SAli.Saidi@ARM.com // Copy over the PC State 1667748SAli.Saidi@ARM.com dest->pcState(src->pcState()); 1677749SAli.Saidi@ARM.com 1687749SAli.Saidi@ARM.com // Invalidate the tlb misc register cache 1697749SAli.Saidi@ARM.com dest->getITBPtr()->invalidateMiscReg(); 1707749SAli.Saidi@ARM.com dest->getDTBPtr()->invalidateMiscReg(); 1716759SAli.Saidi@ARM.com} 1727752SWilliam.Wang@arm.com 17310037SARM gem5 Developersbool 17410037SARM gem5 DevelopersinSecureState(ThreadContext *tc) 17510037SARM gem5 Developers{ 17610037SARM gem5 Developers SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) : 17710037SARM gem5 Developers tc->readMiscReg(MISCREG_SCR); 17810037SARM gem5 Developers return ArmSystem::haveSecurity(tc) && inSecureState( 17910037SARM gem5 Developers scr, tc->readMiscReg(MISCREG_CPSR)); 18010037SARM gem5 Developers} 18110037SARM gem5 Developers 18210037SARM gem5 Developersbool 18310037SARM gem5 DevelopersinAArch64(ThreadContext *tc) 18410037SARM gem5 Developers{ 18510037SARM gem5 Developers CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 18610037SARM gem5 Developers return opModeIs64((OperatingMode) (uint8_t) cpsr.mode); 18710037SARM gem5 Developers} 18810037SARM gem5 Developers 18910037SARM gem5 Developersbool 19010037SARM gem5 DeveloperslongDescFormatInUse(ThreadContext *tc) 19110037SARM gem5 Developers{ 19210037SARM gem5 Developers TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR); 19310037SARM gem5 Developers return ArmSystem::haveLPAE(tc) && ttbcr.eae; 19410037SARM gem5 Developers} 19510037SARM gem5 Developers 19610037SARM gem5 Developersuint32_t 19710037SARM gem5 DevelopersgetMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 19810037SARM gem5 Developers{ 19910190Sakash.bagdia@arm.com // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical 20010190Sakash.bagdia@arm.com // Reference Manual 20110190Sakash.bagdia@arm.com // 20210190Sakash.bagdia@arm.com // bit 31 - Multi-processor extensions available 20310190Sakash.bagdia@arm.com // bit 30 - Uni-processor system 20410190Sakash.bagdia@arm.com // bit 24 - Multi-threaded cores 20510190Sakash.bagdia@arm.com // bit 11-8 - Cluster ID 20610190Sakash.bagdia@arm.com // bit 1-0 - CPU ID 20710190Sakash.bagdia@arm.com // 20810190Sakash.bagdia@arm.com // We deliberately extend both the Cluster ID and CPU ID fields to allow 20910190Sakash.bagdia@arm.com // for simulation of larger systems 21010190Sakash.bagdia@arm.com assert((0 <= tc->cpuId()) && (tc->cpuId() < 256)); 21110190Sakash.bagdia@arm.com assert((0 <= tc->socketId()) && (tc->socketId() < 65536)); 21210037SARM gem5 Developers if (arm_sys->multiProc) { 21310037SARM gem5 Developers return 0x80000000 | // multiprocessor extensions available 21410190Sakash.bagdia@arm.com tc->cpuId() | tc->socketId() << 8; 21510037SARM gem5 Developers } else { 21610037SARM gem5 Developers return 0x80000000 | // multiprocessor extensions available 21710037SARM gem5 Developers 0x40000000 | // in up system 21810190Sakash.bagdia@arm.com tc->cpuId() | tc->socketId() << 8; 21910037SARM gem5 Developers } 22010037SARM gem5 Developers} 22110037SARM gem5 Developers 22210037SARM gem5 Developersbool 22310037SARM gem5 DevelopersELIs64(ThreadContext *tc, ExceptionLevel el) 22410037SARM gem5 Developers{ 22510037SARM gem5 Developers if (ArmSystem::highestEL(tc) == el) 22610037SARM gem5 Developers // Register width is hard-wired 22710037SARM gem5 Developers return ArmSystem::highestELIs64(tc); 22810037SARM gem5 Developers 22910037SARM gem5 Developers switch (el) { 23010037SARM gem5 Developers case EL0: 23110037SARM gem5 Developers return opModeIs64(currOpMode(tc)); 23210037SARM gem5 Developers case EL1: 23310037SARM gem5 Developers { 23410037SARM gem5 Developers // @todo: uncomment this to enable Virtualization 23510037SARM gem5 Developers // if (ArmSystem::haveVirtualization(tc)) { 23610037SARM gem5 Developers // HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 23710037SARM gem5 Developers // return hcr.rw; 23810037SARM gem5 Developers // } 23910037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 24010037SARM gem5 Developers SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 24110037SARM gem5 Developers return scr.rw; 24210037SARM gem5 Developers } 24310037SARM gem5 Developers case EL2: 24410037SARM gem5 Developers { 24510037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 24610037SARM gem5 Developers SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 24710037SARM gem5 Developers return scr.rw; 24810037SARM gem5 Developers } 24910037SARM gem5 Developers default: 25010037SARM gem5 Developers panic("Invalid exception level"); 25110037SARM gem5 Developers break; 25210037SARM gem5 Developers } 25310037SARM gem5 Developers} 25410037SARM gem5 Developers 25510037SARM gem5 Developersbool 25610037SARM gem5 DevelopersisBigEndian64(ThreadContext *tc) 25710037SARM gem5 Developers{ 25810037SARM gem5 Developers switch (opModeToEL(currOpMode(tc))) { 25910037SARM gem5 Developers case EL3: 26010037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee; 26110037SARM gem5 Developers case EL2: 26210037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee; 26310037SARM gem5 Developers case EL1: 26410037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee; 26510037SARM gem5 Developers case EL0: 26610037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e; 26710037SARM gem5 Developers default: 26810037SARM gem5 Developers panic("Invalid exception level"); 26910037SARM gem5 Developers break; 27010037SARM gem5 Developers } 27110037SARM gem5 Developers} 27210037SARM gem5 Developers 27310037SARM gem5 DevelopersAddr 27410037SARM gem5 DeveloperspurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el) 27510037SARM gem5 Developers{ 27610037SARM gem5 Developers TTBCR tcr; 27710037SARM gem5 Developers 27810037SARM gem5 Developers switch (el) { 27910037SARM gem5 Developers case EL0: 28010037SARM gem5 Developers case EL1: 28110037SARM gem5 Developers tcr = tc->readMiscReg(MISCREG_TCR_EL1); 28210037SARM gem5 Developers if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 28310037SARM gem5 Developers return addr | mask(63, 55); 28410037SARM gem5 Developers else if (!bits(addr, 55, 48) && tcr.tbi0) 28510037SARM gem5 Developers return bits(addr,55, 0); 28610037SARM gem5 Developers break; 28710037SARM gem5 Developers // @todo: uncomment this to enable Virtualization 28810037SARM gem5 Developers // case EL2: 28910037SARM gem5 Developers // assert(ArmSystem::haveVirtualization()); 29010037SARM gem5 Developers // tcr = tc->readMiscReg(MISCREG_TCR_EL2); 29110037SARM gem5 Developers // if (tcr.tbi) 29210037SARM gem5 Developers // return addr & mask(56); 29310037SARM gem5 Developers // break; 29410037SARM gem5 Developers case EL3: 29510037SARM gem5 Developers assert(ArmSystem::haveSecurity(tc)); 29610037SARM gem5 Developers tcr = tc->readMiscReg(MISCREG_TCR_EL3); 29710037SARM gem5 Developers if (tcr.tbi) 29810037SARM gem5 Developers return addr & mask(56); 29910037SARM gem5 Developers break; 30010037SARM gem5 Developers default: 30110037SARM gem5 Developers panic("Invalid exception level"); 30210037SARM gem5 Developers break; 30310037SARM gem5 Developers } 30410037SARM gem5 Developers 30510037SARM gem5 Developers return addr; // Nothing to do if this is not a tagged address 30610037SARM gem5 Developers} 30710037SARM gem5 Developers 3087752SWilliam.Wang@arm.comAddr 3097752SWilliam.Wang@arm.comtruncPage(Addr addr) 3107752SWilliam.Wang@arm.com{ 3117752SWilliam.Wang@arm.com return addr & ~(PageBytes - 1); 3127748SAli.Saidi@ARM.com} 3137752SWilliam.Wang@arm.com 3147752SWilliam.Wang@arm.comAddr 3157752SWilliam.Wang@arm.comroundPage(Addr addr) 3167752SWilliam.Wang@arm.com{ 3177752SWilliam.Wang@arm.com return (addr + PageBytes - 1) & ~(PageBytes - 1); 3187752SWilliam.Wang@arm.com} 3197752SWilliam.Wang@arm.com 32010037SARM gem5 Developersbool 32110037SARM gem5 DevelopersmcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 32210037SARM gem5 Developers HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 32310037SARM gem5 Developers{ 32410037SARM gem5 Developers bool isRead; 32510037SARM gem5 Developers uint32_t crm; 32610037SARM gem5 Developers IntRegIndex rt; 32710037SARM gem5 Developers uint32_t crn; 32810037SARM gem5 Developers uint32_t opc1; 32910037SARM gem5 Developers uint32_t opc2; 33010037SARM gem5 Developers bool trapToHype = false; 33110037SARM gem5 Developers 33210037SARM gem5 Developers 33310037SARM gem5 Developers if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 33410037SARM gem5 Developers mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 33510037SARM gem5 Developers trapToHype = ((uint32_t) hstr) & (1 << crn); 33610037SARM gem5 Developers trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12); 33710037SARM gem5 Developers trapToHype |= hcr.tidcp && ( 33810037SARM gem5 Developers ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) || 33910037SARM gem5 Developers ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) || 34010037SARM gem5 Developers ((crn == 11) && ((crm <= 8) || (crm == 15))) ); 34110037SARM gem5 Developers 34210037SARM gem5 Developers if (!trapToHype) { 34310037SARM gem5 Developers switch (unflattenMiscReg(miscReg)) { 34410037SARM gem5 Developers case MISCREG_CPACR: 34510037SARM gem5 Developers trapToHype = hcptr.tcpac; 34610037SARM gem5 Developers break; 34710037SARM gem5 Developers case MISCREG_REVIDR: 34810037SARM gem5 Developers case MISCREG_TCMTR: 34910037SARM gem5 Developers case MISCREG_TLBTR: 35010037SARM gem5 Developers case MISCREG_AIDR: 35110037SARM gem5 Developers trapToHype = hcr.tid1; 35210037SARM gem5 Developers break; 35310037SARM gem5 Developers case MISCREG_CTR: 35410037SARM gem5 Developers case MISCREG_CCSIDR: 35510037SARM gem5 Developers case MISCREG_CLIDR: 35610037SARM gem5 Developers case MISCREG_CSSELR: 35710037SARM gem5 Developers trapToHype = hcr.tid2; 35810037SARM gem5 Developers break; 35910037SARM gem5 Developers case MISCREG_ID_PFR0: 36010037SARM gem5 Developers case MISCREG_ID_PFR1: 36110037SARM gem5 Developers case MISCREG_ID_DFR0: 36210037SARM gem5 Developers case MISCREG_ID_AFR0: 36310037SARM gem5 Developers case MISCREG_ID_MMFR0: 36410037SARM gem5 Developers case MISCREG_ID_MMFR1: 36510037SARM gem5 Developers case MISCREG_ID_MMFR2: 36610037SARM gem5 Developers case MISCREG_ID_MMFR3: 36710037SARM gem5 Developers case MISCREG_ID_ISAR0: 36810037SARM gem5 Developers case MISCREG_ID_ISAR1: 36910037SARM gem5 Developers case MISCREG_ID_ISAR2: 37010037SARM gem5 Developers case MISCREG_ID_ISAR3: 37110037SARM gem5 Developers case MISCREG_ID_ISAR4: 37210037SARM gem5 Developers case MISCREG_ID_ISAR5: 37310037SARM gem5 Developers trapToHype = hcr.tid3; 37410037SARM gem5 Developers break; 37510037SARM gem5 Developers case MISCREG_DCISW: 37610037SARM gem5 Developers case MISCREG_DCCSW: 37710037SARM gem5 Developers case MISCREG_DCCISW: 37810037SARM gem5 Developers trapToHype = hcr.tsw; 37910037SARM gem5 Developers break; 38010037SARM gem5 Developers case MISCREG_DCIMVAC: 38110037SARM gem5 Developers case MISCREG_DCCIMVAC: 38210037SARM gem5 Developers case MISCREG_DCCMVAC: 38310037SARM gem5 Developers trapToHype = hcr.tpc; 38410037SARM gem5 Developers break; 38510037SARM gem5 Developers case MISCREG_ICIMVAU: 38610037SARM gem5 Developers case MISCREG_ICIALLU: 38710037SARM gem5 Developers case MISCREG_ICIALLUIS: 38810037SARM gem5 Developers case MISCREG_DCCMVAU: 38910037SARM gem5 Developers trapToHype = hcr.tpu; 39010037SARM gem5 Developers break; 39110037SARM gem5 Developers case MISCREG_TLBIALLIS: 39210037SARM gem5 Developers case MISCREG_TLBIMVAIS: 39310037SARM gem5 Developers case MISCREG_TLBIASIDIS: 39410037SARM gem5 Developers case MISCREG_TLBIMVAAIS: 39510037SARM gem5 Developers case MISCREG_DTLBIALL: 39610037SARM gem5 Developers case MISCREG_ITLBIALL: 39710037SARM gem5 Developers case MISCREG_DTLBIMVA: 39810037SARM gem5 Developers case MISCREG_ITLBIMVA: 39910037SARM gem5 Developers case MISCREG_DTLBIASID: 40010037SARM gem5 Developers case MISCREG_ITLBIASID: 40110037SARM gem5 Developers case MISCREG_TLBIMVAA: 40210037SARM gem5 Developers case MISCREG_TLBIALL: 40310037SARM gem5 Developers case MISCREG_TLBIMVA: 40410037SARM gem5 Developers case MISCREG_TLBIASID: 40510037SARM gem5 Developers trapToHype = hcr.ttlb; 40610037SARM gem5 Developers break; 40710037SARM gem5 Developers case MISCREG_ACTLR: 40810037SARM gem5 Developers trapToHype = hcr.tac; 40910037SARM gem5 Developers break; 41010037SARM gem5 Developers case MISCREG_SCTLR: 41110037SARM gem5 Developers case MISCREG_TTBR0: 41210037SARM gem5 Developers case MISCREG_TTBR1: 41310037SARM gem5 Developers case MISCREG_TTBCR: 41410037SARM gem5 Developers case MISCREG_DACR: 41510037SARM gem5 Developers case MISCREG_DFSR: 41610037SARM gem5 Developers case MISCREG_IFSR: 41710037SARM gem5 Developers case MISCREG_DFAR: 41810037SARM gem5 Developers case MISCREG_IFAR: 41910037SARM gem5 Developers case MISCREG_ADFSR: 42010037SARM gem5 Developers case MISCREG_AIFSR: 42110037SARM gem5 Developers case MISCREG_PRRR: 42210037SARM gem5 Developers case MISCREG_NMRR: 42310037SARM gem5 Developers case MISCREG_MAIR0: 42410037SARM gem5 Developers case MISCREG_MAIR1: 42510037SARM gem5 Developers case MISCREG_CONTEXTIDR: 42610037SARM gem5 Developers trapToHype = hcr.tvm & !isRead; 42710037SARM gem5 Developers break; 42810037SARM gem5 Developers case MISCREG_PMCR: 42910037SARM gem5 Developers trapToHype = hdcr.tpmcr; 43010037SARM gem5 Developers break; 43110037SARM gem5 Developers // No default action needed 43210037SARM gem5 Developers default: 43310037SARM gem5 Developers break; 43410037SARM gem5 Developers } 43510037SARM gem5 Developers } 43610037SARM gem5 Developers } 43710037SARM gem5 Developers return trapToHype; 43810037SARM gem5 Developers} 43910037SARM gem5 Developers 44010037SARM gem5 Developers 44110037SARM gem5 Developersbool 44210037SARM gem5 DevelopersmcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 44310037SARM gem5 Developers HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 44410037SARM gem5 Developers{ 44510037SARM gem5 Developers bool isRead; 44610037SARM gem5 Developers uint32_t crm; 44710037SARM gem5 Developers IntRegIndex rt; 44810037SARM gem5 Developers uint32_t crn; 44910037SARM gem5 Developers uint32_t opc1; 45010037SARM gem5 Developers uint32_t opc2; 45110037SARM gem5 Developers bool trapToHype = false; 45210037SARM gem5 Developers 45310037SARM gem5 Developers if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 45410037SARM gem5 Developers mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 45510037SARM gem5 Developers inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n", 45610037SARM gem5 Developers crm, crn, opc1, opc2, hdcr, hcptr, hstr); 45710037SARM gem5 Developers trapToHype = hdcr.tda && (opc1 == 0); 45810037SARM gem5 Developers trapToHype |= hcptr.tta && (opc1 == 1); 45910037SARM gem5 Developers if (!trapToHype) { 46010037SARM gem5 Developers switch (unflattenMiscReg(miscReg)) { 46110037SARM gem5 Developers case MISCREG_DBGOSLSR: 46210037SARM gem5 Developers case MISCREG_DBGOSLAR: 46310037SARM gem5 Developers case MISCREG_DBGOSDLR: 46410037SARM gem5 Developers case MISCREG_DBGPRCR: 46510037SARM gem5 Developers trapToHype = hdcr.tdosa; 46610037SARM gem5 Developers break; 46710037SARM gem5 Developers case MISCREG_DBGDRAR: 46810037SARM gem5 Developers case MISCREG_DBGDSAR: 46910037SARM gem5 Developers trapToHype = hdcr.tdra; 47010037SARM gem5 Developers break; 47110037SARM gem5 Developers case MISCREG_JIDR: 47210037SARM gem5 Developers trapToHype = hcr.tid0; 47310037SARM gem5 Developers break; 47410037SARM gem5 Developers case MISCREG_JOSCR: 47510037SARM gem5 Developers case MISCREG_JMCR: 47610037SARM gem5 Developers trapToHype = hstr.tjdbx; 47710037SARM gem5 Developers break; 47810037SARM gem5 Developers case MISCREG_TEECR: 47910037SARM gem5 Developers case MISCREG_TEEHBR: 48010037SARM gem5 Developers trapToHype = hstr.ttee; 48110037SARM gem5 Developers break; 48210037SARM gem5 Developers // No default action needed 48310037SARM gem5 Developers default: 48410037SARM gem5 Developers break; 48510037SARM gem5 Developers } 48610037SARM gem5 Developers } 48710037SARM gem5 Developers } 48810037SARM gem5 Developers return trapToHype; 48910037SARM gem5 Developers} 49010037SARM gem5 Developers 49110037SARM gem5 Developersbool 49210037SARM gem5 DevelopersmcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, 49310037SARM gem5 Developers HCR hcr, uint32_t iss) 49410037SARM gem5 Developers{ 49510037SARM gem5 Developers uint32_t crm; 49610037SARM gem5 Developers IntRegIndex rt; 49710037SARM gem5 Developers uint32_t crn; 49810037SARM gem5 Developers uint32_t opc1; 49910037SARM gem5 Developers uint32_t opc2; 50010037SARM gem5 Developers bool isRead; 50110037SARM gem5 Developers bool trapToHype = false; 50210037SARM gem5 Developers 50310037SARM gem5 Developers if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 50410037SARM gem5 Developers // This is technically the wrong function, but we can re-use it for 50510037SARM gem5 Developers // the moment because we only need one field, which overlaps with the 50610037SARM gem5 Developers // mcrmrc layout 50710037SARM gem5 Developers mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 50810037SARM gem5 Developers trapToHype = ((uint32_t) hstr) & (1 << crm); 50910037SARM gem5 Developers 51010037SARM gem5 Developers if (!trapToHype) { 51110037SARM gem5 Developers switch (unflattenMiscReg(miscReg)) { 51210037SARM gem5 Developers case MISCREG_SCTLR: 51310037SARM gem5 Developers case MISCREG_TTBR0: 51410037SARM gem5 Developers case MISCREG_TTBR1: 51510037SARM gem5 Developers case MISCREG_TTBCR: 51610037SARM gem5 Developers case MISCREG_DACR: 51710037SARM gem5 Developers case MISCREG_DFSR: 51810037SARM gem5 Developers case MISCREG_IFSR: 51910037SARM gem5 Developers case MISCREG_DFAR: 52010037SARM gem5 Developers case MISCREG_IFAR: 52110037SARM gem5 Developers case MISCREG_ADFSR: 52210037SARM gem5 Developers case MISCREG_AIFSR: 52310037SARM gem5 Developers case MISCREG_PRRR: 52410037SARM gem5 Developers case MISCREG_NMRR: 52510037SARM gem5 Developers case MISCREG_MAIR0: 52610037SARM gem5 Developers case MISCREG_MAIR1: 52710037SARM gem5 Developers case MISCREG_CONTEXTIDR: 52810037SARM gem5 Developers trapToHype = hcr.tvm & !isRead; 52910037SARM gem5 Developers break; 53010037SARM gem5 Developers // No default action needed 53110037SARM gem5 Developers default: 53210037SARM gem5 Developers break; 53310037SARM gem5 Developers } 53410037SARM gem5 Developers } 53510037SARM gem5 Developers } 53610037SARM gem5 Developers return trapToHype; 53710037SARM gem5 Developers} 53810037SARM gem5 Developers 53910037SARM gem5 Developersbool 54010037SARM gem5 DevelopersmsrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el, 54110037SARM gem5 Developers CPACR cpacr /* CPACR_EL1 */) 54210037SARM gem5 Developers{ 54310037SARM gem5 Developers bool trapToSup = false; 54410037SARM gem5 Developers switch (miscReg) { 54510037SARM gem5 Developers case MISCREG_FPCR: 54610037SARM gem5 Developers case MISCREG_FPSR: 54710037SARM gem5 Developers case MISCREG_FPEXC32_EL2: 54810037SARM gem5 Developers if ((el == EL0 && cpacr.fpen != 0x3) || 54910037SARM gem5 Developers (el == EL1 && !(cpacr.fpen & 0x1))) 55010037SARM gem5 Developers trapToSup = true; 55110037SARM gem5 Developers break; 55210037SARM gem5 Developers default: 55310037SARM gem5 Developers break; 55410037SARM gem5 Developers } 55510037SARM gem5 Developers return trapToSup; 55610037SARM gem5 Developers} 55710037SARM gem5 Developers 55810037SARM gem5 Developersbool 55910037SARM gem5 DevelopersmsrMrs64TrapToHyp(const MiscRegIndex miscReg, bool isRead, 56010037SARM gem5 Developers CPTR cptr /* CPTR_EL2 */, 56110037SARM gem5 Developers HCR hcr /* HCR_EL2 */, 56210037SARM gem5 Developers bool * isVfpNeon) 56310037SARM gem5 Developers{ 56410037SARM gem5 Developers bool trapToHyp = false; 56510037SARM gem5 Developers *isVfpNeon = false; 56610037SARM gem5 Developers 56710037SARM gem5 Developers switch (miscReg) { 56810037SARM gem5 Developers // FP/SIMD regs 56910037SARM gem5 Developers case MISCREG_FPCR: 57010037SARM gem5 Developers case MISCREG_FPSR: 57110037SARM gem5 Developers case MISCREG_FPEXC32_EL2: 57210037SARM gem5 Developers trapToHyp = cptr.tfp; 57310037SARM gem5 Developers *isVfpNeon = true; 57410037SARM gem5 Developers break; 57510037SARM gem5 Developers // CPACR 57610037SARM gem5 Developers case MISCREG_CPACR_EL1: 57710037SARM gem5 Developers trapToHyp = cptr.tcpac; 57810037SARM gem5 Developers break; 57910037SARM gem5 Developers // Virtual memory control regs 58010037SARM gem5 Developers case MISCREG_SCTLR_EL1: 58110037SARM gem5 Developers case MISCREG_TTBR0_EL1: 58210037SARM gem5 Developers case MISCREG_TTBR1_EL1: 58310037SARM gem5 Developers case MISCREG_TCR_EL1: 58410037SARM gem5 Developers case MISCREG_ESR_EL1: 58510037SARM gem5 Developers case MISCREG_FAR_EL1: 58610037SARM gem5 Developers case MISCREG_AFSR0_EL1: 58710037SARM gem5 Developers case MISCREG_AFSR1_EL1: 58810037SARM gem5 Developers case MISCREG_MAIR_EL1: 58910037SARM gem5 Developers case MISCREG_AMAIR_EL1: 59010037SARM gem5 Developers case MISCREG_CONTEXTIDR_EL1: 59110037SARM gem5 Developers trapToHyp = (hcr.trvm && isRead) || (hcr.tvm && !isRead); 59210037SARM gem5 Developers break; 59310037SARM gem5 Developers // TLB maintenance instructions 59410037SARM gem5 Developers case MISCREG_TLBI_VMALLE1: 59510037SARM gem5 Developers case MISCREG_TLBI_VAE1_Xt: 59610037SARM gem5 Developers case MISCREG_TLBI_ASIDE1_Xt: 59710037SARM gem5 Developers case MISCREG_TLBI_VAAE1_Xt: 59810037SARM gem5 Developers case MISCREG_TLBI_VALE1_Xt: 59910037SARM gem5 Developers case MISCREG_TLBI_VAALE1_Xt: 60010037SARM gem5 Developers case MISCREG_TLBI_VMALLE1IS: 60110037SARM gem5 Developers case MISCREG_TLBI_VAE1IS_Xt: 60210037SARM gem5 Developers case MISCREG_TLBI_ASIDE1IS_Xt: 60310037SARM gem5 Developers case MISCREG_TLBI_VAAE1IS_Xt: 60410037SARM gem5 Developers case MISCREG_TLBI_VALE1IS_Xt: 60510037SARM gem5 Developers case MISCREG_TLBI_VAALE1IS_Xt: 60610037SARM gem5 Developers trapToHyp = hcr.ttlb; 60710037SARM gem5 Developers break; 60810037SARM gem5 Developers // Cache maintenance instructions to the point of unification 60910037SARM gem5 Developers case MISCREG_IC_IVAU_Xt: 61010037SARM gem5 Developers case MISCREG_ICIALLU: 61110037SARM gem5 Developers case MISCREG_ICIALLUIS: 61210037SARM gem5 Developers case MISCREG_DC_CVAU_Xt: 61310037SARM gem5 Developers trapToHyp = hcr.tpu; 61410037SARM gem5 Developers break; 61510037SARM gem5 Developers // Data/Unified cache maintenance instructions to the point of coherency 61610037SARM gem5 Developers case MISCREG_DC_IVAC_Xt: 61710037SARM gem5 Developers case MISCREG_DC_CIVAC_Xt: 61810037SARM gem5 Developers case MISCREG_DC_CVAC_Xt: 61910037SARM gem5 Developers trapToHyp = hcr.tpc; 62010037SARM gem5 Developers break; 62110037SARM gem5 Developers // Data/Unified cache maintenance instructions by set/way 62210037SARM gem5 Developers case MISCREG_DC_ISW_Xt: 62310037SARM gem5 Developers case MISCREG_DC_CSW_Xt: 62410037SARM gem5 Developers case MISCREG_DC_CISW_Xt: 62510037SARM gem5 Developers trapToHyp = hcr.tsw; 62610037SARM gem5 Developers break; 62710037SARM gem5 Developers // ACTLR 62810037SARM gem5 Developers case MISCREG_ACTLR_EL1: 62910037SARM gem5 Developers trapToHyp = hcr.tacr; 63010037SARM gem5 Developers break; 63110037SARM gem5 Developers 63210037SARM gem5 Developers // @todo: Trap implementation-dependent functionality based on 63310037SARM gem5 Developers // hcr.tidcp 63410037SARM gem5 Developers 63510037SARM gem5 Developers // ID regs, group 3 63610037SARM gem5 Developers case MISCREG_ID_PFR0_EL1: 63710037SARM gem5 Developers case MISCREG_ID_PFR1_EL1: 63810037SARM gem5 Developers case MISCREG_ID_DFR0_EL1: 63910037SARM gem5 Developers case MISCREG_ID_AFR0_EL1: 64010037SARM gem5 Developers case MISCREG_ID_MMFR0_EL1: 64110037SARM gem5 Developers case MISCREG_ID_MMFR1_EL1: 64210037SARM gem5 Developers case MISCREG_ID_MMFR2_EL1: 64310037SARM gem5 Developers case MISCREG_ID_MMFR3_EL1: 64410037SARM gem5 Developers case MISCREG_ID_ISAR0_EL1: 64510037SARM gem5 Developers case MISCREG_ID_ISAR1_EL1: 64610037SARM gem5 Developers case MISCREG_ID_ISAR2_EL1: 64710037SARM gem5 Developers case MISCREG_ID_ISAR3_EL1: 64810037SARM gem5 Developers case MISCREG_ID_ISAR4_EL1: 64910037SARM gem5 Developers case MISCREG_ID_ISAR5_EL1: 65010037SARM gem5 Developers case MISCREG_MVFR0_EL1: 65110037SARM gem5 Developers case MISCREG_MVFR1_EL1: 65210037SARM gem5 Developers case MISCREG_MVFR2_EL1: 65310037SARM gem5 Developers case MISCREG_ID_AA64PFR0_EL1: 65410037SARM gem5 Developers case MISCREG_ID_AA64PFR1_EL1: 65510037SARM gem5 Developers case MISCREG_ID_AA64DFR0_EL1: 65610037SARM gem5 Developers case MISCREG_ID_AA64DFR1_EL1: 65710037SARM gem5 Developers case MISCREG_ID_AA64ISAR0_EL1: 65810037SARM gem5 Developers case MISCREG_ID_AA64ISAR1_EL1: 65910037SARM gem5 Developers case MISCREG_ID_AA64MMFR0_EL1: 66010037SARM gem5 Developers case MISCREG_ID_AA64MMFR1_EL1: 66110037SARM gem5 Developers case MISCREG_ID_AA64AFR0_EL1: 66210037SARM gem5 Developers case MISCREG_ID_AA64AFR1_EL1: 66310037SARM gem5 Developers assert(isRead); 66410037SARM gem5 Developers trapToHyp = hcr.tid3; 66510037SARM gem5 Developers break; 66610037SARM gem5 Developers // ID regs, group 2 66710037SARM gem5 Developers case MISCREG_CTR_EL0: 66810037SARM gem5 Developers case MISCREG_CCSIDR_EL1: 66910037SARM gem5 Developers case MISCREG_CLIDR_EL1: 67010037SARM gem5 Developers case MISCREG_CSSELR_EL1: 67110037SARM gem5 Developers trapToHyp = hcr.tid2; 67210037SARM gem5 Developers break; 67310037SARM gem5 Developers // ID regs, group 1 67410037SARM gem5 Developers case MISCREG_AIDR_EL1: 67510037SARM gem5 Developers case MISCREG_REVIDR_EL1: 67610037SARM gem5 Developers assert(isRead); 67710037SARM gem5 Developers trapToHyp = hcr.tid1; 67810037SARM gem5 Developers break; 67910037SARM gem5 Developers default: 68010037SARM gem5 Developers break; 68110037SARM gem5 Developers } 68210037SARM gem5 Developers return trapToHyp; 68310037SARM gem5 Developers} 68410037SARM gem5 Developers 68510037SARM gem5 Developersbool 68610037SARM gem5 DevelopersmsrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */, 68710037SARM gem5 Developers ExceptionLevel el, bool * isVfpNeon) 68810037SARM gem5 Developers{ 68910037SARM gem5 Developers bool trapToMon = false; 69010037SARM gem5 Developers *isVfpNeon = false; 69110037SARM gem5 Developers 69210037SARM gem5 Developers switch (miscReg) { 69310037SARM gem5 Developers // FP/SIMD regs 69410037SARM gem5 Developers case MISCREG_FPCR: 69510037SARM gem5 Developers case MISCREG_FPSR: 69610037SARM gem5 Developers case MISCREG_FPEXC32_EL2: 69710037SARM gem5 Developers trapToMon = cptr.tfp; 69810037SARM gem5 Developers *isVfpNeon = true; 69910037SARM gem5 Developers break; 70010037SARM gem5 Developers // CPACR, CPTR 70110037SARM gem5 Developers case MISCREG_CPACR_EL1: 70210037SARM gem5 Developers if (el == EL1) { 70310037SARM gem5 Developers trapToMon = cptr.tcpac; 70410037SARM gem5 Developers } 70510037SARM gem5 Developers break; 70610037SARM gem5 Developers case MISCREG_CPTR_EL2: 70710037SARM gem5 Developers if (el == EL2) { 70810037SARM gem5 Developers trapToMon = cptr.tcpac; 70910037SARM gem5 Developers } 71010037SARM gem5 Developers break; 71110037SARM gem5 Developers default: 71210037SARM gem5 Developers break; 71310037SARM gem5 Developers } 71410037SARM gem5 Developers return trapToMon; 71510037SARM gem5 Developers} 71610037SARM gem5 Developers 71710037SARM gem5 Developersbool 71810037SARM gem5 DevelopersdecodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, 71910037SARM gem5 Developers CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity) 72010037SARM gem5 Developers{ 72110103Sstephan.diestelhorst@arm.com OperatingMode mode = MODE_UNDEFINED; 72210037SARM gem5 Developers bool ok = true; 72310037SARM gem5 Developers 72410037SARM gem5 Developers // R mostly indicates if its a int register or a misc reg, we override 72510037SARM gem5 Developers // below if the few corner cases 72610037SARM gem5 Developers isIntReg = !r; 72710037SARM gem5 Developers // Loosely based on ARM ARM issue C section B9.3.10 72810037SARM gem5 Developers if (r) { 72910037SARM gem5 Developers switch (sysM) 73010037SARM gem5 Developers { 73110037SARM gem5 Developers case 0xE: 73210037SARM gem5 Developers regIdx = MISCREG_SPSR_FIQ; 73310037SARM gem5 Developers mode = MODE_FIQ; 73410037SARM gem5 Developers break; 73510037SARM gem5 Developers case 0x10: 73610037SARM gem5 Developers regIdx = MISCREG_SPSR_IRQ; 73710037SARM gem5 Developers mode = MODE_IRQ; 73810037SARM gem5 Developers break; 73910037SARM gem5 Developers case 0x12: 74010037SARM gem5 Developers regIdx = MISCREG_SPSR_SVC; 74110037SARM gem5 Developers mode = MODE_SVC; 74210037SARM gem5 Developers break; 74310037SARM gem5 Developers case 0x14: 74410037SARM gem5 Developers regIdx = MISCREG_SPSR_ABT; 74510037SARM gem5 Developers mode = MODE_ABORT; 74610037SARM gem5 Developers break; 74710037SARM gem5 Developers case 0x16: 74810037SARM gem5 Developers regIdx = MISCREG_SPSR_UND; 74910037SARM gem5 Developers mode = MODE_UNDEFINED; 75010037SARM gem5 Developers break; 75110037SARM gem5 Developers case 0x1C: 75210037SARM gem5 Developers regIdx = MISCREG_SPSR_MON; 75310037SARM gem5 Developers mode = MODE_MON; 75410037SARM gem5 Developers break; 75510037SARM gem5 Developers case 0x1E: 75610037SARM gem5 Developers regIdx = MISCREG_SPSR_HYP; 75710037SARM gem5 Developers mode = MODE_HYP; 75810037SARM gem5 Developers break; 75910037SARM gem5 Developers default: 76010037SARM gem5 Developers ok = false; 76110037SARM gem5 Developers break; 76210037SARM gem5 Developers } 76310037SARM gem5 Developers } else { 76410037SARM gem5 Developers int sysM4To3 = bits(sysM, 4, 3); 76510037SARM gem5 Developers 76610037SARM gem5 Developers if (sysM4To3 == 0) { 76710037SARM gem5 Developers mode = MODE_USER; 76810037SARM gem5 Developers regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 76910037SARM gem5 Developers } else if (sysM4To3 == 1) { 77010037SARM gem5 Developers mode = MODE_FIQ; 77110037SARM gem5 Developers regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 77210037SARM gem5 Developers } else if (sysM4To3 == 3) { 77310037SARM gem5 Developers if (bits(sysM, 1) == 0) { 77410037SARM gem5 Developers mode = MODE_MON; 77510037SARM gem5 Developers regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 77610037SARM gem5 Developers } else { 77710037SARM gem5 Developers mode = MODE_HYP; 77810037SARM gem5 Developers if (bits(sysM, 0) == 1) { 77910037SARM gem5 Developers regIdx = intRegInMode(mode, 13); // R13 in HYP 78010037SARM gem5 Developers } else { 78110037SARM gem5 Developers isIntReg = false; 78210037SARM gem5 Developers regIdx = MISCREG_ELR_HYP; 78310037SARM gem5 Developers } 78410037SARM gem5 Developers } 78510037SARM gem5 Developers } else { // Other Banked registers 78610037SARM gem5 Developers int sysM2 = bits(sysM, 2); 78710037SARM gem5 Developers int sysM1 = bits(sysM, 1); 78810037SARM gem5 Developers 78910037SARM gem5 Developers mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) | 79010037SARM gem5 Developers (1 << 1) | 79110037SARM gem5 Developers ((sysM2 && !sysM1) << 2) | 79210037SARM gem5 Developers ((sysM2 && sysM1) << 3) | 79310037SARM gem5 Developers (1 << 4) ); 79410037SARM gem5 Developers regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 79510037SARM gem5 Developers // Don't flatten the register here. This is going to go through 79610037SARM gem5 Developers // setIntReg() which will do the flattening 79710037SARM gem5 Developers ok &= mode != cpsr.mode; 79810037SARM gem5 Developers } 79910037SARM gem5 Developers } 80010037SARM gem5 Developers 80110037SARM gem5 Developers // Check that the requested register is accessable from the current mode 80210037SARM gem5 Developers if (ok && checkSecurity && mode != cpsr.mode) { 80310037SARM gem5 Developers switch (cpsr.mode) 80410037SARM gem5 Developers { 80510037SARM gem5 Developers case MODE_USER: 80610037SARM gem5 Developers ok = false; 80710037SARM gem5 Developers break; 80810037SARM gem5 Developers case MODE_FIQ: 80910037SARM gem5 Developers ok &= mode != MODE_HYP; 81010037SARM gem5 Developers ok &= (mode != MODE_MON) || !scr.ns; 81110037SARM gem5 Developers break; 81210037SARM gem5 Developers case MODE_HYP: 81310037SARM gem5 Developers ok &= mode != MODE_MON; 81410037SARM gem5 Developers ok &= (mode != MODE_FIQ) || !nsacr.rfr; 81510037SARM gem5 Developers break; 81610037SARM gem5 Developers case MODE_IRQ: 81710037SARM gem5 Developers case MODE_SVC: 81810037SARM gem5 Developers case MODE_ABORT: 81910037SARM gem5 Developers case MODE_UNDEFINED: 82010037SARM gem5 Developers case MODE_SYSTEM: 82110037SARM gem5 Developers ok &= mode != MODE_HYP; 82210037SARM gem5 Developers ok &= (mode != MODE_MON) || !scr.ns; 82310037SARM gem5 Developers ok &= (mode != MODE_FIQ) || !nsacr.rfr; 82410037SARM gem5 Developers break; 82510037SARM gem5 Developers // can access everything, no further checks required 82610037SARM gem5 Developers case MODE_MON: 82710037SARM gem5 Developers break; 82810037SARM gem5 Developers default: 82910037SARM gem5 Developers panic("unknown Mode 0x%x\n", cpsr.mode); 83010037SARM gem5 Developers break; 83110037SARM gem5 Developers } 83210037SARM gem5 Developers } 83310037SARM gem5 Developers return (ok); 83410037SARM gem5 Developers} 83510037SARM gem5 Developers 83610037SARM gem5 Developersbool 83710037SARM gem5 DevelopersvfpNeonEnabled(uint32_t &seq, HCPTR hcptr, NSACR nsacr, CPACR cpacr, CPSR cpsr, 83810037SARM gem5 Developers uint32_t &iss, bool &trap, ThreadContext *tc, FPEXC fpexc, 83910037SARM gem5 Developers bool isSIMD) 84010037SARM gem5 Developers{ 84110037SARM gem5 Developers iss = 0; 84210037SARM gem5 Developers trap = false; 84310037SARM gem5 Developers bool undefined = false; 84410037SARM gem5 Developers bool haveSecurity = ArmSystem::haveSecurity(tc); 84510037SARM gem5 Developers bool haveVirtualization = ArmSystem::haveVirtualization(tc); 84610037SARM gem5 Developers bool isSecure = inSecureState(tc); 84710037SARM gem5 Developers 84810037SARM gem5 Developers // Non-secure view of CPACR and HCPTR determines behavior 84910037SARM gem5 Developers // Copy register values 85010037SARM gem5 Developers uint8_t cpacr_cp10 = cpacr.cp10; 85110037SARM gem5 Developers bool cpacr_asedis = cpacr.asedis; 85210037SARM gem5 Developers bool hcptr_cp10 = false; 85310037SARM gem5 Developers bool hcptr_tase = false; 85410037SARM gem5 Developers 85510037SARM gem5 Developers bool cp10_enabled = cpacr.cp10 == 0x3 85610037SARM gem5 Developers || (cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr)); 85710037SARM gem5 Developers 85810037SARM gem5 Developers bool cp11_enabled = cpacr.cp11 == 0x3 85910037SARM gem5 Developers || (cpacr.cp11 == 0x1 && inPrivilegedMode(cpsr)); 86010037SARM gem5 Developers 86110037SARM gem5 Developers if (cp11_enabled) { 86210037SARM gem5 Developers undefined |= !(fpexc.en && cp10_enabled); 86310037SARM gem5 Developers } else { 86410037SARM gem5 Developers undefined |= !(fpexc.en && cp10_enabled && (cpacr.cp11 == cpacr.cp10)); 86510037SARM gem5 Developers } 86610037SARM gem5 Developers 86710037SARM gem5 Developers if (haveVirtualization) { 86810037SARM gem5 Developers hcptr_cp10 = hcptr.tcp10; 86910037SARM gem5 Developers undefined |= hcptr.tcp10 != hcptr.tcp11; 87010037SARM gem5 Developers hcptr_tase = hcptr.tase; 87110037SARM gem5 Developers } 87210037SARM gem5 Developers 87310037SARM gem5 Developers if (haveSecurity) { 87410037SARM gem5 Developers undefined |= nsacr.cp10 != nsacr.cp11; 87510037SARM gem5 Developers if (!isSecure) { 87610037SARM gem5 Developers // Modify register values to the Non-secure view 87710037SARM gem5 Developers if (!nsacr.cp10) { 87810037SARM gem5 Developers cpacr_cp10 = 0; 87910037SARM gem5 Developers if (haveVirtualization) { 88010037SARM gem5 Developers hcptr_cp10 = true; 88110037SARM gem5 Developers } 88210037SARM gem5 Developers } 88310037SARM gem5 Developers if (nsacr.nsasedis) { 88410037SARM gem5 Developers cpacr_asedis = true; 88510037SARM gem5 Developers if (haveVirtualization) { 88610037SARM gem5 Developers hcptr_tase = true; 88710037SARM gem5 Developers } 88810037SARM gem5 Developers } 88910037SARM gem5 Developers } 89010037SARM gem5 Developers } 89110037SARM gem5 Developers 89210037SARM gem5 Developers // Check Coprocessor Access Control Register for permission to use CP10/11. 89310037SARM gem5 Developers if (!haveVirtualization || (cpsr.mode != MODE_HYP)) { 89410037SARM gem5 Developers switch (cpacr_cp10) 89510037SARM gem5 Developers { 89610037SARM gem5 Developers case 0: 89710037SARM gem5 Developers undefined = true; 89810037SARM gem5 Developers break; 89910037SARM gem5 Developers case 1: 90010037SARM gem5 Developers undefined |= inUserMode(cpsr); 90110037SARM gem5 Developers break; 90210037SARM gem5 Developers } 90310037SARM gem5 Developers 90410037SARM gem5 Developers // Check if SIMD operations are disabled 90510037SARM gem5 Developers if (isSIMD && cpacr_asedis) undefined = true; 90610037SARM gem5 Developers } 90710037SARM gem5 Developers 90810037SARM gem5 Developers // If required, check FPEXC enabled bit. 90910037SARM gem5 Developers undefined |= !fpexc.en; 91010037SARM gem5 Developers 91110037SARM gem5 Developers if (haveSecurity && haveVirtualization && !isSecure) { 91210037SARM gem5 Developers if (hcptr_cp10 || (isSIMD && hcptr_tase)) { 91310037SARM gem5 Developers iss = isSIMD ? (1 << 5) : 0xA; 91410037SARM gem5 Developers trap = true; 91510037SARM gem5 Developers } 91610037SARM gem5 Developers } 91710037SARM gem5 Developers 91810037SARM gem5 Developers return (!undefined); 91910037SARM gem5 Developers} 92010037SARM gem5 Developers 92110037SARM gem5 Developersbool 92210037SARM gem5 DevelopersSPAlignmentCheckEnabled(ThreadContext* tc) 92310037SARM gem5 Developers{ 92410037SARM gem5 Developers switch (opModeToEL(currOpMode(tc))) { 92510037SARM gem5 Developers case EL3: 92610037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa; 92710037SARM gem5 Developers case EL2: 92810037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa; 92910037SARM gem5 Developers case EL1: 93010037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa; 93110037SARM gem5 Developers case EL0: 93210037SARM gem5 Developers return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0; 93310037SARM gem5 Developers default: 93410037SARM gem5 Developers panic("Invalid exception level"); 93510037SARM gem5 Developers break; 93610037SARM gem5 Developers } 93710037SARM gem5 Developers} 93810037SARM gem5 Developers 93910037SARM gem5 Developersint 94010037SARM gem5 DevelopersdecodePhysAddrRange64(uint8_t pa_enc) 94110037SARM gem5 Developers{ 94210037SARM gem5 Developers switch (pa_enc) { 94310037SARM gem5 Developers case 0x0: 94410037SARM gem5 Developers return 32; 94510037SARM gem5 Developers case 0x1: 94610037SARM gem5 Developers return 36; 94710037SARM gem5 Developers case 0x2: 94810037SARM gem5 Developers return 40; 94910037SARM gem5 Developers case 0x3: 95010037SARM gem5 Developers return 42; 95110037SARM gem5 Developers case 0x4: 95210037SARM gem5 Developers return 44; 95310037SARM gem5 Developers case 0x5: 95410037SARM gem5 Developers case 0x6: 95510037SARM gem5 Developers case 0x7: 95610037SARM gem5 Developers return 48; 95710037SARM gem5 Developers default: 95810037SARM gem5 Developers panic("Invalid phys. address range encoding"); 95910037SARM gem5 Developers } 96010037SARM gem5 Developers} 96110037SARM gem5 Developers 96210037SARM gem5 Developersuint8_t 96310037SARM gem5 DevelopersencodePhysAddrRange64(int pa_size) 96410037SARM gem5 Developers{ 96510037SARM gem5 Developers switch (pa_size) { 96610037SARM gem5 Developers case 32: 96710037SARM gem5 Developers return 0x0; 96810037SARM gem5 Developers case 36: 96910037SARM gem5 Developers return 0x1; 97010037SARM gem5 Developers case 40: 97110037SARM gem5 Developers return 0x2; 97210037SARM gem5 Developers case 42: 97310037SARM gem5 Developers return 0x3; 97410037SARM gem5 Developers case 44: 97510037SARM gem5 Developers return 0x4; 97610037SARM gem5 Developers case 48: 97710037SARM gem5 Developers return 0x5; 97810037SARM gem5 Developers default: 97910037SARM gem5 Developers panic("Invalid phys. address range"); 98010037SARM gem5 Developers } 98110037SARM gem5 Developers} 98210037SARM gem5 Developers 9837752SWilliam.Wang@arm.com} // namespace ArmISA 984