// 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/pc/memory.h>
#include <platform/pc/pic.h>

#include "interrupt_manager.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 interrupt_polarity::HIGH;
      case ACPI_MADT_FLAG_POLARITY_LOW:
        return interrupt_polarity::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 interrupt_trigger_mode::EDGE;
        break;
      case ACPI_MADT_FLAG_TRIGGER_LEVEL:
        return interrupt_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, interrupt_handler_t handler) {
  return kInterruptManager.RegisterInterruptHandler(vector, ktl::move(handler));
}

zx_status_t register_permanent_int_handler(unsigned int vector, interrupt_handler_t handler) {
  return kInterruptManager.RegisterInterruptHandler(vector, ktl::move(handler),
                                                    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.
}

zx_status_t suspend_interrupts_curr_cpu() { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t resume_interrupts_curr_cpu() { return ZX_ERR_NOT_SUPPORTED; }

// 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) { kInterruptManager.MsiFreeBlock(block); }

void msi_register_handler(const msi_block_t* block, uint msi_id, interrupt_handler_t handler) {
  kInterruptManager.MsiRegisterHandler(block, msi_id, ktl::move(handler));
}
