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