// 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 <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 <fbl/algorithm.h>
#include <kernel/stats.h>
#include <kernel/thread.h>
#include <lk/init.h>
#include <platform/pc.h>
#include <platform/pc/acpi.h>
#include <platform/pic.h>

#include "dev/interrupt.h"
#include "interrupt_manager.h"
#include "lib/acpi_lite/apic.h"
#include "lib/acpi_lite/structures.h"
#include "platform_p.h"

namespace {

// 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());

  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();
  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 */);
}

uint32_t interrupt_get_base_vector(void) {
  // Intel Software Developer's Manual v3 chapter 6.2
  // Vectors 0-31 are reserved for architecture defined interrupts & exceptions.
  // Of that, 16-31 can be allocated to the PCI bus by ACPI and are valid for
  // interrupt objects.
  return 16;
}

uint32_t interrupt_get_max_vector(void) {
  // x64 APIC supports 256 total vectors
  return 255;
}

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