/*
 * Copyright (c) 2010, 2012-2013, 2015-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) 2002-2005 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: Ali Saidi
 */

#ifndef __ARCH_ARM_SYSTEM_HH__
#define __ARCH_ARM_SYSTEM_HH__

#include <memory>
#include <string>
#include <vector>

#include "kern/linux/events.hh"
#include "params/ArmSystem.hh"
#include "params/GenericArmSystem.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"

class GenericTimer;
class BaseGic;
class ThreadContext;

class ArmSystem : public System
{
  protected:
    /**
     * PC based event to skip the dprink() call and emulate its
     * functionality
     */
    Linux::DebugPrintkEvent *debugPrintkEvent;

    /** Bootloaders */
    std::vector<std::unique_ptr<ObjectFile>> bootLoaders;

    /**
     * Pointer to the bootloader object
     */
    ObjectFile *bootldr;

    /**
     * True if this system implements the Security Extensions
     */
    const bool _haveSecurity;

    /**
     * True if this system implements the Large Physical Address Extension
     */
    const bool _haveLPAE;

    /**
     * True if this system implements the virtualization Extensions
     */
    const bool _haveVirtualization;

    /**
     * True if this system implements the Crypto Extension
     */
    const bool _haveCrypto;

    /**
     * Pointer to the Generic Timer wrapper.
     */
    GenericTimer *_genericTimer;
    BaseGic *_gic;

    /**
     * Reset address (ARMv8)
     */
    const Addr _resetAddr;

    /**
     * True if the register width of the highest implemented exception level is
     * 64 bits (ARMv8)
     */
    bool _highestELIs64;

    /**
     * Supported physical address range in bits if the highest implemented
     * exception level is 64 bits (ARMv8)
     */
    const uint8_t _physAddrRange64;

    /**
     * True if ASID is 16 bits in AArch64 (ARMv8)
     */
    const bool _haveLargeAsid64;

    /**
     * True if SVE is implemented (ARMv8)
     */
    const bool _haveSVE;

    /** SVE vector length at reset, in quadwords */
    const unsigned _sveVL;

    /**
     * Range for memory-mapped m5 pseudo ops. The range will be
     * invalid/empty if disabled.
     */
    const AddrRange _m5opRange;

    /**
     * True if the Semihosting interface is enabled.
     */
    ArmSemihosting *const semihosting;

  protected:
    /**
     * Get a boot loader that matches the kernel.
     *
     * @param obj Kernel binary
     * @return Pointer to boot loader ObjectFile or nullptr if there
     *         is no matching boot loader.
     */
    ObjectFile *getBootLoader(ObjectFile *const obj);

  public:
    typedef ArmSystemParams Params;
    const Params *
    params() const
    {
        return dynamic_cast<const Params *>(_params);
    }

    ArmSystem(Params *p);
    ~ArmSystem();

    /**
     * Initialise the system
     */
    virtual void initState();

    virtual Addr fixFuncEventAddr(Addr addr)
    {
        // Remove the low bit that thumb symbols have set
        // but that aren't actually odd aligned
        if (addr & 0x1)
            return addr & ~1;
        return addr;
    }

    /** true if this a multiprocessor system */
    bool multiProc;

    /** Returns true if this system implements the Security Extensions */
    bool haveSecurity() const { return _haveSecurity; }

    /** Returns true if this system implements the Large Physical Address
     * Extension */
    bool haveLPAE() const { return _haveLPAE; }

    /** Returns true if this system implements the virtualization
      * Extensions
      */
    bool haveVirtualization() const { return _haveVirtualization; }

    /** Returns true if this system implements the Crypto
      * Extension
      */
    bool haveCrypto() const { return _haveCrypto; }

    /** Sets the pointer to the Generic Timer. */
    void setGenericTimer(GenericTimer *generic_timer)
    {
        _genericTimer = generic_timer;
    }

    /** Sets the pointer to the GIC. */
    void setGIC(BaseGic *gic)
    {
        _gic = gic;
    }

    /** Get a pointer to the system's generic timer model */
    GenericTimer *getGenericTimer() const { return _genericTimer; }

    /** Get a pointer to the system's GIC */
    BaseGic *getGIC() const { return _gic; }

    /** Returns true if the register width of the highest implemented exception
     * level is 64 bits (ARMv8) */
    bool highestELIs64() const { return _highestELIs64; }

    /** Returns the highest implemented exception level */
    ExceptionLevel highestEL() const
    {
        if (_haveSecurity)
            return EL3;
        if (_haveVirtualization)
            return EL2;
        return EL1;
    }

    /** Returns the reset address if the highest implemented exception level is
     * 64 bits (ARMv8) */
    Addr resetAddr() const { return _resetAddr; }

    /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */
    bool haveLargeAsid64() const { return _haveLargeAsid64; }

    /** Returns true if SVE is implemented (ARMv8) */
    bool haveSVE() const { return _haveSVE; }

    /** Returns the SVE vector length at reset, in quadwords */
    unsigned sveVL() const { return _sveVL; }

    /** Returns the supported physical address range in bits if the highest
     * implemented exception level is 64 bits (ARMv8) */
    uint8_t physAddrRange64() const { return _physAddrRange64; }

    /** Returns the supported physical address range in bits */
    uint8_t physAddrRange() const
    {
        if (_highestELIs64)
            return _physAddrRange64;
        if (_haveLPAE)
            return 40;
        return 32;
    }

    /** Returns the physical address mask */
    Addr physAddrMask() const
    {
        return mask(physAddrRange());
    }

    /**
     * Range used by memory-mapped m5 pseudo-ops if enabled. Returns
     * an invalid/empty range if disabled.
     */
    const AddrRange &m5opRange() const { return _m5opRange; }

    /** Is Arm Semihosting support enabled? */
    bool haveSemihosting() const { return semihosting != nullptr; }

    /**
     * Returns a valid ArmSystem pointer if using ARM ISA, it fails
     * otherwise.
     */
    static ArmSystem* getArmSystem(ThreadContext *tc);

    /** Returns true if the system of a specific thread context implements the
     * Security Extensions
     */
    static bool haveSecurity(ThreadContext *tc);

    /** Returns true if the system of a specific thread context implements the
     * virtualization Extensions
     */
    static bool haveVirtualization(ThreadContext *tc);

    /** Returns true if the system of a specific thread context implements the
     * Large Physical Address Extension
     */
    static bool haveLPAE(ThreadContext *tc);

    /** Returns true if the register width of the highest implemented exception
     * level for the system of a specific thread context is 64 bits (ARMv8)
     */
    static bool highestELIs64(ThreadContext *tc);

    /** Returns the highest implemented exception level for the system of a
     * specific thread context
     */
    static ExceptionLevel highestEL(ThreadContext *tc);

    /** Return true if the system implements a specific exception level */
    static bool haveEL(ThreadContext *tc, ExceptionLevel el);

    /** Returns the reset address if the highest implemented exception level
     * for the system of a specific thread context is 64 bits (ARMv8)
     */
    static Addr resetAddr(ThreadContext *tc);

    /** Returns the supported physical address range in bits for the system of a
     * specific thread context
     */
    static uint8_t physAddrRange(ThreadContext *tc);

    /** Returns the physical address mask for the system of a specific thread
     * context
     */
    static Addr physAddrMask(ThreadContext *tc);

    /** Returns true if ASID is 16 bits for the system of a specific thread
     * context while in AArch64 (ARMv8) */
    static bool haveLargeAsid64(ThreadContext *tc);

    /** Is Arm Semihosting support enabled? */
    static bool haveSemihosting(ThreadContext *tc);

    /** Make a Semihosting call from aarch64 */
    static uint64_t callSemihosting64(ThreadContext *tc,
                                      uint32_t op, uint64_t param);

    /** Make a Semihosting call from aarch32 */
    static uint32_t callSemihosting32(ThreadContext *tc,
                                      uint32_t op, uint32_t param);
};

class GenericArmSystem : public ArmSystem
{
  public:
    typedef GenericArmSystemParams Params;
    const Params *
    params() const
    {
        return dynamic_cast<const Params *>(_params);
    }

    GenericArmSystem(Params *p) : ArmSystem(p) {};
    virtual ~GenericArmSystem() {};

    /**
     * Initialise the system
     */
    virtual void initState();
};

#endif
