isa.hh revision 13173
111986Sandreas.sandberg@arm.com/*
211986Sandreas.sandberg@arm.com * Copyright (c) 2010, 2012-2018 ARM Limited
311986Sandreas.sandberg@arm.com * All rights reserved
411986Sandreas.sandberg@arm.com *
511986Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
611986Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
711986Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
811986Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
911986Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1011986Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1111986Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1211986Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1312391Sjason@lowepower.com *
1412391Sjason@lowepower.com * Copyright (c) 2009 The Regents of The University of Michigan
1512391Sjason@lowepower.com * All rights reserved.
1612391Sjason@lowepower.com *
1712391Sjason@lowepower.com * Redistribution and use in source and binary forms, with or without
1812391Sjason@lowepower.com * modification, are permitted provided that the following conditions are
1912391Sjason@lowepower.com * met: redistributions of source code must retain the above copyright
2012391Sjason@lowepower.com * notice, this list of conditions and the following disclaimer;
2112391Sjason@lowepower.com * redistributions in binary form must reproduce the above copyright
2211986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2312391Sjason@lowepower.com * documentation and/or other materials provided with the distribution;
2412391Sjason@lowepower.com * neither the name of the copyright holders nor the names of its
2512391Sjason@lowepower.com * contributors may be used to endorse or promote products derived from
2612391Sjason@lowepower.com * this software without specific prior written permission.
2712391Sjason@lowepower.com *
2811986Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2912391Sjason@lowepower.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3012391Sjason@lowepower.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3112391Sjason@lowepower.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3212391Sjason@lowepower.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3312391Sjason@lowepower.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3412391Sjason@lowepower.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3511986Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3612391Sjason@lowepower.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3712391Sjason@lowepower.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3812391Sjason@lowepower.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3912391Sjason@lowepower.com *
4011986Sandreas.sandberg@arm.com * Authors: Gabe Black
4112391Sjason@lowepower.com */
4212391Sjason@lowepower.com
4312391Sjason@lowepower.com#ifndef __ARCH_ARM_ISA_HH__
4412391Sjason@lowepower.com#define __ARCH_ARM_ISA_HH__
4512391Sjason@lowepower.com
4612391Sjason@lowepower.com#include "arch/arm/isa_device.hh"
4712391Sjason@lowepower.com#include "arch/arm/miscregs.hh"
4812391Sjason@lowepower.com#include "arch/arm/registers.hh"
4912391Sjason@lowepower.com#include "arch/arm/system.hh"
5011986Sandreas.sandberg@arm.com#include "arch/arm/tlb.hh"
5112391Sjason@lowepower.com#include "arch/arm/types.hh"
5212391Sjason@lowepower.com#include "arch/generic/traits.hh"
5312391Sjason@lowepower.com#include "debug/Checkpoint.hh"
5412391Sjason@lowepower.com#include "enums/VecRegRenameMode.hh"
5512391Sjason@lowepower.com#include "sim/sim_object.hh"
5612391Sjason@lowepower.com#include "enums/DecoderFlavour.hh"
5712391Sjason@lowepower.com
5812391Sjason@lowepower.comstruct ArmISAParams;
5911986Sandreas.sandberg@arm.comstruct DummyArmISADeviceParams;
6011986Sandreas.sandberg@arm.comclass ThreadContext;
6112391Sjason@lowepower.comclass Checkpoint;
6212391Sjason@lowepower.comclass EventManager;
6312391Sjason@lowepower.com
6411986Sandreas.sandberg@arm.comnamespace ArmISA
6512391Sjason@lowepower.com{
6612391Sjason@lowepower.com    class ISA : public SimObject
6712391Sjason@lowepower.com    {
6811986Sandreas.sandberg@arm.com      protected:
6912391Sjason@lowepower.com        // Parent system
7011986Sandreas.sandberg@arm.com        ArmSystem *system;
7112391Sjason@lowepower.com
7212391Sjason@lowepower.com        // Micro Architecture
7312391Sjason@lowepower.com        const Enums::DecoderFlavour _decoderFlavour;
7412391Sjason@lowepower.com        const Enums::VecRegRenameMode _vecRegRenameMode;
7512391Sjason@lowepower.com
7612391Sjason@lowepower.com        /** Dummy device for to handle non-existing ISA devices */
7712391Sjason@lowepower.com        DummyISADevice dummyDevice;
7812391Sjason@lowepower.com
7912391Sjason@lowepower.com        // PMU belonging to this ISA
8011986Sandreas.sandberg@arm.com        BaseISADevice *pmu;
8114299Sbbruce@ucdavis.edu
8211986Sandreas.sandberg@arm.com        // Generic timer interface belonging to this ISA
8311986Sandreas.sandberg@arm.com        std::unique_ptr<BaseISADevice> timer;
8411986Sandreas.sandberg@arm.com
8512391Sjason@lowepower.com        // Cached copies of system-level properties
8612391Sjason@lowepower.com        bool highestELIs64;
8712391Sjason@lowepower.com        bool haveSecurity;
8812391Sjason@lowepower.com        bool haveLPAE;
8912391Sjason@lowepower.com        bool haveVirtualization;
9011986Sandreas.sandberg@arm.com        bool haveCrypto;
9111986Sandreas.sandberg@arm.com        bool haveLargeAsid64;
9211986Sandreas.sandberg@arm.com        uint8_t physAddrRange;
9311986Sandreas.sandberg@arm.com
9411986Sandreas.sandberg@arm.com        /**
9512391Sjason@lowepower.com         * If true, accesses to IMPLEMENTATION DEFINED registers are treated
9611986Sandreas.sandberg@arm.com         * as NOP hence not causing UNDEFINED INSTRUCTION.
9711986Sandreas.sandberg@arm.com         */
9811986Sandreas.sandberg@arm.com        bool impdefAsNop;
9911986Sandreas.sandberg@arm.com
10012391Sjason@lowepower.com        /** MiscReg metadata **/
10111986Sandreas.sandberg@arm.com        struct MiscRegLUTEntry {
10211986Sandreas.sandberg@arm.com            uint32_t lower;  // Lower half mapped to this register
10311986Sandreas.sandberg@arm.com            uint32_t upper;  // Upper half mapped to this register
10411986Sandreas.sandberg@arm.com            uint64_t _reset; // value taken on reset (i.e. initialization)
10511986Sandreas.sandberg@arm.com            uint64_t _res0;  // reserved
10611986Sandreas.sandberg@arm.com            uint64_t _res1;  // reserved
10711986Sandreas.sandberg@arm.com            uint64_t _raz;   // read as zero (fixed at 0)
10811986Sandreas.sandberg@arm.com            uint64_t _rao;   // read as one (fixed at 1)
10911986Sandreas.sandberg@arm.com          public:
11014299Sbbruce@ucdavis.edu            MiscRegLUTEntry() :
11111986Sandreas.sandberg@arm.com              lower(0), upper(0),
11211986Sandreas.sandberg@arm.com              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
11311986Sandreas.sandberg@arm.com            uint64_t reset() const { return _reset; }
11411986Sandreas.sandberg@arm.com            uint64_t res0()  const { return _res0; }
11512391Sjason@lowepower.com            uint64_t res1()  const { return _res1; }
11612391Sjason@lowepower.com            uint64_t raz()   const { return _raz; }
11712391Sjason@lowepower.com            uint64_t rao()   const { return _rao; }
11812391Sjason@lowepower.com            // raz/rao implies writes ignored
11912391Sjason@lowepower.com            uint64_t wi()    const { return _raz | _rao; }
12012391Sjason@lowepower.com        };
12112391Sjason@lowepower.com
12212391Sjason@lowepower.com        /** Metadata table accessible via the value of the register */
12312391Sjason@lowepower.com        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
12412391Sjason@lowepower.com
12512391Sjason@lowepower.com        class MiscRegLUTEntryInitializer {
12612391Sjason@lowepower.com            struct MiscRegLUTEntry &entry;
12712391Sjason@lowepower.com            std::bitset<NUM_MISCREG_INFOS> &info;
12812391Sjason@lowepower.com            typedef const MiscRegLUTEntryInitializer& chain;
12912391Sjason@lowepower.com          public:
13012391Sjason@lowepower.com            chain mapsTo(uint32_t l, uint32_t u = 0) const {
13112391Sjason@lowepower.com                entry.lower = l;
13212391Sjason@lowepower.com                entry.upper = u;
13312391Sjason@lowepower.com                return *this;
13412391Sjason@lowepower.com            }
13512391Sjason@lowepower.com            chain res0(uint64_t mask) const {
13612391Sjason@lowepower.com                entry._res0 = mask;
13712391Sjason@lowepower.com                return *this;
13812391Sjason@lowepower.com            }
13912391Sjason@lowepower.com            chain res1(uint64_t mask) const {
14012391Sjason@lowepower.com                entry._res1 = mask;
14112391Sjason@lowepower.com                return *this;
14212391Sjason@lowepower.com            }
14312391Sjason@lowepower.com            chain raz(uint64_t mask) const {
14412391Sjason@lowepower.com                entry._raz  = mask;
14512391Sjason@lowepower.com                return *this;
14612391Sjason@lowepower.com            }
14712391Sjason@lowepower.com            chain rao(uint64_t mask) const {
14812391Sjason@lowepower.com                entry._rao  = mask;
14912391Sjason@lowepower.com                return *this;
15012391Sjason@lowepower.com            }
15112391Sjason@lowepower.com            chain implemented(bool v = true) const {
15212391Sjason@lowepower.com                info[MISCREG_IMPLEMENTED] = v;
15312391Sjason@lowepower.com                return *this;
15412391Sjason@lowepower.com            }
15512391Sjason@lowepower.com            chain unimplemented() const {
15612391Sjason@lowepower.com                return implemented(false);
15712391Sjason@lowepower.com            }
15812391Sjason@lowepower.com            chain unverifiable(bool v = true) const {
15912391Sjason@lowepower.com                info[MISCREG_UNVERIFIABLE] = v;
16012391Sjason@lowepower.com                return *this;
16112391Sjason@lowepower.com            }
16212391Sjason@lowepower.com            chain warnNotFail(bool v = true) const {
16312391Sjason@lowepower.com                info[MISCREG_WARN_NOT_FAIL] = v;
16412391Sjason@lowepower.com                return *this;
16512391Sjason@lowepower.com            }
16612391Sjason@lowepower.com            chain mutex(bool v = true) const {
16712391Sjason@lowepower.com                info[MISCREG_MUTEX] = v;
16812391Sjason@lowepower.com                return *this;
16912391Sjason@lowepower.com            }
170            chain banked(bool v = true) const {
171                info[MISCREG_BANKED] = v;
172                return *this;
173            }
174            chain bankedChild(bool v = true) const {
175                info[MISCREG_BANKED_CHILD] = v;
176                return *this;
177            }
178            chain userNonSecureRead(bool v = true) const {
179                info[MISCREG_USR_NS_RD] = v;
180                return *this;
181            }
182            chain userNonSecureWrite(bool v = true) const {
183                info[MISCREG_USR_NS_WR] = v;
184                return *this;
185            }
186            chain userSecureRead(bool v = true) const {
187                info[MISCREG_USR_S_RD] = v;
188                return *this;
189            }
190            chain userSecureWrite(bool v = true) const {
191                info[MISCREG_USR_S_WR] = v;
192                return *this;
193            }
194            chain user(bool v = true) const {
195                userNonSecureRead(v);
196                userNonSecureWrite(v);
197                userSecureRead(v);
198                userSecureWrite(v);
199                return *this;
200            }
201            chain privNonSecureRead(bool v = true) const {
202                info[MISCREG_PRI_NS_RD] = v;
203                return *this;
204            }
205            chain privNonSecureWrite(bool v = true) const {
206                info[MISCREG_PRI_NS_WR] = v;
207                return *this;
208            }
209            chain privNonSecure(bool v = true) const {
210                privNonSecureRead(v);
211                privNonSecureWrite(v);
212                return *this;
213            }
214            chain privSecureRead(bool v = true) const {
215                info[MISCREG_PRI_S_RD] = v;
216                return *this;
217            }
218            chain privSecureWrite(bool v = true) const {
219                info[MISCREG_PRI_S_WR] = v;
220                return *this;
221            }
222            chain privSecure(bool v = true) const {
223                privSecureRead(v);
224                privSecureWrite(v);
225                return *this;
226            }
227            chain priv(bool v = true) const {
228                privSecure(v);
229                privNonSecure(v);
230                return *this;
231            }
232            chain hypRead(bool v = true) const {
233                info[MISCREG_HYP_RD] = v;
234                return *this;
235            }
236            chain hypWrite(bool v = true) const {
237                info[MISCREG_HYP_WR] = v;
238                return *this;
239            }
240            chain hyp(bool v = true) const {
241                hypRead(v);
242                hypWrite(v);
243                return *this;
244            }
245            chain monSecureRead(bool v = true) const {
246                info[MISCREG_MON_NS0_RD] = v;
247                return *this;
248            }
249            chain monSecureWrite(bool v = true) const {
250                info[MISCREG_MON_NS0_WR] = v;
251                return *this;
252            }
253            chain monNonSecureRead(bool v = true) const {
254                info[MISCREG_MON_NS1_RD] = v;
255                return *this;
256            }
257            chain monNonSecureWrite(bool v = true) const {
258                info[MISCREG_MON_NS1_WR] = v;
259                return *this;
260            }
261            chain mon(bool v = true) const {
262                monSecureRead(v);
263                monSecureWrite(v);
264                monNonSecureRead(v);
265                monNonSecureWrite(v);
266                return *this;
267            }
268            chain monSecure(bool v = true) const {
269                monSecureRead(v);
270                monSecureWrite(v);
271                return *this;
272            }
273            chain monNonSecure(bool v = true) const {
274                monNonSecureRead(v);
275                monNonSecureWrite(v);
276                return *this;
277            }
278            chain allPrivileges(bool v = true) const {
279                userNonSecureRead(v);
280                userNonSecureWrite(v);
281                userSecureRead(v);
282                userSecureWrite(v);
283                privNonSecureRead(v);
284                privNonSecureWrite(v);
285                privSecureRead(v);
286                privSecureWrite(v);
287                hypRead(v);
288                hypWrite(v);
289                monSecureRead(v);
290                monSecureWrite(v);
291                monNonSecureRead(v);
292                monNonSecureWrite(v);
293                return *this;
294            }
295            chain nonSecure(bool v = true) const {
296                userNonSecureRead(v);
297                userNonSecureWrite(v);
298                privNonSecureRead(v);
299                privNonSecureWrite(v);
300                hypRead(v);
301                hypWrite(v);
302                monNonSecureRead(v);
303                monNonSecureWrite(v);
304                return *this;
305            }
306            chain secure(bool v = true) const {
307                userSecureRead(v);
308                userSecureWrite(v);
309                privSecureRead(v);
310                privSecureWrite(v);
311                monSecureRead(v);
312                monSecureWrite(v);
313                return *this;
314            }
315            chain reads(bool v) const {
316                userNonSecureRead(v);
317                userSecureRead(v);
318                privNonSecureRead(v);
319                privSecureRead(v);
320                hypRead(v);
321                monSecureRead(v);
322                monNonSecureRead(v);
323                return *this;
324            }
325            chain writes(bool v) const {
326                userNonSecureWrite(v);
327                userSecureWrite(v);
328                privNonSecureWrite(v);
329                privSecureWrite(v);
330                hypWrite(v);
331                monSecureWrite(v);
332                monNonSecureWrite(v);
333                return *this;
334            }
335            chain exceptUserMode() const {
336                user(0);
337                return *this;
338            }
339            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
340                                       std::bitset<NUM_MISCREG_INFOS> &i)
341              : entry(e),
342                info(i)
343            {
344                // force unimplemented registers to be thusly declared
345                implemented(1);
346            }
347        };
348
349        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
350            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
351                                              miscRegInfo[reg]);
352        }
353
354        void initializeMiscRegMetadata();
355
356        MiscReg miscRegs[NumMiscRegs];
357        const IntRegIndex *intRegMap;
358
359        void
360        updateRegMap(CPSR cpsr)
361        {
362            if (cpsr.width == 0) {
363                intRegMap = IntReg64Map;
364            } else {
365                switch (cpsr.mode) {
366                  case MODE_USER:
367                  case MODE_SYSTEM:
368                    intRegMap = IntRegUsrMap;
369                    break;
370                  case MODE_FIQ:
371                    intRegMap = IntRegFiqMap;
372                    break;
373                  case MODE_IRQ:
374                    intRegMap = IntRegIrqMap;
375                    break;
376                  case MODE_SVC:
377                    intRegMap = IntRegSvcMap;
378                    break;
379                  case MODE_MON:
380                    intRegMap = IntRegMonMap;
381                    break;
382                  case MODE_ABORT:
383                    intRegMap = IntRegAbtMap;
384                    break;
385                  case MODE_HYP:
386                    intRegMap = IntRegHypMap;
387                    break;
388                  case MODE_UNDEFINED:
389                    intRegMap = IntRegUndMap;
390                    break;
391                  default:
392                    panic("Unrecognized mode setting in CPSR.\n");
393                }
394            }
395        }
396
397        BaseISADevice &getGenericTimer(ThreadContext *tc);
398
399
400      private:
401        inline void assert32(ThreadContext *tc) {
402            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
403            assert(cpsr.width);
404        }
405
406        inline void assert64(ThreadContext *tc) {
407            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
408            assert(!cpsr.width);
409        }
410
411      public:
412        void clear();
413
414      protected:
415        void clear64(const ArmISAParams *p);
416        void initID32(const ArmISAParams *p);
417        void initID64(const ArmISAParams *p);
418
419      public:
420        MiscReg readMiscRegNoEffect(int misc_reg) const;
421        MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
422        void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
423        void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
424
425        RegId
426        flattenRegId(const RegId& regId) const
427        {
428            switch (regId.classValue()) {
429              case IntRegClass:
430                return RegId(IntRegClass, flattenIntIndex(regId.index()));
431              case FloatRegClass:
432                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
433              case VecRegClass:
434                return RegId(VecRegClass, flattenVecIndex(regId.index()));
435              case VecElemClass:
436                return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
437              case CCRegClass:
438                return RegId(CCRegClass, flattenCCIndex(regId.index()));
439              case MiscRegClass:
440                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
441            }
442            return RegId();
443        }
444
445        int
446        flattenIntIndex(int reg) const
447        {
448            assert(reg >= 0);
449            if (reg < NUM_ARCH_INTREGS) {
450                return intRegMap[reg];
451            } else if (reg < NUM_INTREGS) {
452                return reg;
453            } else if (reg == INTREG_SPX) {
454                CPSR cpsr = miscRegs[MISCREG_CPSR];
455                ExceptionLevel el = opModeToEL(
456                    (OperatingMode) (uint8_t) cpsr.mode);
457                if (!cpsr.sp && el != EL0)
458                    return INTREG_SP0;
459                switch (el) {
460                  case EL3:
461                    return INTREG_SP3;
462                  case EL2:
463                    return INTREG_SP2;
464                  case EL1:
465                    return INTREG_SP1;
466                  case EL0:
467                    return INTREG_SP0;
468                  default:
469                    panic("Invalid exception level");
470                    return 0;  // Never happens.
471                }
472            } else {
473                return flattenIntRegModeIndex(reg);
474            }
475        }
476
477        int
478        flattenFloatIndex(int reg) const
479        {
480            assert(reg >= 0);
481            return reg;
482        }
483
484        int
485        flattenVecIndex(int reg) const
486        {
487            assert(reg >= 0);
488            return reg;
489        }
490
491        int
492        flattenVecElemIndex(int reg) const
493        {
494            assert(reg >= 0);
495            return reg;
496        }
497
498        int
499        flattenCCIndex(int reg) const
500        {
501            assert(reg >= 0);
502            return reg;
503        }
504
505        int
506        flattenMiscIndex(int reg) const
507        {
508            assert(reg >= 0);
509            int flat_idx = reg;
510
511            if (reg == MISCREG_SPSR) {
512                CPSR cpsr = miscRegs[MISCREG_CPSR];
513                switch (cpsr.mode) {
514                  case MODE_EL0T:
515                    warn("User mode does not have SPSR\n");
516                    flat_idx = MISCREG_SPSR;
517                    break;
518                  case MODE_EL1T:
519                  case MODE_EL1H:
520                    flat_idx = MISCREG_SPSR_EL1;
521                    break;
522                  case MODE_EL2T:
523                  case MODE_EL2H:
524                    flat_idx = MISCREG_SPSR_EL2;
525                    break;
526                  case MODE_EL3T:
527                  case MODE_EL3H:
528                    flat_idx = MISCREG_SPSR_EL3;
529                    break;
530                  case MODE_USER:
531                    warn("User mode does not have SPSR\n");
532                    flat_idx = MISCREG_SPSR;
533                    break;
534                  case MODE_FIQ:
535                    flat_idx = MISCREG_SPSR_FIQ;
536                    break;
537                  case MODE_IRQ:
538                    flat_idx = MISCREG_SPSR_IRQ;
539                    break;
540                  case MODE_SVC:
541                    flat_idx = MISCREG_SPSR_SVC;
542                    break;
543                  case MODE_MON:
544                    flat_idx = MISCREG_SPSR_MON;
545                    break;
546                  case MODE_ABORT:
547                    flat_idx = MISCREG_SPSR_ABT;
548                    break;
549                  case MODE_HYP:
550                    flat_idx = MISCREG_SPSR_HYP;
551                    break;
552                  case MODE_UNDEFINED:
553                    flat_idx = MISCREG_SPSR_UND;
554                    break;
555                  default:
556                    warn("Trying to access SPSR in an invalid mode: %d\n",
557                         cpsr.mode);
558                    flat_idx = MISCREG_SPSR;
559                    break;
560                }
561            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
562                // Mutually exclusive CP15 register
563                switch (reg) {
564                  case MISCREG_PRRR_MAIR0:
565                  case MISCREG_PRRR_MAIR0_NS:
566                  case MISCREG_PRRR_MAIR0_S:
567                    {
568                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
569                        // If the muxed reg has been flattened, work out the
570                        // offset and apply it to the unmuxed reg
571                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
572                        if (ttbcr.eae)
573                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
574                                                        idxOffset);
575                        else
576                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
577                                                        idxOffset);
578                    }
579                    break;
580                  case MISCREG_NMRR_MAIR1:
581                  case MISCREG_NMRR_MAIR1_NS:
582                  case MISCREG_NMRR_MAIR1_S:
583                    {
584                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
585                        // If the muxed reg has been flattened, work out the
586                        // offset and apply it to the unmuxed reg
587                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
588                        if (ttbcr.eae)
589                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
590                                                        idxOffset);
591                        else
592                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
593                                                        idxOffset);
594                    }
595                    break;
596                  case MISCREG_PMXEVTYPER_PMCCFILTR:
597                    {
598                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
599                        if (pmselr.sel == 31)
600                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
601                        else
602                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
603                    }
604                    break;
605                  default:
606                    panic("Unrecognized misc. register.\n");
607                    break;
608                }
609            } else {
610                if (miscRegInfo[reg][MISCREG_BANKED]) {
611                    bool secureReg = haveSecurity && !highestELIs64 &&
612                                     inSecureState(miscRegs[MISCREG_SCR],
613                                                   miscRegs[MISCREG_CPSR]);
614                    flat_idx += secureReg ? 2 : 1;
615                }
616            }
617            return flat_idx;
618        }
619
620        std::pair<int,int> getMiscIndices(int misc_reg) const
621        {
622            // Note: indexes of AArch64 registers are left unchanged
623            int flat_idx = flattenMiscIndex(misc_reg);
624
625            if (lookUpMiscReg[flat_idx].lower == 0) {
626                return std::make_pair(flat_idx, 0);
627            }
628
629            // do additional S/NS flattenings if mapped to NS while in S
630            bool S = haveSecurity && !highestELIs64 &&
631                     inSecureState(miscRegs[MISCREG_SCR],
632                                   miscRegs[MISCREG_CPSR]);
633            int lower = lookUpMiscReg[flat_idx].lower;
634            int upper = lookUpMiscReg[flat_idx].upper;
635            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
636            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
637            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
638            return std::make_pair(lower, upper);
639        }
640
641        void serialize(CheckpointOut &cp) const
642        {
643            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
644            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
645
646            SERIALIZE_SCALAR(highestELIs64);
647            SERIALIZE_SCALAR(haveSecurity);
648            SERIALIZE_SCALAR(haveLPAE);
649            SERIALIZE_SCALAR(haveVirtualization);
650            SERIALIZE_SCALAR(haveLargeAsid64);
651            SERIALIZE_SCALAR(physAddrRange);
652        }
653        void unserialize(CheckpointIn &cp)
654        {
655            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
656            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
657            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
658            updateRegMap(tmp_cpsr);
659
660            UNSERIALIZE_SCALAR(highestELIs64);
661            UNSERIALIZE_SCALAR(haveSecurity);
662            UNSERIALIZE_SCALAR(haveLPAE);
663            UNSERIALIZE_SCALAR(haveVirtualization);
664            UNSERIALIZE_SCALAR(haveLargeAsid64);
665            UNSERIALIZE_SCALAR(physAddrRange);
666        }
667
668        void startup(ThreadContext *tc);
669
670        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
671
672        Enums::VecRegRenameMode
673        vecRegRenameMode() const
674        {
675            return _vecRegRenameMode;
676        }
677
678        /// Explicitly import the otherwise hidden startup
679        using SimObject::startup;
680
681        typedef ArmISAParams Params;
682
683        const Params *params() const;
684
685        ISA(Params *p);
686    };
687}
688
689template<>
690struct initRenameMode<ArmISA::ISA>
691{
692    static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
693    {
694        return isa->vecRegRenameMode();
695    }
696    static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
697    {
698        return mode(isa1) == mode(isa2);
699    }
700};
701
702#endif
703