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

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