/*
 * Copyright (c) 2010, 2012-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2009 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_ARM_ISA_HH__
#define __ARCH_ARM_ISA_HH__

#include "arch/arm/isa_device.hh"
#include "arch/arm/miscregs.hh"
#include "arch/arm/registers.hh"
#include "arch/arm/system.hh"
#include "arch/arm/tlb.hh"
#include "arch/arm/types.hh"
#include "arch/generic/traits.hh"
#include "debug/Checkpoint.hh"
#include "enums/VecRegRenameMode.hh"
#include "sim/sim_object.hh"
#include "enums/DecoderFlavour.hh"

struct ArmISAParams;
struct DummyArmISADeviceParams;
class ThreadContext;
class Checkpoint;
class EventManager;

namespace ArmISA
{
    class ISA : public SimObject
    {
      protected:
        // Parent system
        ArmSystem *system;

        // Micro Architecture
        const Enums::DecoderFlavour _decoderFlavour;
        const Enums::VecRegRenameMode _vecRegRenameMode;

        /** Dummy device for to handle non-existing ISA devices */
        DummyISADevice dummyDevice;

        // PMU belonging to this ISA
        BaseISADevice *pmu;

        // Generic timer interface belonging to this ISA
        std::unique_ptr<BaseISADevice> timer;

        // Cached copies of system-level properties
        bool highestELIs64;
        bool haveSecurity;
        bool haveLPAE;
        bool haveVirtualization;
        bool haveLargeAsid64;
        uint8_t physAddrRange64;

        /** MiscReg metadata **/
        struct MiscRegLUTEntry {
            uint32_t lower;  // Lower half mapped to this register
            uint32_t upper;  // Upper half mapped to this register
            uint64_t _reset; // value taken on reset (i.e. initialization)
            uint64_t _res0;  // reserved
            uint64_t _res1;  // reserved
            uint64_t _raz;   // read as zero (fixed at 0)
            uint64_t _rao;   // read as one (fixed at 1)
          public:
            MiscRegLUTEntry() :
              lower(0), upper(0),
              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
            uint64_t reset() const { return _reset; }
            uint64_t res0()  const { return _res0; }
            uint64_t res1()  const { return _res1; }
            uint64_t raz()   const { return _raz; }
            uint64_t rao()   const { return _rao; }
            // raz/rao implies writes ignored
            uint64_t wi()    const { return _raz | _rao; }
        };

        /** Metadata table accessible via the value of the register */
        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;

        class MiscRegLUTEntryInitializer {
            struct MiscRegLUTEntry &entry;
            std::bitset<NUM_MISCREG_INFOS> &info;
            typedef const MiscRegLUTEntryInitializer& chain;
          public:
            chain mapsTo(uint32_t l, uint32_t u = 0) const {
                entry.lower = l;
                entry.upper = u;
                return *this;
            }
            chain res0(uint64_t mask) const {
                entry._res0 = mask;
                return *this;
            }
            chain res1(uint64_t mask) const {
                entry._res1 = mask;
                return *this;
            }
            chain raz(uint64_t mask) const {
                entry._raz  = mask;
                return *this;
            }
            chain rao(uint64_t mask) const {
                entry._rao  = mask;
                return *this;
            }
            chain implemented(bool v = true) const {
                info[MISCREG_IMPLEMENTED] = v;
                return *this;
            }
            chain unimplemented() const {
                return implemented(false);
            }
            chain unverifiable(bool v = true) const {
                info[MISCREG_UNVERIFIABLE] = v;
                return *this;
            }
            chain warnNotFail(bool v = true) const {
                info[MISCREG_WARN_NOT_FAIL] = v;
                return *this;
            }
            chain mutex(bool v = true) const {
                info[MISCREG_MUTEX] = v;
                return *this;
            }
            chain banked(bool v = true) const {
                info[MISCREG_BANKED] = v;
                return *this;
            }
            chain bankedChild(bool v = true) const {
                info[MISCREG_BANKED_CHILD] = v;
                return *this;
            }
            chain userNonSecureRead(bool v = true) const {
                info[MISCREG_USR_NS_RD] = v;
                return *this;
            }
            chain userNonSecureWrite(bool v = true) const {
                info[MISCREG_USR_NS_WR] = v;
                return *this;
            }
            chain userSecureRead(bool v = true) const {
                info[MISCREG_USR_S_RD] = v;
                return *this;
            }
            chain userSecureWrite(bool v = true) const {
                info[MISCREG_USR_S_WR] = v;
                return *this;
            }
            chain user(bool v = true) const {
                userNonSecureRead(v);
                userNonSecureWrite(v);
                userSecureRead(v);
                userSecureWrite(v);
                return *this;
            }
            chain privNonSecureRead(bool v = true) const {
                info[MISCREG_PRI_NS_RD] = v;
                return *this;
            }
            chain privNonSecureWrite(bool v = true) const {
                info[MISCREG_PRI_NS_WR] = v;
                return *this;
            }
            chain privSecureRead(bool v = true) const {
                info[MISCREG_PRI_S_RD] = v;
                return *this;
            }
            chain privSecureWrite(bool v = true) const {
                info[MISCREG_PRI_S_WR] = v;
                return *this;
            }
            chain privSecure(bool v = true) const {
                privSecureRead(v);
                privSecureWrite(v);
                return *this;
            }
            chain hypRead(bool v = true) const {
                info[MISCREG_HYP_RD] = v;
                return *this;
            }
            chain hypWrite(bool v = true) const {
                info[MISCREG_HYP_WR] = v;
                return *this;
            }
            chain hyp(bool v = true) const {
                hypRead(v);
                hypWrite(v);
                return *this;
            }
            chain monSecureRead(bool v = true) const {
                info[MISCREG_MON_NS0_RD] = v;
                return *this;
            }
            chain monSecureWrite(bool v = true) const {
                info[MISCREG_MON_NS0_WR] = v;
                return *this;
            }
            chain monNonSecureRead(bool v = true) const {
                info[MISCREG_MON_NS1_RD] = v;
                return *this;
            }
            chain monNonSecureWrite(bool v = true) const {
                info[MISCREG_MON_NS1_WR] = v;
                return *this;
            }
            chain mon(bool v = true) const {
                monSecureRead(v);
                monSecureWrite(v);
                monNonSecureRead(v);
                monNonSecureWrite(v);
                return *this;
            }
            chain monSecure(bool v = true) const {
                monSecureRead(v);
                monSecureWrite(v);
                return *this;
            }
            chain monNonSecure(bool v = true) const {
                monNonSecureRead(v);
                monNonSecureWrite(v);
                return *this;
            }
            chain allPrivileges(bool v = true) const {
                userNonSecureRead(v);
                userNonSecureWrite(v);
                userSecureRead(v);
                userSecureWrite(v);
                privNonSecureRead(v);
                privNonSecureWrite(v);
                privSecureRead(v);
                privSecureWrite(v);
                hypRead(v);
                hypWrite(v);
                monSecureRead(v);
                monSecureWrite(v);
                monNonSecureRead(v);
                monNonSecureWrite(v);
                return *this;
            }
            chain nonSecure(bool v = true) const {
                userNonSecureRead(v);
                userNonSecureWrite(v);
                privNonSecureRead(v);
                privNonSecureWrite(v);
                hypRead(v);
                hypWrite(v);
                monNonSecureRead(v);
                monNonSecureWrite(v);
                return *this;
            }
            chain secure(bool v = true) const {
                userSecureRead(v);
                userSecureWrite(v);
                privSecureRead(v);
                privSecureWrite(v);
                monSecureRead(v);
                monSecureWrite(v);
                return *this;
            }
            chain reads(bool v) const {
                userNonSecureRead(v);
                userSecureRead(v);
                privNonSecureRead(v);
                privSecureRead(v);
                hypRead(v);
                monSecureRead(v);
                monNonSecureRead(v);
                return *this;
            }
            chain writes(bool v) const {
                userNonSecureWrite(v);
                userSecureWrite(v);
                privNonSecureWrite(v);
                privSecureWrite(v);
                hypWrite(v);
                monSecureWrite(v);
                monNonSecureWrite(v);
                return *this;
            }
            chain exceptUserMode() const {
                user(0);
                return *this;
            }
            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
                                       std::bitset<NUM_MISCREG_INFOS> &i)
              : entry(e),
                info(i)
            {
                // force unimplemented registers to be thusly declared
                implemented(1);
            }
        };

        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
                                              miscRegInfo[reg]);
        }

        void initializeMiscRegMetadata();

        MiscReg miscRegs[NumMiscRegs];
        const IntRegIndex *intRegMap;

        void
        updateRegMap(CPSR cpsr)
        {
            if (cpsr.width == 0) {
                intRegMap = IntReg64Map;
            } else {
                switch (cpsr.mode) {
                  case MODE_USER:
                  case MODE_SYSTEM:
                    intRegMap = IntRegUsrMap;
                    break;
                  case MODE_FIQ:
                    intRegMap = IntRegFiqMap;
                    break;
                  case MODE_IRQ:
                    intRegMap = IntRegIrqMap;
                    break;
                  case MODE_SVC:
                    intRegMap = IntRegSvcMap;
                    break;
                  case MODE_MON:
                    intRegMap = IntRegMonMap;
                    break;
                  case MODE_ABORT:
                    intRegMap = IntRegAbtMap;
                    break;
                  case MODE_HYP:
                    intRegMap = IntRegHypMap;
                    break;
                  case MODE_UNDEFINED:
                    intRegMap = IntRegUndMap;
                    break;
                  default:
                    panic("Unrecognized mode setting in CPSR.\n");
                }
            }
        }

        BaseISADevice &getGenericTimer(ThreadContext *tc);


      private:
        inline void assert32(ThreadContext *tc) {
            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
            assert(cpsr.width);
        }

        inline void assert64(ThreadContext *tc) {
            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
            assert(!cpsr.width);
        }

      public:
        void clear();
        void clear64(const ArmISAParams *p);

        MiscReg readMiscRegNoEffect(int misc_reg) const;
        MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
        void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
        void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);

        RegId
        flattenRegId(const RegId& regId) const
        {
            switch (regId.classValue()) {
              case IntRegClass:
                return RegId(IntRegClass, flattenIntIndex(regId.index()));
              case FloatRegClass:
                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
              case VecRegClass:
                return RegId(VecRegClass, flattenVecIndex(regId.index()));
              case VecElemClass:
                return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
              case CCRegClass:
                return RegId(CCRegClass, flattenCCIndex(regId.index()));
              case MiscRegClass:
                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
            }
            return RegId();
        }

        int
        flattenIntIndex(int reg) const
        {
            assert(reg >= 0);
            if (reg < NUM_ARCH_INTREGS) {
                return intRegMap[reg];
            } else if (reg < NUM_INTREGS) {
                return reg;
            } else if (reg == INTREG_SPX) {
                CPSR cpsr = miscRegs[MISCREG_CPSR];
                ExceptionLevel el = opModeToEL(
                    (OperatingMode) (uint8_t) cpsr.mode);
                if (!cpsr.sp && el != EL0)
                    return INTREG_SP0;
                switch (el) {
                  case EL3:
                    return INTREG_SP3;
                  case EL2:
                    return INTREG_SP2;
                  case EL1:
                    return INTREG_SP1;
                  case EL0:
                    return INTREG_SP0;
                  default:
                    panic("Invalid exception level");
                    break;
                }
            } else {
                return flattenIntRegModeIndex(reg);
            }
        }

        int
        flattenFloatIndex(int reg) const
        {
            assert(reg >= 0);
            return reg;
        }

        int
        flattenVecIndex(int reg) const
        {
            assert(reg >= 0);
            return reg;
        }

        int
        flattenVecElemIndex(int reg) const
        {
            assert(reg >= 0);
            return reg;
        }

        int
        flattenCCIndex(int reg) const
        {
            assert(reg >= 0);
            return reg;
        }

        int
        flattenMiscIndex(int reg) const
        {
            assert(reg >= 0);
            int flat_idx = reg;

            if (reg == MISCREG_SPSR) {
                CPSR cpsr = miscRegs[MISCREG_CPSR];
                switch (cpsr.mode) {
                  case MODE_EL0T:
                    warn("User mode does not have SPSR\n");
                    flat_idx = MISCREG_SPSR;
                    break;
                  case MODE_EL1T:
                  case MODE_EL1H:
                    flat_idx = MISCREG_SPSR_EL1;
                    break;
                  case MODE_EL2T:
                  case MODE_EL2H:
                    flat_idx = MISCREG_SPSR_EL2;
                    break;
                  case MODE_EL3T:
                  case MODE_EL3H:
                    flat_idx = MISCREG_SPSR_EL3;
                    break;
                  case MODE_USER:
                    warn("User mode does not have SPSR\n");
                    flat_idx = MISCREG_SPSR;
                    break;
                  case MODE_FIQ:
                    flat_idx = MISCREG_SPSR_FIQ;
                    break;
                  case MODE_IRQ:
                    flat_idx = MISCREG_SPSR_IRQ;
                    break;
                  case MODE_SVC:
                    flat_idx = MISCREG_SPSR_SVC;
                    break;
                  case MODE_MON:
                    flat_idx = MISCREG_SPSR_MON;
                    break;
                  case MODE_ABORT:
                    flat_idx = MISCREG_SPSR_ABT;
                    break;
                  case MODE_HYP:
                    flat_idx = MISCREG_SPSR_HYP;
                    break;
                  case MODE_UNDEFINED:
                    flat_idx = MISCREG_SPSR_UND;
                    break;
                  default:
                    warn("Trying to access SPSR in an invalid mode: %d\n",
                         cpsr.mode);
                    flat_idx = MISCREG_SPSR;
                    break;
                }
            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
                // Mutually exclusive CP15 register
                switch (reg) {
                  case MISCREG_PRRR_MAIR0:
                  case MISCREG_PRRR_MAIR0_NS:
                  case MISCREG_PRRR_MAIR0_S:
                    {
                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
                        // If the muxed reg has been flattened, work out the
                        // offset and apply it to the unmuxed reg
                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
                        if (ttbcr.eae)
                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
                                                        idxOffset);
                        else
                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
                                                        idxOffset);
                    }
                    break;
                  case MISCREG_NMRR_MAIR1:
                  case MISCREG_NMRR_MAIR1_NS:
                  case MISCREG_NMRR_MAIR1_S:
                    {
                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
                        // If the muxed reg has been flattened, work out the
                        // offset and apply it to the unmuxed reg
                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
                        if (ttbcr.eae)
                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
                                                        idxOffset);
                        else
                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
                                                        idxOffset);
                    }
                    break;
                  case MISCREG_PMXEVTYPER_PMCCFILTR:
                    {
                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
                        if (pmselr.sel == 31)
                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
                        else
                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
                    }
                    break;
                  default:
                    panic("Unrecognized misc. register.\n");
                    break;
                }
            } else {
                if (miscRegInfo[reg][MISCREG_BANKED]) {
                    bool secureReg = haveSecurity && !highestELIs64 &&
                                     inSecureState(miscRegs[MISCREG_SCR],
                                                   miscRegs[MISCREG_CPSR]);
                    flat_idx += secureReg ? 2 : 1;
                }
            }
            return flat_idx;
        }

        std::pair<int,int> getMiscIndices(int misc_reg) const
        {
            // Note: indexes of AArch64 registers are left unchanged
            int flat_idx = flattenMiscIndex(misc_reg);

            if (lookUpMiscReg[flat_idx].lower == 0) {
                return std::make_pair(flat_idx, 0);
            }

            // do additional S/NS flattenings if mapped to NS while in S
            bool S = haveSecurity && !highestELIs64 &&
                     inSecureState(miscRegs[MISCREG_SCR],
                                   miscRegs[MISCREG_CPSR]);
            int lower = lookUpMiscReg[flat_idx].lower;
            int upper = lookUpMiscReg[flat_idx].upper;
            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
            return std::make_pair(lower, upper);
        }

        void serialize(CheckpointOut &cp) const
        {
            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);

            SERIALIZE_SCALAR(highestELIs64);
            SERIALIZE_SCALAR(haveSecurity);
            SERIALIZE_SCALAR(haveLPAE);
            SERIALIZE_SCALAR(haveVirtualization);
            SERIALIZE_SCALAR(haveLargeAsid64);
            SERIALIZE_SCALAR(physAddrRange64);
        }
        void unserialize(CheckpointIn &cp)
        {
            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
            updateRegMap(tmp_cpsr);

            UNSERIALIZE_SCALAR(highestELIs64);
            UNSERIALIZE_SCALAR(haveSecurity);
            UNSERIALIZE_SCALAR(haveLPAE);
            UNSERIALIZE_SCALAR(haveVirtualization);
            UNSERIALIZE_SCALAR(haveLargeAsid64);
            UNSERIALIZE_SCALAR(physAddrRange64);
        }

        void startup(ThreadContext *tc) {}

        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }

        Enums::VecRegRenameMode
        vecRegRenameMode() const
        {
            return _vecRegRenameMode;
        }

        /// Explicitly import the otherwise hidden startup
        using SimObject::startup;

        typedef ArmISAParams Params;

        const Params *params() const;

        ISA(Params *p);
    };
}

template<>
struct initRenameMode<ArmISA::ISA>
{
    static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
    {
        return isa->vecRegRenameMode();
    }
    static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
    {
        return mode(isa1) == mode(isa2);
    }
};

#endif
