/*
 * Copyright (c) 2018 Metempsy Technology Consulting
 * 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: Jairo Balart
 */

#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__
#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__

#include "base/addr_range.hh"
#include "dev/arm/gic_v3.hh"
#include "sim/serialize.hh"

class Gicv3CPUInterface;
class Gicv3Distributor;
class Gicv3Its;

class Gicv3Redistributor : public Serializable
{
  private:

    friend class Gicv3CPUInterface;
    friend class Gicv3Distributor;
    friend class Gicv3Its;

  protected:

    Gicv3 * gic;
    Gicv3Distributor * distributor;
    Gicv3CPUInterface * cpuInterface;
    uint32_t cpuId;
    PortProxy * memProxy;

    /*
     * GICv3 defines 2 contiguous 64KB frames for each redistributor.
     * Order of frames must be RD_base, SGI_base.
     */
    static const uint32_t RD_base  = 0x0;
    static const uint32_t SGI_base = 0x10000;

    enum {
        // Control Register
        GICR_CTLR  = RD_base + 0x0000,
        // Implementer Identification Register
        GICR_IIDR  = RD_base + 0x0004,
        // Type Register
        GICR_TYPER = RD_base + 0x0008,
        // Wake Register
        GICR_WAKER = RD_base + 0x0014,
        // Peripheral ID0 Register
        GICR_PIDR0 = RD_base + 0xffe0,
        // Peripheral ID1 Register
        GICR_PIDR1 = RD_base + 0xffe4,
        // Peripheral ID2 Register
        GICR_PIDR2 = RD_base + 0xffe8,
        // Peripheral ID3 Register
        GICR_PIDR3 = RD_base + 0xffec,
        // Peripheral ID4 Register
        GICR_PIDR4 = RD_base + 0xffd0,
        // Peripheral ID5 Register
        GICR_PIDR5 = RD_base + 0xffd4,
        // Peripheral ID6 Register
        GICR_PIDR6 = RD_base + 0xffd8,
        // Peripheral ID7 Register
        GICR_PIDR7 = RD_base + 0xffdc,
    };

    static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1;
    static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2;

    bool peInLowPowerState;

    enum {
        // Interrupt Group Register 0
        GICR_IGROUPR0   = SGI_base + 0x0080,
        // Interrupt Set-Enable Register 0
        GICR_ISENABLER0 = SGI_base + 0x0100,
        // Interrupt Clear-Enable Register 0
        GICR_ICENABLER0 = SGI_base + 0x0180,
        // Interrupt Set-Pending Register 0
        GICR_ISPENDR0   = SGI_base + 0x0200,
        // Interrupt Clear-Pending Register 0
        GICR_ICPENDR0   = SGI_base + 0x0280,
        // Interrupt Set-Active Register 0
        GICR_ISACTIVER0 = SGI_base + 0x0300,
        // Interrupt Clear-Active Register 0
        GICR_ICACTIVER0 = SGI_base + 0x0380,
        // SGI Configuration Register
        GICR_ICFGR0     = SGI_base + 0x0c00,
        // PPI Configuration Register
        GICR_ICFGR1     = SGI_base + 0x0c04,
        // Interrupt Group Modifier Register 0
        GICR_IGRPMODR0  = SGI_base + 0x0d00,
        // Non-secure Access Control Register
        GICR_NSACR      = SGI_base + 0x0e00,
    };

    // Interrupt Priority Registers
    static const AddrRange GICR_IPRIORITYR;

    // GIC physical LPI Redistributor register
    enum {
        // Set LPI Pending Register
        GICR_SETLPIR = RD_base + 0x0040,
        // Clear LPI Pending Register
        GICR_CLRLPIR = RD_base + 0x0048,
        //Redistributor Properties Base Address Register
        GICR_PROPBASER = RD_base + 0x0070,
        // Redistributor LPI Pending Table Base Address Register
        GICR_PENDBASER = RD_base + 0x0078,
        // Redistributor Invalidate LPI Register
        GICR_INVLPIR = RD_base + 0x00A0,
        // Redistributor Invalidate All Register
        GICR_INVALLR = RD_base + 0x00B0,
        // Redistributor Synchronize Register
        GICR_SYNCR = RD_base + 0x00C0,
    };

    std::vector <uint8_t> irqGroup;
    std::vector <bool> irqEnabled;
    std::vector <bool> irqPending;
    std::vector <bool> irqActive;
    std::vector <uint8_t> irqPriority;
    std::vector <Gicv3::IntTriggerType> irqConfig;
    std::vector <uint8_t> irqGrpmod;
    std::vector <uint8_t> irqNsacr;

    bool DPG1S;
    bool DPG1NS;
    bool DPG0;
    bool EnableLPIs;

    Addr lpiConfigurationTablePtr;
    uint8_t lpiIDBits;
    Addr lpiPendingTablePtr;

    BitUnion8(LPIConfigurationTableEntry)
        Bitfield<7, 2> priority;
        Bitfield<1> res1;
        Bitfield<0> enable;
    EndBitUnion(LPIConfigurationTableEntry)

    static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0;
    static const uint32_t GICR_CTLR_DPG0   = 1 << 24;
    static const uint32_t GICR_CTLR_DPG1NS = 1 << 25;
    static const uint32_t GICR_CTLR_DPG1S  = 1 << 26;

  public:

    /*
     * GICv3 defines only 2 64K consecutive frames for the redistributor
     * (RD_base and SGI_base) but we are using 2 extra 64K stride frames
     * to match GICv4 that defines 4 64K consecutive frames for them.
     * Note this must match with DTB/DTS GIC node definition and boot
     * loader code.
     */
    const uint32_t addrRangeSize;

    static const uint32_t SMALLEST_LPI_ID = 8192;


    void activateIRQ(uint32_t int_id);
    bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const;
    void deactivateIRQ(uint32_t int_id);

    inline Gicv3CPUInterface *
    getCPUInterface() const
    {
        return cpuInterface;
    }

    uint32_t
    processorNumber() const
    {
        return cpuId;
    }

    Gicv3::GroupId getIntGroup(int int_id) const;
    Gicv3::IntStatus intStatus(uint32_t int_id) const;
    uint8_t readEntryLPI(uint32_t intid);
    void writeEntryLPI(uint32_t intid, uint8_t lpi_entry);
    bool isPendingLPI(uint32_t intid);
    void setClrLPI(uint64_t data, bool set);
    void reset();
    void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);
    void serialize(CheckpointOut & cp) const override;
    void unserialize(CheckpointIn & cp) override;
    void update();
    void updateDistributor();

  public:

    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
    uint32_t getAffinity() const;
    void init();
    void initState();
    uint64_t read(Addr addr, size_t size, bool is_secure_access);
    void sendPPInt(uint32_t int_id);
    void write(Addr addr, uint64_t data, size_t size, bool is_secure_access);
};

#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__
