/*
 * Copyright (c) 2019-2020 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) 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.
 */

#include "dev/arm/gic_v3_distributor.hh"

#include <algorithm>

#include "base/intmath.hh"
#include "debug/GIC.hh"
#include "dev/arm/gic_v3.hh"
#include "dev/arm/gic_v3_cpu_interface.hh"
#include "dev/arm/gic_v3_redistributor.hh"

const AddrRange Gicv3Distributor::GICD_IGROUPR   (0x0080, 0x0100);
const AddrRange Gicv3Distributor::GICD_ISENABLER (0x0100, 0x0180);
const AddrRange Gicv3Distributor::GICD_ICENABLER (0x0180, 0x0200);
const AddrRange Gicv3Distributor::GICD_ISPENDR   (0x0200, 0x0280);
const AddrRange Gicv3Distributor::GICD_ICPENDR   (0x0280, 0x0300);
const AddrRange Gicv3Distributor::GICD_ISACTIVER (0x0300, 0x0380);
const AddrRange Gicv3Distributor::GICD_ICACTIVER (0x0380, 0x0400);
const AddrRange Gicv3Distributor::GICD_IPRIORITYR(0x0400, 0x0800);
const AddrRange Gicv3Distributor::GICD_ITARGETSR (0x0800, 0x0900);
const AddrRange Gicv3Distributor::GICD_ICFGR     (0x0c00, 0x0d00);
const AddrRange Gicv3Distributor::GICD_IGRPMODR  (0x0d00, 0x0d80);
const AddrRange Gicv3Distributor::GICD_NSACR     (0x0e00, 0x0f00);
const AddrRange Gicv3Distributor::GICD_CPENDSGIR (0x0f10, 0x0f20);
const AddrRange Gicv3Distributor::GICD_SPENDSGIR (0x0f20, 0x0f30);
const AddrRange Gicv3Distributor::GICD_IROUTER   (0x6000, 0x7fe0);

Gicv3Distributor::Gicv3Distributor(Gicv3 * gic, uint32_t it_lines)
    : gic(gic),
      itLines(it_lines),
      ARE(true),
      EnableGrp1S(0),
      EnableGrp1NS(0),
      EnableGrp0(0),
      irqGroup(it_lines, 0),
      irqEnabled(it_lines, false),
      irqPending(it_lines, false),
      irqPendingIspendr(it_lines, false),
      irqActive(it_lines, false),
      irqPriority(it_lines, 0xAA),
      irqConfig(it_lines, Gicv3::INT_LEVEL_SENSITIVE),
      irqGrpmod(it_lines, 0),
      irqNsacr(it_lines, 0),
      irqAffinityRouting(it_lines, 0),
      gicdTyper(0),
      gicdPidr0(0x92),
      gicdPidr1(0xb4),
      gicdPidr2(0x3b),
      gicdPidr3(0),
      gicdPidr4(0x44)
{
    panic_if(it_lines > Gicv3::INTID_SECURE, "Invalid value for it_lines!");
    /*
     * RSS           [26]    == 1
     * (The implementation does supports targeted SGIs with affinity
     * level 0 values of 0 - 255)
     * No1N          [25]    == 1
     * (1 of N SPI interrupts are not supported)
     * A3V           [24]    == 1
     * (Supports nonzero values of Affinity level 3)
     * IDbits        [23:19] == 0xf
     * (The number of interrupt identifier bits supported, minus one)
     * DVIS          [18]    == 0
     * (The implementation does not support Direct Virtual LPI
     * injection)
     * LPIS          [17]    == 1
     * (The implementation does not support LPIs)
     * MBIS          [16]    == 1
     * (The implementation supports message-based interrupts
     * by writing to Distributor registers)
     * SecurityExtn  [10]    == X
     * (The GIC implementation supports two Security states)
     * CPUNumber     [7:5]   == 0
     * (since for us ARE is always 1 [(ARE = 0) == Gicv2 legacy])
     * ITLinesNumber [4:0]   == N
     * (MaxSPIIntId = 32 (N + 1) - 1)
     */
    int max_spi_int_id = itLines - 1;
    int it_lines_number = divCeil(max_spi_int_id + 1, 32) - 1;
    gicdTyper = (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) |
        (1 << 17) | (1 << 16) |
        ((gic->getSystem()->haveSecurity() ? 1 : 0) << 10) |
        (it_lines_number << 0);

    if (gic->getSystem()->haveSecurity()) {
        DS = false;
    } else {
        DS = true;
    }
}

void
Gicv3Distributor::init()
{
}

uint64_t
Gicv3Distributor::read(Addr addr, size_t size, bool is_secure_access)
{
    if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers
        uint64_t val = 0x0;

        if (!DS && !is_secure_access) {
            // RAZ/WI for non-secure accesses
            return 0;
        }

        int first_intid = (addr - GICD_IGROUPR.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {
            val |= irqGroup[int_id] << i;
        }

        return val;
    } else if (GICD_ISENABLER.contains(addr)) {
        // Interrupt Set-Enable Registers
        uint64_t val = 0x0;
        int first_intid = (addr - GICD_ISENABLER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            val |= irqEnabled[int_id] << i;
        }

        return val;
    } else if (GICD_ICENABLER.contains(addr)) {
        // Interrupt Clear-Enable Registers
        uint64_t val = 0x0;
        int first_intid = (addr - GICD_ICENABLER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            val |= (irqEnabled[int_id] << i);
        }

        return val;
    } else if (GICD_ISPENDR.contains(addr)) {
        // Interrupt Set-Pending Registers
        uint64_t val = 0x0;
        int first_intid = (addr - GICD_ISPENDR.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                if (irqNsacr[int_id] == 0) {
                    // Group 0 or Secure Group 1 interrupts are RAZ/WI
                    continue;
                }
            }

            val |= (irqPending[int_id] << i);
        }

        return val;
    } else if (GICD_ICPENDR.contains(addr)) {
        // Interrupt Clear-Pending Registers
        uint64_t val = 0x0;
        int first_intid = (addr - GICD_ICPENDR.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                if (irqNsacr[int_id] < 2) {
                    // Group 0 or Secure Group 1 interrupts are RAZ/WI
                    continue;
                }
            }

            val |= (irqPending[int_id] << i);
        }

        return val;
    } else if (GICD_ISACTIVER.contains(addr)) {
        // Interrupt Set-Active Registers
        int first_intid = (addr - GICD_ISACTIVER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        uint64_t val = 0x0;

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                // Group 0 or Secure Group 1 interrupts are RAZ/WI
                if (irqNsacr[int_id] < 2) {
                    continue;
                }
            }

            val |= (irqActive[int_id] << i);
        }

        return val;
    } else if (GICD_ICACTIVER.contains(addr)) {
        // Interrupt Clear-Active Registers
        int first_intid = (addr - GICD_ICACTIVER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        uint64_t val = 0x0;

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                if (irqNsacr[int_id] < 2) {
                    continue;
                }
            }

            val |= (irqActive[int_id] << i);
        }

        return val;
    } else if (GICD_IPRIORITYR.contains(addr)) {
        // Interrupt Priority Registers
        uint64_t val = 0x0;
        int first_intid = addr - GICD_IPRIORITYR.start();

        if (isNotSPI(first_intid)) {
            return 0;
        }

        for (int i = 0, int_id = first_intid; i < size && int_id < itLines;
             i++, int_id++) {

            uint8_t prio = irqPriority[int_id];

            if (!DS && !is_secure_access) {
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    // RAZ/WI for non-secure accesses for secure interrupts
                    continue;
                } else {
                    // NS view
                    prio = (prio << 1) & 0xff;
                }
            }

            val |= prio << (i * 8);
        }

        return val;
    } else if (GICD_ITARGETSR.contains(addr)) {
        // Interrupt Processor Targets Registers
        // ARE always on, RAZ/WI
        warn("Gicv3Distributor::read(): "
             "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
        return 0;
    } else if (GICD_ICFGR.contains(addr)) {
        // Interrupt Configuration Registers
        int first_intid = (addr - GICD_ICFGR.start()) * 4;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        uint64_t val = 0x0;

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i = i + 2, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            if (irqConfig[int_id] == Gicv3::INT_EDGE_TRIGGERED) {
                val |= (0x2 << i);
            }
        }

        return val;
    } else if (GICD_IGRPMODR.contains(addr)) {
        // Interrupt Group Modifier Registers
        if (DS) {
            // RAZ/WI if security disabled
            return 0;
        } else {
            if (!is_secure_access) {
                // RAZ/WI for non-secure accesses
                return 0;
            } else {
                int first_intid = (addr - GICD_IGRPMODR.start()) * 8;

                if (isNotSPI(first_intid)) {
                    return 0;
                }

                uint64_t val = 0x0;

                for (int i = 0, int_id = first_intid;
                     i < 8 * size && int_id < itLines; i++, int_id++) {
                    val |= irqGrpmod[int_id] << i;
                }

                return val;
            }
        }
    } else if (GICD_NSACR.contains(addr)) {
        // Non-secure Access Control Registers
        // 2 bits per interrupt
        int first_intid = (addr - GICD_NSACR.start()) * 4;

        if (isNotSPI(first_intid)) {
            return 0;
        }

        if (DS || (!DS && !is_secure_access)) {
            return 0;
        }

        uint64_t val = 0x0;

        for (int i = 0, int_id = first_intid;
             i < 8 * size && int_id < itLines; i = i + 2, int_id++) {
            val |= irqNsacr[int_id] << i;
        }

        return val;
    } else if (GICD_CPENDSGIR.contains(addr)) { // SGI Clear-Pending Registers
        // ARE always on, RAZ/WI
        warn("Gicv3Distributor::read(): "
             "GICD_CPENDSGIR is RAZ/WI, legacy not supported!\n");
        return 0x0;
    } else if (GICD_SPENDSGIR.contains(addr)) { // SGI Set-Pending Registers
        // ARE always on, RAZ/WI
        warn("Gicv3Distributor::read(): "
             "GICD_SPENDSGIR is RAZ/WI, legacy not supported!\n");
        return 0x0;
    } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers
        // 64 bit registers. 2 or 1 access.
        int int_id = (addr - GICD_IROUTER.start()) / 8;

        if (isNotSPI(int_id)) {
            return 0;
        }

        if (nsAccessToSecInt(int_id, is_secure_access))
        {
            if (irqNsacr[int_id] < 3) {
                return 0;
            }
        }

        if (size == 4) {
            if (addr & 7) { // high half of 64 bit register
                return irqAffinityRouting[int_id] >> 32;
            } else { // high low of 64 bit register
                return irqAffinityRouting[int_id] & 0xFFFFFFFF;
            }
        } else {
            return irqAffinityRouting[int_id];
        }
    }

    switch (addr) {
      case GICD_CTLR: // Control Register
        if (!DS) {
            if (is_secure_access) {
                // E1NWF [7] RAZ/WI
                // DS [6] - Disable Security
                // ARE_NS [5] RAO/WI
                // ARE_S [4] RAO/WI
                // EnableGrp1S [2]
                // EnableGrp1NS [1]
                // EnableGrp0 [0]
                return (EnableGrp0 << 0) |
                    (EnableGrp1NS << 1) |
                    (EnableGrp1S << 2) |
                    (1 << 4) |
                    (1 << 5) |
                    (DS << 6);
            } else {
                // ARE_NS [4] RAO/WI;
                // EnableGrp1A [1] is a read-write alias of the Secure
                // GICD_CTLR.EnableGrp1NS
                // EnableGrp1 [0] RES0
                return (1 << 4) | (EnableGrp1NS << 1);
            }
        } else {
            return (DS << 6) | (ARE << 4) |
                (EnableGrp1NS << 1) | (EnableGrp0 << 0);
        }

      case GICD_TYPER: // Interrupt Controller Type Register
        return gicdTyper;

      case GICD_IIDR: // Implementer Identification Register
        //return 0x43b; // ARM JEP106 code (r0p0 GIC-500)
        return 0;

      case GICD_TYPER2: // Interrupt Controller Type Register 2
        return 0; // RES0

      case GICD_STATUSR: // Error Reporting Status Register
        // Optional register, RAZ/WI
        return 0x0;

      case GICD_PIDR0: // Peripheral ID0 Register
        return gicdPidr0;

      case GICD_PIDR1: // Peripheral ID1 Register
        return gicdPidr1;

      case GICD_PIDR2: // Peripheral ID2 Register
        return gicdPidr2;

      case GICD_PIDR3: // Peripheral ID3 Register
        return gicdPidr3;

      case GICD_PIDR4: // Peripheral ID4 Register
        return gicdPidr4;

      case GICD_PIDR5: // Peripheral ID5 Register
      case GICD_PIDR6: // Peripheral ID6 Register
      case GICD_PIDR7: // Peripheral ID7 Register
        return 0; // RES0

      default:
        panic("Gicv3Distributor::read(): invalid offset %#x\n", addr);
        break;
    }
}

void
Gicv3Distributor::write(Addr addr, uint64_t data, size_t size,
                        bool is_secure_access)
{
    if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers
        if (!DS && !is_secure_access) {
            // RAZ/WI for non-secure accesses
            return;
        }

        int first_intid = (addr - GICD_IGROUPR.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {
            irqGroup[int_id] = data & (1 << i) ? 1 : 0;
            DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d group %d\n",
                    int_id, irqGroup[int_id]);
        }

        return;
    } else if (GICD_ISENABLER.contains(addr)) {
        // Interrupt Set-Enable Registers
        int first_intid = (addr - GICD_ISENABLER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            bool enable = data & (1 << i) ? 1 : 0;

            if (enable) {
                if (!irqEnabled[int_id]) {
                    DPRINTF(GIC, "Gicv3Distributor::write(): "
                            "int_id %d enabled\n", int_id);
                }

                irqEnabled[int_id] = true;
            }
        }

        return;
    } else if (GICD_ICENABLER.contains(addr)) {
        // Interrupt Clear-Enable Registers
        int first_intid = (addr - GICD_ICENABLER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            bool disable = data & (1 << i) ? 1 : 0;

            if (disable) {
                if (irqEnabled[int_id]) {
                    DPRINTF(GIC, "Gicv3Distributor::write(): "
                            "int_id %d disabled\n", int_id);
                }

                irqEnabled[int_id] = false;
            }
        }

        return;
    } else if (GICD_ISPENDR.contains(addr)) {
        // Interrupt Set-Pending Registers
        int first_intid = (addr - GICD_ISPENDR.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                if (irqNsacr[int_id] == 0) {
                    // Group 0 or Secure Group 1 interrupts are RAZ/WI
                    continue;
                }
            }

            bool pending = data & (1 << i) ? 1 : 0;

            if (pending) {
                DPRINTF(GIC, "Gicv3Distributor::write() (GICD_ISPENDR): "
                        "int_id %d (SPI) pending bit set\n", int_id);
                irqPending[int_id] = true;
                irqPendingIspendr[int_id] = true;
            }
        }

        update();
        return;
    } else if (GICD_ICPENDR.contains(addr)) {
        // Interrupt Clear-Pending Registers
        int first_intid = (addr - GICD_ICPENDR.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                if (irqNsacr[int_id] < 2) {
                    // Group 0 or Secure Group 1 interrupts are RAZ/WI
                    continue;
                }
            }

            bool clear = data & (1 << i) ? 1 : 0;

            if (clear && treatAsEdgeTriggered(int_id)) {
                irqPending[int_id] = false;
                clearIrqCpuInterface(int_id);
            }
        }

        update();
        return;
    } else if (GICD_ISACTIVER.contains(addr)) {
        // Interrupt Set-Active Registers
        int first_intid = (addr - GICD_ISACTIVER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            bool active = data & (1 << i) ? 1 : 0;

            if (active) {
                irqActive[int_id] = 1;
            }
        }

        return;
    } else if (GICD_ICACTIVER.contains(addr)) {
        // Interrupt Clear-Active Registers
        int first_intid = (addr - GICD_ICACTIVER.start()) * 8;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i++, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access))
            {
                continue;
            }

            bool clear = data & (1 << i) ? 1 : 0;

            if (clear) {
                if (irqActive[int_id]) {
                    DPRINTF(GIC, "Gicv3Distributor::write(): "
                            "int_id %d active cleared\n", int_id);
                }

                irqActive[int_id] = false;
            }
        }

        return;
    } else if (GICD_IPRIORITYR.contains(addr)) {
        // Interrupt Priority Registers
        int first_intid = addr - GICD_IPRIORITYR.start();

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < size && int_id < itLines;
                i++, int_id++) {
            uint8_t prio = bits(data, (i + 1) * 8 - 1, (i * 8));

            if (!DS && !is_secure_access) {
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    // RAZ/WI for non-secure accesses to secure interrupts
                    continue;
                } else {
                    prio = 0x80 | (prio >> 1);
                }
            }

            irqPriority[int_id] = prio;
            DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d priority %d\n",
                    int_id, irqPriority[int_id]);
        }

        return;
    } else if (GICD_ITARGETSR.contains(addr)) {
        // Interrupt Processor Targets Registers
        // ARE always on, RAZ/WI
        warn("Gicv3Distributor::write(): "
             "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
        return;
    } else if (GICD_ICFGR.contains(addr)) {
        // Interrupt Configuration Registers
        // for x = 0 to 15:
        //   GICD_ICFGR[2x] = RES0
        //   GICD_ICFGR[2x + 1] =
        //     0 level-sensitive
        //     1 edge-triggered
        int first_intid = (addr - GICD_ICFGR.start()) * 4;

        if (isNotSPI(first_intid)) {
            return;
        }

        for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
             i = i + 2, int_id++) {

            if (nsAccessToSecInt(int_id, is_secure_access)) {
                continue;
            }

            irqConfig[int_id] = data & (0x2 << i) ?
                                Gicv3::INT_EDGE_TRIGGERED :
                                Gicv3::INT_LEVEL_SENSITIVE;
            DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d config %d\n",
                    int_id, irqConfig[int_id]);
        }

        return;
    } else if (GICD_IGRPMODR.contains(addr)) {
        // Interrupt Group Modifier Registers
        if (DS) {
            return;
        } else {
            if (!is_secure_access) {
                // RAZ/WI for non-secure accesses
                return;
            } else {
                int first_intid = (addr - GICD_IGRPMODR.start()) * 8;

                if (isNotSPI(first_intid)) {
                    return;
                }

                for (int i = 0, int_id = first_intid;
                     i < 8 * size && int_id < itLines; i++, int_id++) {
                    irqGrpmod[int_id] = bits(data, i);
                }

                return ;
            }
        }

    } else if (GICD_NSACR.contains(addr)) {
        // Non-secure Access Control Registers
        // 2 bits per interrupt
        int first_intid = (addr - GICD_NSACR.start()) * 4;

        if (isNotSPI(first_intid)) {
            return;
        }

        if (DS || (!DS && !is_secure_access)) {
            return;
        }

        for (int i = 0, int_id = first_intid;
             i < 8 * size && int_id < itLines; i = i + 2, int_id++) {
            irqNsacr[int_id] = (data >> (2 * int_id)) & 0x3;
        }

        return;
    } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers
        // 64 bit registers. 2 accesses.
        int int_id = (addr - GICD_IROUTER.start()) / 8;

        if (isNotSPI(int_id)) {
            return;
        }

        if (nsAccessToSecInt(int_id, is_secure_access))
        {
            if (irqNsacr[int_id] < 3) {
                // Group 0 or Secure Group 1 interrupts are RAZ/WI
                return;
            }
        }

        if (size == 4) {
            if (addr & 7) { // high half of 64 bit register
                irqAffinityRouting[int_id] =
                    (irqAffinityRouting[int_id] & 0xffffffff) | (data << 32);
            } else { // low half of 64 bit register
                irqAffinityRouting[int_id] =
                    (irqAffinityRouting[int_id] & 0xffffffff00000000) |
                    (data & 0xffffffff);
            }
        } else {
            irqAffinityRouting[int_id] = data;
        }

        DPRINTF(GIC, "Gicv3Distributor::write(): "
                "int_id %d GICD_IROUTER %#llx\n",
                int_id, irqAffinityRouting[int_id]);
        return;
    }

    switch (addr) {
      case GICD_CTLR: // Control Register
        if (DS) {
            /*
             * E1NWF [7]
             * 1 of N wakeup functionality not supported, RAZ/WI
             * DS [6] - RAO/WI
             * ARE [4]
             * affinity routing always on, no GICv2 legacy, RAO/WI
             * EnableGrp1 [1]
             * EnableGrp0 [0]
             */
            if ((data & (1 << 4)) == 0) {
                warn("Gicv3Distributor::write(): "
                        "setting ARE to 0 is not supported!\n");
            }

            EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1NS;
            EnableGrp0 = data & GICD_CTLR_ENABLEGRP0;
            DPRINTF(GIC, "Gicv3Distributor::write(): (DS 1)"
                    "EnableGrp1NS %d EnableGrp0 %d\n",
                    EnableGrp1NS, EnableGrp0);
        } else {
            if (is_secure_access) {
                /*
                 * E1NWF [7]
                 * 1 of N wakeup functionality not supported, RAZ/WI
                 * DS [6]
                 * ARE_NS [5]
                 * affinity routing always on, no GICv2 legacy, RAO/WI
                 * ARE_S [4]
                 * affinity routing always on, no GICv2 legacy, RAO/WI
                 * EnableGrp1S [2]
                 * EnableGrp1NS [1]
                 * EnableGrp0 [0]
                 */
                if ((data & (1 << 5)) == 0) {
                    warn("Gicv3Distributor::write(): "
                            "setting ARE_NS to 0 is not supported!\n");
                }

                if ((data & (1 << 4)) == 0) {
                    warn("Gicv3Distributor::write(): "
                            "setting ARE_S to 0 is not supported!\n");
                }

                DS = data & GICD_CTLR_DS;
                EnableGrp1S = data & GICD_CTLR_ENABLEGRP1S;
                EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1NS;
                EnableGrp0 = data & GICD_CTLR_ENABLEGRP0;
                DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 secure)"
                        "DS %d "
                        "EnableGrp1S %d EnableGrp1NS %d EnableGrp0 %d\n",
                        DS, EnableGrp1S, EnableGrp1NS, EnableGrp0);

                if (data & GICD_CTLR_DS) {
                    EnableGrp1S = 0;
                }
            } else {
                /*
                 * ARE_NS [4] RAO/WI;
                 * EnableGrp1A [1] is a read-write alias of the Secure
                 * GICD_CTLR.EnableGrp1NS
                 * EnableGrp1 [0] RES0
                 */
                if ((data & (1 << 4)) == 0) {
                    warn("Gicv3Distributor::write(): "
                            "setting ARE_NS to 0 is not supported!\n");
                }

                EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1A;
                DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 non-secure)"
                        "EnableGrp1NS %d\n", EnableGrp1NS);
            }
        }

        update();

        break;

      case GICD_SGIR: // Error Reporting Status Register
        // Only if affinity routing is disabled, RES0
        break;

      case GICD_SETSPI_NSR: {
        // Writes to this register have no effect if:
        // * The value written specifies an invalid SPI.
        // * The SPI is already pending.
        // * The value written specifies a Secure SPI, the value is
        // written by a Non-secure access, and the value of the
        // corresponding GICD_NSACR<n> register is 0.
        const uint32_t intid = bits(data, 9, 0);
        if (isNotSPI(intid) || irqPending[intid] ||
            (nsAccessToSecInt(intid, is_secure_access) &&
             irqNsacr[intid] == 0)) {
            return;
        } else {
            // Valid SPI, set interrupt pending
            sendInt(intid);
        }
        break;
      }

      case GICD_CLRSPI_NSR: {
        // Writes to this register have no effect if:
        // * The value written specifies an invalid SPI.
        // * The SPI is not pending.
        // * The value written specifies a Secure SPI, the value is
        // written by a Non-secure access, and the value of the
        // corresponding GICD_NSACR<n> register is less than 0b10.
        const uint32_t intid = bits(data, 9, 0);
        if (isNotSPI(intid) || !irqPending[intid] ||
            (nsAccessToSecInt(intid, is_secure_access) &&
             irqNsacr[intid] < 2)) {
            return;
        } else {
            // Valid SPI, clear interrupt pending
            deassertSPI(intid);
        }
        break;
      }

      case GICD_SETSPI_SR: {
        // Writes to this register have no effect if:
        // * GICD_CTLR.DS = 1 (WI)
        // * The value written specifies an invalid SPI.
        // * The SPI is already pending.
        // * The value is written by a Non-secure access.
        const uint32_t intid = bits(data, 9, 0);
        if (DS || isNotSPI(intid) || irqPending[intid] || !is_secure_access) {
            return;
        } else {
            // Valid SPI, set interrupt pending
            sendInt(intid);
        }
        break;
      }

      case GICD_CLRSPI_SR: {
        // Writes to this register have no effect if:
        // * GICD_CTLR.DS = 1 (WI)
        // * The value written specifies an invalid SPI.
        // * The SPI is not pending.
        // * The value is written by a Non-secure access.
        const uint32_t intid = bits(data, 9, 0);
        if (DS || isNotSPI(intid) || !irqPending[intid] || !is_secure_access) {
            return;
        } else {
            // Valid SPI, clear interrupt pending
            deassertSPI(intid);
        }
        break;
      }

      default:
        panic("Gicv3Distributor::write(): invalid offset %#x\n", addr);
        break;
    }
}

void
Gicv3Distributor::sendInt(uint32_t int_id)
{
    panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
    panic_if(int_id > itLines, "Invalid SPI!");
    irqPending[int_id] = true;
    irqPendingIspendr[int_id] = false;
    DPRINTF(GIC, "Gicv3Distributor::sendInt(): "
            "int_id %d (SPI) pending bit set\n", int_id);
    update();
}

void
Gicv3Distributor::clearInt(uint32_t int_id)
{
    // Edge-triggered interrupts remain pending until software
    // writes GICD_ICPENDR, GICD_CLRSPI_* or activates them via ICC_IAR
    if (isLevelSensitive(int_id)) {
        deassertSPI(int_id);
    }
}

void
Gicv3Distributor::deassertSPI(uint32_t int_id)
{
    panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
    panic_if(int_id > itLines, "Invalid SPI!");
    irqPending[int_id] = false;
    clearIrqCpuInterface(int_id);

    update();
}

Gicv3CPUInterface*
Gicv3Distributor::route(uint32_t int_id)
{
    IROUTER affinity_routing = irqAffinityRouting[int_id];
    Gicv3Redistributor * target_redistributor = nullptr;

    const Gicv3::GroupId int_group = getIntGroup(int_id);

    if (affinity_routing.IRM) {
        // Interrupts routed to any PE defined as a participating node
        for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
            Gicv3Redistributor * redistributor_i =
                gic->getRedistributor(i);

            if (redistributor_i->
                    canBeSelectedFor1toNInterrupt(int_group)) {
                target_redistributor = redistributor_i;
                break;
            }
        }
    } else {
        uint32_t affinity = (affinity_routing.Aff3 << 24) |
                            (affinity_routing.Aff2 << 16) |
                            (affinity_routing.Aff1 << 8) |
                            (affinity_routing.Aff0 << 0);
        target_redistributor =
            gic->getRedistributorByAffinity(affinity);
    }

    if (!target_redistributor) {
        // Interrrupts targeting not present cpus must remain pending
        return nullptr;
    } else {
        return target_redistributor->getCPUInterface();
    }
}

void
Gicv3Distributor::clearIrqCpuInterface(uint32_t int_id)
{
    auto cpu_interface = route(int_id);
    if (cpu_interface)
        cpu_interface->resetHppi(int_id);
}

void
Gicv3Distributor::update()
{
    // Find the highest priority pending SPI
    for (int int_id = Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id < itLines;
         int_id++) {
        Gicv3::GroupId int_group = getIntGroup(int_id);
        bool group_enabled = groupEnabled(int_group);

        if (irqPending[int_id] && irqEnabled[int_id] &&
            !irqActive[int_id] && group_enabled) {

            // Find the cpu interface where to route the interrupt
            Gicv3CPUInterface *target_cpu_interface = route(int_id);

            // Invalid routing
            if (!target_cpu_interface) continue;

            if ((irqPriority[int_id] < target_cpu_interface->hppi.prio) ||
                (irqPriority[int_id] == target_cpu_interface->hppi.prio &&
                int_id < target_cpu_interface->hppi.intid)) {

                target_cpu_interface->hppi.intid = int_id;
                target_cpu_interface->hppi.prio = irqPriority[int_id];
                target_cpu_interface->hppi.group = int_group;
            }
        }
    }

    // Update all redistributors
    for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
        gic->getRedistributor(i)->update();
    }
}

Gicv3::IntStatus
Gicv3Distributor::intStatus(uint32_t int_id) const
{
    panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
    panic_if(int_id > itLines, "Invalid SPI!");

    if (irqPending[int_id]) {
        if (irqActive[int_id]) {
            return Gicv3::INT_ACTIVE_PENDING;
        }

        return Gicv3::INT_PENDING;
    } else if (irqActive[int_id]) {
        return Gicv3::INT_ACTIVE;
    } else {
        return Gicv3::INT_INACTIVE;
    }
}

Gicv3::GroupId
Gicv3Distributor::getIntGroup(int int_id) const
{
    panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
    panic_if(int_id > itLines, "Invalid SPI!");

    if (DS) {
        if (irqGroup[int_id] == 1) {
            return Gicv3::G1NS;
        } else {
            return Gicv3::G0S;
        }
    } else {
        if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 0) {
            return Gicv3::G0S;
        } else if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 1) {
            return Gicv3::G1NS;
        } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 0) {
            return Gicv3::G1S;
        } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 1) {
            return Gicv3::G1NS;
        }
    }

    M5_UNREACHABLE;
}

void
Gicv3Distributor::activateIRQ(uint32_t int_id)
{
    if (treatAsEdgeTriggered(int_id)) {
        irqPending[int_id] = false;
    }
    irqActive[int_id] = true;
}

void
Gicv3Distributor::deactivateIRQ(uint32_t int_id)
{
    irqActive[int_id] = false;
}

void
Gicv3Distributor::serialize(CheckpointOut & cp) const
{
    SERIALIZE_SCALAR(ARE);
    SERIALIZE_SCALAR(DS);
    SERIALIZE_SCALAR(EnableGrp1S);
    SERIALIZE_SCALAR(EnableGrp1NS);
    SERIALIZE_SCALAR(EnableGrp0);
    SERIALIZE_CONTAINER(irqGroup);
    SERIALIZE_CONTAINER(irqEnabled);
    SERIALIZE_CONTAINER(irqPending);
    SERIALIZE_CONTAINER(irqPendingIspendr);
    SERIALIZE_CONTAINER(irqActive);
    SERIALIZE_CONTAINER(irqPriority);
    SERIALIZE_CONTAINER(irqConfig);
    SERIALIZE_CONTAINER(irqGrpmod);
    SERIALIZE_CONTAINER(irqNsacr);
    SERIALIZE_CONTAINER(irqAffinityRouting);
}

void
Gicv3Distributor::unserialize(CheckpointIn & cp)
{
    UNSERIALIZE_SCALAR(ARE);
    UNSERIALIZE_SCALAR(DS);
    UNSERIALIZE_SCALAR(EnableGrp1S);
    UNSERIALIZE_SCALAR(EnableGrp1NS);
    UNSERIALIZE_SCALAR(EnableGrp0);
    UNSERIALIZE_CONTAINER(irqGroup);
    UNSERIALIZE_CONTAINER(irqEnabled);
    UNSERIALIZE_CONTAINER(irqPending);
    UNSERIALIZE_CONTAINER(irqPendingIspendr);
    UNSERIALIZE_CONTAINER(irqActive);
    UNSERIALIZE_CONTAINER(irqPriority);
    UNSERIALIZE_CONTAINER(irqConfig);
    UNSERIALIZE_CONTAINER(irqGrpmod);
    UNSERIALIZE_CONTAINER(irqNsacr);
    UNSERIALIZE_CONTAINER(irqAffinityRouting);
}
