/*
 * 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 Gicv3Distributor;
class Gicv3CPUInterface;

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;

    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
    ~Gicv3Redistributor();
    void init();
    void initState();

    uint64_t read(Addr addr, size_t size, bool is_secure_access);
    void write(Addr addr, uint64_t data, size_t size,
               bool is_secure_access);
    void sendPPInt(uint32_t int_id);
    void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);
    void serialize(CheckpointOut & cp) const override;
    void unserialize(CheckpointIn & cp) override;
    uint32_t getAffinity();

    Gicv3CPUInterface *
    getCPUInterface() const
    {
        return cpuInterface;
    }

    bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group);
    void setClrLPI(uint64_t data, bool set);

  protected:

    void reset();
    void update();
    void updateAndInformCPUInterface();
    Gicv3::IntStatus intStatus(uint32_t int_id);
    Gicv3::GroupId getIntGroup(int int_id);
    void activateIRQ(uint32_t int_id);
    void deactivateIRQ(uint32_t int_id);
    void invalLpiConfig(uint32_t lpi_entry_index);
};

#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__
