// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
// Copyright (c) 2015 Intel Corporation
//
// 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 <debug.h>
#include <lib/acpi_lite/apic.h>
#include <lib/acpi_lite/structures.h>
#include <sys/types.h>
#include <trace.h>
#include <zircon/types.h>

#include <arch/regs.h>
#include <arch/x86.h>
#include <arch/x86/feature.h>
#include <arch/x86/platform_access.h>
#include <arch/x86/pv.h>
#include <dev/interrupt.h>
#include <fbl/algorithm.h>
#include <kernel/stats.h>
#include <kernel/thread.h>
#include <ktl/optional.h>
#include <lk/init.h>
#include <object/resource_dispatcher.h>
#include <platform/pc.h>
#include <platform/pc/acpi.h>
#include <platform/pic.h>

#include "interrupt_manager.h"
#include "platform_p.h"

#include <ktl/enforce.h>

namespace {

// Values from ioapic to cache for calls to interrupt_get_base_vector / interrupt_get_max_vector
ktl::optional<GsiRange> x64_gsis;

// Interface passed to InterruptManager to construct the real system interrupt
// manager.
class IoApic {
 public:
  static bool IsValidInterrupt(unsigned int vector, uint32_t flags) {
    return is_valid_interrupt(vector, flags);
  }
  static uint8_t FetchIrqVector(unsigned int vector) { return apic_io_fetch_irq_vector(vector); }
  static void ConfigureIrqVector(uint32_t global_irq, uint8_t x86_vector) {
    apic_io_configure_irq_vector(global_irq, x86_vector);
  }
  static void ConfigureIrq(uint32_t global_irq, enum interrupt_trigger_mode trig_mode,
                           enum interrupt_polarity polarity,
                           enum apic_interrupt_delivery_mode del_mode, bool mask,
                           enum apic_interrupt_dst_mode dst_mode, uint8_t dst, uint8_t vector) {
    apic_io_configure_irq(global_irq, trig_mode, polarity, del_mode, mask, dst_mode, dst, vector);
  }
  static void MaskIrq(uint32_t global_irq, bool mask) { apic_io_mask_irq(global_irq, mask); }
  static zx_status_t FetchIrqConfig(uint32_t global_irq, enum interrupt_trigger_mode* trig_mode,
                                    enum interrupt_polarity* polarity) {
    return apic_io_fetch_irq_config(global_irq, trig_mode, polarity);
  }
};

// Singleton for managing interrupts.  This is fully initialized in
// platform_init_apic().
InterruptManager<IoApic> kInterruptManager;

// Convert an ACPI entry into the format required by the platform's APIC code.
io_apic_isa_override ParseIsaOverride(const acpi_lite::AcpiMadtIntSourceOverrideEntry* record) {
  // 0 means ISA, ISOs are only ever for ISA IRQs
  if (record->bus != 0) {
    panic("Invalid bus for IO APIC interrupt override.\n");
  }

  // "Conforms" below means conforms to the bus spec: edge triggered and active high.
  const uint32_t flags = record->flags;
  const interrupt_polarity polarity = [flags]() {
    uint32_t polarity = flags & ACPI_MADT_FLAG_POLARITY_MASK;
    switch (polarity) {
      case ACPI_MADT_FLAG_POLARITY_CONFORMS:
      case ACPI_MADT_FLAG_POLARITY_HIGH:
        return IRQ_POLARITY_ACTIVE_HIGH;
      case ACPI_MADT_FLAG_POLARITY_LOW:
        return IRQ_POLARITY_ACTIVE_LOW;
      default:
        panic("Unknown IRQ polarity in override: %u\n", polarity);
    }
  }();

  const interrupt_trigger_mode trigger_mode = [flags]() {
    uint32_t trigger = flags & ACPI_MADT_FLAG_TRIGGER_MASK;
    switch (trigger) {
      case ACPI_MADT_FLAG_TRIGGER_CONFORMS:
      case ACPI_MADT_FLAG_TRIGGER_EDGE:
        return IRQ_TRIGGER_MODE_EDGE;
        break;
      case ACPI_MADT_FLAG_TRIGGER_LEVEL:
        return IRQ_TRIGGER_MODE_LEVEL;
      default:
        panic("Unknown IRQ trigger in override: %u\n", trigger);
    }
  }();

  return io_apic_isa_override{
      .isa_irq = record->source,
      .remapped = true,
      .tm = trigger_mode,
      .pol = polarity,
      .global_irq = record->global_sys_interrupt,
  };
}

}  // namespace

static void platform_init_apic(uint level) {
  pic_map(PIC1_BASE, PIC2_BASE);
  pic_disable();

  acpi_lite::AcpiParser& parser = GlobalAcpiLiteParser();

  // Enumerate the IO APICs
  fbl::Vector<io_apic_descriptor> descriptors;
  zx_status_t status = acpi_lite::EnumerateIoApics(
      parser, [&descriptors](const acpi_lite::AcpiMadtIoApicEntry& descriptor) {
        fbl::AllocChecker ac;
        descriptors.push_back(
            io_apic_descriptor{
                .apic_id = descriptor.io_apic_id,
                .global_irq_base = descriptor.global_system_interrupt_base,
                .paddr = descriptor.io_apic_address,
            },
            &ac);
        return ac.check() ? ZX_OK : ZX_ERR_NO_MEMORY;
      });
  if (status != ZX_OK) {
    panic("Could not get IO APIC details: %d\n", status);
  }

  // Enumerate interrupt source overrides.
  fbl::Vector<io_apic_isa_override> overrides;
  status = acpi_lite::EnumerateIoApicIsaOverrides(
      parser, [&overrides](const acpi_lite::AcpiMadtIntSourceOverrideEntry& isa_override) {
        fbl::AllocChecker ac;
        overrides.push_back(ParseIsaOverride(&isa_override), &ac);
        return ac.check() ? ZX_OK : ZX_ERR_NO_MEMORY;
      });
  if (status != ZX_OK) {
    panic("Could not get interrupt source overrides: %d\n", status);
  }

  apic_vm_init();
  apic_local_init();
  apic_io_init(descriptors.data(), descriptors.size(), overrides.data(), overrides.size());
  x64_gsis = apic_io_get_gsi_range();

  ASSERT(arch_ints_disabled());

  // Initialize the delivery modes/targets for the ISA interrupts
  uint8_t bsp_apic_id = apic_bsp_id();
  for (uint8_t irq = 0; irq < 8; ++irq) {
    // Explicitly skip mapping the PIC2 interrupt, since it is actually
    // just used internally on the PICs for daisy chaining.  QEMU remaps
    // ISA IRQ 0 to global IRQ 2, but does not remap ISA IRQ 2 off of
    // global IRQ 2, so skipping this mapping also prevents a collision
    // with the PIT IRQ.
    if (irq != ISA_IRQ_PIC2) {
      apic_io_configure_isa_irq(irq, DELIVERY_MODE_FIXED, IO_APIC_IRQ_MASK, DST_MODE_PHYSICAL,
                                bsp_apic_id, 0);
    }
    apic_io_configure_isa_irq(static_cast<uint8_t>(irq + 8), DELIVERY_MODE_FIXED, IO_APIC_IRQ_MASK,
                              DST_MODE_PHYSICAL, bsp_apic_id, 0);
  }

  status = kInterruptManager.Init();
  ResourceDispatcher::InitializeAllocator(ZX_RSRC_KIND_IRQ, interrupt_get_base_vector(),
                                          interrupt_get_max_vector());
  ASSERT(status == ZX_OK);
}
LK_INIT_HOOK(apic, &platform_init_apic, LK_INIT_LEVEL_VM + 2)

zx_status_t mask_interrupt(unsigned int vector) { return kInterruptManager.MaskInterrupt(vector); }

zx_status_t unmask_interrupt(unsigned int vector) {
  return kInterruptManager.UnmaskInterrupt(vector);
}

zx_status_t configure_interrupt(unsigned int vector, enum interrupt_trigger_mode tm,
                                enum interrupt_polarity pol) {
  return kInterruptManager.ConfigureInterrupt(vector, tm, pol);
}

zx_status_t get_interrupt_config(unsigned int vector, enum interrupt_trigger_mode* tm,
                                 enum interrupt_polarity* pol) {
  return kInterruptManager.GetInterruptConfig(vector, tm, pol);
}

void platform_irq(iframe_t* frame) {
  CPU_STATS_INC(interrupts);
  // get the current vector
  uint64_t x86_vector = frame->vector;
  DEBUG_ASSERT(x86_vector >= X86_INT_PLATFORM_BASE && x86_vector <= X86_INT_PLATFORM_MAX);

  // deliver the interrupt
  kInterruptManager.InvokeX86Vector(static_cast<uint8_t>(x86_vector));

  // NOTE: On x86, we always deactivate the interrupt.
  apic_issue_eoi();
}

zx_status_t register_int_handler(unsigned int vector, int_handler handler, void* arg) {
  return kInterruptManager.RegisterInterruptHandler(vector, handler, arg);
}

zx_status_t register_permanent_int_handler(unsigned int vector, int_handler handler, void* arg) {
  return kInterruptManager.RegisterInterruptHandler(vector, handler, arg, true /* Permanent */);
}

// On x64 these methods return the base and max Global System Interrupts as
// defined by ACPI and described by MADT tables.
// ACPI Spec 6.1, section 5.2.12 & section 5.2.13.
uint32_t interrupt_get_base_vector(void) {
  ZX_DEBUG_ASSERT(x64_gsis.has_value());
  return x64_gsis.value().start;
}
uint32_t interrupt_get_max_vector(void) {
  ZX_DEBUG_ASSERT(x64_gsis.has_value());
  return x64_gsis.value().end;
}

bool is_valid_interrupt(unsigned int vector, uint32_t flags) {
  return apic_io_is_valid_irq(vector);
}

unsigned int remap_interrupt(unsigned int vector) {
  if (vector > NUM_ISA_IRQS) {
    return vector;
  }
  return apic_io_isa_to_global(static_cast<uint8_t>(vector));
}

void shutdown_interrupts(void) { pic_disable(); }

void shutdown_interrupts_curr_cpu(void) {
  if (x86_hypervisor_has_pv_eoi()) {
    MsrAccess msr;
    PvEoi::get()->Disable(&msr);
  }

  // TODO(maniscalco): Walk interrupt redirection entries and make sure nothing targets this CPU.
}

// Intel 64 socs support the IOAPIC and Local APIC which support MSI by default.
// See 10.1, 10.4, and 10.11 of Intel® 64 and IA-32 Architectures Software Developer’s
// Manual 3A
bool msi_is_supported(void) { return true; }
bool msi_supports_masking() { return false; }
// Since we do not support masking on x64 it is an error to call |msi_mask_unmask|.
void msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) { PANIC_UNIMPLEMENTED; }

zx_status_t msi_alloc_block(uint requested_irqs, bool can_target_64bit, bool is_msix,
                            msi_block_t* out_block) {
  return kInterruptManager.MsiAllocBlock(requested_irqs, can_target_64bit, is_msix, out_block);
}

void msi_free_block(msi_block_t* block) { return kInterruptManager.MsiFreeBlock(block); }

void msi_register_handler(const msi_block_t* block, uint msi_id, int_handler handler, void* ctx) {
  return kInterruptManager.MsiRegisterHandler(block, msi_id, handler, ctx);
}
