/*
 * 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 Gicv3Redistributor : public Serializable
{
  private:

    friend class Gicv3CPUInterface;
    friend class Gicv3Distributor;

  protected:

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

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

    std::vector<LPIConfigurationTableEntry> lpiConfigurationTable;

    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.
     */
    static const uint32_t ADDR_RANGE_SIZE = 0x40000;

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

    Gicv3::GroupId getIntGroup(int int_id) const;
    Gicv3::IntStatus intStatus(uint32_t int_id) const;
    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 updateAndInformCPUInterface();

  public:

    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
    void invalLpiConfig(uint32_t lpi_entry_index);
    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__
