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