/*
 * Copyright (c) 2012 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.
 *
 * 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: Andreas Sandberg
 */

#include "arch/arm/kvm/arm_cpu.hh"

#include <linux/kvm.h>

#include <algorithm>
#include <cerrno>
#include <memory>

#include "arch/arm/interrupts.hh"
#include "arch/registers.hh"
#include "cpu/kvm/base.hh"
#include "debug/Kvm.hh"
#include "debug/KvmContext.hh"
#include "debug/KvmInt.hh"
#include "sim/pseudo_inst.hh"

using namespace ArmISA;

#define EXTRACT_FIELD(val, mask, shift)         \
    (((val) & (mask)) >> (shift))

#define REG_IS_ARM(id)                          \
    (((id) & KVM_REG_ARCH_MASK) == KVM_REG_ARM)

#define REG_IS_32BIT(id)                                \
    (((id) & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32)

#define REG_IS_64BIT(id)                                \
    (((id) & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64)

#define REG_IS_CP(id, cp)                       \
    (((id) & KVM_REG_ARM_COPROC_MASK) == (cp))

#define REG_IS_CORE(id) REG_IS_CP((id), KVM_REG_ARM_CORE)

#define REG_IS_VFP(id) REG_IS_CP((id), KVM_REG_ARM_VFP)
#define REG_VFP_REG(id) ((id) & KVM_REG_ARM_VFP_MASK)
// HACK: These aren't really defined in any of the headers, so we'll
// assume some reasonable values for now.
#define REG_IS_VFP_REG(id) (REG_VFP_REG(id) < 0x100)
#define REG_IS_VFP_CTRL(id) (REG_VFP_REG(id) >= 0x100)

#define REG_IS_DEMUX(id) REG_IS_CP((id), KVM_REG_ARM_DEMUX)


// There is no constant in the kernel headers defining the mask to use
// to get the core register index. We'll just do what they do
// internally.
#define REG_CORE_IDX(id)                                                \
    (~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE))

#define REG_CP(id)                                                      \
    EXTRACT_FIELD(id, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_COPROC_SHIFT)

#define REG_CRN(id)                                                     \
    EXTRACT_FIELD(id, KVM_REG_ARM_32_CRN_MASK, KVM_REG_ARM_32_CRN_SHIFT)

#define REG_OPC1(id)                                                    \
    EXTRACT_FIELD(id, KVM_REG_ARM_OPC1_MASK, KVM_REG_ARM_OPC1_SHIFT)

#define REG_CRM(id)                                                     \
    EXTRACT_FIELD(id, KVM_REG_ARM_CRM_MASK, KVM_REG_ARM_CRM_SHIFT)

#define REG_OPC2(id)                                                    \
    EXTRACT_FIELD(id, KVM_REG_ARM_32_OPC2_MASK, KVM_REG_ARM_32_OPC2_SHIFT)

#define REG_CP32(cpnum, crn, opc1, crm, opc2) ( \
        (KVM_REG_ARM | KVM_REG_SIZE_U32) |      \
        ((cpnum) << KVM_REG_ARM_COPROC_SHIFT) | \
        ((crn) << KVM_REG_ARM_32_CRN_SHIFT) |   \
        ((opc1) << KVM_REG_ARM_OPC1_SHIFT) |    \
        ((crm) << KVM_REG_ARM_CRM_SHIFT) |      \
        ((opc2) << KVM_REG_ARM_32_OPC2_SHIFT))

#define REG_CP64(cpnum, opc1, crm) (            \
        (KVM_REG_ARM | KVM_REG_SIZE_U64) |      \
        ((cpnum) << KVM_REG_ARM_COPROC_SHIFT) | \
        ((opc1) << KVM_REG_ARM_OPC1_SHIFT) |    \
        ((crm) << KVM_REG_ARM_CRM_SHIFT))

#define REG_CORE32(kname) (                     \
        (KVM_REG_ARM | KVM_REG_SIZE_U32) |      \
        (KVM_REG_ARM_CORE) |                    \
        (KVM_REG_ARM_CORE_REG(kname)))

#define REG_VFP32(regno) (                      \
        (KVM_REG_ARM | KVM_REG_SIZE_U32) |      \
        KVM_REG_ARM_VFP | (regno))

#define REG_VFP64(regno) (                      \
        (KVM_REG_ARM | KVM_REG_SIZE_U64) |      \
        KVM_REG_ARM_VFP | (regno))

#define REG_DEMUX32(dmxid, val) (               \
        (KVM_REG_ARM | KVM_REG_SIZE_U32) |      \
        (dmxid) | (val))

// Some of the co-processor registers are invariants and must have the
// same value on both the host and the guest. We need to keep a list
// of these to prevent gem5 from fiddling with them on the guest.
static uint64_t invariant_reg_vector[] = {
    REG_CP32(15, 0, 0, 0, 0), // MIDR
    REG_CP32(15, 0, 0, 0, 1), // CTR
    REG_CP32(15, 0, 0, 0, 2), // TCMTR
    REG_CP32(15, 0, 0, 0, 3), // TLBTR
    REG_CP32(15, 0, 0, 0, 6), // REVIDR

    REG_CP32(15, 0, 0, 1, 0), // ID_PFR0
    REG_CP32(15, 0, 0, 1, 1), // ID_PFR1
    REG_CP32(15, 0, 0, 1, 2), // ID_DFR0
    REG_CP32(15, 0, 0, 1, 3), // ID_AFR0
    REG_CP32(15, 0, 0, 1, 4), // ID_MMFR0
    REG_CP32(15, 0, 0, 1, 5), // ID_MMFR1
    REG_CP32(15, 0, 0, 1, 6), // ID_MMFR2
    REG_CP32(15, 0, 0, 1, 7), // ID_MMFR3

    REG_CP32(15, 0, 0, 2, 0), // ID_ISAR0
    REG_CP32(15, 0, 0, 2, 1), // ID_ISAR1
    REG_CP32(15, 0, 0, 2, 2), // ID_ISAR2
    REG_CP32(15, 0, 0, 2, 3), // ID_ISAR3
    REG_CP32(15, 0, 0, 2, 4), // ID_ISAR4
    REG_CP32(15, 0, 0, 2, 5), // ID_ISAR5

    REG_CP32(15, 0, 1, 0, 0), // CSSIDR
    REG_CP32(15, 0, 1, 0, 1), // CLIDR
    REG_CP32(15, 0, 1, 0, 7), // AIDR

    REG_VFP32(KVM_REG_ARM_VFP_MVFR0),
    REG_VFP32(KVM_REG_ARM_VFP_MVFR1),
    REG_VFP32(KVM_REG_ARM_VFP_FPSID),

    REG_DEMUX32(KVM_REG_ARM_DEMUX_ID_CCSIDR, 0),
};

const static uint64_t KVM_REG64_TTBR0(REG_CP64(15, 0, 2));
const static uint64_t KVM_REG64_TTBR1(REG_CP64(15, 1, 2));

#define INTERRUPT_ID(type, vcpu, irq) (                    \
        ((type) << KVM_ARM_IRQ_TYPE_SHIFT) |               \
        ((vcpu) << KVM_ARM_IRQ_VCPU_SHIFT) |               \
        ((irq) << KVM_ARM_IRQ_NUM_SHIFT))

#define INTERRUPT_VCPU_IRQ(vcpu)                                \
    INTERRUPT_ID(KVM_ARM_IRQ_TYPE_CPU, vcpu, KVM_ARM_IRQ_CPU_IRQ)

#define INTERRUPT_VCPU_FIQ(vcpu)                                \
    INTERRUPT_ID(KVM_ARM_IRQ_TYPE_CPU, vcpu, KVM_ARM_IRQ_CPU_FIQ)


#define COUNT_OF(l) (sizeof(l) / sizeof(*l))

const std::set<uint64_t> ArmKvmCPU::invariant_regs(
    invariant_reg_vector,
    invariant_reg_vector + COUNT_OF(invariant_reg_vector));


ArmKvmCPU::KvmIntRegInfo ArmKvmCPU::kvmIntRegs[] = {
    { REG_CORE32(usr_regs.ARM_r0), INTREG_R0, "R0" },
    { REG_CORE32(usr_regs.ARM_r1), INTREG_R1, "R1" },
    { REG_CORE32(usr_regs.ARM_r2), INTREG_R2, "R2" },
    { REG_CORE32(usr_regs.ARM_r3), INTREG_R3, "R3" },
    { REG_CORE32(usr_regs.ARM_r4), INTREG_R4, "R4" },
    { REG_CORE32(usr_regs.ARM_r5), INTREG_R5, "R5" },
    { REG_CORE32(usr_regs.ARM_r6), INTREG_R6, "R6" },
    { REG_CORE32(usr_regs.ARM_r7), INTREG_R7, "R7" },
    { REG_CORE32(usr_regs.ARM_r8), INTREG_R8, "R8" },
    { REG_CORE32(usr_regs.ARM_r9), INTREG_R9, "R9" },
    { REG_CORE32(usr_regs.ARM_r10), INTREG_R10, "R10" },
    { REG_CORE32(usr_regs.ARM_fp), INTREG_R11, "R11" },
    { REG_CORE32(usr_regs.ARM_ip), INTREG_R12, "R12" },
    { REG_CORE32(usr_regs.ARM_sp), INTREG_R13, "R13(USR)" },
    { REG_CORE32(usr_regs.ARM_lr), INTREG_R14, "R14(USR)" },

    { REG_CORE32(svc_regs[0]), INTREG_SP_SVC, "R13(SVC)" },
    { REG_CORE32(svc_regs[1]), INTREG_LR_SVC, "R14(SVC)" },

    { REG_CORE32(abt_regs[0]), INTREG_SP_ABT, "R13(ABT)" },
    { REG_CORE32(abt_regs[1]), INTREG_LR_ABT, "R14(ABT)" },

    { REG_CORE32(und_regs[0]), INTREG_SP_UND, "R13(UND)" },
    { REG_CORE32(und_regs[1]), INTREG_LR_UND, "R14(UND)" },

    { REG_CORE32(irq_regs[0]), INTREG_SP_IRQ, "R13(IRQ)" },
    { REG_CORE32(irq_regs[1]), INTREG_LR_IRQ, "R14(IRQ)" },


    { REG_CORE32(fiq_regs[0]), INTREG_R8_FIQ, "R8(FIQ)" },
    { REG_CORE32(fiq_regs[1]), INTREG_R9_FIQ, "R9(FIQ)" },
    { REG_CORE32(fiq_regs[2]), INTREG_R10_FIQ, "R10(FIQ)" },
    { REG_CORE32(fiq_regs[3]), INTREG_R11_FIQ, "R11(FIQ)" },
    { REG_CORE32(fiq_regs[4]), INTREG_R12_FIQ, "R12(FIQ)" },
    { REG_CORE32(fiq_regs[5]), INTREG_R13_FIQ, "R13(FIQ)" },
    { REG_CORE32(fiq_regs[6]), INTREG_R14_FIQ, "R14(FIQ)" },
    { 0, NUM_INTREGS, NULL }
};

ArmKvmCPU::KvmCoreMiscRegInfo ArmKvmCPU::kvmCoreMiscRegs[] = {
    { REG_CORE32(usr_regs.ARM_cpsr), MISCREG_CPSR, "CPSR" },
    { REG_CORE32(svc_regs[2]), MISCREG_SPSR_SVC, "SPSR(SVC)" },
    { REG_CORE32(abt_regs[2]), MISCREG_SPSR_ABT, "SPSR(ABT)" },
    { REG_CORE32(und_regs[2]), MISCREG_SPSR_UND, "SPSR(UND)" },
    { REG_CORE32(irq_regs[2]), MISCREG_SPSR_IRQ, "SPSR(IRQ)" },
    { REG_CORE32(fiq_regs[2]), MISCREG_SPSR_FIQ, "SPSR(FIQ)" },
    { 0, NUM_MISCREGS }
};

ArmKvmCPU::ArmKvmCPU(ArmKvmCPUParams *params)
    : BaseKvmCPU(params),
      irqAsserted(false), fiqAsserted(false)
{
}

ArmKvmCPU::~ArmKvmCPU()
{
}

void
ArmKvmCPU::startup()
{
    BaseKvmCPU::startup();

    /* TODO: This needs to be moved when we start to support VMs with
     * multiple threads since kvmArmVCpuInit requires that all CPUs in
     * the VM have been created.
     */
    /* TODO: The CPU type needs to be configurable once KVM on ARM
     * starts to support more CPUs.
     */
    kvmArmVCpuInit(KVM_ARM_TARGET_CORTEX_A15);
}

Tick
ArmKvmCPU::kvmRun(Tick ticks)
{
    auto interrupt = static_cast<ArmISA::Interrupts *>(interrupts[0]);
    const bool simFIQ(interrupt->checkRaw(INT_FIQ));
    const bool simIRQ(interrupt->checkRaw(INT_IRQ));

    if (fiqAsserted != simFIQ) {
        fiqAsserted = simFIQ;
        DPRINTF(KvmInt, "KVM: Update FIQ state: %i\n", simFIQ);
        vm.setIRQLine(INTERRUPT_VCPU_FIQ(vcpuID), simFIQ);
    }
    if (irqAsserted != simIRQ) {
        irqAsserted = simIRQ;
        DPRINTF(KvmInt, "KVM: Update IRQ state: %i\n", simIRQ);
        vm.setIRQLine(INTERRUPT_VCPU_IRQ(vcpuID), simIRQ);
    }

    return BaseKvmCPU::kvmRun(ticks);
}

void
ArmKvmCPU::dump()
{
    dumpKvmStateCore();
    dumpKvmStateMisc();
}

void
ArmKvmCPU::updateKvmState()
{
    DPRINTF(KvmContext, "Updating KVM state...\n");

    updateKvmStateCore();
    updateKvmStateMisc();
}

void
ArmKvmCPU::updateThreadContext()
{
    DPRINTF(KvmContext, "Updating gem5 state...\n");

    updateTCStateCore();
    updateTCStateMisc();
}

Tick
ArmKvmCPU::onKvmExitHypercall()
{
    ThreadContext *tc(getContext(0));
    const uint32_t reg_ip(tc->readIntRegFlat(INTREG_R12));
    const uint8_t func((reg_ip >> 8) & 0xFF);

    DPRINTF(Kvm, "KVM Hypercall: %#x/%#x\n", func, subfunc);
    const uint64_t ret =
        PseudoInst::pseudoInst<PseudoInstABI>(getContext(0), func);

    // Just set the return value using the KVM API instead of messing
    // with the context. We could have used the context, but that
    // would have required us to request a full context sync.
    setOneReg(REG_CORE32(usr_regs.ARM_r0), ret & 0xFFFFFFFF);
    setOneReg(REG_CORE32(usr_regs.ARM_r1), (ret >> 32) & 0xFFFFFFFF);

    return 0;
}

const ArmKvmCPU::RegIndexVector &
ArmKvmCPU::getRegList() const
{
    if (_regIndexList.size() == 0) {
        std::unique_ptr<struct kvm_reg_list> regs;
        uint64_t i(1);

        do {
            i <<= 1;
            regs.reset((struct kvm_reg_list *)
                       operator new(sizeof(struct kvm_reg_list) +
                                    i * sizeof(uint64_t)));
            regs->n = i;
        } while (!getRegList(*regs));
        _regIndexList.assign(regs->reg,
                             regs->reg + regs->n);
    }

    return _regIndexList;
}

void
ArmKvmCPU::kvmArmVCpuInit(uint32_t target)
{
    struct kvm_vcpu_init init;

    memset(&init, 0, sizeof(init));

    init.target = target;

    kvmArmVCpuInit(init);
}

void
ArmKvmCPU::kvmArmVCpuInit(const struct kvm_vcpu_init &init)
{
    if (ioctl(KVM_ARM_VCPU_INIT, (void *)&init) == -1)
        panic("KVM: Failed to initialize vCPU\n");
}

MiscRegIndex
ArmKvmCPU::decodeCoProcReg(uint64_t id) const
{
    const unsigned cp(REG_CP(id));
    const bool is_reg32(REG_IS_32BIT(id));
    const bool is_reg64(REG_IS_64BIT(id));

    // CP numbers larger than 15 are reserved for KVM extensions
    if (cp > 15)
        return NUM_MISCREGS;

    const unsigned crm(REG_CRM(id));
    const unsigned crn(REG_CRN(id));
    const unsigned opc1(REG_OPC1(id));
    const unsigned opc2(REG_OPC2(id));

    if (is_reg32) {
        switch (cp) {
          case 14:
            return decodeCP14Reg(crn, opc1, crm, opc2);

          case 15:
            return decodeCP15Reg(crn, opc1, crm, opc2);

          default:
            return NUM_MISCREGS;
        }
    } else if (is_reg64) {
        return NUM_MISCREGS;
    } else {
        warn("Unhandled register length, register (0x%x) ignored.\n");
        return NUM_MISCREGS;
    }
}

ArmISA::MiscRegIndex
ArmKvmCPU::decodeVFPCtrlReg(uint64_t id) const
{
    if (!REG_IS_ARM(id) || !REG_IS_VFP(id) || !REG_IS_VFP_CTRL(id))
        return NUM_MISCREGS;

    const unsigned vfp_reg(REG_VFP_REG(id));
    switch (vfp_reg) {
      case KVM_REG_ARM_VFP_FPSID: return MISCREG_FPSID;
      case KVM_REG_ARM_VFP_FPSCR: return MISCREG_FPSCR;
      case KVM_REG_ARM_VFP_MVFR0: return MISCREG_MVFR0;
      case KVM_REG_ARM_VFP_MVFR1: return MISCREG_MVFR1;
      case KVM_REG_ARM_VFP_FPEXC: return MISCREG_FPEXC;

      case KVM_REG_ARM_VFP_FPINST:
      case KVM_REG_ARM_VFP_FPINST2:
        warn_once("KVM: FPINST not implemented.\n");
        return NUM_MISCREGS;

      default:
        return NUM_MISCREGS;
    }
}

bool
ArmKvmCPU::isInvariantReg(uint64_t id)
{
    /* Mask away the value field from multiplexed registers, we assume
     * that entire groups of multiplexed registers can be treated as
     * invariant. */
    if (REG_IS_ARM(id) && REG_IS_DEMUX(id))
        id &= ~KVM_REG_ARM_DEMUX_VAL_MASK;

    return invariant_regs.find(id) != invariant_regs.end();
}

bool
ArmKvmCPU::getRegList(struct kvm_reg_list &regs) const
{
    if (ioctl(KVM_GET_REG_LIST, (void *)&regs) == -1) {
        if (errno == E2BIG) {
            return false;
        } else {
            panic("KVM: Failed to get vCPU register list (errno: %i)\n",
                  errno);
        }
    } else {
        return true;
    }
}

void
ArmKvmCPU::dumpKvmStateCore()
{
    /* Print core registers */
    uint32_t pc(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
    inform("PC: 0x%x\n", pc);

    for (const KvmIntRegInfo *ri(kvmIntRegs);
         ri->idx != NUM_INTREGS; ++ri) {

        uint32_t value(getOneRegU32(ri->id));
        inform("%s: 0x%x\n", ri->name, value);
    }

    for (const KvmCoreMiscRegInfo *ri(kvmCoreMiscRegs);
         ri->idx != NUM_MISCREGS; ++ri) {

        uint32_t value(getOneRegU32(ri->id));
        inform("%s: 0x%x\n", miscRegName[ri->idx], value);
    }
}

void
ArmKvmCPU::dumpKvmStateMisc()
{
    /* Print co-processor registers */
    const RegIndexVector &reg_ids(getRegList());;
    for (RegIndexVector::const_iterator it(reg_ids.begin());
         it != reg_ids.end(); ++it) {
        uint64_t id(*it);

        if (REG_IS_ARM(id) && REG_CP(id) <= 15) {
            dumpKvmStateCoProc(id);
        } else if (REG_IS_ARM(id) && REG_IS_VFP(id)) {
            dumpKvmStateVFP(id);
        } else if (REG_IS_ARM(id) && REG_IS_DEMUX(id)) {
            switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
              case KVM_REG_ARM_DEMUX_ID_CCSIDR:
                inform("CCSIDR [0x%x]: %s\n",
                       EXTRACT_FIELD(id,
                                     KVM_REG_ARM_DEMUX_VAL_MASK,
                                     KVM_REG_ARM_DEMUX_VAL_SHIFT),
                       getAndFormatOneReg(id));
                break;
              default:
                inform("DEMUX [0x%x, 0x%x]: %s\n",
                       EXTRACT_FIELD(id,
                                     KVM_REG_ARM_DEMUX_ID_MASK,
                                     KVM_REG_ARM_DEMUX_ID_SHIFT),
                       EXTRACT_FIELD(id,
                                     KVM_REG_ARM_DEMUX_VAL_MASK,
                                     KVM_REG_ARM_DEMUX_VAL_SHIFT),
                       getAndFormatOneReg(id));
                break;
            }
        } else if (!REG_IS_CORE(id)) {
            inform("0x%x: %s\n", id, getAndFormatOneReg(id));
        }
    }
}

void
ArmKvmCPU::dumpKvmStateCoProc(uint64_t id)
{
    assert(REG_IS_ARM(id));
    assert(REG_CP(id) <= 15);

    if (REG_IS_32BIT(id)) {
        // 32-bit co-proc registers
        MiscRegIndex idx(decodeCoProcReg(id));
        uint32_t value(getOneRegU32(id));

        if (idx != NUM_MISCREGS &&
            !(idx >= MISCREG_CP15_UNIMP_START && idx < MISCREG_CP15_END)) {
            const char *name(miscRegName[idx]);
            const unsigned m5_ne(tc->readMiscRegNoEffect(idx));
            const unsigned m5_e(tc->readMiscReg(idx));
            inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: "
                   "[%s]: 0x%x/0x%x\n",
                   REG_CP(id), REG_CRN(id), REG_OPC1(id), REG_CRM(id),
                   REG_OPC2(id), isInvariantReg(id),
                   name, value, m5_e);
            if (m5_e != m5_ne) {
                inform("readMiscReg: %x, readMiscRegNoEffect: %x\n",
                       m5_e, m5_ne);
            }
        } else {
            const char *name(idx != NUM_MISCREGS ? miscRegName[idx] : "-");
            inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: [%s]: "
                   "0x%x\n",
                   REG_CP(id), REG_CRN(id), REG_OPC1(id), REG_CRM(id),
                   REG_OPC2(id), isInvariantReg(id), name, value);
        }
    } else {
        inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i "
               "len: 0x%x]: %s\n",
               REG_CP(id), REG_CRN(id), REG_OPC1(id), REG_CRM(id),
               REG_OPC2(id), isInvariantReg(id),
               EXTRACT_FIELD(id, KVM_REG_SIZE_MASK, KVM_REG_SIZE_SHIFT),
               getAndFormatOneReg(id));
    }
}

void
ArmKvmCPU::dumpKvmStateVFP(uint64_t id)
{
    assert(REG_IS_ARM(id));
    assert(REG_IS_VFP(id));

    if (REG_IS_VFP_REG(id)) {
        const unsigned idx(id & KVM_REG_ARM_VFP_MASK);
        inform("VFP reg %i: %s", idx, getAndFormatOneReg(id));
    } else if (REG_IS_VFP_CTRL(id)) {
        MiscRegIndex idx(decodeVFPCtrlReg(id));
        if (idx != NUM_MISCREGS) {
            inform("VFP [%s]: %s", miscRegName[idx], getAndFormatOneReg(id));
        } else {
            inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
        }
    } else {
        inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
    }
}

void
ArmKvmCPU::updateKvmStateCore()
{
    for (const KvmIntRegInfo *ri(kvmIntRegs);
         ri->idx != NUM_INTREGS; ++ri) {

        uint64_t value(tc->readIntRegFlat(ri->idx));
        DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
        setOneReg(ri->id, value);
    }

    DPRINTF(KvmContext, "kvm(PC) := 0x%x\n", tc->instAddr());
    setOneReg(REG_CORE32(usr_regs.ARM_pc), tc->instAddr());

    for (const KvmCoreMiscRegInfo *ri(kvmCoreMiscRegs);
         ri->idx != NUM_MISCREGS; ++ri) {

        uint64_t value(tc->readMiscReg(ri->idx));
        DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
        setOneReg(ri->id, value);
    }

    if (DTRACE(KvmContext))
        dumpKvmStateCore();
}

void
ArmKvmCPU::updateKvmStateMisc()
{
    static bool warned(false); // We can't use warn_once since we want
                               // to show /all/ registers

    const RegIndexVector &regs(getRegList());

    for (RegIndexVector::const_iterator it(regs.begin());
         it != regs.end();
         ++it) {

        if (!REG_IS_ARM(*it)) {
            if (!warned)
                warn("Skipping non-ARM register: 0x%x\n", *it);
        } else if (isInvariantReg(*it)) {
            DPRINTF(Kvm, "Skipping invariant register: 0x%x\n", *it);
        } else if (REG_IS_CORE(*it)) {
            // Core registers are handled in updateKvmStateCore
            continue;
        } else if (REG_CP(*it) <= 15) {
            updateKvmStateCoProc(*it, !warned);
        } else if (REG_IS_VFP(*it)) {
            updateKvmStateVFP(*it, !warned);
        } else {
            if (!warned) {
                warn("Skipping register with unknown CP (%i) id: 0x%x\n",
                     REG_CP(*it), *it);
            }
        }

    }

    warned = true;
    if (DTRACE(KvmContext))
        dumpKvmStateMisc();
}

void
ArmKvmCPU::updateKvmStateCoProc(uint64_t id, bool show_warnings)
{
    MiscRegIndex reg(decodeCoProcReg(id));

    assert(REG_IS_ARM(id));
    assert(REG_CP(id) <= 15);

    if (id == KVM_REG64_TTBR0 || id == KVM_REG64_TTBR1) {
        // HACK HACK HACK: Workaround for 64-bit TTBRx
        reg = (id == KVM_REG64_TTBR0 ? MISCREG_TTBR0 : MISCREG_TTBR1);
        if (show_warnings)
            hack("KVM: 64-bit TTBBRx workaround\n");
    }

    if (reg == NUM_MISCREGS) {
        if (show_warnings) {
            warn("KVM: Ignoring unknown KVM co-processor register (0x%.8x):\n",
                 id);
            warn("\t0x%x: [CP: %i 64: %i CRn: c%i opc1: %.2i CRm: c%i"
                 " opc2: %i]\n",
                 id, REG_CP(id), REG_IS_64BIT(id), REG_CRN(id),
                 REG_OPC1(id), REG_CRM(id), REG_OPC2(id));
        }
    } else if (reg >= MISCREG_CP15_UNIMP_START && reg < MISCREG_CP15_END) {
        if (show_warnings)
            warn("KVM: Co-processor reg. %s not implemented by gem5.\n",
                 miscRegName[reg]);
    } else {
        setOneReg(id, tc->readMiscRegNoEffect(reg));
    }
}


void
ArmKvmCPU::updateKvmStateVFP(uint64_t id, bool show_warnings)
{
    assert(REG_IS_ARM(id));
    assert(REG_IS_VFP(id));

    if (REG_IS_VFP_REG(id)) {
        if (!REG_IS_64BIT(id)) {
            if (show_warnings)
                warn("Unexpected VFP register length (reg: 0x%x).\n", id);
            return;
        }
        const unsigned idx(id & KVM_REG_ARM_VFP_MASK);
        const unsigned idx_base(idx << 1);
        const unsigned idx_hi(idx_base + 1);
        const unsigned idx_lo(idx_base + 0);
        uint64_t value(
            ((uint64_t)tc->readFloatRegFlat(idx_hi) << 32) |
            tc->readFloatRegFlat(idx_lo));

        setOneReg(id, value);
    } else if (REG_IS_VFP_CTRL(id)) {
        MiscRegIndex idx(decodeVFPCtrlReg(id));
        if (idx == NUM_MISCREGS) {
            if (show_warnings)
                warn("Unhandled VFP control register: 0x%x\n", id);
            return;
        }
        if (!REG_IS_32BIT(id)) {
            if (show_warnings)
                warn("Ignoring VFP control register (%s) with "
                     "unexpected size.\n",
                     miscRegName[idx]);
            return;
        }
        setOneReg(id, (uint32_t)tc->readMiscReg(idx));
    } else {
        if (show_warnings)
            warn("Unhandled VFP register: 0x%x\n", id);
    }
}

void
ArmKvmCPU::updateTCStateCore()
{
    for (const KvmIntRegInfo *ri(kvmIntRegs);
         ri->idx != NUM_INTREGS; ++ri) {

        tc->setIntRegFlat(ri->idx, getOneRegU32(ri->id));
    }

    for (const KvmCoreMiscRegInfo *ri(kvmCoreMiscRegs);
         ri->idx != NUM_MISCREGS; ++ri) {

        tc->setMiscRegNoEffect(ri->idx, getOneRegU32(ri->id));
    }

    /* We want the simulator to execute all side-effects of the CPSR
     * update since this updates PC state and register maps.
     */
    tc->setMiscReg(MISCREG_CPSR, tc->readMiscRegNoEffect(MISCREG_CPSR));

    // We update the PC state after we have updated the CPSR the
    // contents of the CPSR affects how the npc is updated.
    PCState pc(tc->pcState());
    pc.set(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
    tc->pcState(pc);

    if (DTRACE(KvmContext))
        dumpKvmStateCore();
}

void
ArmKvmCPU::updateTCStateMisc()
{
    static bool warned(false); // We can't use warn_once since we want
                               // to show /all/ registers

    const RegIndexVector &reg_ids(getRegList());;
    for (RegIndexVector::const_iterator it(reg_ids.begin());
         it != reg_ids.end(); ++it) {

        if (!REG_IS_ARM(*it)) {
            if (!warned)
                warn("Skipping non-ARM register: 0x%x\n", *it);
        } else if (REG_IS_CORE(*it)) {
            // Core registers are handled in updateKvmStateCore
        } else if (REG_CP(*it) <= 15) {
            updateTCStateCoProc(*it, !warned);
        } else if (REG_IS_VFP(*it)) {
            updateTCStateVFP(*it, !warned);
        } else {
            if (!warned) {
                warn("Skipping register with unknown CP (%i) id: 0x%x\n",
                     REG_CP(*it), *it);
            }
        }
    }

    warned = true;

    if (DTRACE(KvmContext))
        dumpKvmStateMisc();
}

void
ArmKvmCPU::updateTCStateCoProc(uint64_t id, bool show_warnings)
{
    MiscRegIndex reg(decodeCoProcReg(id));

    assert(REG_IS_ARM(id));
    assert(REG_CP(id) <= 15);

    if (id == KVM_REG64_TTBR0 || id == KVM_REG64_TTBR1) {
        // HACK HACK HACK: We don't currently support 64-bit TTBR0/TTBR1
        hack_once("KVM: 64-bit TTBRx workaround\n");
        tc->setMiscRegNoEffect(
            id == KVM_REG64_TTBR0 ? MISCREG_TTBR0 : MISCREG_TTBR1,
            (uint32_t)(getOneRegU64(id) & 0xFFFFFFFF));
    } else if (reg == MISCREG_TTBCR) {
        uint32_t value(getOneRegU64(id));
        if (value & 0x80000000)
            panic("KVM: Guest tried to enable LPAE.\n");
        tc->setMiscRegNoEffect(reg, value);
    } else if (reg == NUM_MISCREGS) {
        if (show_warnings) {
            warn("KVM: Ignoring unknown KVM co-processor register:\n", id);
            warn("\t0x%x: [CP: %i 64: %i CRn: c%i opc1: %.2i CRm: c%i"
                 " opc2: %i]\n",
                 id, REG_CP(id), REG_IS_64BIT(id), REG_CRN(id),
                 REG_OPC1(id), REG_CRM(id), REG_OPC2(id));
        }
    } else if (reg >= MISCREG_CP15_UNIMP_START && reg < MISCREG_CP15_END) {
        if (show_warnings)
            warn_once("KVM: Co-processor reg. %s not implemented by gem5.\n",
                      miscRegName[reg]);
    } else {
        tc->setMiscRegNoEffect(reg, getOneRegU32(id));
    }
}

void
ArmKvmCPU::updateTCStateVFP(uint64_t id, bool show_warnings)
{
    assert(REG_IS_ARM(id));
    assert(REG_IS_VFP(id));

    if (REG_IS_VFP_REG(id)) {
        if (!REG_IS_64BIT(id)) {
            if (show_warnings)
                warn("Unexpected VFP register length (reg: 0x%x).\n", id);
            return;
        }
        const unsigned idx(id & KVM_REG_ARM_VFP_MASK);
        const unsigned idx_base(idx << 1);
        const unsigned idx_hi(idx_base + 1);
        const unsigned idx_lo(idx_base + 0);
        uint64_t value(getOneRegU64(id));

        tc->setFloatRegFlat(idx_hi, (value >> 32) & 0xFFFFFFFF);
        tc->setFloatRegFlat(idx_lo, value & 0xFFFFFFFF);
    } else if (REG_IS_VFP_CTRL(id)) {
        MiscRegIndex idx(decodeVFPCtrlReg(id));
        if (idx == NUM_MISCREGS) {
            if (show_warnings)
                warn("Unhandled VFP control register: 0x%x\n", id);
            return;
        }
        if (!REG_IS_32BIT(id)) {
            if (show_warnings)
                warn("Ignoring VFP control register (%s) with "
                     "unexpected size.\n",
                     miscRegName[idx]);
            return;
        }
        tc->setMiscReg(idx, getOneRegU64(id));
    } else {
        if (show_warnings)
            warn("Unhandled VFP register: 0x%x\n", id);
    }
}

ArmKvmCPU *
ArmKvmCPUParams::create()
{
    return new ArmKvmCPU(this);
}
