/*
 * Copyright (c) 2012-2013, 2017-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.
 *
 * 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: Andreas Sandberg
 */

/** @file
 * Base class for ARM GIC implementations
 */

#ifndef __DEV_ARM_BASE_GIC_H__
#define __DEV_ARM_BASE_GIC_H__

#include <unordered_map>

#include "arch/arm/system.hh"
#include "dev/io_device.hh"

class Platform;
class RealView;
class ThreadContext;
class ArmInterruptPin;
class ArmSPI;
class ArmPPI;

struct ArmInterruptPinParams;
struct ArmPPIParams;
struct ArmSPIParams;
struct BaseGicParams;

class BaseGic :  public PioDevice
{
  public:
    typedef BaseGicParams Params;
    enum class GicVersion { GIC_V2, GIC_V3, GIC_V4 };

    BaseGic(const Params *p);
    virtual ~BaseGic();
    void init() override;

    const Params * params() const;

    /**
     * Post an interrupt from a device that is connected to the GIC.
     *
     * Depending on the configuration, the GIC will pass this interrupt
     * on through to a CPU.
     *
     * @param num number of interrupt to send
     */
    virtual void sendInt(uint32_t num) = 0;

    /**
     * Interface call for private peripheral interrupts.
     *
     * @param num number of interrupt to send
     * @param cpu CPU to forward interrupt to
     */
    virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0;
    virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0;

    /**
     * Clear an interrupt from a device that is connected to the GIC.
     *
     * Depending on the configuration, the GIC may de-assert it's CPU
     * line.
     *
     * @param num number of interrupt to send
     */
    virtual void clearInt(uint32_t num) = 0;

    ArmSystem *
    getSystem() const
    {
        return (ArmSystem *) sys;
    }

    /** Check if version supported */
    virtual bool supportsVersion(GicVersion version) = 0;

  protected:
    /** Platform this GIC belongs to. */
    Platform *platform;
};

class BaseGicRegisters
{
  public:
    virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
    virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;

    virtual void writeDistributor(ContextID ctx, Addr daddr,
                                  uint32_t data) = 0;
    virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
};

/**
 * This SimObject is instantiated in the python world and
 * serves as an ArmInterruptPin generator. In this way it
 * is possible to instantiate a single generator per component
 * during configuration, and to dynamically spawn ArmInterruptPins.
 * See ArmPPIGen for more info on how this is used.
 */
class ArmInterruptPinGen : public SimObject
{
  public:
    ArmInterruptPinGen(const ArmInterruptPinParams *p);

    virtual ArmInterruptPin* get(ThreadContext *tc = nullptr) = 0;
};

/**
 * Shared Peripheral Interrupt Generator
 * It is capable of generating one interrupt only: it maintains a pointer
 * to it and returns it every time it is asked for it (via the get metod)
 */
class ArmSPIGen : public ArmInterruptPinGen
{
  public:
    ArmSPIGen(const ArmSPIParams *p);

    ArmInterruptPin* get(ThreadContext *tc = nullptr) override;
  protected:
    ArmSPI* pin;
};

/**
 * Private Peripheral Interrupt Generator
 * Since PPIs are banked in the GIC, this class is capable of generating
 * more than one interrupt (one per ContextID).
 */
class ArmPPIGen : public ArmInterruptPinGen
{
  public:
    ArmPPIGen(const ArmPPIParams *p);

    ArmInterruptPin* get(ThreadContext* tc = nullptr) override;
  protected:
    std::unordered_map<ContextID, ArmPPI*> pins;
};

/**
 * Generic representation of an Arm interrupt pin.
 */
class ArmInterruptPin
{
    friend class ArmInterruptPinGen;
  protected:
    ArmInterruptPin(Platform *platform, ThreadContext *tc,
                    uint32_t int_num);

  public: /* Public interface */
    /**
     * Set the thread context owning this interrupt.
     *
     * This method is used to set the thread context for interrupts
     * that are thread/CPU-specific. Only devices that are used in
     * such a context are expected to call this method.
     */
    void setThreadContext(ThreadContext *tc);

    /** Get interrupt number */
    uint32_t num() const { return intNum; }

    /** Signal an interrupt */
    virtual void raise() = 0;
    /** Clear a signalled interrupt */
    virtual void clear() = 0;

  protected:
    /**
     * Get the target context ID of this interrupt.
     *
     * @pre setThreadContext() must have been called prior to calling
     * this method.
     */
    ContextID targetContext() const;

    /**
     * Pointer to the thread context that owns this interrupt in case
     * it is a thread-/CPU-private interrupt
     */
    const ThreadContext *threadContext;

    /** Arm platform to use for interrupt generation */
    RealView *const platform;

    /** Interrupt number to generate */
    const uint32_t intNum;
};

class ArmSPI : public ArmInterruptPin
{
    friend class ArmSPIGen;
  private:
    ArmSPI(Platform *platform, uint32_t int_num);

  public:
    void raise() override;
    void clear() override;
};

class ArmPPI : public ArmInterruptPin
{
    friend class ArmPPIGen;
  private:
    ArmPPI(Platform *platform, ThreadContext *tc, uint32_t int_num);

  public:
    void raise() override;
    void clear() override;
};

#endif
