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