utility.cc revision 10934:5af8f40d8f2c
1/*
2 * Copyright (c) 2009-2014 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    // Copy vector registers when vector registers put to use.
160    assert(NumVectorRegs == 0);
161
162    for (int i = 0; i < NumMiscRegs; i++)
163        dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
164
165    // setMiscReg "with effect" will set the misc register mapping correctly.
166    // e.g. updateRegMap(val)
167    dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
168
169    // Copy over the PC State
170    dest->pcState(src->pcState());
171
172    // Invalidate the tlb misc register cache
173    dest->getITBPtr()->invalidateMiscReg();
174    dest->getDTBPtr()->invalidateMiscReg();
175}
176
177bool
178inSecureState(ThreadContext *tc)
179{
180    SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) :
181        tc->readMiscReg(MISCREG_SCR);
182    return ArmSystem::haveSecurity(tc) && inSecureState(
183        scr, tc->readMiscReg(MISCREG_CPSR));
184}
185
186bool
187inAArch64(ThreadContext *tc)
188{
189    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
190    return opModeIs64((OperatingMode) (uint8_t) cpsr.mode);
191}
192
193bool
194longDescFormatInUse(ThreadContext *tc)
195{
196    TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR);
197    return ArmSystem::haveLPAE(tc) && ttbcr.eae;
198}
199
200uint32_t
201getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
202{
203    // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
204    // Reference Manual
205    //
206    // bit   31 - Multi-processor extensions available
207    // bit   30 - Uni-processor system
208    // bit   24 - Multi-threaded cores
209    // bit 11-8 - Cluster ID
210    // bit  1-0 - CPU ID
211    //
212    // We deliberately extend both the Cluster ID and CPU ID fields to allow
213    // for simulation of larger systems
214    assert((0 <= tc->cpuId()) && (tc->cpuId() < 256));
215    assert((0 <= tc->socketId()) && (tc->socketId() < 65536));
216    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            // @todo: uncomment this to enable Virtualization
239            // if (ArmSystem::haveVirtualization(tc)) {
240            //     HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
241            //     return hcr.rw;
242            // }
243            assert(ArmSystem::haveSecurity(tc));
244            SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
245            return scr.rw;
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      // @todo: uncomment this to enable Virtualization
290      // case EL2:
291      //   assert(ArmSystem::haveVirtualization());
292      //   tcr = tc->readMiscReg(MISCREG_TCR_EL2);
293      //   if (tcr.tbi)
294      //       return addr & mask(56);
295      //   break;
296      case EL3:
297        assert(ArmSystem::haveSecurity(tc));
298        if (tcr.tbi)
299            return addr & mask(56);
300        break;
301      default:
302        panic("Invalid exception level");
303        break;
304    }
305
306    return addr;  // Nothing to do if this is not a tagged address
307}
308
309Addr
310purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el)
311{
312    TTBCR tcr;
313
314    switch (el) {
315      case EL0:
316      case EL1:
317        tcr = tc->readMiscReg(MISCREG_TCR_EL1);
318        if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
319            return addr | mask(63, 55);
320        else if (!bits(addr, 55, 48) && tcr.tbi0)
321            return bits(addr,55, 0);
322        break;
323      // @todo: uncomment this to enable Virtualization
324      // case EL2:
325      //   assert(ArmSystem::haveVirtualization());
326      //   tcr = tc->readMiscReg(MISCREG_TCR_EL2);
327      //   if (tcr.tbi)
328      //       return addr & mask(56);
329      //   break;
330      case EL3:
331        assert(ArmSystem::haveSecurity(tc));
332        tcr = tc->readMiscReg(MISCREG_TCR_EL3);
333        if (tcr.tbi)
334            return addr & mask(56);
335        break;
336      default:
337        panic("Invalid exception level");
338        break;
339    }
340
341    return addr;  // Nothing to do if this is not a tagged address
342}
343
344Addr
345truncPage(Addr addr)
346{
347    return addr & ~(PageBytes - 1);
348}
349
350Addr
351roundPage(Addr addr)
352{
353    return (addr + PageBytes - 1) & ~(PageBytes - 1);
354}
355
356bool
357mcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
358                  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
359{
360    bool        isRead;
361    uint32_t    crm;
362    IntRegIndex rt;
363    uint32_t    crn;
364    uint32_t    opc1;
365    uint32_t    opc2;
366    bool        trapToHype = false;
367
368
369    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
370        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
371        trapToHype  = ((uint32_t) hstr) & (1 << crn);
372        trapToHype |= hdcr.tpm  && (crn == 9) && (crm >= 12);
373        trapToHype |= hcr.tidcp && (
374            ((crn ==  9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
375            ((crn == 10) && ((crm <= 1) ||  (crm == 4) || (crm == 8)))  ||
376            ((crn == 11) && ((crm <= 8) ||  (crm == 15)))               );
377
378        if (!trapToHype) {
379            switch (unflattenMiscReg(miscReg)) {
380              case MISCREG_CPACR:
381                trapToHype = hcptr.tcpac;
382                break;
383              case MISCREG_REVIDR:
384              case MISCREG_TCMTR:
385              case MISCREG_TLBTR:
386              case MISCREG_AIDR:
387                trapToHype = hcr.tid1;
388                break;
389              case MISCREG_CTR:
390              case MISCREG_CCSIDR:
391              case MISCREG_CLIDR:
392              case MISCREG_CSSELR:
393                trapToHype = hcr.tid2;
394                break;
395              case MISCREG_ID_PFR0:
396              case MISCREG_ID_PFR1:
397              case MISCREG_ID_DFR0:
398              case MISCREG_ID_AFR0:
399              case MISCREG_ID_MMFR0:
400              case MISCREG_ID_MMFR1:
401              case MISCREG_ID_MMFR2:
402              case MISCREG_ID_MMFR3:
403              case MISCREG_ID_ISAR0:
404              case MISCREG_ID_ISAR1:
405              case MISCREG_ID_ISAR2:
406              case MISCREG_ID_ISAR3:
407              case MISCREG_ID_ISAR4:
408              case MISCREG_ID_ISAR5:
409                trapToHype = hcr.tid3;
410                break;
411              case MISCREG_DCISW:
412              case MISCREG_DCCSW:
413              case MISCREG_DCCISW:
414                trapToHype = hcr.tsw;
415                break;
416              case MISCREG_DCIMVAC:
417              case MISCREG_DCCIMVAC:
418              case MISCREG_DCCMVAC:
419                trapToHype = hcr.tpc;
420                break;
421              case MISCREG_ICIMVAU:
422              case MISCREG_ICIALLU:
423              case MISCREG_ICIALLUIS:
424              case MISCREG_DCCMVAU:
425                trapToHype = hcr.tpu;
426                break;
427              case MISCREG_TLBIALLIS:
428              case MISCREG_TLBIMVAIS:
429              case MISCREG_TLBIASIDIS:
430              case MISCREG_TLBIMVAAIS:
431              case MISCREG_DTLBIALL:
432              case MISCREG_ITLBIALL:
433              case MISCREG_DTLBIMVA:
434              case MISCREG_ITLBIMVA:
435              case MISCREG_DTLBIASID:
436              case MISCREG_ITLBIASID:
437              case MISCREG_TLBIMVAA:
438              case MISCREG_TLBIALL:
439              case MISCREG_TLBIMVA:
440              case MISCREG_TLBIASID:
441                trapToHype = hcr.ttlb;
442                break;
443              case MISCREG_ACTLR:
444                trapToHype = hcr.tac;
445                break;
446              case MISCREG_SCTLR:
447              case MISCREG_TTBR0:
448              case MISCREG_TTBR1:
449              case MISCREG_TTBCR:
450              case MISCREG_DACR:
451              case MISCREG_DFSR:
452              case MISCREG_IFSR:
453              case MISCREG_DFAR:
454              case MISCREG_IFAR:
455              case MISCREG_ADFSR:
456              case MISCREG_AIFSR:
457              case MISCREG_PRRR:
458              case MISCREG_NMRR:
459              case MISCREG_MAIR0:
460              case MISCREG_MAIR1:
461              case MISCREG_CONTEXTIDR:
462                trapToHype = hcr.tvm & !isRead;
463                break;
464              case MISCREG_PMCR:
465                trapToHype = hdcr.tpmcr;
466                break;
467              // No default action needed
468              default:
469                break;
470            }
471        }
472    }
473    return trapToHype;
474}
475
476
477bool
478mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
479                  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
480{
481    bool        isRead;
482    uint32_t    crm;
483    IntRegIndex rt;
484    uint32_t    crn;
485    uint32_t    opc1;
486    uint32_t    opc2;
487    bool        trapToHype = false;
488
489    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
490        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
491        inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
492                crm, crn, opc1, opc2, hdcr, hcptr, hstr);
493        trapToHype  = hdcr.tda  && (opc1 == 0);
494        trapToHype |= hcptr.tta && (opc1 == 1);
495        if (!trapToHype) {
496            switch (unflattenMiscReg(miscReg)) {
497              case MISCREG_DBGOSLSR:
498              case MISCREG_DBGOSLAR:
499              case MISCREG_DBGOSDLR:
500              case MISCREG_DBGPRCR:
501                trapToHype = hdcr.tdosa;
502                break;
503              case MISCREG_DBGDRAR:
504              case MISCREG_DBGDSAR:
505                trapToHype = hdcr.tdra;
506                break;
507              case MISCREG_JIDR:
508                trapToHype = hcr.tid0;
509                break;
510              case MISCREG_JOSCR:
511              case MISCREG_JMCR:
512                trapToHype = hstr.tjdbx;
513                break;
514              case MISCREG_TEECR:
515              case MISCREG_TEEHBR:
516                trapToHype = hstr.ttee;
517                break;
518              // No default action needed
519              default:
520                break;
521            }
522        }
523    }
524    return trapToHype;
525}
526
527bool
528mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
529                    HCR hcr, uint32_t iss)
530{
531    uint32_t    crm;
532    IntRegIndex rt;
533    uint32_t    crn;
534    uint32_t    opc1;
535    uint32_t    opc2;
536    bool        isRead;
537    bool        trapToHype = false;
538
539    if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
540        // This is technically the wrong function, but we can re-use it for
541        // the moment because we only need one field, which overlaps with the
542        // mcrmrc layout
543        mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
544        trapToHype = ((uint32_t) hstr) & (1 << crm);
545
546        if (!trapToHype) {
547            switch (unflattenMiscReg(miscReg)) {
548              case MISCREG_SCTLR:
549              case MISCREG_TTBR0:
550              case MISCREG_TTBR1:
551              case MISCREG_TTBCR:
552              case MISCREG_DACR:
553              case MISCREG_DFSR:
554              case MISCREG_IFSR:
555              case MISCREG_DFAR:
556              case MISCREG_IFAR:
557              case MISCREG_ADFSR:
558              case MISCREG_AIFSR:
559              case MISCREG_PRRR:
560              case MISCREG_NMRR:
561              case MISCREG_MAIR0:
562              case MISCREG_MAIR1:
563              case MISCREG_CONTEXTIDR:
564                trapToHype = hcr.tvm & !isRead;
565                break;
566              // No default action needed
567              default:
568                break;
569            }
570        }
571    }
572    return trapToHype;
573}
574
575bool
576msrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el,
577                  CPACR cpacr /* CPACR_EL1 */)
578{
579    bool trapToSup = false;
580    switch (miscReg) {
581      case MISCREG_FPCR:
582      case MISCREG_FPSR:
583      case MISCREG_FPEXC32_EL2:
584        if ((el == EL0 && cpacr.fpen != 0x3) ||
585            (el == EL1 && !(cpacr.fpen & 0x1)))
586            trapToSup = true;
587        break;
588      default:
589        break;
590    }
591    return trapToSup;
592}
593
594bool
595msrMrs64TrapToHyp(const MiscRegIndex miscReg, bool isRead,
596                  CPTR cptr /* CPTR_EL2 */,
597                  HCR hcr /* HCR_EL2 */,
598                  bool * isVfpNeon)
599{
600    bool trapToHyp = false;
601    *isVfpNeon = false;
602
603    switch (miscReg) {
604      // FP/SIMD regs
605      case MISCREG_FPCR:
606      case MISCREG_FPSR:
607      case MISCREG_FPEXC32_EL2:
608        trapToHyp = cptr.tfp;
609        *isVfpNeon = true;
610        break;
611      // CPACR
612      case MISCREG_CPACR_EL1:
613        trapToHyp = cptr.tcpac;
614        break;
615      // Virtual memory control regs
616      case MISCREG_SCTLR_EL1:
617      case MISCREG_TTBR0_EL1:
618      case MISCREG_TTBR1_EL1:
619      case MISCREG_TCR_EL1:
620      case MISCREG_ESR_EL1:
621      case MISCREG_FAR_EL1:
622      case MISCREG_AFSR0_EL1:
623      case MISCREG_AFSR1_EL1:
624      case MISCREG_MAIR_EL1:
625      case MISCREG_AMAIR_EL1:
626      case MISCREG_CONTEXTIDR_EL1:
627        trapToHyp = (hcr.trvm && isRead) || (hcr.tvm && !isRead);
628        break;
629      // TLB maintenance instructions
630      case MISCREG_TLBI_VMALLE1:
631      case MISCREG_TLBI_VAE1_Xt:
632      case MISCREG_TLBI_ASIDE1_Xt:
633      case MISCREG_TLBI_VAAE1_Xt:
634      case MISCREG_TLBI_VALE1_Xt:
635      case MISCREG_TLBI_VAALE1_Xt:
636      case MISCREG_TLBI_VMALLE1IS:
637      case MISCREG_TLBI_VAE1IS_Xt:
638      case MISCREG_TLBI_ASIDE1IS_Xt:
639      case MISCREG_TLBI_VAAE1IS_Xt:
640      case MISCREG_TLBI_VALE1IS_Xt:
641      case MISCREG_TLBI_VAALE1IS_Xt:
642        trapToHyp = hcr.ttlb;
643        break;
644      // Cache maintenance instructions to the point of unification
645      case MISCREG_IC_IVAU_Xt:
646      case MISCREG_ICIALLU:
647      case MISCREG_ICIALLUIS:
648      case MISCREG_DC_CVAU_Xt:
649        trapToHyp = hcr.tpu;
650        break;
651      // Data/Unified cache maintenance instructions to the point of coherency
652      case MISCREG_DC_IVAC_Xt:
653      case MISCREG_DC_CIVAC_Xt:
654      case MISCREG_DC_CVAC_Xt:
655        trapToHyp = hcr.tpc;
656        break;
657      // Data/Unified cache maintenance instructions by set/way
658      case MISCREG_DC_ISW_Xt:
659      case MISCREG_DC_CSW_Xt:
660      case MISCREG_DC_CISW_Xt:
661        trapToHyp = hcr.tsw;
662        break;
663      // ACTLR
664      case MISCREG_ACTLR_EL1:
665        trapToHyp = hcr.tacr;
666        break;
667
668      // @todo: Trap implementation-dependent functionality based on
669      // hcr.tidcp
670
671      // ID regs, group 3
672      case MISCREG_ID_PFR0_EL1:
673      case MISCREG_ID_PFR1_EL1:
674      case MISCREG_ID_DFR0_EL1:
675      case MISCREG_ID_AFR0_EL1:
676      case MISCREG_ID_MMFR0_EL1:
677      case MISCREG_ID_MMFR1_EL1:
678      case MISCREG_ID_MMFR2_EL1:
679      case MISCREG_ID_MMFR3_EL1:
680      case MISCREG_ID_ISAR0_EL1:
681      case MISCREG_ID_ISAR1_EL1:
682      case MISCREG_ID_ISAR2_EL1:
683      case MISCREG_ID_ISAR3_EL1:
684      case MISCREG_ID_ISAR4_EL1:
685      case MISCREG_ID_ISAR5_EL1:
686      case MISCREG_MVFR0_EL1:
687      case MISCREG_MVFR1_EL1:
688      case MISCREG_MVFR2_EL1:
689      case MISCREG_ID_AA64PFR0_EL1:
690      case MISCREG_ID_AA64PFR1_EL1:
691      case MISCREG_ID_AA64DFR0_EL1:
692      case MISCREG_ID_AA64DFR1_EL1:
693      case MISCREG_ID_AA64ISAR0_EL1:
694      case MISCREG_ID_AA64ISAR1_EL1:
695      case MISCREG_ID_AA64MMFR0_EL1:
696      case MISCREG_ID_AA64MMFR1_EL1:
697      case MISCREG_ID_AA64AFR0_EL1:
698      case MISCREG_ID_AA64AFR1_EL1:
699        assert(isRead);
700        trapToHyp = hcr.tid3;
701        break;
702      // ID regs, group 2
703      case MISCREG_CTR_EL0:
704      case MISCREG_CCSIDR_EL1:
705      case MISCREG_CLIDR_EL1:
706      case MISCREG_CSSELR_EL1:
707        trapToHyp = hcr.tid2;
708        break;
709      // ID regs, group 1
710      case MISCREG_AIDR_EL1:
711      case MISCREG_REVIDR_EL1:
712        assert(isRead);
713        trapToHyp = hcr.tid1;
714        break;
715      default:
716        break;
717    }
718    return trapToHyp;
719}
720
721bool
722msrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */,
723                  ExceptionLevel el, bool * isVfpNeon)
724{
725    bool trapToMon = false;
726    *isVfpNeon = false;
727
728    switch (miscReg) {
729      // FP/SIMD regs
730      case MISCREG_FPCR:
731      case MISCREG_FPSR:
732      case MISCREG_FPEXC32_EL2:
733        trapToMon = cptr.tfp;
734        *isVfpNeon = true;
735        break;
736      // CPACR, CPTR
737      case MISCREG_CPACR_EL1:
738        if (el == EL1) {
739           trapToMon = cptr.tcpac;
740        }
741        break;
742      case MISCREG_CPTR_EL2:
743        if (el == EL2) {
744            trapToMon = cptr.tcpac;
745        }
746        break;
747      default:
748        break;
749    }
750    return trapToMon;
751}
752
753bool
754decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
755                      CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
756{
757    OperatingMode mode = MODE_UNDEFINED;
758    bool          ok = true;
759
760    // R mostly indicates if its a int register or a misc reg, we override
761    // below if the few corner cases
762    isIntReg = !r;
763    // Loosely based on ARM ARM issue C section B9.3.10
764    if (r) {
765        switch (sysM)
766        {
767          case 0xE:
768            regIdx = MISCREG_SPSR_FIQ;
769            mode   = MODE_FIQ;
770            break;
771          case 0x10:
772            regIdx = MISCREG_SPSR_IRQ;
773            mode   = MODE_IRQ;
774            break;
775          case 0x12:
776            regIdx = MISCREG_SPSR_SVC;
777            mode   = MODE_SVC;
778            break;
779          case 0x14:
780            regIdx = MISCREG_SPSR_ABT;
781            mode   = MODE_ABORT;
782            break;
783          case 0x16:
784            regIdx = MISCREG_SPSR_UND;
785            mode   = MODE_UNDEFINED;
786            break;
787          case 0x1C:
788            regIdx = MISCREG_SPSR_MON;
789            mode   = MODE_MON;
790            break;
791          case 0x1E:
792            regIdx = MISCREG_SPSR_HYP;
793            mode   = MODE_HYP;
794            break;
795          default:
796            ok = false;
797            break;
798        }
799    } else {
800        int sysM4To3 = bits(sysM, 4, 3);
801
802        if (sysM4To3 == 0) {
803            mode = MODE_USER;
804            regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
805        } else if (sysM4To3 == 1) {
806            mode = MODE_FIQ;
807            regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
808        } else if (sysM4To3 == 3) {
809            if (bits(sysM, 1) == 0) {
810                mode = MODE_MON;
811                regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
812            } else {
813                mode = MODE_HYP;
814                if (bits(sysM, 0) == 1) {
815                    regIdx = intRegInMode(mode, 13); // R13 in HYP
816                } else {
817                    isIntReg = false;
818                    regIdx   = MISCREG_ELR_HYP;
819                }
820            }
821        } else { // Other Banked registers
822            int sysM2 = bits(sysM, 2);
823            int sysM1 = bits(sysM, 1);
824
825            mode  = (OperatingMode) ( ((sysM2 ||  sysM1) << 0) |
826                                      (1                 << 1) |
827                                      ((sysM2 && !sysM1) << 2) |
828                                      ((sysM2 &&  sysM1) << 3) |
829                                      (1                 << 4) );
830            regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
831            // Don't flatten the register here. This is going to go through
832            // setIntReg() which will do the flattening
833            ok &= mode != cpsr.mode;
834        }
835    }
836
837    // Check that the requested register is accessable from the current mode
838    if (ok && checkSecurity && mode != cpsr.mode) {
839        switch (cpsr.mode)
840        {
841          case MODE_USER:
842            ok = false;
843            break;
844          case MODE_FIQ:
845            ok &=  mode != MODE_HYP;
846            ok &= (mode != MODE_MON) || !scr.ns;
847            break;
848          case MODE_HYP:
849            ok &=  mode != MODE_MON;
850            ok &= (mode != MODE_FIQ) || !nsacr.rfr;
851            break;
852          case MODE_IRQ:
853          case MODE_SVC:
854          case MODE_ABORT:
855          case MODE_UNDEFINED:
856          case MODE_SYSTEM:
857            ok &=  mode != MODE_HYP;
858            ok &= (mode != MODE_MON) || !scr.ns;
859            ok &= (mode != MODE_FIQ) || !nsacr.rfr;
860            break;
861          // can access everything, no further checks required
862          case MODE_MON:
863            break;
864          default:
865            panic("unknown Mode 0x%x\n", cpsr.mode);
866            break;
867        }
868    }
869    return (ok);
870}
871
872bool
873vfpNeonEnabled(uint32_t &seq, HCPTR hcptr, NSACR nsacr, CPACR cpacr, CPSR cpsr,
874               uint32_t &iss, bool &trap, ThreadContext *tc, FPEXC fpexc,
875               bool isSIMD)
876{
877    iss                     = 0;
878    trap                    = false;
879    bool undefined          = false;
880    bool haveSecurity       = ArmSystem::haveSecurity(tc);
881    bool haveVirtualization = ArmSystem::haveVirtualization(tc);
882    bool isSecure           = inSecureState(tc);
883
884    // Non-secure view of CPACR and HCPTR determines behavior
885    // Copy register values
886    uint8_t cpacr_cp10   = cpacr.cp10;
887    bool    cpacr_asedis = cpacr.asedis;
888    bool    hcptr_cp10   = false;
889    bool    hcptr_tase   = false;
890
891    bool cp10_enabled = cpacr.cp10 == 0x3
892                      || (cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr));
893
894    bool cp11_enabled =  cpacr.cp11 == 0x3
895                      || (cpacr.cp11 == 0x1 && inPrivilegedMode(cpsr));
896
897    if (cp11_enabled) {
898        undefined |= !(fpexc.en && cp10_enabled);
899    } else {
900        undefined |= !(fpexc.en && cp10_enabled && (cpacr.cp11 == cpacr.cp10));
901    }
902
903    if (haveVirtualization) {
904        hcptr_cp10 = hcptr.tcp10;
905        undefined |= hcptr.tcp10 != hcptr.tcp11;
906        hcptr_tase = hcptr.tase;
907    }
908
909    if (haveSecurity) {
910        undefined |= nsacr.cp10 != nsacr.cp11;
911        if (!isSecure) {
912            // Modify register values to the Non-secure view
913            if (!nsacr.cp10) {
914                cpacr_cp10 = 0;
915                if (haveVirtualization) {
916                    hcptr_cp10 = true;
917                }
918            }
919            if (nsacr.nsasedis) {
920                cpacr_asedis = true;
921                if (haveVirtualization) {
922                    hcptr_tase = true;
923                }
924            }
925        }
926    }
927
928    // Check Coprocessor Access Control Register for permission to use CP10/11.
929    if (!haveVirtualization || (cpsr.mode != MODE_HYP)) {
930        switch (cpacr_cp10)
931        {
932            case 0:
933                undefined = true;
934                break;
935            case 1:
936                undefined |= inUserMode(cpsr);
937                break;
938        }
939
940        // Check if SIMD operations are disabled
941        if (isSIMD && cpacr_asedis) undefined = true;
942    }
943
944    // If required, check FPEXC enabled bit.
945    undefined |= !fpexc.en;
946
947    if (haveSecurity && haveVirtualization && !isSecure) {
948        if (hcptr_cp10 || (isSIMD && hcptr_tase)) {
949            iss  = isSIMD ? (1 << 5) : 0xA;
950            trap = true;
951        }
952    }
953
954    return (!undefined);
955}
956
957bool
958SPAlignmentCheckEnabled(ThreadContext* tc)
959{
960    switch (opModeToEL(currOpMode(tc))) {
961      case EL3:
962        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa;
963      case EL2:
964        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa;
965      case EL1:
966        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa;
967      case EL0:
968        return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0;
969      default:
970        panic("Invalid exception level");
971        break;
972    }
973}
974
975int
976decodePhysAddrRange64(uint8_t pa_enc)
977{
978    switch (pa_enc) {
979      case 0x0:
980        return 32;
981      case 0x1:
982        return 36;
983      case 0x2:
984        return 40;
985      case 0x3:
986        return 42;
987      case 0x4:
988        return 44;
989      case 0x5:
990      case 0x6:
991      case 0x7:
992        return 48;
993      default:
994        panic("Invalid phys. address range encoding");
995    }
996}
997
998uint8_t
999encodePhysAddrRange64(int pa_size)
1000{
1001    switch (pa_size) {
1002      case 32:
1003        return 0x0;
1004      case 36:
1005        return 0x1;
1006      case 40:
1007        return 0x2;
1008      case 42:
1009        return 0x3;
1010      case 44:
1011        return 0x4;
1012      case 48:
1013        return 0x5;
1014      default:
1015        panic("Invalid phys. address range");
1016    }
1017}
1018
1019} // namespace ArmISA
1020