/*
 * 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.
 */

#ifndef __ARCH_ARM_KVM_ARM_CPU_HH__
#define __ARCH_ARM_KVM_ARM_CPU_HH__

#include <set>
#include <vector>

#include "arch/arm/pcstate.hh"
#include "cpu/kvm/base.hh"
#include "params/ArmKvmCPU.hh"

namespace gem5
{

/**
 * ARM implementation of a KVM-based hardware virtualized CPU.
 * Architecture specific limitations:
 *  * LPAE is currently not supported by gem5. We therefore panic if LPAE
 *    is enabled when returning to gem5.
 *  * The co-processor based interface to the architected timer is
 *    unsupported. We can't support this due to limitations in the KVM
 *    API on ARM.
 *  * M5 ops are currently not supported. This requires either a kernel
 *  hack or a memory mapped device that handles the guest<->m5
 *  interface.
 */
class ArmKvmCPU : public BaseKvmCPU
{
  public:
    ArmKvmCPU(const ArmKvmCPUParams &params);
    virtual ~ArmKvmCPU();

    void startup();

    void dump();

  protected:
    struct KvmIntRegInfo
    {
        /** KVM ID */
        const uint64_t id;
        /** gem5 index */
        const RegIndex idx;
        /** Name in debug output */
        const char *name;
    };

    struct KvmCoreMiscRegInfo
    {
        /** KVM ID */
        const uint64_t id;
        /** gem5 index */
        const ArmISA::MiscRegIndex idx;
        /** Name in debug output */
        const char *name;
    };

    typedef std::vector<uint64_t> RegIndexVector;

    Tick kvmRun(Tick ticks);

    void updateKvmState();
    void updateThreadContext();
    void
    stutterPC(PCStateBase &pc) const
    {
        pc.as<X86ISA::PCState>().setNPC(pc->instAddr());
    }

    /**
     * Get a list of registers supported by getOneReg() and setOneReg().
     */
    const RegIndexVector &getRegList() const;

    void kvmArmVCpuInit(uint32_t target);
    void kvmArmVCpuInit(const struct kvm_vcpu_init &init);

    ArmISA::MiscRegIndex decodeCoProcReg(uint64_t id) const;

    ArmISA::MiscRegIndex decodeVFPCtrlReg(uint64_t id) const;

    /**
     * Determine if a register is invariant.
     *
     * Some registers must have the same value in both the host and
     * the guest. Such registers are referred to as "invariant"
     * registers in KVM. This is a restriction imposed by KVM as
     * having different values in ID registers (e.g., the cache
     * identification registers) would confuse the guest kernel.
     */
    bool isInvariantReg(uint64_t id);

    static KvmIntRegInfo kvmIntRegs[];
    static KvmCoreMiscRegInfo kvmCoreMiscRegs[];

  private:
    /**
     * Get a list of registers supported by getOneReg() and setOneReg().
     *
     * @return False if the number of elements allocated in the list
     * is too small to hold the complete register list (the required
     * value is written into n in this case). True on success.
     */
    bool getRegList(struct kvm_reg_list &regs) const;

    void dumpKvmStateCore();
    void dumpKvmStateMisc();
    void dumpKvmStateCoProc(uint64_t id);
    void dumpKvmStateVFP(uint64_t id);

    void updateKvmStateCore();
    void updateKvmStateMisc();
    void updateKvmStateCoProc(uint64_t id, bool show_warnings);
    void updateKvmStateVFP(uint64_t id, bool show_warnings);

    void updateTCStateCore();
    void updateTCStateMisc();
    void updateTCStateCoProc(uint64_t id, bool show_warnings);
    void updateTCStateVFP(uint64_t id, bool show_warnings);


    /** Cached state of the IRQ line */
    bool irqAsserted;
    /** Cached state of the FIQ line */
    bool fiqAsserted;

    /**
     * Cached copy of the list of co-processor registers supported by
     * KVM
     */
    mutable RegIndexVector _regIndexList;

    /**
     * List of co-processor registers that KVM requires to be
     * identical on both the host and the guest. KVM does not allow
     * writes to these registers.
     */
    static const std::set<uint64_t> invariant_regs;
};

} // namespace gem5

#endif // __ARCH_ARM_KVM_ARM_CPU_HH__
