// Copyright 2017 The Fuchsia Authors
// Copyright (c) 2017, Google Inc. All rights reserved.
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <assert.h>
#include <bits.h>
#include <inttypes.h>
#include <lib/arch/intrin.h>
#include <lib/ktrace.h>
#include <lib/root_resource_filter.h>
#include <string.h>
#include <trace.h>
#include <zircon/boot/driver-config.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <arch/arm64/hypervisor/gic/gicv3.h>
#include <arch/arm64/periphmap.h>
#include <arch/regs.h>
#include <dev/interrupt.h>
#include <dev/interrupt/arm_gic_common.h>
#include <dev/interrupt/arm_gic_hw_interface.h>
#include <dev/interrupt/arm_gicv3_init.h>
#include <kernel/cpu.h>
#include <kernel/stats.h>
#include <kernel/thread.h>
#include <lk/init.h>
#include <pdev/interrupt.h>
#include <vm/vm.h>

#include "arm_gicv3_pcie.h"

#define LOCAL_TRACE 0

#include <arch/arm64.h>
#define IFRAME_PC(frame) ((frame)->elr)

// Values read from the config.
static uint64_t mmio_phys = 0;
vaddr_t arm_gicv3_gic_base = 0;
uint64_t arm_gicv3_gicd_offset = 0;
uint64_t arm_gicv3_gicr_offset = 0;
uint64_t arm_gicv3_gicr_stride = 0;
static uint32_t ipi_base = 0;

// this header uses the arm_gicv3_gic_* variables above
#include <dev/interrupt/arm_gicv3_regs.h>

static uint gic_max_int;

static bool gic_is_valid_interrupt(unsigned int vector, uint32_t flags) {
  return (vector < gic_max_int);
}

static uint32_t gic_get_base_vector() {
  // ARM Generic Interrupt Controller v3&4 chapter 2.2
  // INTIDs 0-15 are local CPU interrupts
  return 16;
}

static uint32_t gic_get_max_vector() { return gic_max_int; }

static void gic_wait_for_rwp(uint64_t reg) {
  int count = 1000000;
  while (GICREG(0, reg) & (1 << 31)) {
    count -= 1;
    if (!count) {
      LTRACEF("arm_gicv3: rwp timeout 0x%x\n", GICREG(0, reg));
      return;
    }
  }
}

static void gic_set_enable(uint vector, bool enable) {
  int reg = vector / 32;
  uint32_t mask = (uint32_t)(1ULL << (vector % 32));

  if (vector < 32) {
    for (cpu_num_t i = 0; i < arch_max_num_cpus(); i++) {
      if (enable) {
        GICREG(0, GICR_ISENABLER0(i)) = mask;
      } else {
        GICREG(0, GICR_ICENABLER0(i)) = mask;
      }
      gic_wait_for_rwp(GICR_CTLR(i));
    }
  } else {
    if (enable) {
      GICREG(0, GICD_ISENABLER(reg)) = mask;
    } else {
      GICREG(0, GICD_ICENABLER(reg)) = mask;
    }
    gic_wait_for_rwp(GICD_CTLR);
  }
}

static void gic_init_percpu_early() {
  cpu_num_t cpu = arch_curr_cpu_num();

  // redistributer config: configure sgi/ppi as non-secure group 1.
  GICREG(0, GICR_IGROUPR0(cpu)) = ~0;
  gic_wait_for_rwp(GICR_CTLR(cpu));

  // redistributer config: clear and mask sgi/ppi.
  GICREG(0, GICR_ICENABLER0(cpu)) = 0xffffffff;
  GICREG(0, GICR_ICPENDR0(cpu)) = ~0;
  gic_wait_for_rwp(GICR_CTLR(cpu));

  // TODO lpi init

  // enable system register interface
  uint32_t sre = gic_read_sre();
  if (!(sre & 0x1)) {
    gic_write_sre(sre | 0x1);
    sre = gic_read_sre();
    DEBUG_ASSERT(sre & 0x1);
  }

  // set priority threshold to max.
  gic_write_pmr(0xff);

  // ICC_CTLR_EL1.EOImode.
  gic_write_ctlr(1u << 1);

  // enable group 1 interrupts.
  gic_write_igrpen(1);
}

static zx_status_t gic_init() {
  LTRACE_ENTRY;

  DEBUG_ASSERT(arch_ints_disabled());

  uint pidr2 = GICREG(0, GICD_PIDR2);
  uint rev = BITS_SHIFT(pidr2, 7, 4);
  if (rev != GICV3 && rev != GICV4) {
    return ZX_ERR_NOT_FOUND;
  }

  uint32_t typer = GICREG(0, GICD_TYPER);
  gic_max_int = (BITS(typer, 4, 0) + 1) * 32;

  printf("GICv3 detected: rev %u, max interrupts %u, TYPER %#x\n", rev, gic_max_int, typer);

  // disable the distributor
  GICREG(0, GICD_CTLR) = 0;
  gic_wait_for_rwp(GICD_CTLR);
  __isb(ARM_MB_SY);

  // distributor config: mask and clear all spis, set group 1.
  uint i;
  for (i = 32; i < gic_max_int; i += 32) {
    GICREG(0, GICD_ICENABLER(i / 32)) = ~0;
    GICREG(0, GICD_ICPENDR(i / 32)) = ~0;
    GICREG(0, GICD_IGROUPR(i / 32)) = ~0;
    GICREG(0, GICD_IGRPMODR(i / 32)) = 0;
  }
  gic_wait_for_rwp(GICD_CTLR);

  // enable distributor with ARE, group 1 enable
  GICREG(0, GICD_CTLR) = CTLR_ENABLE_G0 | CTLR_ENABLE_G1NS | CTLR_ARE_S;
  gic_wait_for_rwp(GICD_CTLR);

  // ensure we're running on cpu 0 and that cpu 0 corresponds to affinity 0.0.0.0
  DEBUG_ASSERT(arch_curr_cpu_num() == 0);
  DEBUG_ASSERT(arch_cpu_num_to_cpu_id(0u) == 0);      // AFF0
  DEBUG_ASSERT(arch_cpu_num_to_cluster_id(0u) == 0);  // AFF1

  // TODO(maniscalco): If/when we support AFF2/AFF3, be sure to assert those here.

  // set spi to target cpu 0 (affinity 0.0.0.0). must do this after ARE enable
  uint max_cpu = BITS_SHIFT(typer, 7, 5);
  if (max_cpu > 0) {
    for (i = 32; i < gic_max_int; i++) {
      GICREG64(0, GICD_IROUTER(i)) = 0;
    }
  }

  gic_init_percpu_early();

  arch::DeviceMemoryBarrier();
  __isb(ARM_MB_SY);

  return ZX_OK;
}

static zx_status_t arm_gic_sgi(unsigned int irq, unsigned int flags, unsigned int cpu_mask) {
  LTRACEF("irq %u, flags %u, cpu_mask %#x\n", irq, flags, cpu_mask);

  if (flags != ARM_GIC_SGI_FLAG_NS) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (irq >= 16) {
    return ZX_ERR_INVALID_ARGS;
  }

  arch::ThreadMemoryBarrier();

  cpu_num_t cpu = 0;
  uint cluster = 0;
  uint64_t val = 0;
  while (cpu_mask && cpu < arch_max_num_cpus()) {
    unsigned int mask = 0;

    // within a single cluster (aff1) find all of the matching cpus
    while (cpu < arch_max_num_cpus() && arch_cpu_num_to_cluster_id(cpu) == cluster) {
      if (cpu_mask & (1u << cpu)) {
        cpu_mask &= ~(1u << cpu);

        auto aff0 = arch_cpu_num_to_cpu_id(cpu);
        mask |= 1u << aff0;
      }
      cpu += 1;
    }

    LTRACEF("computed mask %#x for cluster %u\n", mask, cluster);

    // Without the RS field set, we can only deal with the first
    // 16 cpus within a single cluster
    DEBUG_ASSERT((mask & 0xffff) == mask);

    val = ((irq & 0xf) << 24) | ((cluster & 0xff) << 16) | (mask & 0xffff);
    cluster += 1;

    // nothing in this cluster intersected with the cpu_mask
    if (mask == 0) {
      continue;
    }

    gic_write_sgi1r(val);
  }

  return ZX_OK;
}

static zx_status_t gic_mask_interrupt(unsigned int vector) {
  LTRACEF("vector %u\n", vector);

  if (vector >= gic_max_int) {
    return ZX_ERR_INVALID_ARGS;
  }

  gic_set_enable(vector, false);

  return ZX_OK;
}

static zx_status_t gic_unmask_interrupt(unsigned int vector) {
  LTRACEF("vector %u\n", vector);

  if (vector >= gic_max_int) {
    return ZX_ERR_INVALID_ARGS;
  }

  gic_set_enable(vector, true);

  return ZX_OK;
}

static zx_status_t gic_deactivate_interrupt(unsigned int vector) {
  if (vector >= gic_max_int) {
    return ZX_ERR_INVALID_ARGS;
  }

  uint32_t reg = 1 << (vector % 32);
  GICREG(0, GICD_ICACTIVER(vector / 32)) = reg;

  return ZX_OK;
}

static zx_status_t gic_configure_interrupt(unsigned int vector, enum interrupt_trigger_mode tm,
                                           enum interrupt_polarity pol) {
  LTRACEF("vector %u, trigger mode %d, polarity %d\n", vector, tm, pol);

  if (vector <= 15 || vector >= gic_max_int) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (pol != IRQ_POLARITY_ACTIVE_HIGH) {
    // TODO: polarity should actually be configure through a GPIO controller
    return ZX_ERR_NOT_SUPPORTED;
  }

  uint reg = vector / 16;
  uint mask = 0x2 << ((vector % 16) * 2);
  uint32_t val = GICREG(0, GICD_ICFGR(reg));
  if (tm == IRQ_TRIGGER_MODE_EDGE) {
    val |= mask;
  } else {
    val &= ~mask;
  }
  GICREG(0, GICD_ICFGR(reg)) = val;

  const uint32_t clear_reg = vector / 32;
  const uint32_t clear_mask = 1 << (vector % 32);
  GICREG(0, GICD_ICPENDR(clear_reg)) = clear_mask;

  return ZX_OK;
}

static zx_status_t gic_get_interrupt_config(unsigned int vector, enum interrupt_trigger_mode* tm,
                                            enum interrupt_polarity* pol) {
  LTRACEF("vector %u\n", vector);

  if (vector >= gic_max_int) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (tm) {
    *tm = IRQ_TRIGGER_MODE_EDGE;
  }
  if (pol) {
    *pol = IRQ_POLARITY_ACTIVE_HIGH;
  }

  return ZX_OK;
}

static unsigned int gic_remap_interrupt(unsigned int vector) {
  LTRACEF("vector %u\n", vector);
  return vector;
}

// called from assembly
static void gic_handle_irq(iframe_t* frame) {
  // get the current vector
  uint32_t iar = gic_read_iar();
  unsigned vector = iar & 0x3ff;

  LTRACEF_LEVEL(2, "iar %#x, vector %u\n", iar, vector);

  if (vector >= 0x3fe) {
    // spurious
    // TODO check this
    return;
  }

  // tracking external hardware irqs in this variable
  if (vector >= 32) {
    CPU_STATS_INC(interrupts);
  }

  cpu_num_t cpu = arch_curr_cpu_num();

  ktrace_tiny(TAG_IRQ_ENTER, (vector << 8) | cpu);

  LTRACEF_LEVEL(2, "iar 0x%x cpu %u currthread %p vector %u pc %#" PRIxPTR "\n", iar, cpu,
                Thread::Current::Get(), vector, (uintptr_t)IFRAME_PC(frame));

  // deliver the interrupt
  interrupt_eoi eoi;
  if (!pdev_invoke_int_if_present(vector, &eoi)) {
    eoi = IRQ_EOI_DEACTIVATE;
  }
  gic_write_eoir(vector);
  if (eoi == IRQ_EOI_DEACTIVATE) {
    gic_write_dir(vector);
  }

  LTRACEF_LEVEL(2, "cpu %u exit\n", cpu);

  ktrace_tiny(TAG_IRQ_EXIT, (vector << 8) | cpu);
}

static void gic_send_ipi(cpu_mask_t target, mp_ipi_t ipi) {
  uint gic_ipi_num = ipi + ipi_base;

  // filter out targets outside of the range of cpus we care about
  target &= (cpu_mask_t)(((1UL << arch_max_num_cpus()) - 1));
  if (target != 0) {
    LTRACEF("target 0x%x, gic_ipi %u\n", target, gic_ipi_num);
    arm_gic_sgi(gic_ipi_num, ARM_GIC_SGI_FLAG_NS, target);
  }
}

static interrupt_eoi arm_ipi_halt_handler(void*) {
  LTRACEF("cpu %u\n", arch_curr_cpu_num());

  arch_disable_ints();
  while (true) {
    __wfi();
  }

  return IRQ_EOI_DEACTIVATE;
}

static void gic_init_percpu() {
  mp_set_curr_cpu_online(true);
  unmask_interrupt(MP_IPI_GENERIC + ipi_base);
  unmask_interrupt(MP_IPI_RESCHEDULE + ipi_base);
  unmask_interrupt(MP_IPI_INTERRUPT + ipi_base);
  unmask_interrupt(MP_IPI_HALT + ipi_base);
}

static void gic_shutdown() {
  // Turn off all GIC0 interrupts at the distributor.
  GICREG(0, GICD_CTLR) = 0;
}

// Returns true if any PPIs are enabled on the calling CPU.
static bool is_ppi_enabled() {
  DEBUG_ASSERT(arch_ints_disabled());

  // PPIs are 16-31.
  uint32_t mask = 0xffff0000;

  cpu_num_t cpu_num = arch_curr_cpu_num();
  uint32_t reg = GICREG(0, GICR_ICENABLER0(cpu_num));
  if ((reg & mask) != 0) {
    return true;
  }

  return false;
}

// Returns true if any SPIs are enabled on the calling CPU.
static bool is_spi_enabled() {
  DEBUG_ASSERT(arch_ints_disabled());

  cpu_num_t cpu_num = arch_curr_cpu_num();

  // TODO(maniscalco): If/when we support AFF2/AFF3, update the mask below.
  uint aff0 = arch_cpu_num_to_cpu_id(cpu_num);
  uint aff1 = arch_cpu_num_to_cluster_id(cpu_num);
  uint64_t aff_mask = (aff1 << 8) + aff0;

  // Check each SPI to see if it's routed to this CPU.
  for (uint i = 32u; i < gic_max_int; ++i) {
    if ((GICREG64(0, GICD_IROUTER(i)) & aff_mask) != 0) {
      return true;
    }
  }

  return false;
}

static void gic_shutdown_cpu() {
  DEBUG_ASSERT(arch_ints_disabled());

  // If we're running on a secondary CPU there's a good chance this CPU will be powered off shortly
  // (PSCI_CPU_OFF).  Sending an interrupt to a CPU that's been powered off may result in an
  // "erronerous state" (see Power State Coordination Interface (PSCI) System Software on ARM
  // specification, 5.5.2).  So before we shutdown the GIC, make sure we've migrated/disabled any
  // and all peripheral interrupts targeted at this CPU (PPIs and SPIs).
  //
  // Note, we don't perform these checks on the boot CPU because we don't call PSCI_CPU_OFF on the
  // boot CPU, and we likely still have PPIs and SPIs targeting the boot CPU.
  DEBUG_ASSERT(arch_curr_cpu_num() == BOOT_CPU_ID || !is_ppi_enabled());
  DEBUG_ASSERT(arch_curr_cpu_num() == BOOT_CPU_ID || !is_spi_enabled());
  // TODO(maniscalco): If/when we start using LPIs, make sure none are targeted at this CPU.

  // Disable group 1 interrupts at the CPU interface.
  gic_write_igrpen(0);
}

static bool gic_msi_is_supported() { return false; }

static bool gic_msi_supports_masking() { return false; }

static void gic_msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) {
  PANIC_UNIMPLEMENTED;
}

static zx_status_t gic_msi_alloc_block(uint requested_irqs, bool can_target_64bit, bool is_msix,
                                       msi_block_t* out_block) {
  PANIC_UNIMPLEMENTED;
}

static void gic_msi_free_block(msi_block_t* block) { PANIC_UNIMPLEMENTED; }

static void gic_msi_register_handler(const msi_block_t* block, uint msi_id, int_handler handler,
                                     void* ctx) {
  PANIC_UNIMPLEMENTED;
}

static const struct pdev_interrupt_ops gic_ops = {
    .mask = gic_mask_interrupt,
    .unmask = gic_unmask_interrupt,
    .deactivate = gic_deactivate_interrupt,
    .configure = gic_configure_interrupt,
    .get_config = gic_get_interrupt_config,
    .is_valid = gic_is_valid_interrupt,
    .get_base_vector = gic_get_base_vector,
    .get_max_vector = gic_get_max_vector,
    .remap = gic_remap_interrupt,
    .send_ipi = gic_send_ipi,
    .init_percpu_early = gic_init_percpu_early,
    .init_percpu = gic_init_percpu,
    .handle_irq = gic_handle_irq,
    .shutdown = gic_shutdown,
    .shutdown_cpu = gic_shutdown_cpu,
    .msi_is_supported = gic_msi_is_supported,
    .msi_supports_masking = gic_msi_supports_masking,
    .msi_mask_unmask = gic_msi_mask_unmask,
    .msi_alloc_block = gic_msi_alloc_block,
    .msi_free_block = gic_msi_free_block,
    .msi_register_handler = gic_msi_register_handler,
};

void ArmGicInitEarly(const dcfg_arm_gicv3_driver_t& config) {
  ASSERT(config.mmio_phys);

  LTRACE_ENTRY;

  mmio_phys = config.mmio_phys;
  arm_gicv3_gic_base = periph_paddr_to_vaddr(mmio_phys);
  ASSERT(arm_gicv3_gic_base);
  arm_gicv3_gicd_offset = config.gicd_offset;
  arm_gicv3_gicr_offset = config.gicr_offset;
  arm_gicv3_gicr_stride = config.gicr_stride;
  ipi_base = config.ipi_base;

  if (gic_init() != ZX_OK) {
    if (config.optional) {
      // failed to detect gic v3 but it's marked optional. continue
      return;
    }
    printf("GICv3: failed to detect GICv3, interrupts will be broken\n");
    return;
  }

  dprintf(SPEW, "GICv3, IPI base %u\n", ipi_base);

  pdev_register_interrupts(&gic_ops);

  zx_status_t status = gic_register_sgi_handler(MP_IPI_GENERIC + ipi_base, &mp_mbx_generic_irq);
  DEBUG_ASSERT(status == ZX_OK);
  status = gic_register_sgi_handler(MP_IPI_RESCHEDULE + ipi_base, &mp_mbx_reschedule_irq);
  DEBUG_ASSERT(status == ZX_OK);
  status = gic_register_sgi_handler(MP_IPI_INTERRUPT + ipi_base, &mp_mbx_interrupt_irq);
  DEBUG_ASSERT(status == ZX_OK);
  status = gic_register_sgi_handler(MP_IPI_HALT + ipi_base, &arm_ipi_halt_handler);
  DEBUG_ASSERT(status == ZX_OK);

  gicv3_hw_interface_register();

  LTRACE_EXIT;
}

void ArmGicInitLate(const dcfg_arm_gicv3_driver_t& config) {
  ASSERT(mmio_phys);

  arm_gicv3_pcie_init();

  // Place the physical address of the GICv3 registers on the MMIO deny list.
  // Users will not be able to create MMIO resources which permit mapping of the
  // GIC registers, even if they have access to the root resource.
  //
  // Unlike GICv2, only the distributor and re-distributor registers are memory
  // mapped. There is one block of distributor registers for the system, and
  // one block of redistributor registers for each CPU.
  root_resource_filter_add_deny_region(mmio_phys + arm_gicv3_gicd_offset, GICD_REG_SIZE,
                                       ZX_RSRC_KIND_MMIO);
  for (cpu_num_t i = 0; i < arch_max_num_cpus(); i++) {
    root_resource_filter_add_deny_region(
        mmio_phys + arm_gicv3_gicr_offset + (arm_gicv3_gicr_stride * i), GICR_REG_SIZE,
        ZX_RSRC_KIND_MMIO);
  }
}
