utility.cc revision 12788
1955SN/A/* 2955SN/A * Copyright (c) 2009-2014, 2016-2018 ARM Limited 31762SN/A * All rights reserved. 4955SN/A * 5955SN/A * The license below extends only to copyright in the software and shall 6955SN/A * not be construed as granting a license to any other intellectual 7955SN/A * property including but not limited to intellectual property relating 8955SN/A * to a hardware implementation of the functionality of the software 9955SN/A * licensed hereunder. You may use the software subject to the license 10955SN/A * terms below provided that you ensure that this notice is replicated 11955SN/A * unmodified and in its entirety in all distributions of the software, 12955SN/A * modified or unmodified, in source code or in binary form. 13955SN/A * 14955SN/A * Redistribution and use in source and binary forms, with or without 15955SN/A * modification, are permitted provided that the following conditions are 16955SN/A * met: redistributions of source code must retain the above copyright 17955SN/A * notice, this list of conditions and the following disclaimer; 18955SN/A * redistributions in binary form must reproduce the above copyright 19955SN/A * notice, this list of conditions and the following disclaimer in the 20955SN/A * documentation and/or other materials provided with the distribution; 21955SN/A * neither the name of the copyright holders nor the names of its 22955SN/A * contributors may be used to endorse or promote products derived from 23955SN/A * this software without specific prior written permission. 24955SN/A * 25955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 294762Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 315522Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326143Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 334762Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 345522Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 365522Snate@binkert.org * 37955SN/A * Authors: Ali Saidi 385522Snate@binkert.org */ 394202Sbinkertn@umich.edu 405742Snate@binkert.org#include "arch/arm/utility.hh" 41955SN/A 424381Sbinkertn@umich.edu#include <memory> 434381Sbinkertn@umich.edu 44955SN/A#include "arch/arm/faults.hh" 45955SN/A#include "arch/arm/isa_traits.hh" 46955SN/A#include "arch/arm/system.hh" 474202Sbinkertn@umich.edu#include "arch/arm/tlb.hh" 48955SN/A#include "arch/arm/vtophys.hh" 494382Sbinkertn@umich.edu#include "cpu/base.hh" 504382Sbinkertn@umich.edu#include "cpu/checker/cpu.hh" 514382Sbinkertn@umich.edu#include "cpu/thread_context.hh" 526654Snate@binkert.org#include "mem/fs_translating_port_proxy.hh" 535517Snate@binkert.org#include "sim/full_system.hh" 546143Snate@binkert.org 556143Snate@binkert.orgnamespace ArmISA { 566143Snate@binkert.org 576143Snate@binkert.orgvoid 586143Snate@binkert.orginitCPU(ThreadContext *tc, int cpuId) 596143Snate@binkert.org{ 606143Snate@binkert.org // Reset CP15?? What does that mean -- ali 616143Snate@binkert.org 626143Snate@binkert.org // FPEXC.EN = 0 636143Snate@binkert.org 646143Snate@binkert.org static Fault reset = std::make_shared<Reset>(); 656143Snate@binkert.org reset->invoke(tc); 666143Snate@binkert.org} 676143Snate@binkert.org 686143Snate@binkert.orguint64_t 694762Snate@binkert.orggetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 706143Snate@binkert.org{ 716143Snate@binkert.org if (!FullSystem) { 726143Snate@binkert.org panic("getArgument() only implemented for full system mode.\n"); 736143Snate@binkert.org M5_DUMMY_RETURN 746143Snate@binkert.org } 756143Snate@binkert.org 766143Snate@binkert.org if (fp) 776143Snate@binkert.org panic("getArgument(): Floating point arguments not implemented\n"); 786143Snate@binkert.org 796143Snate@binkert.org if (inAArch64(tc)) { 806143Snate@binkert.org if (size == (uint16_t)(-1)) 816143Snate@binkert.org size = sizeof(uint64_t); 826143Snate@binkert.org 836143Snate@binkert.org if (number < 8 /*NumArgumentRegs64*/) { 846143Snate@binkert.org return tc->readIntReg(number); 856143Snate@binkert.org } else { 866143Snate@binkert.org panic("getArgument(): No support reading stack args for AArch64\n"); 876143Snate@binkert.org } 886143Snate@binkert.org } else { 896143Snate@binkert.org if (size == (uint16_t)(-1)) 906143Snate@binkert.org // todo: should this not be sizeof(uint32_t) rather? 916143Snate@binkert.org size = ArmISA::MachineBytes; 926143Snate@binkert.org 936143Snate@binkert.org if (number < NumArgumentRegs) { 946143Snate@binkert.org // If the argument is 64 bits, it must be in an even regiser 956143Snate@binkert.org // number. Increment the number here if it isn't even. 966143Snate@binkert.org if (size == sizeof(uint64_t)) { 976143Snate@binkert.org if ((number % 2) != 0) 986143Snate@binkert.org number++; 996143Snate@binkert.org // Read the two halves of the data. Number is inc here to 1006143Snate@binkert.org // get the second half of the 64 bit reg. 1016143Snate@binkert.org uint64_t tmp; 1026143Snate@binkert.org tmp = tc->readIntReg(number++); 1036143Snate@binkert.org tmp |= tc->readIntReg(number) << 32; 1046143Snate@binkert.org return tmp; 1056143Snate@binkert.org } else { 1066143Snate@binkert.org return tc->readIntReg(number); 1076143Snate@binkert.org } 1086143Snate@binkert.org } else { 1096143Snate@binkert.org Addr sp = tc->readIntReg(StackPointerReg); 1106143Snate@binkert.org FSTranslatingPortProxy &vp = tc->getVirtProxy(); 1116143Snate@binkert.org uint64_t arg; 1126143Snate@binkert.org if (size == sizeof(uint64_t)) { 1135522Snate@binkert.org // If the argument is even it must be aligned 1146143Snate@binkert.org if ((number % 2) != 0) 1156143Snate@binkert.org number++; 1166143Snate@binkert.org arg = vp.read<uint64_t>(sp + 1176143Snate@binkert.org (number-NumArgumentRegs) * sizeof(uint32_t)); 1186143Snate@binkert.org // since two 32 bit args == 1 64 bit arg, increment number 1196143Snate@binkert.org number++; 1206143Snate@binkert.org } else { 1216143Snate@binkert.org arg = vp.read<uint32_t>(sp + 1226143Snate@binkert.org (number-NumArgumentRegs) * sizeof(uint32_t)); 1236143Snate@binkert.org } 1245522Snate@binkert.org return arg; 1255522Snate@binkert.org } 1265522Snate@binkert.org } 1275522Snate@binkert.org panic("getArgument() should always return\n"); 1285604Snate@binkert.org} 1295604Snate@binkert.org 1306143Snate@binkert.orgvoid 1316143Snate@binkert.orgskipFunction(ThreadContext *tc) 1324762Snate@binkert.org{ 1334762Snate@binkert.org PCState newPC = tc->pcState(); 1346143Snate@binkert.org if (inAArch64(tc)) { 1356143Snate@binkert.org newPC.set(tc->readIntReg(INTREG_X30)); 1366143Snate@binkert.org } else { 1376143Snate@binkert.org newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1)); 1384762Snate@binkert.org } 1396143Snate@binkert.org 1406143Snate@binkert.org CheckerCPU *checker = tc->getCheckerCpuPtr(); 1416143Snate@binkert.org if (checker) { 1426143Snate@binkert.org tc->pcStateNoRecord(newPC); 1436143Snate@binkert.org } else { 1446143Snate@binkert.org tc->pcState(newPC); 1456143Snate@binkert.org } 1466143Snate@binkert.org} 1475604Snate@binkert.org 1486143Snate@binkert.orgvoid 1496143Snate@binkert.orgcopyRegs(ThreadContext *src, ThreadContext *dest) 1506143Snate@binkert.org{ 1514762Snate@binkert.org for (int i = 0; i < NumIntRegs; i++) 1526143Snate@binkert.org dest->setIntRegFlat(i, src->readIntRegFlat(i)); 1534762Snate@binkert.org 1544762Snate@binkert.org for (int i = 0; i < NumFloatRegs; i++) 1554762Snate@binkert.org dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 1566143Snate@binkert.org 1576143Snate@binkert.org for (int i = 0; i < NumVecRegs; i++) 1584762Snate@binkert.org dest->setVecRegFlat(i, src->readVecRegFlat(i)); 1596143Snate@binkert.org 1606143Snate@binkert.org for (int i = 0; i < NumCCRegs; i++) 1616143Snate@binkert.org dest->setCCReg(i, src->readCCReg(i)); 1626143Snate@binkert.org 1634762Snate@binkert.org for (int i = 0; i < NumMiscRegs; i++) 1646143Snate@binkert.org dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 1654762Snate@binkert.org 1666143Snate@binkert.org // setMiscReg "with effect" will set the misc register mapping correctly. 1674762Snate@binkert.org // e.g. updateRegMap(val) 1686143Snate@binkert.org dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR)); 1696143Snate@binkert.org 1706143Snate@binkert.org // Copy over the PC State 1716143Snate@binkert.org dest->pcState(src->pcState()); 1726143Snate@binkert.org 1736143Snate@binkert.org // Invalidate the tlb misc register cache 1746143Snate@binkert.org dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg(); 1756143Snate@binkert.org dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg(); 1766143Snate@binkert.org} 1776143Snate@binkert.org 1786143Snate@binkert.orgbool 1796143Snate@binkert.orginSecureState(ThreadContext *tc) 1806143Snate@binkert.org{ 181955SN/A SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) : 1825584Snate@binkert.org tc->readMiscReg(MISCREG_SCR); 1835584Snate@binkert.org return ArmSystem::haveSecurity(tc) && inSecureState( 1845584Snate@binkert.org scr, tc->readMiscReg(MISCREG_CPSR)); 1855584Snate@binkert.org} 1866143Snate@binkert.org 1876143Snate@binkert.orginline bool 1886143Snate@binkert.orgisSecureBelowEL3(ThreadContext *tc) 1895584Snate@binkert.org{ 1904382Sbinkertn@umich.edu SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 1914202Sbinkertn@umich.edu return ArmSystem::haveEL(tc, EL3) && scr.ns == 0; 1924382Sbinkertn@umich.edu} 1934382Sbinkertn@umich.edu 1944382Sbinkertn@umich.edubool 1955584Snate@binkert.orginAArch64(ThreadContext *tc) 1964382Sbinkertn@umich.edu{ 1974382Sbinkertn@umich.edu CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 1984382Sbinkertn@umich.edu return opModeIs64((OperatingMode) (uint8_t) cpsr.mode); 1995192Ssaidi@eecs.umich.edu} 2005192Ssaidi@eecs.umich.edu 2015799Snate@binkert.orgbool 2025799Snate@binkert.orglongDescFormatInUse(ThreadContext *tc) 2035799Snate@binkert.org{ 2045192Ssaidi@eecs.umich.edu TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR); 2055799Snate@binkert.org return ArmSystem::haveLPAE(tc) && ttbcr.eae; 2065192Ssaidi@eecs.umich.edu} 2075799Snate@binkert.org 2085799Snate@binkert.orguint32_t 2095192Ssaidi@eecs.umich.edugetMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 2105192Ssaidi@eecs.umich.edu{ 2115192Ssaidi@eecs.umich.edu // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical 2125799Snate@binkert.org // Reference Manual 2135192Ssaidi@eecs.umich.edu // 2145192Ssaidi@eecs.umich.edu // bit 31 - Multi-processor extensions available 2155192Ssaidi@eecs.umich.edu // bit 30 - Uni-processor system 2165192Ssaidi@eecs.umich.edu // bit 24 - Multi-threaded cores 2175192Ssaidi@eecs.umich.edu // bit 11-8 - Cluster ID 2185192Ssaidi@eecs.umich.edu // bit 1-0 - CPU ID 2194382Sbinkertn@umich.edu // 2204382Sbinkertn@umich.edu // We deliberately extend both the Cluster ID and CPU ID fields to allow 2214382Sbinkertn@umich.edu // for simulation of larger systems 2222667Sstever@eecs.umich.edu assert((0 <= tc->cpuId()) && (tc->cpuId() < 256)); 2232667Sstever@eecs.umich.edu assert(tc->socketId() < 65536); 2242667Sstever@eecs.umich.edu if (arm_sys->multiThread) { 2252667Sstever@eecs.umich.edu return 0x80000000 | // multiprocessor extensions available 2262667Sstever@eecs.umich.edu 0x01000000 | // multi-threaded cores 2272667Sstever@eecs.umich.edu tc->contextId(); 2285742Snate@binkert.org } else if (arm_sys->multiProc) { 2295742Snate@binkert.org return 0x80000000 | // multiprocessor extensions available 2305742Snate@binkert.org tc->cpuId() | tc->socketId() << 8; 2312037SN/A } else { 2322037SN/A return 0x80000000 | // multiprocessor extensions available 2332037SN/A 0x40000000 | // in up system 2345793Snate@binkert.org tc->cpuId() | tc->socketId() << 8; 2355793Snate@binkert.org } 2365793Snate@binkert.org} 2375793Snate@binkert.org 2385793Snate@binkert.orgbool 2394382Sbinkertn@umich.eduELIs64(ThreadContext *tc, ExceptionLevel el) 2404762Snate@binkert.org{ 2415344Sstever@gmail.com return !ELIs32(tc, el); 2424382Sbinkertn@umich.edu} 2435341Sstever@gmail.com 2445742Snate@binkert.orgbool 2455742Snate@binkert.orgELIs32(ThreadContext *tc, ExceptionLevel el) 2465742Snate@binkert.org{ 2475742Snate@binkert.org bool known, aarch32; 2485742Snate@binkert.org std::tie(known, aarch32) = ELUsingAArch32K(tc, el); 2494762Snate@binkert.org panic_if(!known, "EL state is UNKNOWN"); 2505742Snate@binkert.org return aarch32; 2515742Snate@binkert.org} 2525742Snate@binkert.org 2535742Snate@binkert.orgstd::pair<bool, bool> 2545742Snate@binkert.orgELUsingAArch32K(ThreadContext *tc, ExceptionLevel el) 2555742Snate@binkert.org{ 2565742Snate@binkert.org // Return true if the specified EL is in aarch32 state. 2575341Sstever@gmail.com const bool have_el3 = ArmSystem::haveSecurity(tc); 2585742Snate@binkert.org const bool have_el2 = ArmSystem::haveVirtualization(tc); 2595341Sstever@gmail.com 2604773Snate@binkert.org panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist"); 2616108Snate@binkert.org panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist"); 2621858SN/A 2631085SN/A bool known, aarch32; 2644382Sbinkertn@umich.edu known = aarch32 = false; 2654382Sbinkertn@umich.edu if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) { 2664762Snate@binkert.org // Target EL is the highest one in a system where 2674762Snate@binkert.org // the highest is using AArch64. 2684762Snate@binkert.org known = true; aarch32 = false; 2696654Snate@binkert.org } else if (!ArmSystem::highestELIs64(tc)) { 2706654Snate@binkert.org // All ELs are using AArch32: 2715517Snate@binkert.org known = true; aarch32 = true; 2725517Snate@binkert.org } else { 2735517Snate@binkert.org SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 2745517Snate@binkert.org bool aarch32_below_el3 = (have_el3 && scr.rw == 0); 2755517Snate@binkert.org 2765517Snate@binkert.org HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 2775517Snate@binkert.org bool aarch32_at_el1 = (aarch32_below_el3 2785517Snate@binkert.org || (have_el2 2795517Snate@binkert.org && !isSecureBelowEL3(tc) && hcr.rw == 0)); 2805517Snate@binkert.org 2815517Snate@binkert.org // Only know if EL0 using AArch32 from PSTATE 2825517Snate@binkert.org if (el == EL0 && !aarch32_at_el1) { 2835517Snate@binkert.org // EL0 controlled by PSTATE 2845517Snate@binkert.org CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 2855517Snate@binkert.org 2865517Snate@binkert.org known = (cpsr.el == EL0); 2875517Snate@binkert.org aarch32 = (cpsr.width == 1); 2886654Snate@binkert.org } else { 2895517Snate@binkert.org known = true; 2905517Snate@binkert.org aarch32 = (aarch32_below_el3 && el != EL3) 2915517Snate@binkert.org || (aarch32_at_el1 && (el == EL0 || el == EL1) ); 2925517Snate@binkert.org } 2935517Snate@binkert.org } 2945517Snate@binkert.org 2955517Snate@binkert.org return std::make_pair(known, aarch32); 2965517Snate@binkert.org} 2976143Snate@binkert.org 2986654Snate@binkert.orgbool 2995517Snate@binkert.orgisBigEndian64(ThreadContext *tc) 3005517Snate@binkert.org{ 3015517Snate@binkert.org switch (opModeToEL(currOpMode(tc))) { 3025517Snate@binkert.org case EL3: 3035517Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee; 3045517Snate@binkert.org case EL2: 3055517Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee; 3065517Snate@binkert.org case EL1: 3075517Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee; 3085517Snate@binkert.org case EL0: 3095517Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e; 3105517Snate@binkert.org default: 3115517Snate@binkert.org panic("Invalid exception level"); 3125517Snate@binkert.org break; 3136654Snate@binkert.org } 3146654Snate@binkert.org} 3155517Snate@binkert.org 3165517Snate@binkert.orgbool 3176143Snate@binkert.orgbadMode32(ThreadContext *tc, OperatingMode mode) 3186143Snate@binkert.org{ 3196143Snate@binkert.org return unknownMode32(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode)); 3206143Snate@binkert.org} 3215517Snate@binkert.org 3226143Snate@binkert.orgbool 3235517Snate@binkert.orgbadMode(ThreadContext *tc, OperatingMode mode) 3245517Snate@binkert.org{ 3255517Snate@binkert.org return unknownMode(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode)); 3266654Snate@binkert.org} 3276654Snate@binkert.org 3286654Snate@binkert.orgAddr 3296654Snate@binkert.orgpurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, 3306654Snate@binkert.org TTBCR tcr) 3316654Snate@binkert.org{ 3325517Snate@binkert.org switch (el) { 3335517Snate@binkert.org case EL0: 3345517Snate@binkert.org case EL1: 3356143Snate@binkert.org if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 3365517Snate@binkert.org return addr | mask(63, 55); 3374762Snate@binkert.org else if (!bits(addr, 55, 48) && tcr.tbi0) 3385517Snate@binkert.org return bits(addr,55, 0); 3395517Snate@binkert.org break; 3406143Snate@binkert.org case EL2: 3416143Snate@binkert.org assert(ArmSystem::haveVirtualization(tc)); 3425517Snate@binkert.org tcr = tc->readMiscReg(MISCREG_TCR_EL2); 3435517Snate@binkert.org if (tcr.tbi) 3445517Snate@binkert.org return addr & mask(56); 3455517Snate@binkert.org break; 3465517Snate@binkert.org case EL3: 3475517Snate@binkert.org assert(ArmSystem::haveSecurity(tc)); 3485517Snate@binkert.org if (tcr.tbi) 3495517Snate@binkert.org return addr & mask(56); 3505517Snate@binkert.org break; 3515517Snate@binkert.org default: 3526143Snate@binkert.org panic("Invalid exception level"); 3535517Snate@binkert.org break; 3546654Snate@binkert.org } 3556654Snate@binkert.org 3566654Snate@binkert.org return addr; // Nothing to do if this is not a tagged address 3576654Snate@binkert.org} 3586654Snate@binkert.org 3596654Snate@binkert.orgAddr 3605517Snate@binkert.orgpurifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el) 3615517Snate@binkert.org{ 3625517Snate@binkert.org TTBCR tcr; 3635517Snate@binkert.org 3645517Snate@binkert.org switch (el) { 3654762Snate@binkert.org case EL0: 3664762Snate@binkert.org case EL1: 3674762Snate@binkert.org tcr = tc->readMiscReg(MISCREG_TCR_EL1); 3684762Snate@binkert.org if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 3694762Snate@binkert.org return addr | mask(63, 55); 3704762Snate@binkert.org else if (!bits(addr, 55, 48) && tcr.tbi0) 3716143Snate@binkert.org return bits(addr,55, 0); 3724762Snate@binkert.org break; 3734762Snate@binkert.org case EL2: 3744762Snate@binkert.org assert(ArmSystem::haveVirtualization(tc)); 3754762Snate@binkert.org tcr = tc->readMiscReg(MISCREG_TCR_EL2); 3764382Sbinkertn@umich.edu if (tcr.tbi) 3774382Sbinkertn@umich.edu return addr & mask(56); 3785517Snate@binkert.org break; 3796654Snate@binkert.org case EL3: 3805517Snate@binkert.org assert(ArmSystem::haveSecurity(tc)); 3815798Snate@binkert.org tcr = tc->readMiscReg(MISCREG_TCR_EL3); 3826654Snate@binkert.org if (tcr.tbi) 3836654Snate@binkert.org return addr & mask(56); 3846654Snate@binkert.org break; 3856654Snate@binkert.org default: 3866654Snate@binkert.org panic("Invalid exception level"); 3876654Snate@binkert.org break; 3886654Snate@binkert.org } 3896654Snate@binkert.org 3906654Snate@binkert.org return addr; // Nothing to do if this is not a tagged address 3916654Snate@binkert.org} 3926654Snate@binkert.org 3936654Snate@binkert.orgAddr 3946654Snate@binkert.orgtruncPage(Addr addr) 3956654Snate@binkert.org{ 3966654Snate@binkert.org return addr & ~(PageBytes - 1); 3975517Snate@binkert.org} 3985863Snate@binkert.org 3995798Snate@binkert.orgAddr 4005798Snate@binkert.orgroundPage(Addr addr) 4015798Snate@binkert.org{ 4025798Snate@binkert.org return (addr + PageBytes - 1) & ~(PageBytes - 1); 4035517Snate@binkert.org} 4045517Snate@binkert.org 4055517Snate@binkert.orgbool 4065517Snate@binkert.orgmcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 4075517Snate@binkert.org HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 4085517Snate@binkert.org{ 4095517Snate@binkert.org bool isRead; 4105517Snate@binkert.org uint32_t crm; 4115798Snate@binkert.org IntRegIndex rt; 4125798Snate@binkert.org uint32_t crn; 4135798Snate@binkert.org uint32_t opc1; 4145798Snate@binkert.org uint32_t opc2; 4155798Snate@binkert.org bool trapToHype = false; 4165798Snate@binkert.org 4175517Snate@binkert.org 4185517Snate@binkert.org if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 4195517Snate@binkert.org mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 4205517Snate@binkert.org trapToHype = ((uint32_t) hstr) & (1 << crn); 4215517Snate@binkert.org trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12); 4225517Snate@binkert.org trapToHype |= hcr.tidcp && ( 4235517Snate@binkert.org ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) || 4245517Snate@binkert.org ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) || 4255517Snate@binkert.org ((crn == 11) && ((crm <= 8) || (crm == 15))) ); 4264762Snate@binkert.org 4274382Sbinkertn@umich.edu if (!trapToHype) { 4286143Snate@binkert.org switch (unflattenMiscReg(miscReg)) { 4295517Snate@binkert.org case MISCREG_CPACR: 4304382Sbinkertn@umich.edu trapToHype = hcptr.tcpac; 4314382Sbinkertn@umich.edu break; 4324762Snate@binkert.org case MISCREG_REVIDR: 4334762Snate@binkert.org case MISCREG_TCMTR: 4344762Snate@binkert.org case MISCREG_TLBTR: 4354762Snate@binkert.org case MISCREG_AIDR: 4364762Snate@binkert.org trapToHype = hcr.tid1; 4375517Snate@binkert.org break; 4385517Snate@binkert.org case MISCREG_CTR: 4395517Snate@binkert.org case MISCREG_CCSIDR: 4405517Snate@binkert.org case MISCREG_CLIDR: 4415517Snate@binkert.org case MISCREG_CSSELR: 4425517Snate@binkert.org trapToHype = hcr.tid2; 4435517Snate@binkert.org break; 4445517Snate@binkert.org case MISCREG_ID_PFR0: 4456143Snate@binkert.org case MISCREG_ID_PFR1: 4465517Snate@binkert.org case MISCREG_ID_DFR0: 4475517Snate@binkert.org case MISCREG_ID_AFR0: 4485517Snate@binkert.org case MISCREG_ID_MMFR0: 4495517Snate@binkert.org case MISCREG_ID_MMFR1: 4505517Snate@binkert.org case MISCREG_ID_MMFR2: 4515517Snate@binkert.org case MISCREG_ID_MMFR3: 4525517Snate@binkert.org case MISCREG_ID_ISAR0: 4535517Snate@binkert.org case MISCREG_ID_ISAR1: 4545517Snate@binkert.org case MISCREG_ID_ISAR2: 4555517Snate@binkert.org case MISCREG_ID_ISAR3: 4566143Snate@binkert.org case MISCREG_ID_ISAR4: 4575517Snate@binkert.org case MISCREG_ID_ISAR5: 4585517Snate@binkert.org trapToHype = hcr.tid3; 4595517Snate@binkert.org break; 4605517Snate@binkert.org case MISCREG_DCISW: 4615517Snate@binkert.org case MISCREG_DCCSW: 4625517Snate@binkert.org case MISCREG_DCCISW: 4635517Snate@binkert.org trapToHype = hcr.tsw; 4645517Snate@binkert.org break; 4655517Snate@binkert.org case MISCREG_DCIMVAC: 4665517Snate@binkert.org case MISCREG_DCCIMVAC: 4675517Snate@binkert.org case MISCREG_DCCMVAC: 4685517Snate@binkert.org trapToHype = hcr.tpc; 4695517Snate@binkert.org break; 4705517Snate@binkert.org case MISCREG_ICIMVAU: 4715517Snate@binkert.org case MISCREG_ICIALLU: 4725517Snate@binkert.org case MISCREG_ICIALLUIS: 4735517Snate@binkert.org case MISCREG_DCCMVAU: 4745517Snate@binkert.org trapToHype = hcr.tpu; 4755517Snate@binkert.org break; 4766143Snate@binkert.org case MISCREG_TLBIALLIS: 4775517Snate@binkert.org case MISCREG_TLBIMVAIS: 4784762Snate@binkert.org case MISCREG_TLBIASIDIS: 4794762Snate@binkert.org case MISCREG_TLBIMVAAIS: 4806143Snate@binkert.org case MISCREG_TLBIMVALIS: 4816143Snate@binkert.org case MISCREG_TLBIMVAALIS: 4826143Snate@binkert.org case MISCREG_DTLBIALL: 4834762Snate@binkert.org case MISCREG_ITLBIALL: 4844762Snate@binkert.org case MISCREG_DTLBIMVA: 4854762Snate@binkert.org case MISCREG_ITLBIMVA: 4865517Snate@binkert.org case MISCREG_DTLBIASID: 4874762Snate@binkert.org case MISCREG_ITLBIASID: 4884762Snate@binkert.org case MISCREG_TLBIMVAA: 4894762Snate@binkert.org case MISCREG_TLBIALL: 4905463Snate@binkert.org case MISCREG_TLBIMVA: 4915517Snate@binkert.org case MISCREG_TLBIMVAL: 4924762Snate@binkert.org case MISCREG_TLBIMVAAL: 4934762Snate@binkert.org case MISCREG_TLBIASID: 4944762Snate@binkert.org trapToHype = hcr.ttlb; 4954762Snate@binkert.org break; 4964762Snate@binkert.org case MISCREG_ACTLR: 4974762Snate@binkert.org trapToHype = hcr.tac; 4985463Snate@binkert.org break; 4995517Snate@binkert.org case MISCREG_SCTLR: 5004762Snate@binkert.org case MISCREG_TTBR0: 5014762Snate@binkert.org case MISCREG_TTBR1: 5024762Snate@binkert.org case MISCREG_TTBCR: 5036143Snate@binkert.org case MISCREG_DACR: 5046143Snate@binkert.org case MISCREG_DFSR: 5056143Snate@binkert.org case MISCREG_IFSR: 5064762Snate@binkert.org case MISCREG_DFAR: 5074762Snate@binkert.org case MISCREG_IFAR: 5085517Snate@binkert.org case MISCREG_ADFSR: 5094762Snate@binkert.org case MISCREG_AIFSR: 5104762Snate@binkert.org case MISCREG_PRRR: 5114762Snate@binkert.org case MISCREG_NMRR: 5124762Snate@binkert.org case MISCREG_MAIR0: 5135517Snate@binkert.org case MISCREG_MAIR1: 5144762Snate@binkert.org case MISCREG_CONTEXTIDR: 5154762Snate@binkert.org trapToHype = hcr.tvm & !isRead; 5164762Snate@binkert.org break; 5174762Snate@binkert.org case MISCREG_PMCR: 5185517Snate@binkert.org trapToHype = hdcr.tpmcr; 5195517Snate@binkert.org break; 5205517Snate@binkert.org // No default action needed 5215517Snate@binkert.org default: 5225517Snate@binkert.org break; 5235517Snate@binkert.org } 5245517Snate@binkert.org } 5255517Snate@binkert.org } 5265517Snate@binkert.org return trapToHype; 5275517Snate@binkert.org} 5285517Snate@binkert.org 5295517Snate@binkert.org 5305517Snate@binkert.orgbool 5315517Snate@binkert.orgmcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 5325517Snate@binkert.org HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 5335517Snate@binkert.org{ 5345517Snate@binkert.org bool isRead; 5355517Snate@binkert.org uint32_t crm; 5365517Snate@binkert.org IntRegIndex rt; 5375517Snate@binkert.org uint32_t crn; 5385517Snate@binkert.org uint32_t opc1; 5395517Snate@binkert.org uint32_t opc2; 5405517Snate@binkert.org bool trapToHype = false; 5415517Snate@binkert.org 5425517Snate@binkert.org if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 5435517Snate@binkert.org mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 5445517Snate@binkert.org inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n", 5455517Snate@binkert.org crm, crn, opc1, opc2, hdcr, hcptr, hstr); 5465517Snate@binkert.org trapToHype = hdcr.tda && (opc1 == 0); 5475517Snate@binkert.org trapToHype |= hcptr.tta && (opc1 == 1); 5485517Snate@binkert.org if (!trapToHype) { 5495517Snate@binkert.org switch (unflattenMiscReg(miscReg)) { 5505517Snate@binkert.org case MISCREG_DBGOSLSR: 5515517Snate@binkert.org case MISCREG_DBGOSLAR: 5525517Snate@binkert.org case MISCREG_DBGOSDLR: 5535517Snate@binkert.org case MISCREG_DBGPRCR: 5545517Snate@binkert.org trapToHype = hdcr.tdosa; 5555517Snate@binkert.org break; 5565517Snate@binkert.org case MISCREG_DBGDRAR: 5575517Snate@binkert.org case MISCREG_DBGDSAR: 5585517Snate@binkert.org trapToHype = hdcr.tdra; 5595517Snate@binkert.org break; 5605517Snate@binkert.org case MISCREG_JIDR: 5615517Snate@binkert.org trapToHype = hcr.tid0; 5625517Snate@binkert.org break; 5635517Snate@binkert.org case MISCREG_JOSCR: 5645517Snate@binkert.org case MISCREG_JMCR: 5655517Snate@binkert.org trapToHype = hstr.tjdbx; 5665517Snate@binkert.org break; 5675517Snate@binkert.org case MISCREG_TEECR: 5685517Snate@binkert.org case MISCREG_TEEHBR: 5695517Snate@binkert.org trapToHype = hstr.ttee; 5705517Snate@binkert.org break; 5715517Snate@binkert.org // No default action needed 5725517Snate@binkert.org default: 5735517Snate@binkert.org break; 5745517Snate@binkert.org } 5755517Snate@binkert.org } 5765517Snate@binkert.org } 5775517Snate@binkert.org return trapToHype; 5785517Snate@binkert.org} 5795517Snate@binkert.org 5805517Snate@binkert.orgbool 5815517Snate@binkert.orgmcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, 5825517Snate@binkert.org HCR hcr, uint32_t iss) 5835517Snate@binkert.org{ 5845610Snate@binkert.org uint32_t crm; 5855623Snate@binkert.org IntRegIndex rt; 5865623Snate@binkert.org uint32_t crn; 5875623Snate@binkert.org uint32_t opc1; 5885610Snate@binkert.org uint32_t opc2; 5895517Snate@binkert.org bool isRead; 5905623Snate@binkert.org bool trapToHype = false; 5915623Snate@binkert.org 5925623Snate@binkert.org if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 5935623Snate@binkert.org // This is technically the wrong function, but we can re-use it for 5945623Snate@binkert.org // the moment because we only need one field, which overlaps with the 5955623Snate@binkert.org // mcrmrc layout 5965623Snate@binkert.org mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 5975517Snate@binkert.org trapToHype = ((uint32_t) hstr) & (1 << crm); 5985610Snate@binkert.org 5995610Snate@binkert.org if (!trapToHype) { 6005610Snate@binkert.org switch (unflattenMiscReg(miscReg)) { 6015610Snate@binkert.org case MISCREG_SCTLR: 6025517Snate@binkert.org case MISCREG_TTBR0: 6035517Snate@binkert.org case MISCREG_TTBR1: 6045610Snate@binkert.org case MISCREG_TTBCR: 6055610Snate@binkert.org case MISCREG_DACR: 6065517Snate@binkert.org case MISCREG_DFSR: 6075517Snate@binkert.org case MISCREG_IFSR: 6085517Snate@binkert.org case MISCREG_DFAR: 6095517Snate@binkert.org case MISCREG_IFAR: 6105517Snate@binkert.org case MISCREG_ADFSR: 6115517Snate@binkert.org case MISCREG_AIFSR: 6125517Snate@binkert.org case MISCREG_PRRR: 6135517Snate@binkert.org case MISCREG_NMRR: 6145517Snate@binkert.org case MISCREG_MAIR0: 6155517Snate@binkert.org case MISCREG_MAIR1: 6164762Snate@binkert.org case MISCREG_CONTEXTIDR: 6176143Snate@binkert.org trapToHype = hcr.tvm & !isRead; 6186143Snate@binkert.org break; 6195463Snate@binkert.org // No default action needed 6204762Snate@binkert.org default: 6214762Snate@binkert.org break; 6224762Snate@binkert.org } 6236143Snate@binkert.org } 6246143Snate@binkert.org } 6254382Sbinkertn@umich.edu return trapToHype; 6264382Sbinkertn@umich.edu} 6276143Snate@binkert.org 6286143Snate@binkert.orgbool 6294382Sbinkertn@umich.edumsrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el, 6304762Snate@binkert.org CPACR cpacr /* CPACR_EL1 */) 6315517Snate@binkert.org{ 6325517Snate@binkert.org bool trapToSup = false; 6335517Snate@binkert.org switch (miscReg) { 6345517Snate@binkert.org case MISCREG_FPCR: 6355517Snate@binkert.org case MISCREG_FPSR: 6365517Snate@binkert.org case MISCREG_FPEXC32_EL2: 6375522Snate@binkert.org if ((el == EL0 && cpacr.fpen != 0x3) || 6385517Snate@binkert.org (el == EL1 && !(cpacr.fpen & 0x1))) 6395517Snate@binkert.org trapToSup = true; 6405517Snate@binkert.org break; 6415517Snate@binkert.org default: 6425517Snate@binkert.org break; 6436143Snate@binkert.org } 6446143Snate@binkert.org return trapToSup; 6456143Snate@binkert.org} 6465522Snate@binkert.org 6474382Sbinkertn@umich.edubool 6486229Snate@binkert.orgmsrMrs64TrapToHyp(const MiscRegIndex miscReg, 6496229Snate@binkert.org ExceptionLevel el, 6506229Snate@binkert.org bool isRead, 6516229Snate@binkert.org CPTR cptr /* CPTR_EL2 */, 6526229Snate@binkert.org HCR hcr /* HCR_EL2 */, 6536229Snate@binkert.org bool * isVfpNeon) 6546229Snate@binkert.org{ 6556229Snate@binkert.org bool trapToHyp = false; 6566229Snate@binkert.org *isVfpNeon = false; 6576229Snate@binkert.org 6586229Snate@binkert.org switch (miscReg) { 6596229Snate@binkert.org // FP/SIMD regs 6606229Snate@binkert.org case MISCREG_FPCR: 6616229Snate@binkert.org case MISCREG_FPSR: 6626229Snate@binkert.org case MISCREG_FPEXC32_EL2: 6636229Snate@binkert.org trapToHyp = cptr.tfp; 6646229Snate@binkert.org *isVfpNeon = true; 6656229Snate@binkert.org break; 6666229Snate@binkert.org // CPACR 6676229Snate@binkert.org case MISCREG_CPACR_EL1: 6686229Snate@binkert.org trapToHyp = cptr.tcpac && el == EL1; 6695192Ssaidi@eecs.umich.edu break; 6705517Snate@binkert.org // Virtual memory control regs 6715517Snate@binkert.org case MISCREG_SCTLR_EL1: 6725517Snate@binkert.org case MISCREG_TTBR0_EL1: 6735517Snate@binkert.org case MISCREG_TTBR1_EL1: 6746229Snate@binkert.org case MISCREG_TCR_EL1: 6756229Snate@binkert.org case MISCREG_ESR_EL1: 6765799Snate@binkert.org case MISCREG_FAR_EL1: 6775799Snate@binkert.org case MISCREG_AFSR0_EL1: 6785517Snate@binkert.org case MISCREG_AFSR1_EL1: 6795517Snate@binkert.org case MISCREG_MAIR_EL1: 6805517Snate@binkert.org case MISCREG_AMAIR_EL1: 6815517Snate@binkert.org case MISCREG_CONTEXTIDR_EL1: 6825517Snate@binkert.org trapToHyp = ((hcr.trvm && isRead) || (hcr.tvm && !isRead)) 6835517Snate@binkert.org && el == EL1; 6845799Snate@binkert.org break; 6855517Snate@binkert.org // TLB maintenance instructions 6865517Snate@binkert.org case MISCREG_TLBI_VMALLE1: 6875517Snate@binkert.org case MISCREG_TLBI_VAE1_Xt: 6885517Snate@binkert.org case MISCREG_TLBI_ASIDE1_Xt: 6895517Snate@binkert.org case MISCREG_TLBI_VAAE1_Xt: 6905517Snate@binkert.org case MISCREG_TLBI_VALE1_Xt: 6915517Snate@binkert.org case MISCREG_TLBI_VAALE1_Xt: 6925799Snate@binkert.org case MISCREG_TLBI_VMALLE1IS: 6935517Snate@binkert.org case MISCREG_TLBI_VAE1IS_Xt: 6945517Snate@binkert.org case MISCREG_TLBI_ASIDE1IS_Xt: 6955799Snate@binkert.org case MISCREG_TLBI_VAAE1IS_Xt: 6965517Snate@binkert.org case MISCREG_TLBI_VALE1IS_Xt: 6975517Snate@binkert.org case MISCREG_TLBI_VAALE1IS_Xt: 6985517Snate@binkert.org trapToHyp = hcr.ttlb && el == EL1; 6995517Snate@binkert.org break; 7005517Snate@binkert.org // Cache maintenance instructions to the point of unification 7015517Snate@binkert.org case MISCREG_IC_IVAU_Xt: 7025517Snate@binkert.org case MISCREG_ICIALLU: 7035517Snate@binkert.org case MISCREG_ICIALLUIS: 7045799Snate@binkert.org case MISCREG_DC_CVAU_Xt: 7055517Snate@binkert.org trapToHyp = hcr.tpu && el <= EL1; 7065517Snate@binkert.org break; 7075517Snate@binkert.org // Data/Unified cache maintenance instructions to the point of coherency 7085517Snate@binkert.org case MISCREG_DC_IVAC_Xt: 7095517Snate@binkert.org case MISCREG_DC_CIVAC_Xt: 7105517Snate@binkert.org case MISCREG_DC_CVAC_Xt: 7115517Snate@binkert.org trapToHyp = hcr.tpc && el <= EL1; 7125517Snate@binkert.org break; 7135517Snate@binkert.org // Data/Unified cache maintenance instructions by set/way 7145517Snate@binkert.org case MISCREG_DC_ISW_Xt: 7155517Snate@binkert.org case MISCREG_DC_CSW_Xt: 7165517Snate@binkert.org case MISCREG_DC_CISW_Xt: 7176229Snate@binkert.org trapToHyp = hcr.tsw && el == EL1; 7185517Snate@binkert.org break; 7195517Snate@binkert.org // ACTLR 7205517Snate@binkert.org case MISCREG_ACTLR_EL1: 7215517Snate@binkert.org trapToHyp = hcr.tacr && el == EL1; 7225517Snate@binkert.org break; 7235517Snate@binkert.org 7245517Snate@binkert.org // @todo: Trap implementation-dependent functionality based on 7255517Snate@binkert.org // hcr.tidcp 7265517Snate@binkert.org 7275517Snate@binkert.org // ID regs, group 3 7285517Snate@binkert.org case MISCREG_ID_PFR0_EL1: 7295517Snate@binkert.org case MISCREG_ID_PFR1_EL1: 7305517Snate@binkert.org case MISCREG_ID_DFR0_EL1: 7315517Snate@binkert.org case MISCREG_ID_AFR0_EL1: 7325517Snate@binkert.org case MISCREG_ID_MMFR0_EL1: 7335517Snate@binkert.org case MISCREG_ID_MMFR1_EL1: 7345517Snate@binkert.org case MISCREG_ID_MMFR2_EL1: 7355517Snate@binkert.org case MISCREG_ID_MMFR3_EL1: 7365517Snate@binkert.org case MISCREG_ID_ISAR0_EL1: 7375517Snate@binkert.org case MISCREG_ID_ISAR1_EL1: 7385517Snate@binkert.org case MISCREG_ID_ISAR2_EL1: 7395517Snate@binkert.org case MISCREG_ID_ISAR3_EL1: 7405517Snate@binkert.org case MISCREG_ID_ISAR4_EL1: 7415517Snate@binkert.org case MISCREG_ID_ISAR5_EL1: 7425517Snate@binkert.org case MISCREG_MVFR0_EL1: 7435517Snate@binkert.org case MISCREG_MVFR1_EL1: 7445517Snate@binkert.org case MISCREG_MVFR2_EL1: 7455517Snate@binkert.org case MISCREG_ID_AA64PFR0_EL1: 7465517Snate@binkert.org case MISCREG_ID_AA64PFR1_EL1: 7475517Snate@binkert.org case MISCREG_ID_AA64DFR0_EL1: 7485517Snate@binkert.org case MISCREG_ID_AA64DFR1_EL1: 7495517Snate@binkert.org case MISCREG_ID_AA64ISAR0_EL1: 7505517Snate@binkert.org case MISCREG_ID_AA64ISAR1_EL1: 7515517Snate@binkert.org case MISCREG_ID_AA64MMFR0_EL1: 7525517Snate@binkert.org case MISCREG_ID_AA64MMFR1_EL1: 7535517Snate@binkert.org case MISCREG_ID_AA64AFR0_EL1: 7545517Snate@binkert.org case MISCREG_ID_AA64AFR1_EL1: 7555517Snate@binkert.org assert(isRead); 7565517Snate@binkert.org trapToHyp = hcr.tid3 && el == EL1; 7575517Snate@binkert.org break; 7585517Snate@binkert.org // ID regs, group 2 7595517Snate@binkert.org case MISCREG_CTR_EL0: 7605517Snate@binkert.org case MISCREG_CCSIDR_EL1: 7615517Snate@binkert.org case MISCREG_CLIDR_EL1: 7625517Snate@binkert.org case MISCREG_CSSELR_EL1: 7635517Snate@binkert.org trapToHyp = hcr.tid2 && el <= EL1; 7645517Snate@binkert.org break; 7655517Snate@binkert.org // ID regs, group 1 7665517Snate@binkert.org case MISCREG_AIDR_EL1: 7675517Snate@binkert.org case MISCREG_REVIDR_EL1: 7685517Snate@binkert.org assert(isRead); 7695517Snate@binkert.org trapToHyp = hcr.tid1 && el == EL1; 7705517Snate@binkert.org break; 7715517Snate@binkert.org default: 7725517Snate@binkert.org break; 7735517Snate@binkert.org } 7745517Snate@binkert.org return trapToHyp; 7755517Snate@binkert.org} 7765517Snate@binkert.org 7775517Snate@binkert.orgbool 7785517Snate@binkert.orgmsrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */, 7795517Snate@binkert.org ExceptionLevel el, bool * isVfpNeon) 7805517Snate@binkert.org{ 7815517Snate@binkert.org bool trapToMon = false; 7825517Snate@binkert.org *isVfpNeon = false; 7835517Snate@binkert.org 7845517Snate@binkert.org switch (miscReg) { 7855517Snate@binkert.org // FP/SIMD regs 7865517Snate@binkert.org case MISCREG_FPCR: 7875517Snate@binkert.org case MISCREG_FPSR: 7885517Snate@binkert.org case MISCREG_FPEXC32_EL2: 7895517Snate@binkert.org trapToMon = cptr.tfp; 7906229Snate@binkert.org *isVfpNeon = true; 7915517Snate@binkert.org break; 7925517Snate@binkert.org // CPACR, CPTR 7935517Snate@binkert.org case MISCREG_CPACR_EL1: 7945517Snate@binkert.org if (el == EL1) { 7955517Snate@binkert.org trapToMon = cptr.tcpac; 7965517Snate@binkert.org } 7975517Snate@binkert.org break; 7985517Snate@binkert.org case MISCREG_CPTR_EL2: 7995517Snate@binkert.org if (el == EL2) { 8005517Snate@binkert.org trapToMon = cptr.tcpac; 8015517Snate@binkert.org } 8025517Snate@binkert.org break; 8035517Snate@binkert.org default: 8045517Snate@binkert.org break; 8055517Snate@binkert.org } 8065517Snate@binkert.org return trapToMon; 8075517Snate@binkert.org} 8085517Snate@binkert.org 8095517Snate@binkert.orgbool 8105517Snate@binkert.orgdecodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, 8115517Snate@binkert.org CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity) 8125517Snate@binkert.org{ 8135517Snate@binkert.org OperatingMode mode = MODE_UNDEFINED; 8145517Snate@binkert.org bool ok = true; 8155517Snate@binkert.org 8165517Snate@binkert.org // R mostly indicates if its a int register or a misc reg, we override 8175517Snate@binkert.org // below if the few corner cases 8185517Snate@binkert.org isIntReg = !r; 8195517Snate@binkert.org // Loosely based on ARM ARM issue C section B9.3.10 8205517Snate@binkert.org if (r) { 8215517Snate@binkert.org switch (sysM) 8225517Snate@binkert.org { 8235517Snate@binkert.org case 0xE: 8245517Snate@binkert.org regIdx = MISCREG_SPSR_FIQ; 8255517Snate@binkert.org mode = MODE_FIQ; 8265517Snate@binkert.org break; 8275517Snate@binkert.org case 0x10: 8285517Snate@binkert.org regIdx = MISCREG_SPSR_IRQ; 8295517Snate@binkert.org mode = MODE_IRQ; 8305517Snate@binkert.org break; 8315517Snate@binkert.org case 0x12: 8325517Snate@binkert.org regIdx = MISCREG_SPSR_SVC; 8335517Snate@binkert.org mode = MODE_SVC; 8345517Snate@binkert.org break; 8355517Snate@binkert.org case 0x14: 8365517Snate@binkert.org regIdx = MISCREG_SPSR_ABT; 8375517Snate@binkert.org mode = MODE_ABORT; 8385517Snate@binkert.org break; 8395517Snate@binkert.org case 0x16: 8405517Snate@binkert.org regIdx = MISCREG_SPSR_UND; 8415517Snate@binkert.org mode = MODE_UNDEFINED; 8425517Snate@binkert.org break; 8435517Snate@binkert.org case 0x1C: 8445517Snate@binkert.org regIdx = MISCREG_SPSR_MON; 8455517Snate@binkert.org mode = MODE_MON; 8465517Snate@binkert.org break; 8475517Snate@binkert.org case 0x1E: 8485517Snate@binkert.org regIdx = MISCREG_SPSR_HYP; 8495517Snate@binkert.org mode = MODE_HYP; 8505517Snate@binkert.org break; 8515517Snate@binkert.org default: 8526143Snate@binkert.org ok = false; 8535517Snate@binkert.org break; 8545192Ssaidi@eecs.umich.edu } 8555192Ssaidi@eecs.umich.edu } else { 8565517Snate@binkert.org int sysM4To3 = bits(sysM, 4, 3); 8575517Snate@binkert.org 8585192Ssaidi@eecs.umich.edu if (sysM4To3 == 0) { 8595192Ssaidi@eecs.umich.edu mode = MODE_USER; 8605522Snate@binkert.org regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 8615522Snate@binkert.org } else if (sysM4To3 == 1) { 8625522Snate@binkert.org mode = MODE_FIQ; 8635522Snate@binkert.org regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 8645522Snate@binkert.org } else if (sysM4To3 == 3) { 8655522Snate@binkert.org if (bits(sysM, 1) == 0) { 8665522Snate@binkert.org mode = MODE_MON; 8675522Snate@binkert.org regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 8685522Snate@binkert.org } else { 8695522Snate@binkert.org mode = MODE_HYP; 8705517Snate@binkert.org if (bits(sysM, 0) == 1) { 8715522Snate@binkert.org regIdx = intRegInMode(mode, 13); // R13 in HYP 8725522Snate@binkert.org } else { 8735517Snate@binkert.org isIntReg = false; 8746143Snate@binkert.org regIdx = MISCREG_ELR_HYP; 8755604Snate@binkert.org } 8765522Snate@binkert.org } 8775522Snate@binkert.org } else { // Other Banked registers 8785522Snate@binkert.org int sysM2 = bits(sysM, 2); 8795517Snate@binkert.org int sysM1 = bits(sysM, 1); 8805522Snate@binkert.org 8815522Snate@binkert.org mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) | 8825522Snate@binkert.org (1 << 1) | 8835522Snate@binkert.org ((sysM2 && !sysM1) << 2) | 8845522Snate@binkert.org ((sysM2 && sysM1) << 3) | 8855522Snate@binkert.org (1 << 4) ); 8865522Snate@binkert.org regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 8875522Snate@binkert.org // Don't flatten the register here. This is going to go through 8885522Snate@binkert.org // setIntReg() which will do the flattening 8895522Snate@binkert.org ok &= mode != cpsr.mode; 8905522Snate@binkert.org } 8915522Snate@binkert.org } 8925522Snate@binkert.org 8935522Snate@binkert.org // Check that the requested register is accessable from the current mode 8945522Snate@binkert.org if (ok && checkSecurity && mode != cpsr.mode) { 8955522Snate@binkert.org switch (cpsr.mode) 8965522Snate@binkert.org { 8975522Snate@binkert.org case MODE_USER: 8985522Snate@binkert.org ok = false; 8996143Snate@binkert.org break; 9005522Snate@binkert.org case MODE_FIQ: 9015522Snate@binkert.org ok &= mode != MODE_HYP; 9024382Sbinkertn@umich.edu ok &= (mode != MODE_MON) || !scr.ns; 9035522Snate@binkert.org break; 9045522Snate@binkert.org case MODE_HYP: 9055522Snate@binkert.org ok &= mode != MODE_MON; 9065522Snate@binkert.org ok &= (mode != MODE_FIQ) || !nsacr.rfr; 9075522Snate@binkert.org break; 9085522Snate@binkert.org case MODE_IRQ: 9095522Snate@binkert.org case MODE_SVC: 9104382Sbinkertn@umich.edu case MODE_ABORT: 9115522Snate@binkert.org case MODE_UNDEFINED: 9126143Snate@binkert.org case MODE_SYSTEM: 9135522Snate@binkert.org ok &= mode != MODE_HYP; 9145522Snate@binkert.org ok &= (mode != MODE_MON) || !scr.ns; 9155522Snate@binkert.org ok &= (mode != MODE_FIQ) || !nsacr.rfr; 9165522Snate@binkert.org break; 9175522Snate@binkert.org // can access everything, no further checks required 9185522Snate@binkert.org case MODE_MON: 9195522Snate@binkert.org break; 9205522Snate@binkert.org default: 9215522Snate@binkert.org panic("unknown Mode 0x%x\n", cpsr.mode); 9225522Snate@binkert.org break; 9235522Snate@binkert.org } 9245522Snate@binkert.org } 9255522Snate@binkert.org return (ok); 9265522Snate@binkert.org} 9275522Snate@binkert.org 9285522Snate@binkert.orgbool 9295522Snate@binkert.orgSPAlignmentCheckEnabled(ThreadContext* tc) 9305522Snate@binkert.org{ 9315522Snate@binkert.org switch (opModeToEL(currOpMode(tc))) { 9325522Snate@binkert.org case EL3: 9335522Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa; 9345522Snate@binkert.org case EL2: 9355522Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa; 9365522Snate@binkert.org case EL1: 9375522Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa; 9385522Snate@binkert.org case EL0: 9396143Snate@binkert.org return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0; 9406143Snate@binkert.org default: 9416143Snate@binkert.org panic("Invalid exception level"); 9426143Snate@binkert.org break; 9435522Snate@binkert.org } 9444382Sbinkertn@umich.edu} 9454382Sbinkertn@umich.edu 9464382Sbinkertn@umich.eduint 9474382Sbinkertn@umich.edudecodePhysAddrRange64(uint8_t pa_enc) 9484382Sbinkertn@umich.edu{ 9494382Sbinkertn@umich.edu switch (pa_enc) { 9504382Sbinkertn@umich.edu case 0x0: 9514382Sbinkertn@umich.edu return 32; 9524382Sbinkertn@umich.edu case 0x1: 9534382Sbinkertn@umich.edu return 36; 9546143Snate@binkert.org case 0x2: 955955SN/A return 40; 9562655Sstever@eecs.umich.edu case 0x3: 9572655Sstever@eecs.umich.edu return 42; 9582655Sstever@eecs.umich.edu case 0x4: 9592655Sstever@eecs.umich.edu return 44; 9602655Sstever@eecs.umich.edu case 0x5: 9615601Snate@binkert.org case 0x6: 9625601Snate@binkert.org case 0x7: 9635601Snate@binkert.org return 48; 9645601Snate@binkert.org default: 9655522Snate@binkert.org panic("Invalid phys. address range encoding"); 9665863Snate@binkert.org } 9675601Snate@binkert.org} 9685601Snate@binkert.org 9695601Snate@binkert.orguint8_t 9705863Snate@binkert.orgencodePhysAddrRange64(int pa_size) 9716143Snate@binkert.org{ 9725559Snate@binkert.org switch (pa_size) { 9735559Snate@binkert.org case 32: 9745559Snate@binkert.org return 0x0; 9755559Snate@binkert.org case 36: 9765601Snate@binkert.org return 0x1; 9776143Snate@binkert.org case 40: 9786143Snate@binkert.org return 0x2; 9796143Snate@binkert.org case 42: 9806143Snate@binkert.org return 0x3; 9816143Snate@binkert.org case 44: 9826143Snate@binkert.org return 0x4; 9836143Snate@binkert.org case 48: 9846143Snate@binkert.org return 0x5; 9856143Snate@binkert.org default: 9866143Snate@binkert.org panic("Invalid phys. address range"); 9876143Snate@binkert.org } 9886143Snate@binkert.org} 9896143Snate@binkert.org 9906143Snate@binkert.org} // namespace ArmISA 9916143Snate@binkert.org