/*
 * Copyright (c) 2019-2022 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_redistributor.hh"

#include "arch/arm/utility.hh"
#include "base/compiler.hh"
#include "debug/GIC.hh"
#include "dev/arm/gic_v3_cpu_interface.hh"
#include "dev/arm/gic_v3_distributor.hh"

namespace gem5
{

using namespace ArmISA;

const AddrRange Gicv3Redistributor::GICR_IPRIORITYR(SGI_base + 0x0400,
                                                    SGI_base + 0x0420);

Gicv3Redistributor::Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id)
    : gic(gic),
      distributor(nullptr),
      cpuInterface(nullptr),
      cpuId(cpu_id),
      memProxy(nullptr),
      peInLowPowerState(true),
      irqGroup(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
      irqEnabled(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
      irqPending(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
      irqPendingIspendr(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
      irqActive(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
      irqPriority(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
      irqConfig(Gicv3::SGI_MAX + Gicv3::PPI_MAX, Gicv3::INT_EDGE_TRIGGERED),
      irqGrpmod(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
      irqNsacr(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
      DPG1S(false),
      DPG1NS(false),
      DPG0(false),
      EnableLPIs(false),
      lpiConfigurationTablePtr(0),
      lpiIDBits(0),
      lpiPendingTablePtr(0),
      addrRangeSize(gic->params().gicv4 ? 0x40000 : 0x20000)
{
}

void
Gicv3Redistributor::init()
{
    distributor = gic->getDistributor();
    cpuInterface = gic->getCPUInterface(cpuId);

    memProxy = &gic->getSystem()->physProxy;
}

uint64_t
Gicv3Redistributor::read(Addr addr, size_t size, bool is_secure_access)
{
    if (GICR_IPRIORITYR.contains(addr)) { // Interrupt Priority Registers
        uint64_t value = 0;
        int first_intid = addr - GICR_IPRIORITYR.start();

        for (int i = 0, int_id = first_intid; i < size; i++, int_id++) {
            uint8_t prio = irqPriority[int_id];

            if (!distributor->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;
                }
            }

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

        return value;
    }

    switch (addr) {
      case GICR_CTLR: { // Control Register
          uint64_t value = 0;

          if (DPG1S) {
              value |= GICR_CTLR_DPG1S;
          }

          if (DPG1NS) {
              value |= GICR_CTLR_DPG1NS;
          }

          if (DPG0) {
              value |= GICR_CTLR_DPG0;
          }

          if (EnableLPIs) {
              value |= GICR_CTLR_ENABLE_LPIS;
          }

          return value;
      }

      case GICR_IIDR: // Implementer Identification Register
        //return 0x43b; // r0p0 GIC-500
        return 0;

      case GICR_TYPER: { // Type Register
          /*
           * Affinity_Value   [63:32] == X
           * (The identity of the PE associated with this Redistributor)
           * CommonLPIAff     [25:24] == 01
           * (All Redistributors with the same Aff3 value must share an
           * LPI Configuration table)
           * Processor_Number [23:8]  == X
           * (A unique identifier for the PE)
           * DPGS             [5]     == 1
           * (GICR_CTLR.DPG* bits are supported)
           * Last             [4]     == X
           * (This Redistributor is the highest-numbered Redistributor in
           * a series of contiguous Redistributor pages)
           * DirectLPI        [3]     == 1
           * (direct injection of LPIs supported)
           * VLPIS            [1]     == 0
           * (virtual LPIs not supported)
           * PLPIS            [0]     == 1
           * (physical LPIs supported)
           */
          uint64_t affinity = getAffinity();
          int last = cpuId == (gic->getSystem()->threads.size() - 1);
          return (affinity << 32) | (1 << 24) | (cpuId << 8) |
              (1 << 5) | (last << 4) | (1 << 3) | (1 << 0);
      }

      case GICR_WAKER: // Wake Register
        if (!distributor->DS && !is_secure_access) {
            // RAZ/WI for non-secure accesses
            return 0;
        }

        if (peInLowPowerState) {
            return GICR_WAKER_ChildrenAsleep | GICR_WAKER_ProcessorSleep;
        } else {
            return 0;
        }

      case GICR_PIDR0: { // Peripheral ID0 Register
          return 0x92; // Part number, bits[7:0]
      }

      case GICR_PIDR1: { // Peripheral ID1 Register
          uint8_t des_0 = 0xB; // JEP106 identification code, bits[3:0]
          uint8_t part_1 = 0x4; // Part number, bits[11:8]
          return (des_0 << 4) | (part_1 << 0);
      }

      case GICR_PIDR2: { // Peripheral ID2 Register
          return gic->getDistributor()->gicdPidr2;
      }

      case GICR_PIDR3: // Peripheral ID3 Register
        return 0x0; // Implementation defined

      case GICR_PIDR4: { // Peripheral ID4 Register
          uint8_t size = 0x4; // 64 KB software visible page
          uint8_t des_2 = 0x4; // ARM implementation
          return (size << 4) | (des_2 << 0);
      }

      case GICR_PIDR5: // Peripheral ID5 Register
      case GICR_PIDR6: // Peripheral ID6 Register
      case GICR_PIDR7: // Peripheral ID7 Register
        return 0; // RES0

      case GICR_IGROUPR0: { // Interrupt Group Register 0
          uint64_t value = 0;

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

          for (int int_id = 0; int_id < 8 * size; int_id++) {
              value |= (irqGroup[int_id] << int_id);
          }

          return value;
      }

      case GICR_ISENABLER0: // Interrupt Set-Enable Register 0
      case GICR_ICENABLER0: { // Interrupt Clear-Enable Register 0
          uint64_t value = 0;

          for (int int_id = 0; int_id < 8 * size; int_id++) {
              if (!distributor->DS && !is_secure_access) {
                  // RAZ/WI for non-secure accesses for secure interrupts
                  if (getIntGroup(int_id) != Gicv3::G1NS) {
                      continue;
                  }
              }

              if (irqEnabled[int_id]) {
                  value |= (1 << int_id);
              }
          }

          return value;
      }

      case GICR_ISPENDR0: // Interrupt Set-Pending Register 0
      case GICR_ICPENDR0: { // Interrupt Clear-Pending Register 0
          uint64_t value = 0;

          for (int int_id = 0; int_id < 8 * size; int_id++) {
              if (!distributor->DS && !is_secure_access) {
                  // RAZ/WI for non-secure accesses for secure interrupts
                  if (getIntGroup(int_id) != Gicv3::G1NS) {
                      continue;
                  }
              }

              value |= (irqPending[int_id] << int_id);
          }

          return value;
      }

      case GICR_ISACTIVER0: // Interrupt Set-Active Register 0
      case GICR_ICACTIVER0: { // Interrupt Clear-Active Register 0
          uint64_t value = 0;

          for (int int_id = 0; int_id < 8 * size; int_id++) {
              if (!distributor->DS && !is_secure_access) {
                  // RAZ/WI for non-secure accesses for secure interrupts
                  if (getIntGroup(int_id) != Gicv3::G1NS) {
                      continue;
                  }
              }

              value |=  irqActive[int_id] << int_id;
          }

          return value;
      }

      case GICR_ICFGR0: // SGI Configuration Register
      case GICR_ICFGR1: { // PPI Configuration Register
          uint64_t value = 0;
          uint32_t first_int_id = addr == GICR_ICFGR0 ? 0 : Gicv3::SGI_MAX;

          for (int i = 0, int_id = first_int_id; i < 32;
               i = i + 2, int_id++) {
              if (!distributor->DS && !is_secure_access) {
                  // RAZ/WI for non-secure accesses for secure interrupts
                  if (getIntGroup(int_id) != Gicv3::G1NS) {
                      continue;
                  }
              }

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

          return value;
      }

      case GICR_IGRPMODR0: { // Interrupt Group Modifier Register 0
          uint64_t value = 0;

          if (distributor->DS) {
              value = 0;
          } else {
              if (!is_secure_access) {
                  // RAZ/WI for non-secure accesses
                  value = 0;
              } else {
                  for (int int_id = 0; int_id < 8 * size; int_id++) {
                      value |= irqGrpmod[int_id] << int_id;
                  }
              }
          }

          return value;
      }

      case GICR_NSACR: { // Non-secure Access Control Register
          uint64_t value = 0;

          if (distributor->DS) {
              // RAZ/WI
              value = 0;
          } else {
              if (!is_secure_access) {
                  // RAZ/WI
                  value = 0;
              } else {
                  for (int i = 0, int_id = 0; i < 8 * size;
                       i = i + 2, int_id++) {
                      value |= irqNsacr[int_id] << i;
                  }
              }
          }

          return value;
      }

      case GICR_PROPBASER: // Redistributor Properties Base Address Register
        // OuterCache, bits [58:56]
        //   000 Memory type defined in InnerCache field
        // Physical_Address, bits [51:12]
        //   Bits [51:12] of the physical address containing the LPI
        //   Configuration table
        // Shareability, bits [11:10]
        //   00 Non-shareable
        // InnerCache, bits [9:7]
        //   000 Device-nGnRnE
        // IDbits, bits [4:0]
        //   limited by GICD_TYPER.IDbits
        return lpiConfigurationTablePtr | lpiIDBits;

      // Redistributor LPI Pending Table Base Address Register
      case GICR_PENDBASER:
        // PTZ, bit [62]
        //   Pending Table Zero
        // OuterCache, bits [58:56]
        //   000 Memory type defined in InnerCache field
        // Physical_Address, bits [51:16]
        //   Bits [51:16] of the physical address containing the LPI Pending
        //   table
        // Shareability, bits [11:10]
        //   00 Non-shareable
        // InnerCache, bits [9:7]
        //   000 Device-nGnRnE
        return lpiPendingTablePtr;

      // Redistributor Synchronize Register
      case GICR_SYNCR:
        return 0;

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

void
Gicv3Redistributor::write(Addr addr, uint64_t data, size_t size,
                          bool is_secure_access)
{
    if (GICR_IPRIORITYR.contains(addr)) { // Interrupt Priority Registers
        int first_intid = addr - GICR_IPRIORITYR.start();

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

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

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

        return;
    }

    switch (addr) {
      case GICR_CTLR: {
          // GICR_TYPER.LPIS is 0 so EnableLPIs is RES0
          EnableLPIs = data & GICR_CTLR_ENABLE_LPIS;
          DPG1S = data & GICR_CTLR_DPG1S;
          DPG1NS = data & GICR_CTLR_DPG1NS;
          DPG0 = data & GICR_CTLR_DPG0;
          break;
      }

      case GICR_WAKER: // Wake Register
      {
        if (!distributor->DS && !is_secure_access) {
            // RAZ/WI for non-secure accesses
            return;
        }

        bool pe_was_low_power = peInLowPowerState;
        peInLowPowerState = data & GICR_WAKER_ProcessorSleep;
        if (!pe_was_low_power && peInLowPowerState) {
            DPRINTF(GIC, "Gicv3Redistributor::write(): "
                    "PE entering in low power state\n");
            updateDistributor();
        } else if (pe_was_low_power && !peInLowPowerState) {
            DPRINTF(GIC, "Gicv3Redistributor::write(): powering up PE\n");
            cpuInterface->deassertWakeRequest();
            updateDistributor();
        }
        break;
      }

      case GICR_IGROUPR0: // Interrupt Group Register 0
        if (!distributor->DS && !is_secure_access) {
            // RAZ/WI for non-secure accesses
            return;
        }

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

        break;

      case GICR_ISENABLER0: // Interrupt Set-Enable Register 0
        for (int int_id = 0; int_id < 8 * size; int_id++) {
            if (!distributor->DS && !is_secure_access) {
                // RAZ/WI for non-secure accesses for secure interrupts
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    continue;
                }
            }

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

            if (enable) {
                irqEnabled[int_id] = true;
            }

            DPRINTF(GIC, "Gicv3Redistributor::write(): "
                    "int_id %d enable %i\n", int_id, irqEnabled[int_id]);
        }

        break;

      case GICR_ICENABLER0: // Interrupt Clear-Enable Register 0
        for (int int_id = 0; int_id < 8 * size; int_id++) {
            if (!distributor->DS && !is_secure_access) {
                // RAZ/WI for non-secure accesses for secure interrupts
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    continue;
                }
            }

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

            if (disable) {
                irqEnabled[int_id] = false;
            }

            DPRINTF(GIC, "Gicv3Redistributor::write(): "
                    "int_id %d enable %i\n", int_id, irqEnabled[int_id]);
        }

        break;

      case GICR_ISPENDR0: // Interrupt Set-Pending Register 0
        for (int int_id = 0; int_id < 8 * size; int_id++) {
            if (!distributor->DS && !is_secure_access) {
                // RAZ/WI for non-secure accesses for secure interrupts
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    continue;
                }
            }

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

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

        updateDistributor();
        break;

      case GICR_ICPENDR0:// Interrupt Clear-Pending Register 0
        for (int int_id = 0; int_id < 8 * size; int_id++) {
            if (!distributor->DS && !is_secure_access) {
                // RAZ/WI for non-secure accesses for secure interrupts
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    continue;
                }
            }

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

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

        break;

      case GICR_ISACTIVER0: // Interrupt Set-Active Register 0
        for (int int_id = 0; int_id < 8 * size; int_id++) {
            if (!distributor->DS && !is_secure_access) {
                // RAZ/WI for non-secure accesses for secure interrupts
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    continue;
                }
            }

            bool activate = data & (1 << int_id) ? 1 : 0;

            if (activate) {
                if (!irqActive[int_id]) {
                    DPRINTF(GIC, "Gicv3Redistributor::write(): "
                            "int_id %d active set\n", int_id);
                }

                irqActive[int_id] = true;
            }
        }

        break;

      case GICR_ICACTIVER0: // Interrupt Clear-Active Register 0
        for (int int_id = 0; int_id < 8 * size; int_id++) {
            if (!distributor->DS && !is_secure_access) {
                // RAZ/WI for non-secure accesses for secure interrupts
                if (getIntGroup(int_id) != Gicv3::G1NS) {
                    continue;
                }
            }

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

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

                irqActive[int_id] = false;
            }
        }

        break;

      case GICR_ICFGR0: // SGI Configuration Register
        // WI
        return;
      case GICR_ICFGR1: { // PPI Configuration Register
          int first_intid = Gicv3::SGI_MAX;

          for (int i = 0, int_id = first_intid; i < 8 * size;
               i = i + 2, int_id++) {
              if (!distributor->DS && !is_secure_access) {
                  // RAZ/WI for non-secure accesses for secure interrupts
                  if (getIntGroup(int_id) != Gicv3::G1NS) {
                      continue;
                  }
              }

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

          break;
      }

      case GICR_IGRPMODR0: { // Interrupt Group Modifier Register 0
          if (distributor->DS) {
              // RAZ/WI if secutiry disabled
          } else {
              for (int int_id = 0; int_id < 8 * size; int_id++) {
                  if (!is_secure_access) {
                      // RAZ/WI for non-secure accesses
                      continue;
                  }

                  irqGrpmod[int_id] = data & (1 << int_id);
              }
          }

          break;
      }

      case GICR_NSACR: { // Non-secure Access Control Register
          if (distributor->DS) {
              // RAZ/WI
          } else {
              if (!is_secure_access) {
                  // RAZ/WI
              } else {
                  for (int i = 0, int_id = 0; i < 8 * size;
                       i = i + 2, int_id++) {
                      irqNsacr[int_id] = (data >> i) & 0x3;
                  }
              }
          }

          break;
      }

      case GICR_SETLPIR: // Set LPI Pending Register
        setClrLPI(data, true);
        break;

      case GICR_CLRLPIR: // Clear LPI Pending Register
        setClrLPI(data, false);
        break;

      case GICR_PROPBASER: { // Redistributor Properties Base Address Register
          // OuterCache, bits [58:56]
          //   000 Memory type defined in InnerCache field
          // Physical_Address, bits [51:12]
          //   Bits [51:12] of the physical address containing the LPI
          //   Configuration table
          // Shareability, bits [11:10]
          //   00 Non-shareable
          // InnerCache, bits [9:7]
          //   000 Device-nGnRnE
          // IDbits, bits [4:0]
          //   limited by GICD_TYPER.IDbits (= 0xf)
          lpiConfigurationTablePtr = data & 0xFFFFFFFFFF000;
          lpiIDBits = data & 0x1f;

          // 0xf here matches the value of GICD_TYPER.IDbits.
          // TODO - make GICD_TYPER.IDbits a parameter instead of a hardcoded
          // value
          if (lpiIDBits > 0xf) {
              lpiIDBits = 0xf;
          }

          break;
      }

      // Redistributor LPI Pending Table Base Address Register
      case GICR_PENDBASER:
        // PTZ, bit [62]
        //   Pending Table Zero
        // OuterCache, bits [58:56]
        //   000 Memory type defined in InnerCache field
        // Physical_Address, bits [51:16]
        //   Bits [51:16] of the physical address containing the LPI Pending
        //   table
        // Shareability, bits [11:10]
        //   00 Non-shareable
        // InnerCache, bits [9:7]
        //   000 Device-nGnRnE
        lpiPendingTablePtr = data & 0xFFFFFFFFF0000;
        break;

      case GICR_INVLPIR: { // Redistributor Invalidate LPI Register
          // Do nothing: no caching supported
          break;
      }

      case GICR_INVALLR: { // Redistributor Invalidate All Register
          // Do nothing: no caching supported
          break;
      }

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

void
Gicv3Redistributor::sendPPInt(uint32_t int_id)
{
    assert((int_id >= Gicv3::SGI_MAX) &&
           (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX));
    irqPending[int_id] = true;
    irqPendingIspendr[int_id] = false;
    DPRINTF(GIC, "Gicv3Redistributor::sendPPInt(): "
            "int_id %d (PPI) pending bit set\n", int_id);
    updateDistributor();
}

void
Gicv3Redistributor::clearPPInt(uint32_t int_id)
{
    assert((int_id >= Gicv3::SGI_MAX) &&
           (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX));

    if (isLevelSensitive(int_id)) {
        irqPending[int_id] = false;
    }
}

void
Gicv3Redistributor::sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
{
    assert(int_id < Gicv3::SGI_MAX);
    Gicv3::GroupId int_group = getIntGroup(int_id);

    bool forward = false;

    if (ns) {
        // Non-Secure EL1 and EL2 access
        int nsaccess = irqNsacr[int_id];
        if (int_group == Gicv3::G0S) {

            forward = distributor->DS || (nsaccess >= 1);

        } else if (int_group == Gicv3::G1S) {
            forward = ((group == Gicv3::G1S || group == Gicv3::G1NS ) &&
                      nsaccess == 2);
        } else {
            // G1NS
            forward = group == Gicv3::G1NS;
        }
    } else {
        // Secure EL1 and EL3 access
        forward = (group == int_group) ||
            (group == Gicv3::G1S && int_group == Gicv3::G0S &&
            distributor->DS);
    }

    if (!forward) return;

    irqPending[int_id] = true;
    irqPendingIspendr[int_id] = false;
    DPRINTF(GIC, "Gicv3ReDistributor::sendSGI(): "
            "int_id %d (SGI) pending bit set\n", int_id);
    updateDistributor();
}

Gicv3::IntStatus
Gicv3Redistributor::intStatus(uint32_t int_id) const
{
    assert(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX);

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

void
Gicv3Redistributor::updateDistributor()
{
    distributor->update();
}

/*
 * Recalculate the highest priority pending interrupt after a
 * change to redistributor state.
 */
void
Gicv3Redistributor::update()
{
    if (gic->blockIntUpdate())
        return;

    for (int int_id = 0; int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id++) {
        Gicv3::GroupId int_group = getIntGroup(int_id);
        bool group_enabled = distributor->groupEnabled(int_group);

        if (irqPending[int_id] && irqEnabled[int_id] &&
                !irqActive[int_id] && group_enabled) {
            if ((irqPriority[int_id] < cpuInterface->hppi.prio) ||
                /*
                 * Multiple pending ints with same priority.
                 * Implementation choice which one to signal.
                 * Our implementation selects the one with the lower id.
                 */
                (irqPriority[int_id] == cpuInterface->hppi.prio &&
                 int_id < cpuInterface->hppi.intid)) {
                cpuInterface->hppi.intid = int_id;
                cpuInterface->hppi.prio = irqPriority[int_id];
                cpuInterface->hppi.group = int_group;
            }
        }
    }

    // Check LPIs
    if (EnableLPIs) {

        const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1);
        const uint32_t number_lpis = largest_lpi_id - SMALLEST_LPI_ID + 1;

        uint8_t lpi_pending_table[largest_lpi_id / 8];
        uint8_t lpi_config_table[number_lpis];

        memProxy->readBlob(lpiPendingTablePtr,
                           lpi_pending_table,
                           sizeof(lpi_pending_table));

        memProxy->readBlob(lpiConfigurationTablePtr,
                           lpi_config_table,
                           sizeof(lpi_config_table));

        for (int lpi_id = SMALLEST_LPI_ID; lpi_id < largest_lpi_id;
             lpi_id++) {
            uint32_t lpi_pending_entry_byte = lpi_id / 8;
            uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
            bool lpi_is_pending = lpi_pending_table[lpi_pending_entry_byte] &
                                  1 << lpi_pending_entry_bit_position;
            uint32_t lpi_configuration_entry_index = lpi_id - SMALLEST_LPI_ID;

            LPIConfigurationTableEntry config_entry =
                lpi_config_table[lpi_configuration_entry_index];

            bool lpi_is_enable = config_entry.enable;

            // LPIs are always Non-secure Group 1 interrupts,
            // in a system where two Security states are enabled.
            Gicv3::GroupId lpi_group = Gicv3::G1NS;
            bool group_enabled = distributor->groupEnabled(lpi_group);

            if (lpi_is_pending && lpi_is_enable && group_enabled) {
                uint8_t lpi_priority = config_entry.priority << 2;

                if ((lpi_priority < cpuInterface->hppi.prio) ||
                    (lpi_priority == cpuInterface->hppi.prio &&
                     lpi_id < cpuInterface->hppi.intid)) {
                    cpuInterface->hppi.intid = lpi_id;
                    cpuInterface->hppi.prio = lpi_priority;
                    cpuInterface->hppi.group = lpi_group;
                }
            }
        }
    }

    if (peInLowPowerState) {
        if (cpuInterface->havePendingInterrupts()) {
            cpuInterface->assertWakeRequest();
            cpuInterface->clearPendingInterrupts();
        }
    } else {
        cpuInterface->update();
    }
}

uint8_t
Gicv3Redistributor::readEntryLPI(uint32_t lpi_id)
{
    Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);

    uint8_t lpi_pending_entry;
    memProxy->readBlob(lpi_pending_entry_ptr,
                       &lpi_pending_entry,
                       sizeof(lpi_pending_entry));

    return lpi_pending_entry;
}

void
Gicv3Redistributor::writeEntryLPI(uint32_t lpi_id, uint8_t lpi_pending_entry)
{
    Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);

    memProxy->writeBlob(lpi_pending_entry_ptr,
                        &lpi_pending_entry,
                        sizeof(lpi_pending_entry));
}

bool
Gicv3Redistributor::isPendingLPI(uint32_t lpi_id)
{
    // Fetch the LPI pending entry from memory
    uint8_t lpi_pending_entry = readEntryLPI(lpi_id);

    uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
    bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);

    return is_set;
}

void
Gicv3Redistributor::setClrLPI(uint64_t data, bool set)
{
    if (!EnableLPIs) {
        // Writes to GICR_SETLPIR or GICR_CLRLPIR have not effect if
        // GICR_CTLR.EnableLPIs == 0.
        return;
    }

    uint32_t lpi_id = data & 0xffffffff;
    uint32_t largest_lpi_id = 1 << (lpiIDBits + 1);

    if (lpi_id > largest_lpi_id) {
        // Writes to GICR_SETLPIR or GICR_CLRLPIR have not effect if
        // pINTID value specifies an unimplemented LPI.
        return;
    }

    // Fetch the LPI pending entry from memory
    uint8_t lpi_pending_entry = readEntryLPI(lpi_id);

    uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
    bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);

    if (set) {
        if (is_set) {
            // Writes to GICR_SETLPIR have not effect if the pINTID field
            // corresponds to an LPI that is already pending.
            return;
        }

        lpi_pending_entry |= 1 << (lpi_pending_entry_bit_position);
    } else {
        if (!is_set) {
            // Writes to GICR_SETLPIR have not effect if the pINTID field
            // corresponds to an LPI that is not pending.
            return;
        }

        lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position));

        // Remove the pending state from the cpu interface
        cpuInterface->resetHppi(lpi_id);
    }

    writeEntryLPI(lpi_id, lpi_pending_entry);

    updateDistributor();
}

Gicv3::GroupId
Gicv3Redistributor::getIntGroup(int int_id) const
{
    assert(int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX));

    if (distributor->DS) {
        if (irqGroup[int_id] == 0) {
            return Gicv3::G0S;
        } else {
            return Gicv3::G1NS;
        }
    } 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;
        }
    }

    GEM5_UNREACHABLE;
}

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

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

uint32_t
Gicv3Redistributor::getAffinity() const
{
    ThreadContext *tc = gic->getSystem()->threads[cpuId];
    return gem5::ArmISA::getAffinity(gic->getSystem(), tc);
}

bool
Gicv3Redistributor::canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const
{
    if (peInLowPowerState) {
        return false;
    }

    if (!distributor->groupEnabled(group)) {
        return false;
    }

    if ((group == Gicv3::G1S) && DPG1S) {
        return false;
    }

    if ((group == Gicv3::G1NS) && DPG1NS) {
        return false;
    }

    if ((group == Gicv3::G0S) && DPG0) {
        return false;
    }

    return true;
}

void
Gicv3Redistributor::copy(Gicv3Registers *from, Gicv3Registers *to)
{
    const auto affinity = getAffinity();
    // SGI_Base regs
    gic->copyRedistRegister(from, to, affinity, GICR_CTLR);
    gic->copyRedistRegister(from, to, affinity, GICR_WAKER);

    gic->clearRedistRegister(to, affinity, GICR_ICENABLER0);
    gic->clearRedistRegister(to, affinity, GICR_ICPENDR0);
    gic->clearRedistRegister(to, affinity, GICR_ICACTIVER0);

    gic->copyRedistRegister(from, to, affinity, GICR_ISENABLER0);
    gic->copyRedistRegister(from, to, affinity, GICR_ISPENDR0);
    gic->copyRedistRegister(from, to, affinity, GICR_ISACTIVER0);
    gic->copyRedistRegister(from, to, affinity, GICR_ICFGR0);
    gic->copyRedistRegister(from, to, affinity, GICR_ICFGR1);
    gic->copyRedistRegister(from, to, affinity, GICR_IGRPMODR0);
    gic->copyRedistRegister(from, to, affinity, GICR_NSACR);

    gic->copyRedistRange(from, to, affinity,
        GICR_IPRIORITYR.start(), GICR_IPRIORITYR.size());

    // RD_Base regs
    gic->copyRedistRegister(from, to, affinity, GICR_PROPBASER);
    gic->copyRedistRegister(from, to, affinity, GICR_PENDBASER);
}

void
Gicv3Redistributor::serialize(CheckpointOut & cp) const
{
    SERIALIZE_SCALAR(peInLowPowerState);
    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_SCALAR(DPG1S);
    SERIALIZE_SCALAR(DPG1NS);
    SERIALIZE_SCALAR(DPG0);
    SERIALIZE_SCALAR(EnableLPIs);
    SERIALIZE_SCALAR(lpiConfigurationTablePtr);
    SERIALIZE_SCALAR(lpiIDBits);
    SERIALIZE_SCALAR(lpiPendingTablePtr);
}

void
Gicv3Redistributor::unserialize(CheckpointIn & cp)
{
    UNSERIALIZE_SCALAR(peInLowPowerState);
    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_SCALAR(DPG1S);
    UNSERIALIZE_SCALAR(DPG1NS);
    UNSERIALIZE_SCALAR(DPG0);
    UNSERIALIZE_SCALAR(EnableLPIs);
    UNSERIALIZE_SCALAR(lpiConfigurationTablePtr);
    UNSERIALIZE_SCALAR(lpiIDBits);
    UNSERIALIZE_SCALAR(lpiPendingTablePtr);
}

} // namespace gem5
