// Copyright 2017 The Fuchsia Authors
//
// 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 <pdev/interrupt.h>

#include <err.h>
#include <kernel/auto_lock.h>
#include <kernel/spinlock.h>
#include <lk/init.h>
#include <zircon/types.h>

#define ARM_MAX_INT 1024

static SpinLock lock;
static struct int_handler_struct int_handler_table[ARM_MAX_INT];

struct int_handler_struct* pdev_get_int_handler(unsigned int vector) {
    DEBUG_ASSERT(vector < ARM_MAX_INT);
    return &int_handler_table[vector];
}

zx_status_t register_int_handler(unsigned int vector, int_handler handler, void* arg) {
    if (!is_valid_interrupt(vector, 0)) {
        return ZX_ERR_INVALID_ARGS;
    }

    AutoSpinLock guard(&lock);

    auto h = pdev_get_int_handler(vector);
    if (handler && h->handler) {
        return ZX_ERR_ALREADY_BOUND;
    }
    h->handler = handler;
    h->arg = arg;

    return ZX_OK;
}

static zx_status_t default_mask(unsigned int vector) {
    return ZX_ERR_NOT_CONFIGURED;
}

static zx_status_t default_unmask(unsigned int vector) {
    return ZX_ERR_NOT_CONFIGURED;
}

static zx_status_t default_configure(unsigned int vector,
                                     enum interrupt_trigger_mode tm,
                                     enum interrupt_polarity pol) {
    return ZX_ERR_NOT_CONFIGURED;
}

static zx_status_t default_get_config(unsigned int vector,
                                      enum interrupt_trigger_mode* tm,
                                      enum interrupt_polarity* pol) {
    return ZX_ERR_NOT_CONFIGURED;
}

static bool default_is_valid(unsigned int vector, uint32_t flags) {
    return false;
}
static unsigned int default_remap(unsigned int vector) {
    return 0;
}

static zx_status_t default_send_ipi(cpu_mask_t target, mp_ipi_t ipi) {
    return ZX_ERR_NOT_CONFIGURED;
}

static void default_init_percpu_early() {
}

static void default_init_percpu() {
}

static void default_handle_irq(iframe* frame) {
}

static void default_handle_fiq(iframe* frame) {
}

static void default_shutdown() {
}

static void default_shutdown_cpu() {
}

static bool default_msi_is_supported() {
    return false;
}

static bool default_msi_supports_masking() {
    return false;
}

static zx_status_t default_msi_alloc_block(uint requested_irqs, bool can_target_64bit,
                                           bool is_msix, msi_block_t* out_block) {
    return ZX_ERR_NOT_CONFIGURED;
}

static void default_msi_free_block(msi_block_t* block) {
}

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

static void default_msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) {
}

static uint32_t default_get_base_vector() {
    return 0;
}

static uint32_t default_get_max_vector() {
    return 0;
}

// by default, most interrupt operations for pdev/arm are implemented in the gic specific source
// files and accessed via configuring this pointer table at runtime. By default most of these
// are merely empty stubs.
static const struct pdev_interrupt_ops default_ops = {
    .mask = default_mask,
    .unmask = default_unmask,
    .configure = default_configure,
    .get_config = default_get_config,
    .is_valid = default_is_valid,
    .get_base_vector = default_get_base_vector,
    .get_max_vector = default_get_max_vector,
    .remap = default_remap,
    .send_ipi = default_send_ipi,
    .init_percpu_early = default_init_percpu_early,
    .init_percpu = default_init_percpu,
    .handle_irq = default_handle_irq,
    .handle_fiq = default_handle_fiq,
    .shutdown = default_shutdown,
    .shutdown_cpu = default_shutdown_cpu,
    .msi_is_supported = default_msi_is_supported,
    .msi_supports_masking = default_msi_supports_masking,
    .msi_mask_unmask = default_msi_mask_unmask,
    .msi_alloc_block = default_msi_alloc_block,
    .msi_free_block = default_msi_free_block,
    .msi_register_handler = default_msi_register_handler,
};

static const struct pdev_interrupt_ops* intr_ops = &default_ops;

zx_status_t mask_interrupt(unsigned int vector) {
    return intr_ops->mask(vector);
}

zx_status_t unmask_interrupt(unsigned int vector) {
    return intr_ops->unmask(vector);
}

zx_status_t configure_interrupt(unsigned int vector, enum interrupt_trigger_mode tm,
                                enum interrupt_polarity pol) {
    return intr_ops->configure(vector, tm, pol);
}

zx_status_t get_interrupt_config(unsigned int vector, enum interrupt_trigger_mode* tm,
                                 enum interrupt_polarity* pol) {
    return intr_ops->get_config(vector, tm, pol);
}

uint32_t interrupt_get_base_vector() {
    return intr_ops->get_base_vector();
}

uint32_t interrupt_get_max_vector() {
    return intr_ops->get_max_vector();
}

bool is_valid_interrupt(unsigned int vector, uint32_t flags) {
    return intr_ops->is_valid(vector, flags);
}

unsigned int remap_interrupt(unsigned int vector) {
    return intr_ops->remap(vector);
}

zx_status_t interrupt_send_ipi(cpu_mask_t target, mp_ipi_t ipi) {
    return intr_ops->send_ipi(target, ipi);
}

void interrupt_init_percpu() {
    intr_ops->init_percpu();
}

void platform_irq(iframe* frame) {
    intr_ops->handle_irq(frame);
}

void platform_fiq(iframe* frame) {
    intr_ops->handle_fiq(frame);
}

void pdev_register_interrupts(const struct pdev_interrupt_ops* ops) {
    intr_ops = ops;
    smp_mb();
}

static void interrupt_init_percpu_early(uint level) {
    intr_ops->init_percpu_early();
}

void shutdown_interrupts() {
    intr_ops->shutdown();
}

void shutdown_interrupts_curr_cpu() {
    intr_ops->shutdown_cpu();
}

bool msi_is_supported() {
    return intr_ops->msi_is_supported();
}

bool msi_supports_masking() {
    return intr_ops->msi_supports_masking();
}

void msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) {
    intr_ops->msi_mask_unmask(block, msi_id, mask);
}

zx_status_t msi_alloc_block(uint requested_irqs, bool can_target_64bit,
                            bool is_msix, msi_block_t* out_block) {
    return intr_ops->msi_alloc_block(requested_irqs, can_target_64bit, is_msix, out_block);
}

void msi_free_block(msi_block_t* block) {
    intr_ops->msi_free_block(block);
}

void msi_register_handler(const msi_block_t* block, uint msi_id, int_handler handler, void* ctx) {
    intr_ops->msi_register_handler(block, msi_id, handler, ctx);
}

LK_INIT_HOOK_FLAGS(interrupt_init_percpu_early, interrupt_init_percpu_early, LK_INIT_LEVEL_PLATFORM_EARLY, LK_INIT_FLAG_SECONDARY_CPUS);
