utility.cc revision 12494
1/*
2 * Copyright (c) 2009-2014, 2016-2017 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 */
39
40#include "arch/arm/utility.hh"
41
42#include <memory>
43
44#include "arch/arm/faults.hh"
45#include "arch/arm/isa_traits.hh"
46#include "arch/arm/system.hh"
47#include "arch/arm/tlb.hh"
48#include "arch/arm/vtophys.hh"
49#include "cpu/base.hh"
50#include "cpu/checker/cpu.hh"
51#include "cpu/thread_context.hh"
52#include "mem/fs_translating_port_proxy.hh"
53#include "sim/full_system.hh"
54
55namespace ArmISA {
56
57void
58initCPU(ThreadContext *tc, int cpuId)
59{
60    // Reset CP15?? What does that mean -- ali
61
62    // FPEXC.EN = 0
63
64    static Fault reset = std::make_shared<Reset>();
65    reset->invoke(tc);
66}
67
68uint64_t
69getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
70{
71    if (!FullSystem) {
72        panic("getArgument() only implemented for full system mode.\n");
73        M5_DUMMY_RETURN
74    }
75
76    if (fp)
77        panic("getArgument(): Floating point arguments not implemented\n");
78
79    if (inAArch64(tc)) {
80        if (size == (uint16_t)(-1))
81            size = sizeof(uint64_t);
82
83        if (number < 8 /*NumArgumentRegs64*/) {
84               return tc->readIntReg(number);
85        } else {
86            panic("getArgument(): No support reading stack args for AArch64\n");
87        }
88    } else {
89        if (size == (uint16_t)(-1))
90            // todo: should this not be sizeof(uint32_t) rather?
91            size = ArmISA::MachineBytes;
92
93        if (number < NumArgumentRegs) {
94            // If the argument is 64 bits, it must be in an even regiser
95            // number. Increment the number here if it isn't even.
96            if (size == sizeof(uint64_t)) {
97                if ((number % 2) != 0)
98                    number++;
99                // Read the two halves of the data. Number is inc here to
100                // get the second half of the 64 bit reg.
101                uint64_t tmp;
102                tmp = tc->readIntReg(number++);
103                tmp |= tc->readIntReg(number) << 32;
104                return tmp;
105            } else {
106               return tc->readIntReg(number);
107            }
108        } else {
109            Addr sp = tc->readIntReg(StackPointerReg);
110            FSTranslatingPortProxy &vp = tc->getVirtProxy();
111            uint64_t arg;
112            if (size == sizeof(uint64_t)) {
113                // If the argument is even it must be aligned
114                if ((number % 2) != 0)
115                    number++;
116                arg = vp.read<uint64_t>(sp +
117                        (number-NumArgumentRegs) * sizeof(uint32_t));
118                // since two 32 bit args == 1 64 bit arg, increment number
119                number++;
120            } else {
121                arg = vp.read<uint32_t>(sp +
122                               (number-NumArgumentRegs) * sizeof(uint32_t));
123            }
124            return arg;
125        }
126    }
127    panic("getArgument() should always return\n");
128}
129
130void
131skipFunction(ThreadContext *tc)
132{
133    PCState newPC = tc->pcState();
134    if (inAArch64(tc)) {
135        newPC.set(tc->readIntReg(INTREG_X30));
136    } else {
137        newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
138    }
139
140    CheckerCPU *checker = tc->getCheckerCpuPtr();
141    if (checker) {
142        tc->pcStateNoRecord(newPC);
143    } else {
144        tc->pcState(newPC);
145    }
146}
147
148void
149copyRegs(ThreadContext *src, ThreadContext *dest)
150{
151    for (int i = 0; i < NumIntRegs; i++)
152        dest->setIntRegFlat(i, src->readIntRegFlat(i));
153
154    for (int i = 0; i < NumFloatRegs; i++)
155        dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
156
157    for (int i = 0; i < NumVecRegs; i++)
158        dest->setVecRegFlat(i, src->readVecRegFlat(i));
159
160    for (int i = 0; i < NumCCRegs; i++)
161        dest->setCCReg(i, src->readCCReg(i));
162
163    for (int i = 0; i < NumMiscRegs; i++)
164        dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
165
166    // setMiscReg "with effect" will set the misc register mapping correctly.
167    // e.g. updateRegMap(val)
168    dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
169
170    // Copy over the PC State
171    dest->pcState(src->pcState());
172
173    // Invalidate the tlb misc register cache
174    dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg();
175    dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg();
176}
177
178bool
179inSecureState(ThreadContext *tc)
180{
181    SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) :
182        tc->readMiscReg(MISCREG_SCR);
183    return ArmSystem::haveSecurity(tc) && inSecureState(
184        scr, tc->readMiscReg(MISCREG_CPSR));
185}
186
187bool
188inAArch64(ThreadContext *tc)
189{
190    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
191    return opModeIs64((OperatingMode) (uint8_t) cpsr.mode);
192}
193
194bool
195longDescFormatInUse(ThreadContext *tc)
196{
197    TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR);
198    return ArmSystem::haveLPAE(tc) && ttbcr.eae;
199}
200
201uint32_t
202getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
203{
204    // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
205    // Reference Manual
206    //
207    // bit   31 - Multi-processor extensions available
208    // bit   30 - Uni-processor system
209    // bit   24 - Multi-threaded cores
210    // bit 11-8 - Cluster ID
211    // bit  1-0 - CPU ID
212    //
213    // We deliberately extend both the Cluster ID and CPU ID fields to allow
214    // for simulation of larger systems
215    assert((0 <= tc->cpuId()) && (tc->cpuId() < 256));
216    assert(tc->socketId() < 65536);
217    if (arm_sys->multiThread) {
218       return 0x80000000 | // multiprocessor extensions available
219              tc->contextId();
220    } else if (arm_sys->multiProc) {
221       return 0x80000000 | // multiprocessor extensions available
222              tc->cpuId() | tc->socketId() << 8;
223    } else {
224       return 0x80000000 |  // multiprocessor extensions available
225              0x40000000 |  // in up system
226              tc->cpuId() | tc->socketId() << 8;
227    }
228}
229
230bool
231ELIs64(ThreadContext *tc, ExceptionLevel el)
232{
233    return !ELIs32(tc, el);
234}
235
236bool
237ELIs32(ThreadContext *tc, ExceptionLevel el)
238{
239    // Return true if the specified EL is in aarch32 state.
240
241    const bool have_el3 = ArmSystem::haveSecurity(tc);
242    const bool have_el2 = ArmSystem::haveVirtualization(tc);
243
244    panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist");
245    panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist");
246
247    if (ArmSystem::highestELIs64(tc)
248              && ArmSystem::highestEL(tc) == el) {
249        return false;
250    } else if (!ArmSystem::highestELIs64(tc)) {
251        // All levels are using AArch32
252        return true;
253    } else {
254        SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
255        bool aarch32_below_el3 = (have_el3 && scr.rw == 0);
256
257        HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
258        bool aarch32_at_el1 = (aarch32_below_el3
259                                || (have_el2
260                                && !inSecureState(tc) && hcr.rw == 0));
261
262        // Only know if EL0 using AArch32 from PSTATE
263        if (el == EL0 && !aarch32_at_el1) {
264            CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
265            panic_if(cpsr.el != EL0, "EL0 state is UNKNOWN");
266            // EL0 controlled by PSTATE
267            return cpsr.width != 0;
268        } else {
269            return (aarch32_below_el3 && el != EL3)
270                     || (aarch32_at_el1 && (el == EL0 || el == EL1) );
271        }
272    }
273}
274
275bool
276isBigEndian64(ThreadContext *tc)
277{
278    switch (opModeToEL(currOpMode(tc))) {
279      case EL3:
280        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee;
281      case EL2:
282        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee;
283      case EL1:
284        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee;
285      case EL0:
286        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e;
287      default:
288        panic("Invalid exception level");
289        break;
290    }
291}
292
293Addr
294purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
295                 TTBCR tcr)
296{
297    switch (el) {
298      case EL0:
299      case EL1:
300        if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
301            return addr | mask(63, 55);
302        else if (!bits(addr, 55, 48) && tcr.tbi0)
303            return bits(addr,55, 0);
304        break;
305      case EL2:
306        assert(ArmSystem::haveVirtualization(tc));
307        tcr = tc->readMiscReg(MISCREG_TCR_EL2);
308        if (tcr.tbi)
309            return addr & mask(56);
310        break;
311      case EL3:
312        assert(ArmSystem::haveSecurity(tc));
313        if (tcr.tbi)
314            return addr & mask(56);
315        break;
316      default:
317        panic("Invalid exception level");
318        break;
319    }
320
321    return addr;  // Nothing to do if this is not a tagged address
322}
323
324Addr
325purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el)
326{
327    TTBCR tcr;
328
329    switch (el) {
330      case EL0:
331      case EL1:
332        tcr = tc->readMiscReg(MISCREG_TCR_EL1);
333        if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
334            return addr | mask(63, 55);
335        else if (!bits(addr, 55, 48) && tcr.tbi0)
336            return bits(addr,55, 0);
337        break;
338      case EL2:
339        assert(ArmSystem::haveVirtualization(tc));
340        tcr = tc->readMiscReg(MISCREG_TCR_EL2);
341        if (tcr.tbi)
342            return addr & mask(56);
343        break;
344      case EL3:
345        assert(ArmSystem::haveSecurity(tc));
346        tcr = tc->readMiscReg(MISCREG_TCR_EL3);
347        if (tcr.tbi)
348            return addr & mask(56);
349        break;
350      default:
351        panic("Invalid exception level");
352        break;
353    }
354
355    return addr;  // Nothing to do if this is not a tagged address
356}
357
358Addr
359truncPage(Addr addr)
360{
361    return addr & ~(PageBytes - 1);
362}
363
364Addr
365roundPage(Addr addr)
366{
367    return (addr + PageBytes - 1) & ~(PageBytes - 1);
368}
369
370bool
371mcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
372                  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
373{
374    bool        isRead;
375    uint32_t    crm;
376    IntRegIndex rt;
377    uint32_t    crn;
378    uint32_t    opc1;
379    uint32_t    opc2;
380    bool        trapToHype = false;
381
382
383    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
384        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
385        trapToHype  = ((uint32_t) hstr) & (1 << crn);
386        trapToHype |= hdcr.tpm  && (crn == 9) && (crm >= 12);
387        trapToHype |= hcr.tidcp && (
388            ((crn ==  9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
389            ((crn == 10) && ((crm <= 1) ||  (crm == 4) || (crm == 8)))  ||
390            ((crn == 11) && ((crm <= 8) ||  (crm == 15)))               );
391
392        if (!trapToHype) {
393            switch (unflattenMiscReg(miscReg)) {
394              case MISCREG_CPACR:
395                trapToHype = hcptr.tcpac;
396                break;
397              case MISCREG_REVIDR:
398              case MISCREG_TCMTR:
399              case MISCREG_TLBTR:
400              case MISCREG_AIDR:
401                trapToHype = hcr.tid1;
402                break;
403              case MISCREG_CTR:
404              case MISCREG_CCSIDR:
405              case MISCREG_CLIDR:
406              case MISCREG_CSSELR:
407                trapToHype = hcr.tid2;
408                break;
409              case MISCREG_ID_PFR0:
410              case MISCREG_ID_PFR1:
411              case MISCREG_ID_DFR0:
412              case MISCREG_ID_AFR0:
413              case MISCREG_ID_MMFR0:
414              case MISCREG_ID_MMFR1:
415              case MISCREG_ID_MMFR2:
416              case MISCREG_ID_MMFR3:
417              case MISCREG_ID_ISAR0:
418              case MISCREG_ID_ISAR1:
419              case MISCREG_ID_ISAR2:
420              case MISCREG_ID_ISAR3:
421              case MISCREG_ID_ISAR4:
422              case MISCREG_ID_ISAR5:
423                trapToHype = hcr.tid3;
424                break;
425              case MISCREG_DCISW:
426              case MISCREG_DCCSW:
427              case MISCREG_DCCISW:
428                trapToHype = hcr.tsw;
429                break;
430              case MISCREG_DCIMVAC:
431              case MISCREG_DCCIMVAC:
432              case MISCREG_DCCMVAC:
433                trapToHype = hcr.tpc;
434                break;
435              case MISCREG_ICIMVAU:
436              case MISCREG_ICIALLU:
437              case MISCREG_ICIALLUIS:
438              case MISCREG_DCCMVAU:
439                trapToHype = hcr.tpu;
440                break;
441              case MISCREG_TLBIALLIS:
442              case MISCREG_TLBIMVAIS:
443              case MISCREG_TLBIASIDIS:
444              case MISCREG_TLBIMVAAIS:
445              case MISCREG_DTLBIALL:
446              case MISCREG_ITLBIALL:
447              case MISCREG_DTLBIMVA:
448              case MISCREG_ITLBIMVA:
449              case MISCREG_DTLBIASID:
450              case MISCREG_ITLBIASID:
451              case MISCREG_TLBIMVAA:
452              case MISCREG_TLBIALL:
453              case MISCREG_TLBIMVA:
454              case MISCREG_TLBIASID:
455                trapToHype = hcr.ttlb;
456                break;
457              case MISCREG_ACTLR:
458                trapToHype = hcr.tac;
459                break;
460              case MISCREG_SCTLR:
461              case MISCREG_TTBR0:
462              case MISCREG_TTBR1:
463              case MISCREG_TTBCR:
464              case MISCREG_DACR:
465              case MISCREG_DFSR:
466              case MISCREG_IFSR:
467              case MISCREG_DFAR:
468              case MISCREG_IFAR:
469              case MISCREG_ADFSR:
470              case MISCREG_AIFSR:
471              case MISCREG_PRRR:
472              case MISCREG_NMRR:
473              case MISCREG_MAIR0:
474              case MISCREG_MAIR1:
475              case MISCREG_CONTEXTIDR:
476                trapToHype = hcr.tvm & !isRead;
477                break;
478              case MISCREG_PMCR:
479                trapToHype = hdcr.tpmcr;
480                break;
481              // No default action needed
482              default:
483                break;
484            }
485        }
486    }
487    return trapToHype;
488}
489
490
491bool
492mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
493                  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
494{
495    bool        isRead;
496    uint32_t    crm;
497    IntRegIndex rt;
498    uint32_t    crn;
499    uint32_t    opc1;
500    uint32_t    opc2;
501    bool        trapToHype = false;
502
503    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
504        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
505        inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
506                crm, crn, opc1, opc2, hdcr, hcptr, hstr);
507        trapToHype  = hdcr.tda  && (opc1 == 0);
508        trapToHype |= hcptr.tta && (opc1 == 1);
509        if (!trapToHype) {
510            switch (unflattenMiscReg(miscReg)) {
511              case MISCREG_DBGOSLSR:
512              case MISCREG_DBGOSLAR:
513              case MISCREG_DBGOSDLR:
514              case MISCREG_DBGPRCR:
515                trapToHype = hdcr.tdosa;
516                break;
517              case MISCREG_DBGDRAR:
518              case MISCREG_DBGDSAR:
519                trapToHype = hdcr.tdra;
520                break;
521              case MISCREG_JIDR:
522                trapToHype = hcr.tid0;
523                break;
524              case MISCREG_JOSCR:
525              case MISCREG_JMCR:
526                trapToHype = hstr.tjdbx;
527                break;
528              case MISCREG_TEECR:
529              case MISCREG_TEEHBR:
530                trapToHype = hstr.ttee;
531                break;
532              // No default action needed
533              default:
534                break;
535            }
536        }
537    }
538    return trapToHype;
539}
540
541bool
542mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
543                    HCR hcr, uint32_t iss)
544{
545    uint32_t    crm;
546    IntRegIndex rt;
547    uint32_t    crn;
548    uint32_t    opc1;
549    uint32_t    opc2;
550    bool        isRead;
551    bool        trapToHype = false;
552
553    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
554        // This is technically the wrong function, but we can re-use it for
555        // the moment because we only need one field, which overlaps with the
556        // mcrmrc layout
557        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
558        trapToHype = ((uint32_t) hstr) & (1 << crm);
559
560        if (!trapToHype) {
561            switch (unflattenMiscReg(miscReg)) {
562              case MISCREG_SCTLR:
563              case MISCREG_TTBR0:
564              case MISCREG_TTBR1:
565              case MISCREG_TTBCR:
566              case MISCREG_DACR:
567              case MISCREG_DFSR:
568              case MISCREG_IFSR:
569              case MISCREG_DFAR:
570              case MISCREG_IFAR:
571              case MISCREG_ADFSR:
572              case MISCREG_AIFSR:
573              case MISCREG_PRRR:
574              case MISCREG_NMRR:
575              case MISCREG_MAIR0:
576              case MISCREG_MAIR1:
577              case MISCREG_CONTEXTIDR:
578                trapToHype = hcr.tvm & !isRead;
579                break;
580              // No default action needed
581              default:
582                break;
583            }
584        }
585    }
586    return trapToHype;
587}
588
589bool
590msrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el,
591                  CPACR cpacr /* CPACR_EL1 */)
592{
593    bool trapToSup = false;
594    switch (miscReg) {
595      case MISCREG_FPCR:
596      case MISCREG_FPSR:
597      case MISCREG_FPEXC32_EL2:
598        if ((el == EL0 && cpacr.fpen != 0x3) ||
599            (el == EL1 && !(cpacr.fpen & 0x1)))
600            trapToSup = true;
601        break;
602      default:
603        break;
604    }
605    return trapToSup;
606}
607
608bool
609msrMrs64TrapToHyp(const MiscRegIndex miscReg,
610                  ExceptionLevel el,
611                  bool isRead,
612                  CPTR cptr /* CPTR_EL2 */,
613                  HCR hcr /* HCR_EL2 */,
614                  bool * isVfpNeon)
615{
616    bool trapToHyp = false;
617    *isVfpNeon = false;
618
619    switch (miscReg) {
620      // FP/SIMD regs
621      case MISCREG_FPCR:
622      case MISCREG_FPSR:
623      case MISCREG_FPEXC32_EL2:
624        trapToHyp = cptr.tfp;
625        *isVfpNeon = true;
626        break;
627      // CPACR
628      case MISCREG_CPACR_EL1:
629        trapToHyp = cptr.tcpac && el == EL1;
630        break;
631      // Virtual memory control regs
632      case MISCREG_SCTLR_EL1:
633      case MISCREG_TTBR0_EL1:
634      case MISCREG_TTBR1_EL1:
635      case MISCREG_TCR_EL1:
636      case MISCREG_ESR_EL1:
637      case MISCREG_FAR_EL1:
638      case MISCREG_AFSR0_EL1:
639      case MISCREG_AFSR1_EL1:
640      case MISCREG_MAIR_EL1:
641      case MISCREG_AMAIR_EL1:
642      case MISCREG_CONTEXTIDR_EL1:
643        trapToHyp = ((hcr.trvm && isRead) || (hcr.tvm && !isRead))
644                    && el == EL1;
645        break;
646      // TLB maintenance instructions
647      case MISCREG_TLBI_VMALLE1:
648      case MISCREG_TLBI_VAE1_Xt:
649      case MISCREG_TLBI_ASIDE1_Xt:
650      case MISCREG_TLBI_VAAE1_Xt:
651      case MISCREG_TLBI_VALE1_Xt:
652      case MISCREG_TLBI_VAALE1_Xt:
653      case MISCREG_TLBI_VMALLE1IS:
654      case MISCREG_TLBI_VAE1IS_Xt:
655      case MISCREG_TLBI_ASIDE1IS_Xt:
656      case MISCREG_TLBI_VAAE1IS_Xt:
657      case MISCREG_TLBI_VALE1IS_Xt:
658      case MISCREG_TLBI_VAALE1IS_Xt:
659        trapToHyp = hcr.ttlb && el == EL1;
660        break;
661      // Cache maintenance instructions to the point of unification
662      case MISCREG_IC_IVAU_Xt:
663      case MISCREG_ICIALLU:
664      case MISCREG_ICIALLUIS:
665      case MISCREG_DC_CVAU_Xt:
666        trapToHyp = hcr.tpu && el <= EL1;
667        break;
668      // Data/Unified cache maintenance instructions to the point of coherency
669      case MISCREG_DC_IVAC_Xt:
670      case MISCREG_DC_CIVAC_Xt:
671      case MISCREG_DC_CVAC_Xt:
672        trapToHyp = hcr.tpc && el <= EL1;
673        break;
674      // Data/Unified cache maintenance instructions by set/way
675      case MISCREG_DC_ISW_Xt:
676      case MISCREG_DC_CSW_Xt:
677      case MISCREG_DC_CISW_Xt:
678        trapToHyp = hcr.tsw && el == EL1;
679        break;
680      // ACTLR
681      case MISCREG_ACTLR_EL1:
682        trapToHyp = hcr.tacr && el == EL1;
683        break;
684
685      // @todo: Trap implementation-dependent functionality based on
686      // hcr.tidcp
687
688      // ID regs, group 3
689      case MISCREG_ID_PFR0_EL1:
690      case MISCREG_ID_PFR1_EL1:
691      case MISCREG_ID_DFR0_EL1:
692      case MISCREG_ID_AFR0_EL1:
693      case MISCREG_ID_MMFR0_EL1:
694      case MISCREG_ID_MMFR1_EL1:
695      case MISCREG_ID_MMFR2_EL1:
696      case MISCREG_ID_MMFR3_EL1:
697      case MISCREG_ID_ISAR0_EL1:
698      case MISCREG_ID_ISAR1_EL1:
699      case MISCREG_ID_ISAR2_EL1:
700      case MISCREG_ID_ISAR3_EL1:
701      case MISCREG_ID_ISAR4_EL1:
702      case MISCREG_ID_ISAR5_EL1:
703      case MISCREG_MVFR0_EL1:
704      case MISCREG_MVFR1_EL1:
705      case MISCREG_MVFR2_EL1:
706      case MISCREG_ID_AA64PFR0_EL1:
707      case MISCREG_ID_AA64PFR1_EL1:
708      case MISCREG_ID_AA64DFR0_EL1:
709      case MISCREG_ID_AA64DFR1_EL1:
710      case MISCREG_ID_AA64ISAR0_EL1:
711      case MISCREG_ID_AA64ISAR1_EL1:
712      case MISCREG_ID_AA64MMFR0_EL1:
713      case MISCREG_ID_AA64MMFR1_EL1:
714      case MISCREG_ID_AA64AFR0_EL1:
715      case MISCREG_ID_AA64AFR1_EL1:
716        assert(isRead);
717        trapToHyp = hcr.tid3 && el == EL1;
718        break;
719      // ID regs, group 2
720      case MISCREG_CTR_EL0:
721      case MISCREG_CCSIDR_EL1:
722      case MISCREG_CLIDR_EL1:
723      case MISCREG_CSSELR_EL1:
724        trapToHyp = hcr.tid2 && el <= EL1;
725        break;
726      // ID regs, group 1
727      case MISCREG_AIDR_EL1:
728      case MISCREG_REVIDR_EL1:
729        assert(isRead);
730        trapToHyp = hcr.tid1 && el == EL1;
731        break;
732      default:
733        break;
734    }
735    return trapToHyp;
736}
737
738bool
739msrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */,
740                  ExceptionLevel el, bool * isVfpNeon)
741{
742    bool trapToMon = false;
743    *isVfpNeon = false;
744
745    switch (miscReg) {
746      // FP/SIMD regs
747      case MISCREG_FPCR:
748      case MISCREG_FPSR:
749      case MISCREG_FPEXC32_EL2:
750        trapToMon = cptr.tfp;
751        *isVfpNeon = true;
752        break;
753      // CPACR, CPTR
754      case MISCREG_CPACR_EL1:
755        if (el == EL1) {
756           trapToMon = cptr.tcpac;
757        }
758        break;
759      case MISCREG_CPTR_EL2:
760        if (el == EL2) {
761            trapToMon = cptr.tcpac;
762        }
763        break;
764      default:
765        break;
766    }
767    return trapToMon;
768}
769
770bool
771decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
772                      CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
773{
774    OperatingMode mode = MODE_UNDEFINED;
775    bool          ok = true;
776
777    // R mostly indicates if its a int register or a misc reg, we override
778    // below if the few corner cases
779    isIntReg = !r;
780    // Loosely based on ARM ARM issue C section B9.3.10
781    if (r) {
782        switch (sysM)
783        {
784          case 0xE:
785            regIdx = MISCREG_SPSR_FIQ;
786            mode   = MODE_FIQ;
787            break;
788          case 0x10:
789            regIdx = MISCREG_SPSR_IRQ;
790            mode   = MODE_IRQ;
791            break;
792          case 0x12:
793            regIdx = MISCREG_SPSR_SVC;
794            mode   = MODE_SVC;
795            break;
796          case 0x14:
797            regIdx = MISCREG_SPSR_ABT;
798            mode   = MODE_ABORT;
799            break;
800          case 0x16:
801            regIdx = MISCREG_SPSR_UND;
802            mode   = MODE_UNDEFINED;
803            break;
804          case 0x1C:
805            regIdx = MISCREG_SPSR_MON;
806            mode   = MODE_MON;
807            break;
808          case 0x1E:
809            regIdx = MISCREG_SPSR_HYP;
810            mode   = MODE_HYP;
811            break;
812          default:
813            ok = false;
814            break;
815        }
816    } else {
817        int sysM4To3 = bits(sysM, 4, 3);
818
819        if (sysM4To3 == 0) {
820            mode = MODE_USER;
821            regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
822        } else if (sysM4To3 == 1) {
823            mode = MODE_FIQ;
824            regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
825        } else if (sysM4To3 == 3) {
826            if (bits(sysM, 1) == 0) {
827                mode = MODE_MON;
828                regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
829            } else {
830                mode = MODE_HYP;
831                if (bits(sysM, 0) == 1) {
832                    regIdx = intRegInMode(mode, 13); // R13 in HYP
833                } else {
834                    isIntReg = false;
835                    regIdx   = MISCREG_ELR_HYP;
836                }
837            }
838        } else { // Other Banked registers
839            int sysM2 = bits(sysM, 2);
840            int sysM1 = bits(sysM, 1);
841
842            mode  = (OperatingMode) ( ((sysM2 ||  sysM1) << 0) |
843                                      (1                 << 1) |
844                                      ((sysM2 && !sysM1) << 2) |
845                                      ((sysM2 &&  sysM1) << 3) |
846                                      (1                 << 4) );
847            regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
848            // Don't flatten the register here. This is going to go through
849            // setIntReg() which will do the flattening
850            ok &= mode != cpsr.mode;
851        }
852    }
853
854    // Check that the requested register is accessable from the current mode
855    if (ok && checkSecurity && mode != cpsr.mode) {
856        switch (cpsr.mode)
857        {
858          case MODE_USER:
859            ok = false;
860            break;
861          case MODE_FIQ:
862            ok &=  mode != MODE_HYP;
863            ok &= (mode != MODE_MON) || !scr.ns;
864            break;
865          case MODE_HYP:
866            ok &=  mode != MODE_MON;
867            ok &= (mode != MODE_FIQ) || !nsacr.rfr;
868            break;
869          case MODE_IRQ:
870          case MODE_SVC:
871          case MODE_ABORT:
872          case MODE_UNDEFINED:
873          case MODE_SYSTEM:
874            ok &=  mode != MODE_HYP;
875            ok &= (mode != MODE_MON) || !scr.ns;
876            ok &= (mode != MODE_FIQ) || !nsacr.rfr;
877            break;
878          // can access everything, no further checks required
879          case MODE_MON:
880            break;
881          default:
882            panic("unknown Mode 0x%x\n", cpsr.mode);
883            break;
884        }
885    }
886    return (ok);
887}
888
889bool
890SPAlignmentCheckEnabled(ThreadContext* tc)
891{
892    switch (opModeToEL(currOpMode(tc))) {
893      case EL3:
894        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa;
895      case EL2:
896        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa;
897      case EL1:
898        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa;
899      case EL0:
900        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0;
901      default:
902        panic("Invalid exception level");
903        break;
904    }
905}
906
907int
908decodePhysAddrRange64(uint8_t pa_enc)
909{
910    switch (pa_enc) {
911      case 0x0:
912        return 32;
913      case 0x1:
914        return 36;
915      case 0x2:
916        return 40;
917      case 0x3:
918        return 42;
919      case 0x4:
920        return 44;
921      case 0x5:
922      case 0x6:
923      case 0x7:
924        return 48;
925      default:
926        panic("Invalid phys. address range encoding");
927    }
928}
929
930uint8_t
931encodePhysAddrRange64(int pa_size)
932{
933    switch (pa_size) {
934      case 32:
935        return 0x0;
936      case 36:
937        return 0x1;
938      case 40:
939        return 0x2;
940      case 42:
941        return 0x3;
942      case 44:
943        return 0x4;
944      case 48:
945        return 0x5;
946      default:
947        panic("Invalid phys. address range");
948    }
949}
950
951} // namespace ArmISA
952