/*
 * Copyright (c) 2010, 2012-2013, 2015-2021 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.
 */

#ifndef __ARCH_ARM_SYSTEM_HH__
#define __ARCH_ARM_SYSTEM_HH__

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

#include "arch/arm/page_size.hh"
#include "arch/arm/types.hh"
#include "kern/linux/events.hh"
#include "params/ArmSystem.hh"
#include "sim/full_system.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"
#include "enums/ArmExtension.hh"


namespace gem5
{

class GenericTimer;
class BaseGic;
class FVPBasePwrCtrl;
class ThreadContext;

struct ArmReleaseParams;

class ArmRelease : public SimObject
{
  public:
    PARAMS(ArmRelease);
    ArmRelease(const Params &p);

    bool
    has(ArmExtension ext) const
    {
        if (auto it = _extensions.find(ext); it != _extensions.end()) {
            return it->second;
        } else {
            return false;
        }
    }

  protected:
    /**
     * List of implemented extensions
     */
    std::unordered_map<ArmExtension, bool> _extensions;
};

class ArmSystem : public System
{
  protected:
    /**
     * Pointer to the Generic Timer wrapper.
     */
    GenericTimer *_genericTimer;
    BaseGic *_gic;

    /**
     * Pointer to the Power Controller (if any)
     */
    FVPBasePwrCtrl *_pwrCtrl;

    /**
     * Reset address (ARMv8)
     */
    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;

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

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

    /**
     * Arm Release object: contains a list of implemented
     * features
     */
    const ArmRelease *release;

  public:
    static constexpr Addr PageBytes = ArmISA::PageBytes;
    static constexpr Addr PageShift = ArmISA::PageShift;

    PARAMS(ArmSystem);

    ArmSystem(const Params &p);

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

    const ArmRelease* releaseFS() const { return release; }

    bool has(ArmExtension ext) const { return release->has(ext); }

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

    /** Sets the pointer to the Power Controller */
    void setPowerController(FVPBasePwrCtrl *pwr_ctrl)
    {
        _pwrCtrl = pwr_ctrl;
    }

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

    /** Get a pointer to the system's power controller */
    FVPBasePwrCtrl *getPowerController() const { return _pwrCtrl; }

    /** 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 */
    ArmISA::ExceptionLevel
    highestEL() const
    {
        if (has(ArmExtension::SECURITY))
            return ArmISA::EL3;
        if (has(ArmExtension::VIRTUALIZATION))
            return ArmISA::EL2;
        return ArmISA::EL1;
    }

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

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

    /** 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 (has(ArmExtension::LPAE))
            return 40;
        return 32;
    }

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

    /** 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)
    {
        assert(FullSystem);
        return static_cast<ArmSystem *>(tc->getSystemPtr());
    }

    static bool has(ArmExtension ext, ThreadContext *tc);

    static bool highestELIs64(ThreadContext *tc);

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

    /** Return true if the system implements a specific exception level */
    static bool haveEL(ThreadContext *tc, ArmISA::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 bool callSemihosting64(ThreadContext *tc, bool gem5_ops=false);

    /** Make a Semihosting call from aarch32 */
    static bool callSemihosting32(ThreadContext *tc, bool gem5_ops=false);

    /** Make a Semihosting call from either aarch64 or aarch32 */
    static bool callSemihosting(ThreadContext *tc, bool gem5_ops=false);

    /** Make a call to notify the power controller of STANDBYWFI assertion */
    static void callSetStandByWfi(ThreadContext *tc);

    /** Make a call to notify the power controller of STANDBYWFI deassertion */
    static void callClearStandByWfi(ThreadContext *tc);

    /**
     * Notify the power controller of WAKEREQUEST assertion. Returns true
     * if WAKEREQUEST is enabled as a power-on mechanism, and the core is now
     * powered, false otherwise
     */
    static bool callSetWakeRequest(ThreadContext *tc);

    /** Notify the power controller of WAKEREQUEST deassertion */
    static void callClearWakeRequest(ThreadContext *tc);
};

} // namespace gem5

#endif
