/*
 * Copyright 2019, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#include <assert.h>
#include <stdbool.h>

#include <platsupport/fdt.h>

#include "irqchip.h"

/* Force the _allocated_irqs section to be created even if no modules are defined. */
static USED SECTION("_ps_irqchips") struct {} dummy_ps_irqchips;
/* Definitions so that we can find the exposed IRQ information */
extern ps_irqchip_t *__start__ps_irqchips[];
extern ps_irqchip_t *__stop__ps_irqchips[];

/* Private internal struct */
struct ps_fdt_cookie {
    int node_offset;
};

/* Used for the ps_fdt_index_* helper functions */

typedef struct index_helper_token {
    ps_io_ops_t *io_ops;
    unsigned desired_offset;
    /* These are used for the 'register index' helper */
    void *mapped_addr;
    pmem_region_t region;
    /* These are used for the 'IRQ index' helper */
    irq_id_t irq_id;
    irq_callback_fn_t irq_callback;
    void *irq_callback_data;
} index_helper_token_t;

int ps_fdt_read_path(ps_io_fdt_t *io_fdt, ps_malloc_ops_t *malloc_ops, const char *path, ps_fdt_cookie_t **ret_cookie)
{
    if (!path || !ret_cookie) {
        return -EINVAL;
    }

    int error = ps_calloc(malloc_ops, 1, sizeof(**ret_cookie), (void **) ret_cookie);
    if (error) {
        return -ENOMEM;
    }

    char *dtb_blob = ps_io_fdt_get(io_fdt);
    if (!dtb_blob) {
        ZF_LOGF_IF(ps_fdt_cleanup_cookie(malloc_ops, *ret_cookie), "Failed to cleanup FDT cookie");
        return -EINVAL;
    }

    int node_offset = fdt_path_offset(dtb_blob, path);
    if (node_offset < 0) {
        ZF_LOGF_IF(ps_fdt_cleanup_cookie(malloc_ops, *ret_cookie), "Failed to cleanup FDT cookie");
        return node_offset;
    }

    (*ret_cookie)->node_offset = node_offset;

    return 0;
}

int ps_fdt_cleanup_cookie(ps_malloc_ops_t *malloc_ops, ps_fdt_cookie_t *cookie)
{
    if (!malloc_ops || !cookie) {
        return -EINVAL;
    }

    return ps_free(malloc_ops, sizeof(*cookie), cookie);
}

int ps_fdt_walk_registers(ps_io_fdt_t *io_fdt, ps_fdt_cookie_t *cookie, reg_walk_cb_fn_t callback, void *token)
{
    if (!io_fdt || !callback || !cookie) {
        return -EINVAL;
    }

    char *dtb_blob = ps_io_fdt_get(io_fdt);
    if (!dtb_blob) {
        return -EINVAL;
    }

    int node_offset = cookie->node_offset;

    /* NOTE: apparently fdt_parent_offset is expensive to use,
     * maybe manipulate the path to get the parent's node path instead? */
    int parent_offset = fdt_parent_offset(dtb_blob, node_offset);
    if (parent_offset < 0) {
        return parent_offset;
    }

    /* get the number of address and size cells */
    int num_address_cells = fdt_address_cells(dtb_blob, parent_offset);
    if (num_address_cells < 0) {
        return num_address_cells;
    }
    int num_size_cells = fdt_size_cells(dtb_blob, parent_offset);
    if (num_size_cells < 0) {
        return num_size_cells;
    }

    if (num_address_cells == 0 || num_size_cells == 0) {
        /* this isn't really a standard device, so we just return */
        return -FDT_ERR_NOTFOUND;
    }

    int prop_len = 0;
    const void *reg_prop = fdt_getprop(dtb_blob, node_offset, "reg", &prop_len);
    if (!reg_prop) {
        /* The error is written to the variable passed in */
        return prop_len;
    }
    int total_cells = prop_len / sizeof(uint32_t);

    /* sanity check */
    assert(total_cells % (num_address_cells + num_size_cells) == 0);

    int stride = num_address_cells + num_size_cells;
    int num_regs = total_cells / stride;

    for (int i = 0; i < num_regs; i++) {
        pmem_region_t curr_pmem = {0};
        const void *curr = reg_prop + (i * stride * sizeof(uint32_t));
        curr_pmem.type = PMEM_TYPE_DEVICE;
        curr_pmem.base_addr = READ_CELL(num_address_cells, curr, 0);
        curr_pmem.length = READ_CELL(num_size_cells, curr, num_address_cells);
        int error = callback(curr_pmem, i, num_regs, token);
        if (error) {
            return error;
        }
    }

    return 0;
}

static inline ps_irqchip_t **find_compatible_irq_controller(char *dtb_blob, int intr_controller_offset)
{
    for (ps_irqchip_t **irqchip = __start__ps_irqchips; irqchip < __stop__ps_irqchips; irqchip++) {
        for (char **compatible_str = (*irqchip)->compatible_list; *compatible_str != NULL; compatible_str++) {
            if (fdt_node_check_compatible(dtb_blob, intr_controller_offset, *compatible_str) == 0) {
                return irqchip;
            }
        }
    }

    return NULL;
}

int ps_fdt_walk_irqs(ps_io_fdt_t *io_fdt, ps_fdt_cookie_t *cookie, irq_walk_cb_fn_t callback, void *token)
{
    if (!io_fdt || !callback || !cookie) {
        return -EINVAL;
    }

    char *dtb_blob = ps_io_fdt_get(io_fdt);
    if (!dtb_blob) {
        return -EINVAL;
    }

    int node_offset = cookie->node_offset;

    /* check that this node actually has interrupts */
    const void *intr_addr = fdt_getprop(dtb_blob, node_offset, "interrupts", NULL);
    if (!intr_addr) {
        intr_addr = fdt_getprop(dtb_blob, node_offset, "interrupts-extended", NULL);
        if (!intr_addr) {
            return -FDT_ERR_NOTFOUND;
        }
    }

    /* get the interrupt controller of the node */
    int curr_offset = node_offset;
    bool found_controller = false;
    const void *intr_parent_prop;
    while (curr_offset >= 0 && !found_controller) {
        intr_parent_prop = fdt_getprop(dtb_blob, curr_offset, "interrupt-parent", NULL);
        if (!intr_parent_prop) {
            /* move up a level
             * NOTE: fdt_parent_offset is apparently expensive to use,
             * maybe avoid using fdt_parent_offset and manipulate the path instead? */
            curr_offset = fdt_parent_offset(dtb_blob, curr_offset);
        } else {
            found_controller = true;
        }
    }

    if (!found_controller) {
        /* something is really wrong with the FDT */
        return -FDT_ERR_BADSTRUCTURE;
    }

    /* check if this controller is just a interrupt forwarder/not the root interrupt controller,
     * and if it is, find the root controller
     */
    bool is_root_controller = false;
    int root_intr_controller_offset = 0;
    uint32_t root_intr_controller_phandle = 0;
    while (!is_root_controller) {
        uint32_t intr_controller_phandle = READ_CELL(1, intr_parent_prop, 0);
        ZF_LOGF_IF(intr_controller_phandle == 0,
                   "Failed to get the phandle of the interrupt controller of this node");
        int intr_controller_offset = fdt_node_offset_by_phandle(dtb_blob, intr_controller_phandle);
        ZF_LOGF_IF(intr_controller_offset < 0, "Failed to get the offset of the interrupt controller");
        intr_parent_prop = fdt_getprop(dtb_blob, intr_controller_offset, "interrupt-parent", NULL);

        /* The root interrupt controller node has one of two characteristics:
         *      1. It has a 'interrupt-parent' property that points back to itself
         *      2. It has no 'interrupt-parent' property
         */
        if (intr_parent_prop && intr_controller_phandle == READ_CELL(1, intr_parent_prop, 0)) {
            is_root_controller = true;
        } else if (!intr_parent_prop) {
            is_root_controller = true;
        }

        if (is_root_controller) {
            root_intr_controller_offset = intr_controller_offset;
            root_intr_controller_phandle = intr_controller_phandle;
        }
    }

    /* check the compatible string against our list of support interrupt controllers */
    ps_irqchip_t **irqchip = find_compatible_irq_controller(dtb_blob, root_intr_controller_offset);
    if (irqchip == NULL) {
        ZF_LOGE("Could not find a parser for this particular interrupt controller");
        return -ENOENT;
    }

    /* delegate to the interrupt controller specific code */
    int error = (*irqchip)->parser_fn(dtb_blob, node_offset, root_intr_controller_phandle, callback, token);
    if (error) {
        ZF_LOGE("Failed to parse and walk the interrupt field");
        return error;
    }

    return 0;
}

static int register_index_helper_walker(pmem_region_t pmem, unsigned curr_num, size_t num_regs, void *token)
{
    index_helper_token_t *helper_token = token;
    if (helper_token->desired_offset >= num_regs) {
        /* Bail early if we will never find it */
        return -ENOENT;
    }

    if (helper_token->desired_offset == curr_num) {
        void *ret_addr = ps_pmem_map(helper_token->io_ops, pmem, false, PS_MEM_NORMAL);
        if (ret_addr == NULL) {
            return -ENOMEM;
        } else {
            helper_token->mapped_addr = ret_addr;
            helper_token->region = pmem;
        }
    }

    return 0;
}

void *ps_fdt_index_map_register(ps_io_ops_t *io_ops, ps_fdt_cookie_t *cookie, unsigned offset,
                                pmem_region_t *ret_pmem)
{
    if (io_ops == NULL) {
        ZF_LOGE("io_ops is NULL!");
        return NULL;
    }

    if (cookie == NULL) {
        ZF_LOGE("cookie is NULL");
        return NULL;
    }

    index_helper_token_t token = { .io_ops = io_ops, .desired_offset = offset };

    int error = ps_fdt_walk_registers(&io_ops->io_fdt, cookie, register_index_helper_walker,
                                      &token);
    if (error) {
        return NULL;
    }

    if (ret_pmem) {
        *ret_pmem = token.region;
    }

    return token.mapped_addr;
}

static int irq_index_helper_walker(ps_irq_t irq, unsigned curr_num, size_t num_irqs, void *token)
{
    index_helper_token_t *helper_token = token;
    if (helper_token->desired_offset >= num_irqs) {
        /* Bail early if we will never find it */
        return -ENOENT;
    }

    if (helper_token->desired_offset == curr_num) {
        irq_id_t registered_id = ps_irq_register(&helper_token->io_ops->irq_ops,
                                                 irq, helper_token->irq_callback,
                                                 helper_token->irq_callback_data);
        if (registered_id >= 0) {
            helper_token->irq_id = registered_id;
        } else {
            /* Bail on error */
            return registered_id;
        }
    }

    return 0;
}

irq_id_t ps_fdt_index_register_irq(ps_io_ops_t *io_ops, ps_fdt_cookie_t *cookie, unsigned offset,
                                   irq_callback_fn_t irq_callback, void *irq_callback_data)
{
    if (io_ops == NULL) {
        ZF_LOGE("io_ops is NULL!");
        return -EINVAL;
    }

    if (cookie == NULL) {
        ZF_LOGE("cookie is NULL");
        return -EINVAL;
    }

    index_helper_token_t token = { .io_ops = io_ops, .desired_offset = offset,
                                   .irq_callback = irq_callback,
                                   .irq_callback_data = irq_callback_data
                                 };

    int error = ps_fdt_walk_irqs(&io_ops->io_fdt, cookie, irq_index_helper_walker, &token);
    if (error) {
        assert(error <= PS_INVALID_IRQ_ID);
        return error;
    }

    return token.irq_id;
}
