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{
22814172Sgiacomo.travaglini@arm.com    const ExceptionLevel current_el = currEL(tc);
22913550Sgiacomo.travaglini@arm.com
23013550Sgiacomo.travaglini@arm.com    const bool is_secure = isSecureBelowEL3(tc);
23113550Sgiacomo.travaglini@arm.com
23213550Sgiacomo.travaglini@arm.com    switch (current_el) {
23313550Sgiacomo.travaglini@arm.com      case EL0:
23413550Sgiacomo.travaglini@arm.com        // Note: in MsrMrs instruction we read the register value before
23513550Sgiacomo.travaglini@arm.com        // checking access permissions. This means that EL0 entry must
23613550Sgiacomo.travaglini@arm.com        // be part of the table even if MPIDR is not accessible in user
23713550Sgiacomo.travaglini@arm.com        // mode.
23813550Sgiacomo.travaglini@arm.com        warn_once("Trying to read MPIDR at EL0\n");
23913550Sgiacomo.travaglini@arm.com        M5_FALLTHROUGH;
24013550Sgiacomo.travaglini@arm.com      case EL1:
24113550Sgiacomo.travaglini@arm.com        if (ArmSystem::haveEL(tc, EL2) && !is_secure)
24213550Sgiacomo.travaglini@arm.com            return tc->readMiscReg(MISCREG_VMPIDR_EL2);
24313550Sgiacomo.travaglini@arm.com        else
24413550Sgiacomo.travaglini@arm.com            return getMPIDR(arm_sys, tc);
24513550Sgiacomo.travaglini@arm.com      case EL2:
24613550Sgiacomo.travaglini@arm.com      case EL3:
24713550Sgiacomo.travaglini@arm.com        return getMPIDR(arm_sys, tc);
24813550Sgiacomo.travaglini@arm.com      default:
24913550Sgiacomo.travaglini@arm.com        panic("Invalid EL for reading MPIDR register\n");
25013550Sgiacomo.travaglini@arm.com    }
25113550Sgiacomo.travaglini@arm.com}
25213550Sgiacomo.travaglini@arm.com
25313585Sgabeblack@google.comRegVal
25410037SARM gem5 DevelopersgetMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
25510037SARM gem5 Developers{
25610190Sakash.bagdia@arm.com    // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
25710190Sakash.bagdia@arm.com    // Reference Manual
25810190Sakash.bagdia@arm.com    //
25910190Sakash.bagdia@arm.com    // bit   31 - Multi-processor extensions available
26010190Sakash.bagdia@arm.com    // bit   30 - Uni-processor system
26110190Sakash.bagdia@arm.com    // bit   24 - Multi-threaded cores
26210190Sakash.bagdia@arm.com    // bit 11-8 - Cluster ID
26310190Sakash.bagdia@arm.com    // bit  1-0 - CPU ID
26410190Sakash.bagdia@arm.com    //
26510190Sakash.bagdia@arm.com    // We deliberately extend both the Cluster ID and CPU ID fields to allow
26610190Sakash.bagdia@arm.com    // for simulation of larger systems
26710190Sakash.bagdia@arm.com    assert((0 <= tc->cpuId()) && (tc->cpuId() < 256));
26811294Sandreas.hansson@arm.com    assert(tc->socketId() < 65536);
26911149Smitch.hayenga@arm.com    if (arm_sys->multiThread) {
27011149Smitch.hayenga@arm.com       return 0x80000000 | // multiprocessor extensions available
27112712Sgiacomo.travaglini@arm.com              0x01000000 | // multi-threaded cores
27211149Smitch.hayenga@arm.com              tc->contextId();
27311149Smitch.hayenga@arm.com    } else if (arm_sys->multiProc) {
27410037SARM gem5 Developers       return 0x80000000 | // multiprocessor extensions available
27510190Sakash.bagdia@arm.com              tc->cpuId() | tc->socketId() << 8;
27610037SARM gem5 Developers    } else {
27710037SARM gem5 Developers       return 0x80000000 |  // multiprocessor extensions available
27810037SARM gem5 Developers              0x40000000 |  // in up system
27910190Sakash.bagdia@arm.com              tc->cpuId() | tc->socketId() << 8;
28010037SARM gem5 Developers    }
28110037SARM gem5 Developers}
28210037SARM gem5 Developers
28310037SARM gem5 Developersbool
28410037SARM gem5 DevelopersELIs64(ThreadContext *tc, ExceptionLevel el)
28510037SARM gem5 Developers{
28612494Schuan.zhu@arm.com    return !ELIs32(tc, el);
28712494Schuan.zhu@arm.com}
28810037SARM gem5 Developers
28912494Schuan.zhu@arm.combool
29012494Schuan.zhu@arm.comELIs32(ThreadContext *tc, ExceptionLevel el)
29112494Schuan.zhu@arm.com{
29212496Sgiacomo.travaglini@arm.com    bool known, aarch32;
29312496Sgiacomo.travaglini@arm.com    std::tie(known, aarch32) = ELUsingAArch32K(tc, el);
29412496Sgiacomo.travaglini@arm.com    panic_if(!known, "EL state is UNKNOWN");
29512496Sgiacomo.travaglini@arm.com    return aarch32;
29612496Sgiacomo.travaglini@arm.com}
29712496Sgiacomo.travaglini@arm.com
29813759Sgiacomo.gabrielli@arm.combool
29913759Sgiacomo.gabrielli@arm.comELIsInHost(ThreadContext *tc, ExceptionLevel el)
30013759Sgiacomo.gabrielli@arm.com{
30113759Sgiacomo.gabrielli@arm.com    if (!ArmSystem::haveVirtualization(tc)) {
30213759Sgiacomo.gabrielli@arm.com        return false;
30313759Sgiacomo.gabrielli@arm.com    }
30413759Sgiacomo.gabrielli@arm.com    HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
30513759Sgiacomo.gabrielli@arm.com    return (!isSecureBelowEL3(tc) && !ELIs32(tc, EL2) && hcr.e2h == 1 &&
30613759Sgiacomo.gabrielli@arm.com            (el == EL2 || (el == EL0 && hcr.tge == 1)));
30713759Sgiacomo.gabrielli@arm.com}
30813759Sgiacomo.gabrielli@arm.com
30912496Sgiacomo.travaglini@arm.comstd::pair<bool, bool>
31012496Sgiacomo.travaglini@arm.comELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
31112496Sgiacomo.travaglini@arm.com{
31212494Schuan.zhu@arm.com    // Return true if the specified EL is in aarch32 state.
31312494Schuan.zhu@arm.com    const bool have_el3 = ArmSystem::haveSecurity(tc);
31412494Schuan.zhu@arm.com    const bool have_el2 = ArmSystem::haveVirtualization(tc);
31512494Schuan.zhu@arm.com
31612494Schuan.zhu@arm.com    panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist");
31712494Schuan.zhu@arm.com    panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist");
31812494Schuan.zhu@arm.com
31912496Sgiacomo.travaglini@arm.com    bool known, aarch32;
32012496Sgiacomo.travaglini@arm.com    known = aarch32 = false;
32112496Sgiacomo.travaglini@arm.com    if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) {
32212496Sgiacomo.travaglini@arm.com        // Target EL is the highest one in a system where
32312496Sgiacomo.travaglini@arm.com        // the highest is using AArch64.
32412496Sgiacomo.travaglini@arm.com        known = true; aarch32 = false;
32512494Schuan.zhu@arm.com    } else if (!ArmSystem::highestELIs64(tc)) {
32612496Sgiacomo.travaglini@arm.com        // All ELs are using AArch32:
32712496Sgiacomo.travaglini@arm.com        known = true; aarch32 = true;
32812494Schuan.zhu@arm.com    } else {
32912494Schuan.zhu@arm.com        SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
33012494Schuan.zhu@arm.com        bool aarch32_below_el3 = (have_el3 && scr.rw == 0);
33112494Schuan.zhu@arm.com
33212494Schuan.zhu@arm.com        HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
33312494Schuan.zhu@arm.com        bool aarch32_at_el1 = (aarch32_below_el3
33412495Sgiacomo.travaglini@arm.com                               || (have_el2
33512495Sgiacomo.travaglini@arm.com                               && !isSecureBelowEL3(tc) && hcr.rw == 0));
33612494Schuan.zhu@arm.com
33712494Schuan.zhu@arm.com        // Only know if EL0 using AArch32 from PSTATE
33812494Schuan.zhu@arm.com        if (el == EL0 && !aarch32_at_el1) {
33912496Sgiacomo.travaglini@arm.com            // EL0 controlled by PSTATE
34012494Schuan.zhu@arm.com            CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
34112496Sgiacomo.travaglini@arm.com
34214171Sgiacomo.travaglini@arm.com            known = (currEL(tc) == EL0);
34312496Sgiacomo.travaglini@arm.com            aarch32 = (cpsr.width == 1);
34412494Schuan.zhu@arm.com        } else {
34512496Sgiacomo.travaglini@arm.com            known = true;
34612496Sgiacomo.travaglini@arm.com            aarch32 = (aarch32_below_el3 && el != EL3)
34712496Sgiacomo.travaglini@arm.com                      || (aarch32_at_el1 && (el == EL0 || el == EL1) );
34810037SARM gem5 Developers        }
34910037SARM gem5 Developers    }
35012496Sgiacomo.travaglini@arm.com
35112496Sgiacomo.travaglini@arm.com    return std::make_pair(known, aarch32);
35210037SARM gem5 Developers}
35310037SARM gem5 Developers
35410037SARM gem5 Developersbool
35510037SARM gem5 DevelopersisBigEndian64(ThreadContext *tc)
35610037SARM gem5 Developers{
35714172Sgiacomo.travaglini@arm.com    switch (currEL(tc)) {
35810037SARM gem5 Developers      case EL3:
35910037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee;
36010037SARM gem5 Developers      case EL2:
36110037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee;
36210037SARM gem5 Developers      case EL1:
36310037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee;
36410037SARM gem5 Developers      case EL0:
36510037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e;
36610037SARM gem5 Developers      default:
36710037SARM gem5 Developers        panic("Invalid exception level");
36810037SARM gem5 Developers        break;
36910037SARM gem5 Developers    }
37010037SARM gem5 Developers}
37110037SARM gem5 Developers
37212788Sgiacomo.travaglini@arm.combool
37312788Sgiacomo.travaglini@arm.combadMode32(ThreadContext *tc, OperatingMode mode)
37412788Sgiacomo.travaglini@arm.com{
37512788Sgiacomo.travaglini@arm.com    return unknownMode32(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode));
37612788Sgiacomo.travaglini@arm.com}
37712788Sgiacomo.travaglini@arm.com
37812788Sgiacomo.travaglini@arm.combool
37912788Sgiacomo.travaglini@arm.combadMode(ThreadContext *tc, OperatingMode mode)
38012788Sgiacomo.travaglini@arm.com{
38112788Sgiacomo.travaglini@arm.com    return unknownMode(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode));
38212788Sgiacomo.travaglini@arm.com}
38312788Sgiacomo.travaglini@arm.com
38410037SARM gem5 DevelopersAddr
38510854SNathanael.Premillieu@arm.compurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
38610854SNathanael.Premillieu@arm.com                 TTBCR tcr)
38710854SNathanael.Premillieu@arm.com{
38810854SNathanael.Premillieu@arm.com    switch (el) {
38910854SNathanael.Premillieu@arm.com      case EL0:
39010854SNathanael.Premillieu@arm.com      case EL1:
39110854SNathanael.Premillieu@arm.com        if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
39210854SNathanael.Premillieu@arm.com            return addr | mask(63, 55);
39310854SNathanael.Premillieu@arm.com        else if (!bits(addr, 55, 48) && tcr.tbi0)
39410854SNathanael.Premillieu@arm.com            return bits(addr,55, 0);
39510854SNathanael.Premillieu@arm.com        break;
39611574SCurtis.Dunham@arm.com      case EL2:
39711574SCurtis.Dunham@arm.com        assert(ArmSystem::haveVirtualization(tc));
39811574SCurtis.Dunham@arm.com        tcr = tc->readMiscReg(MISCREG_TCR_EL2);
39911574SCurtis.Dunham@arm.com        if (tcr.tbi)
40011574SCurtis.Dunham@arm.com            return addr & mask(56);
40111574SCurtis.Dunham@arm.com        break;
40210854SNathanael.Premillieu@arm.com      case EL3:
40310854SNathanael.Premillieu@arm.com        assert(ArmSystem::haveSecurity(tc));
40410854SNathanael.Premillieu@arm.com        if (tcr.tbi)
40510854SNathanael.Premillieu@arm.com            return addr & mask(56);
40610854SNathanael.Premillieu@arm.com        break;
40710854SNathanael.Premillieu@arm.com      default:
40810854SNathanael.Premillieu@arm.com        panic("Invalid exception level");
40910854SNathanael.Premillieu@arm.com        break;
41010854SNathanael.Premillieu@arm.com    }
41110854SNathanael.Premillieu@arm.com
41210854SNathanael.Premillieu@arm.com    return addr;  // Nothing to do if this is not a tagged address
41310854SNathanael.Premillieu@arm.com}
41410854SNathanael.Premillieu@arm.com
41510854SNathanael.Premillieu@arm.comAddr
41610037SARM gem5 DeveloperspurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el)
41710037SARM gem5 Developers{
41810037SARM gem5 Developers    TTBCR tcr;
41910037SARM gem5 Developers
42010037SARM gem5 Developers    switch (el) {
42110037SARM gem5 Developers      case EL0:
42210037SARM gem5 Developers      case EL1:
42310037SARM gem5 Developers        tcr = tc->readMiscReg(MISCREG_TCR_EL1);
42410037SARM gem5 Developers        if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
42510037SARM gem5 Developers            return addr | mask(63, 55);
42610037SARM gem5 Developers        else if (!bits(addr, 55, 48) && tcr.tbi0)
42710037SARM gem5 Developers            return bits(addr,55, 0);
42810037SARM gem5 Developers        break;
42911574SCurtis.Dunham@arm.com      case EL2:
43011574SCurtis.Dunham@arm.com        assert(ArmSystem::haveVirtualization(tc));
43111574SCurtis.Dunham@arm.com        tcr = tc->readMiscReg(MISCREG_TCR_EL2);
43211574SCurtis.Dunham@arm.com        if (tcr.tbi)
43311574SCurtis.Dunham@arm.com            return addr & mask(56);
43411574SCurtis.Dunham@arm.com        break;
43510037SARM gem5 Developers      case EL3:
43610037SARM gem5 Developers        assert(ArmSystem::haveSecurity(tc));
43710037SARM gem5 Developers        tcr = tc->readMiscReg(MISCREG_TCR_EL3);
43810037SARM gem5 Developers        if (tcr.tbi)
43910037SARM gem5 Developers            return addr & mask(56);
44010037SARM gem5 Developers        break;
44110037SARM gem5 Developers      default:
44210037SARM gem5 Developers        panic("Invalid exception level");
44310037SARM gem5 Developers        break;
44410037SARM gem5 Developers    }
44510037SARM gem5 Developers
44610037SARM gem5 Developers    return addr;  // Nothing to do if this is not a tagged address
44710037SARM gem5 Developers}
44810037SARM gem5 Developers
4497752SWilliam.Wang@arm.comAddr
4507752SWilliam.Wang@arm.comtruncPage(Addr addr)
4517752SWilliam.Wang@arm.com{
4527752SWilliam.Wang@arm.com    return addr & ~(PageBytes - 1);
4537748SAli.Saidi@ARM.com}
4547752SWilliam.Wang@arm.com
4557752SWilliam.Wang@arm.comAddr
4567752SWilliam.Wang@arm.comroundPage(Addr addr)
4577752SWilliam.Wang@arm.com{
4587752SWilliam.Wang@arm.com    return (addr + PageBytes - 1) & ~(PageBytes - 1);
4597752SWilliam.Wang@arm.com}
4607752SWilliam.Wang@arm.com
46110037SARM gem5 Developersbool
46213999Sgiacomo.travaglini@arm.commcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss)
46310037SARM gem5 Developers{
46410037SARM gem5 Developers    bool        isRead;
46510037SARM gem5 Developers    uint32_t    crm;
46610037SARM gem5 Developers    IntRegIndex rt;
46710037SARM gem5 Developers    uint32_t    crn;
46810037SARM gem5 Developers    uint32_t    opc1;
46910037SARM gem5 Developers    uint32_t    opc2;
47010037SARM gem5 Developers    bool        trapToHype = false;
47110037SARM gem5 Developers
47213999Sgiacomo.travaglini@arm.com    const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
47313999Sgiacomo.travaglini@arm.com    const HCR hcr = tc->readMiscReg(MISCREG_HCR);
47413999Sgiacomo.travaglini@arm.com    const SCR scr = tc->readMiscReg(MISCREG_SCR);
47513999Sgiacomo.travaglini@arm.com    const HDCR hdcr = tc->readMiscReg(MISCREG_HDCR);
47613999Sgiacomo.travaglini@arm.com    const HSTR hstr = tc->readMiscReg(MISCREG_HSTR);
47713999Sgiacomo.travaglini@arm.com    const HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
47810037SARM gem5 Developers
47910037SARM gem5 Developers    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
48010037SARM gem5 Developers        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
48110037SARM gem5 Developers        trapToHype  = ((uint32_t) hstr) & (1 << crn);
48210037SARM gem5 Developers        trapToHype |= hdcr.tpm  && (crn == 9) && (crm >= 12);
48310037SARM gem5 Developers        trapToHype |= hcr.tidcp && (
48410037SARM gem5 Developers            ((crn ==  9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
48510037SARM gem5 Developers            ((crn == 10) && ((crm <= 1) ||  (crm == 4) || (crm == 8)))  ||
48610037SARM gem5 Developers            ((crn == 11) && ((crm <= 8) ||  (crm == 15)))               );
48710037SARM gem5 Developers
48810037SARM gem5 Developers        if (!trapToHype) {
48910037SARM gem5 Developers            switch (unflattenMiscReg(miscReg)) {
49010037SARM gem5 Developers              case MISCREG_CPACR:
49110037SARM gem5 Developers                trapToHype = hcptr.tcpac;
49210037SARM gem5 Developers                break;
49310037SARM gem5 Developers              case MISCREG_REVIDR:
49410037SARM gem5 Developers              case MISCREG_TCMTR:
49510037SARM gem5 Developers              case MISCREG_TLBTR:
49610037SARM gem5 Developers              case MISCREG_AIDR:
49710037SARM gem5 Developers                trapToHype = hcr.tid1;
49810037SARM gem5 Developers                break;
49910037SARM gem5 Developers              case MISCREG_CTR:
50010037SARM gem5 Developers              case MISCREG_CCSIDR:
50110037SARM gem5 Developers              case MISCREG_CLIDR:
50210037SARM gem5 Developers              case MISCREG_CSSELR:
50310037SARM gem5 Developers                trapToHype = hcr.tid2;
50410037SARM gem5 Developers                break;
50510037SARM gem5 Developers              case MISCREG_ID_PFR0:
50610037SARM gem5 Developers              case MISCREG_ID_PFR1:
50710037SARM gem5 Developers              case MISCREG_ID_DFR0:
50810037SARM gem5 Developers              case MISCREG_ID_AFR0:
50910037SARM gem5 Developers              case MISCREG_ID_MMFR0:
51010037SARM gem5 Developers              case MISCREG_ID_MMFR1:
51110037SARM gem5 Developers              case MISCREG_ID_MMFR2:
51210037SARM gem5 Developers              case MISCREG_ID_MMFR3:
51310037SARM gem5 Developers              case MISCREG_ID_ISAR0:
51410037SARM gem5 Developers              case MISCREG_ID_ISAR1:
51510037SARM gem5 Developers              case MISCREG_ID_ISAR2:
51610037SARM gem5 Developers              case MISCREG_ID_ISAR3:
51710037SARM gem5 Developers              case MISCREG_ID_ISAR4:
51810037SARM gem5 Developers              case MISCREG_ID_ISAR5:
51910037SARM gem5 Developers                trapToHype = hcr.tid3;
52010037SARM gem5 Developers                break;
52110037SARM gem5 Developers              case MISCREG_DCISW:
52210037SARM gem5 Developers              case MISCREG_DCCSW:
52310037SARM gem5 Developers              case MISCREG_DCCISW:
52410037SARM gem5 Developers                trapToHype = hcr.tsw;
52510037SARM gem5 Developers                break;
52610037SARM gem5 Developers              case MISCREG_DCIMVAC:
52710037SARM gem5 Developers              case MISCREG_DCCIMVAC:
52810037SARM gem5 Developers              case MISCREG_DCCMVAC:
52910037SARM gem5 Developers                trapToHype = hcr.tpc;
53010037SARM gem5 Developers                break;
53110037SARM gem5 Developers              case MISCREG_ICIMVAU:
53210037SARM gem5 Developers              case MISCREG_ICIALLU:
53310037SARM gem5 Developers              case MISCREG_ICIALLUIS:
53410037SARM gem5 Developers              case MISCREG_DCCMVAU:
53510037SARM gem5 Developers                trapToHype = hcr.tpu;
53610037SARM gem5 Developers                break;
53710037SARM gem5 Developers              case MISCREG_TLBIALLIS:
53810037SARM gem5 Developers              case MISCREG_TLBIMVAIS:
53910037SARM gem5 Developers              case MISCREG_TLBIASIDIS:
54010037SARM gem5 Developers              case MISCREG_TLBIMVAAIS:
54112576Sgiacomo.travaglini@arm.com              case MISCREG_TLBIMVALIS:
54212576Sgiacomo.travaglini@arm.com              case MISCREG_TLBIMVAALIS:
54310037SARM gem5 Developers              case MISCREG_DTLBIALL:
54410037SARM gem5 Developers              case MISCREG_ITLBIALL:
54510037SARM gem5 Developers              case MISCREG_DTLBIMVA:
54610037SARM gem5 Developers              case MISCREG_ITLBIMVA:
54710037SARM gem5 Developers              case MISCREG_DTLBIASID:
54810037SARM gem5 Developers              case MISCREG_ITLBIASID:
54910037SARM gem5 Developers              case MISCREG_TLBIMVAA:
55010037SARM gem5 Developers              case MISCREG_TLBIALL:
55110037SARM gem5 Developers              case MISCREG_TLBIMVA:
55212576Sgiacomo.travaglini@arm.com              case MISCREG_TLBIMVAL:
55312576Sgiacomo.travaglini@arm.com              case MISCREG_TLBIMVAAL:
55410037SARM gem5 Developers              case MISCREG_TLBIASID:
55510037SARM gem5 Developers                trapToHype = hcr.ttlb;
55610037SARM gem5 Developers                break;
55710037SARM gem5 Developers              case MISCREG_ACTLR:
55810037SARM gem5 Developers                trapToHype = hcr.tac;
55910037SARM gem5 Developers                break;
56010037SARM gem5 Developers              case MISCREG_SCTLR:
56110037SARM gem5 Developers              case MISCREG_TTBR0:
56210037SARM gem5 Developers              case MISCREG_TTBR1:
56310037SARM gem5 Developers              case MISCREG_TTBCR:
56410037SARM gem5 Developers              case MISCREG_DACR:
56510037SARM gem5 Developers              case MISCREG_DFSR:
56610037SARM gem5 Developers              case MISCREG_IFSR:
56710037SARM gem5 Developers              case MISCREG_DFAR:
56810037SARM gem5 Developers              case MISCREG_IFAR:
56910037SARM gem5 Developers              case MISCREG_ADFSR:
57010037SARM gem5 Developers              case MISCREG_AIFSR:
57110037SARM gem5 Developers              case MISCREG_PRRR:
57210037SARM gem5 Developers              case MISCREG_NMRR:
57310037SARM gem5 Developers              case MISCREG_MAIR0:
57410037SARM gem5 Developers              case MISCREG_MAIR1:
57510037SARM gem5 Developers              case MISCREG_CONTEXTIDR:
57610037SARM gem5 Developers                trapToHype = hcr.tvm & !isRead;
57710037SARM gem5 Developers                break;
57810037SARM gem5 Developers              case MISCREG_PMCR:
57910037SARM gem5 Developers                trapToHype = hdcr.tpmcr;
58010037SARM gem5 Developers                break;
58114001Sgiacomo.travaglini@arm.com              // GICv3 regs
58214001Sgiacomo.travaglini@arm.com              case MISCREG_ICC_SGI0R:
58314001Sgiacomo.travaglini@arm.com                if (tc->getIsaPtr()->haveGICv3CpuIfc())
58414001Sgiacomo.travaglini@arm.com                    trapToHype = hcr.fmo;
58514001Sgiacomo.travaglini@arm.com                break;
58614001Sgiacomo.travaglini@arm.com              case MISCREG_ICC_SGI1R:
58714001Sgiacomo.travaglini@arm.com              case MISCREG_ICC_ASGI1R:
58814001Sgiacomo.travaglini@arm.com                if (tc->getIsaPtr()->haveGICv3CpuIfc())
58914001Sgiacomo.travaglini@arm.com                    trapToHype = hcr.imo;
59014001Sgiacomo.travaglini@arm.com                break;
59110037SARM gem5 Developers              // No default action needed
59210037SARM gem5 Developers              default:
59310037SARM gem5 Developers                break;
59410037SARM gem5 Developers            }
59510037SARM gem5 Developers        }
59610037SARM gem5 Developers    }
59710037SARM gem5 Developers    return trapToHype;
59810037SARM gem5 Developers}
59910037SARM gem5 Developers
60010037SARM gem5 Developers
60110037SARM gem5 Developersbool
60210037SARM gem5 DevelopersmcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
60310037SARM gem5 Developers                  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
60410037SARM gem5 Developers{
60510037SARM gem5 Developers    bool        isRead;
60610037SARM gem5 Developers    uint32_t    crm;
60710037SARM gem5 Developers    IntRegIndex rt;
60810037SARM gem5 Developers    uint32_t    crn;
60910037SARM gem5 Developers    uint32_t    opc1;
61010037SARM gem5 Developers    uint32_t    opc2;
61110037SARM gem5 Developers    bool        trapToHype = false;
61210037SARM gem5 Developers
61310037SARM gem5 Developers    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
61410037SARM gem5 Developers        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
61510037SARM gem5 Developers        inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
61610037SARM gem5 Developers                crm, crn, opc1, opc2, hdcr, hcptr, hstr);
61710037SARM gem5 Developers        trapToHype  = hdcr.tda  && (opc1 == 0);
61810037SARM gem5 Developers        trapToHype |= hcptr.tta && (opc1 == 1);
61910037SARM gem5 Developers        if (!trapToHype) {
62010037SARM gem5 Developers            switch (unflattenMiscReg(miscReg)) {
62110037SARM gem5 Developers              case MISCREG_DBGOSLSR:
62210037SARM gem5 Developers              case MISCREG_DBGOSLAR:
62310037SARM gem5 Developers              case MISCREG_DBGOSDLR:
62410037SARM gem5 Developers              case MISCREG_DBGPRCR:
62510037SARM gem5 Developers                trapToHype = hdcr.tdosa;
62610037SARM gem5 Developers                break;
62710037SARM gem5 Developers              case MISCREG_DBGDRAR:
62810037SARM gem5 Developers              case MISCREG_DBGDSAR:
62910037SARM gem5 Developers                trapToHype = hdcr.tdra;
63010037SARM gem5 Developers                break;
63110037SARM gem5 Developers              case MISCREG_JIDR:
63210037SARM gem5 Developers                trapToHype = hcr.tid0;
63310037SARM gem5 Developers                break;
63410037SARM gem5 Developers              case MISCREG_JOSCR:
63510037SARM gem5 Developers              case MISCREG_JMCR:
63610037SARM gem5 Developers                trapToHype = hstr.tjdbx;
63710037SARM gem5 Developers                break;
63810037SARM gem5 Developers              case MISCREG_TEECR:
63910037SARM gem5 Developers              case MISCREG_TEEHBR:
64010037SARM gem5 Developers                trapToHype = hstr.ttee;
64110037SARM gem5 Developers                break;
64210037SARM gem5 Developers              // No default action needed
64310037SARM gem5 Developers              default:
64410037SARM gem5 Developers                break;
64510037SARM gem5 Developers            }
64610037SARM gem5 Developers        }
64710037SARM gem5 Developers    }
64810037SARM gem5 Developers    return trapToHype;
64910037SARM gem5 Developers}
65010037SARM gem5 Developers
65110037SARM gem5 Developersbool
65210037SARM gem5 DevelopersmcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
65310037SARM gem5 Developers                    HCR hcr, uint32_t iss)
65410037SARM gem5 Developers{
65510037SARM gem5 Developers    uint32_t    crm;
65610037SARM gem5 Developers    IntRegIndex rt;
65710037SARM gem5 Developers    uint32_t    crn;
65810037SARM gem5 Developers    uint32_t    opc1;
65910037SARM gem5 Developers    uint32_t    opc2;
66010037SARM gem5 Developers    bool        isRead;
66110037SARM gem5 Developers    bool        trapToHype = false;
66210037SARM gem5 Developers
66310037SARM gem5 Developers    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
66410037SARM gem5 Developers        // This is technically the wrong function, but we can re-use it for
66510037SARM gem5 Developers        // the moment because we only need one field, which overlaps with the
66610037SARM gem5 Developers        // mcrmrc layout
66710037SARM gem5 Developers        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
66810037SARM gem5 Developers        trapToHype = ((uint32_t) hstr) & (1 << crm);
66910037SARM gem5 Developers
67010037SARM gem5 Developers        if (!trapToHype) {
67110037SARM gem5 Developers            switch (unflattenMiscReg(miscReg)) {
67210037SARM gem5 Developers              case MISCREG_SCTLR:
67310037SARM gem5 Developers              case MISCREG_TTBR0:
67410037SARM gem5 Developers              case MISCREG_TTBR1:
67510037SARM gem5 Developers              case MISCREG_TTBCR:
67610037SARM gem5 Developers              case MISCREG_DACR:
67710037SARM gem5 Developers              case MISCREG_DFSR:
67810037SARM gem5 Developers              case MISCREG_IFSR:
67910037SARM gem5 Developers              case MISCREG_DFAR:
68010037SARM gem5 Developers              case MISCREG_IFAR:
68110037SARM gem5 Developers              case MISCREG_ADFSR:
68210037SARM gem5 Developers              case MISCREG_AIFSR:
68310037SARM gem5 Developers              case MISCREG_PRRR:
68410037SARM gem5 Developers              case MISCREG_NMRR:
68510037SARM gem5 Developers              case MISCREG_MAIR0:
68610037SARM gem5 Developers              case MISCREG_MAIR1:
68710037SARM gem5 Developers              case MISCREG_CONTEXTIDR:
68810037SARM gem5 Developers                trapToHype = hcr.tvm & !isRead;
68910037SARM gem5 Developers                break;
69010037SARM gem5 Developers              // No default action needed
69110037SARM gem5 Developers              default:
69210037SARM gem5 Developers                break;
69310037SARM gem5 Developers            }
69410037SARM gem5 Developers        }
69510037SARM gem5 Developers    }
69610037SARM gem5 Developers    return trapToHype;
69710037SARM gem5 Developers}
69810037SARM gem5 Developers
69910037SARM gem5 Developersbool
70010037SARM gem5 DevelopersdecodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
70110037SARM gem5 Developers                      CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
70210037SARM gem5 Developers{
70310103Sstephan.diestelhorst@arm.com    OperatingMode mode = MODE_UNDEFINED;
70410037SARM gem5 Developers    bool          ok = true;
70510037SARM gem5 Developers
70610037SARM gem5 Developers    // R mostly indicates if its a int register or a misc reg, we override
70710037SARM gem5 Developers    // below if the few corner cases
70810037SARM gem5 Developers    isIntReg = !r;
70910037SARM gem5 Developers    // Loosely based on ARM ARM issue C section B9.3.10
71010037SARM gem5 Developers    if (r) {
71110037SARM gem5 Developers        switch (sysM)
71210037SARM gem5 Developers        {
71310037SARM gem5 Developers          case 0xE:
71410037SARM gem5 Developers            regIdx = MISCREG_SPSR_FIQ;
71510037SARM gem5 Developers            mode   = MODE_FIQ;
71610037SARM gem5 Developers            break;
71710037SARM gem5 Developers          case 0x10:
71810037SARM gem5 Developers            regIdx = MISCREG_SPSR_IRQ;
71910037SARM gem5 Developers            mode   = MODE_IRQ;
72010037SARM gem5 Developers            break;
72110037SARM gem5 Developers          case 0x12:
72210037SARM gem5 Developers            regIdx = MISCREG_SPSR_SVC;
72310037SARM gem5 Developers            mode   = MODE_SVC;
72410037SARM gem5 Developers            break;
72510037SARM gem5 Developers          case 0x14:
72610037SARM gem5 Developers            regIdx = MISCREG_SPSR_ABT;
72710037SARM gem5 Developers            mode   = MODE_ABORT;
72810037SARM gem5 Developers            break;
72910037SARM gem5 Developers          case 0x16:
73010037SARM gem5 Developers            regIdx = MISCREG_SPSR_UND;
73110037SARM gem5 Developers            mode   = MODE_UNDEFINED;
73210037SARM gem5 Developers            break;
73310037SARM gem5 Developers          case 0x1C:
73410037SARM gem5 Developers            regIdx = MISCREG_SPSR_MON;
73510037SARM gem5 Developers            mode   = MODE_MON;
73610037SARM gem5 Developers            break;
73710037SARM gem5 Developers          case 0x1E:
73810037SARM gem5 Developers            regIdx = MISCREG_SPSR_HYP;
73910037SARM gem5 Developers            mode   = MODE_HYP;
74010037SARM gem5 Developers            break;
74110037SARM gem5 Developers          default:
74210037SARM gem5 Developers            ok = false;
74310037SARM gem5 Developers            break;
74410037SARM gem5 Developers        }
74510037SARM gem5 Developers    } else {
74610037SARM gem5 Developers        int sysM4To3 = bits(sysM, 4, 3);
74710037SARM gem5 Developers
74810037SARM gem5 Developers        if (sysM4To3 == 0) {
74910037SARM gem5 Developers            mode = MODE_USER;
75010037SARM gem5 Developers            regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
75110037SARM gem5 Developers        } else if (sysM4To3 == 1) {
75210037SARM gem5 Developers            mode = MODE_FIQ;
75310037SARM gem5 Developers            regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
75410037SARM gem5 Developers        } else if (sysM4To3 == 3) {
75510037SARM gem5 Developers            if (bits(sysM, 1) == 0) {
75610037SARM gem5 Developers                mode = MODE_MON;
75710037SARM gem5 Developers                regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
75810037SARM gem5 Developers            } else {
75910037SARM gem5 Developers                mode = MODE_HYP;
76010037SARM gem5 Developers                if (bits(sysM, 0) == 1) {
76110037SARM gem5 Developers                    regIdx = intRegInMode(mode, 13); // R13 in HYP
76210037SARM gem5 Developers                } else {
76310037SARM gem5 Developers                    isIntReg = false;
76410037SARM gem5 Developers                    regIdx   = MISCREG_ELR_HYP;
76510037SARM gem5 Developers                }
76610037SARM gem5 Developers            }
76710037SARM gem5 Developers        } else { // Other Banked registers
76810037SARM gem5 Developers            int sysM2 = bits(sysM, 2);
76910037SARM gem5 Developers            int sysM1 = bits(sysM, 1);
77010037SARM gem5 Developers
77110037SARM gem5 Developers            mode  = (OperatingMode) ( ((sysM2 ||  sysM1) << 0) |
77210037SARM gem5 Developers                                      (1                 << 1) |
77310037SARM gem5 Developers                                      ((sysM2 && !sysM1) << 2) |
77410037SARM gem5 Developers                                      ((sysM2 &&  sysM1) << 3) |
77510037SARM gem5 Developers                                      (1                 << 4) );
77610037SARM gem5 Developers            regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
77710037SARM gem5 Developers            // Don't flatten the register here. This is going to go through
77810037SARM gem5 Developers            // setIntReg() which will do the flattening
77910037SARM gem5 Developers            ok &= mode != cpsr.mode;
78010037SARM gem5 Developers        }
78110037SARM gem5 Developers    }
78210037SARM gem5 Developers
78310037SARM gem5 Developers    // Check that the requested register is accessable from the current mode
78410037SARM gem5 Developers    if (ok && checkSecurity && mode != cpsr.mode) {
78510037SARM gem5 Developers        switch (cpsr.mode)
78610037SARM gem5 Developers        {
78710037SARM gem5 Developers          case MODE_USER:
78810037SARM gem5 Developers            ok = false;
78910037SARM gem5 Developers            break;
79010037SARM gem5 Developers          case MODE_FIQ:
79110037SARM gem5 Developers            ok &=  mode != MODE_HYP;
79210037SARM gem5 Developers            ok &= (mode != MODE_MON) || !scr.ns;
79310037SARM gem5 Developers            break;
79410037SARM gem5 Developers          case MODE_HYP:
79510037SARM gem5 Developers            ok &=  mode != MODE_MON;
79610037SARM gem5 Developers            ok &= (mode != MODE_FIQ) || !nsacr.rfr;
79710037SARM gem5 Developers            break;
79810037SARM gem5 Developers          case MODE_IRQ:
79910037SARM gem5 Developers          case MODE_SVC:
80010037SARM gem5 Developers          case MODE_ABORT:
80110037SARM gem5 Developers          case MODE_UNDEFINED:
80210037SARM gem5 Developers          case MODE_SYSTEM:
80310037SARM gem5 Developers            ok &=  mode != MODE_HYP;
80410037SARM gem5 Developers            ok &= (mode != MODE_MON) || !scr.ns;
80510037SARM gem5 Developers            ok &= (mode != MODE_FIQ) || !nsacr.rfr;
80610037SARM gem5 Developers            break;
80710037SARM gem5 Developers          // can access everything, no further checks required
80810037SARM gem5 Developers          case MODE_MON:
80910037SARM gem5 Developers            break;
81010037SARM gem5 Developers          default:
81110037SARM gem5 Developers            panic("unknown Mode 0x%x\n", cpsr.mode);
81210037SARM gem5 Developers            break;
81310037SARM gem5 Developers        }
81410037SARM gem5 Developers    }
81510037SARM gem5 Developers    return (ok);
81610037SARM gem5 Developers}
81710037SARM gem5 Developers
81810037SARM gem5 Developersbool
81910037SARM gem5 DevelopersSPAlignmentCheckEnabled(ThreadContext* tc)
82010037SARM gem5 Developers{
82114172Sgiacomo.travaglini@arm.com    switch (currEL(tc)) {
82210037SARM gem5 Developers      case EL3:
82310037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa;
82410037SARM gem5 Developers      case EL2:
82510037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa;
82610037SARM gem5 Developers      case EL1:
82710037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa;
82810037SARM gem5 Developers      case EL0:
82910037SARM gem5 Developers        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0;
83010037SARM gem5 Developers      default:
83110037SARM gem5 Developers        panic("Invalid exception level");
83210037SARM gem5 Developers        break;
83310037SARM gem5 Developers    }
83410037SARM gem5 Developers}
83510037SARM gem5 Developers
83610037SARM gem5 Developersint
83710037SARM gem5 DevelopersdecodePhysAddrRange64(uint8_t pa_enc)
83810037SARM gem5 Developers{
83910037SARM gem5 Developers    switch (pa_enc) {
84010037SARM gem5 Developers      case 0x0:
84110037SARM gem5 Developers        return 32;
84210037SARM gem5 Developers      case 0x1:
84310037SARM gem5 Developers        return 36;
84410037SARM gem5 Developers      case 0x2:
84510037SARM gem5 Developers        return 40;
84610037SARM gem5 Developers      case 0x3:
84710037SARM gem5 Developers        return 42;
84810037SARM gem5 Developers      case 0x4:
84910037SARM gem5 Developers        return 44;
85010037SARM gem5 Developers      case 0x5:
85110037SARM gem5 Developers      case 0x6:
85210037SARM gem5 Developers      case 0x7:
85310037SARM gem5 Developers        return 48;
85410037SARM gem5 Developers      default:
85510037SARM gem5 Developers        panic("Invalid phys. address range encoding");
85610037SARM gem5 Developers    }
85710037SARM gem5 Developers}
85810037SARM gem5 Developers
85910037SARM gem5 Developersuint8_t
86010037SARM gem5 DevelopersencodePhysAddrRange64(int pa_size)
86110037SARM gem5 Developers{
86210037SARM gem5 Developers    switch (pa_size) {
86310037SARM gem5 Developers      case 32:
86410037SARM gem5 Developers        return 0x0;
86510037SARM gem5 Developers      case 36:
86610037SARM gem5 Developers        return 0x1;
86710037SARM gem5 Developers      case 40:
86810037SARM gem5 Developers        return 0x2;
86910037SARM gem5 Developers      case 42:
87010037SARM gem5 Developers        return 0x3;
87110037SARM gem5 Developers      case 44:
87210037SARM gem5 Developers        return 0x4;
87310037SARM gem5 Developers      case 48:
87410037SARM gem5 Developers        return 0x5;
87510037SARM gem5 Developers      default:
87610037SARM gem5 Developers        panic("Invalid phys. address range");
87710037SARM gem5 Developers    }
87810037SARM gem5 Developers}
87910037SARM gem5 Developers
8807752SWilliam.Wang@arm.com} // namespace ArmISA
881