/*
 * 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 <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#include <errno.h>

#include <sel4/sel4.h>
#include <sel4platsupport/irq.h>
#include <sel4platsupport/device.h>
#include <platsupport/irq.h>
#include <platsupport/io.h>
#include <simple/simple.h>
#include <utils/util.h>
#include <vka/vka.h>
#include <vka/capops.h>

#define UNPAIRED_ID -1
#define UNALLOCATED_BADGE_INDEX -1

typedef enum irq_iface_type {
    STANDARD_IFACE,
    MINI_IFACE
} irq_iface_type_t;

typedef struct {
    /* These are always non-empty if this particular IRQ ID is in use */
    bool allocated;
    ps_irq_t irq;
    cspacepath_t handler_path;

    /* These are not always non-empty if this particular IRQ ID is in use */

    /* Driver registers these */
    irq_callback_fn_t irq_callback_fn;
    void *callback_data;

    /* User registers these */
    cspacepath_t ntfn_path;
    ntfn_id_t paired_ntfn;
    int8_t allocated_badge_index;
} irq_entry_t;

typedef struct {
    bool allocated;
    cspacepath_t root_ntfn_path;
    size_t num_irqs_bound;

    seL4_Word usable_mask;
    /* Bitfield tracking which of the bits in the badge are allocated */
    seL4_Word status_bitfield;
    /* Bitfield tracking which IRQs have arrived but not served */
    seL4_Word pending_bitfield;

    irq_id_t bound_irqs[MAX_INTERRUPTS_TO_NOTIFICATIONS];
} ntfn_entry_t;

typedef struct {
    irq_iface_type_t iface_type;
    size_t num_registered_irqs;
    size_t num_allocated_ntfns;

    size_t max_irq_ids;
    size_t max_ntfn_ids;
    size_t num_irq_bitfields;
    size_t num_ntfn_bitfields;
    /* Array of bitfields tracking which IDs have been allocated */
    seL4_Word *allocated_irq_bitfields;
    seL4_Word *allocated_ntfn_bitfields;

    irq_entry_t *irq_table;
    ntfn_entry_t *ntfn_table;
    simple_t *simple;
    vka_t *vka;
    ps_malloc_ops_t *malloc_ops;
} irq_cookie_t;

typedef struct {
    irq_cookie_t *irq_cookie;
    irq_id_t irq_id;
} ack_data_t;

static inline bool check_irq_id_is_valid(irq_cookie_t *irq_cookie, irq_id_t id)
{
    if (unlikely(id < 0 || id >= irq_cookie->max_irq_ids)) {
        return false;
    }
    return true;
}

static inline bool check_ntfn_id_is_valid(irq_cookie_t *irq_cookie, ntfn_id_t id)
{
    if (unlikely(id < 0 || id >= irq_cookie->max_ntfn_ids)) {
        return false;
    }
    return true;
}

static inline bool check_irq_id_all_allocated(irq_cookie_t *irq_cookie)
{
    if (unlikely(irq_cookie->num_registered_irqs >= irq_cookie->max_irq_ids)) {
        return true;
    }
    return false;
}

static inline bool check_ntfn_id_all_allocated(irq_cookie_t *irq_cookie)
{
    if (unlikely(irq_cookie->num_allocated_ntfns >= irq_cookie->max_ntfn_ids)) {
        return true;
    }
    return false;
}

static inline bool check_ntfn_id_is_allocated(irq_cookie_t *irq_cookie, ntfn_id_t id)
{
    if (likely(irq_cookie->ntfn_table[id].allocated)) {
        return true;
    }
    return false;
}

static inline bool check_irq_id_is_allocated(irq_cookie_t *irq_cookie, irq_id_t id)
{
    if (likely(irq_cookie->irq_table[id].allocated)) {
        return true;
    }
    return false;
}

static inline void fill_bit_in_bitfield(seL4_Word *bitfield_array, int index)
{
    int bitfield_index = index % (sizeof(seL4_Word) * CHAR_BIT);
    int array_index  = index / (sizeof(seL4_Word) * CHAR_BIT);
    bitfield_array[array_index] |= BIT(bitfield_index);
}

static inline void unfill_bit_in_bitfield(seL4_Word *bitfield_array, int index)
{
    int bitfield_index = index % (sizeof(seL4_Word) * CHAR_BIT);
    int array_index  = index / (sizeof(seL4_Word) * CHAR_BIT);
    bitfield_array[array_index] &= ~(BIT(bitfield_index));
}

static irq_id_t find_free_irq_id(irq_cookie_t *irq_cookie)
{
    for (int i = 0; i < irq_cookie->num_irq_bitfields; i++) {
        unsigned long unallocated_bitfield = ~(irq_cookie->allocated_irq_bitfields[i]);
        if (i == irq_cookie->num_irq_bitfields - 1) {
            /* Hide the bits that cannot be allocated, i.e. max_irq_ids is
             * not a multiple of sizeof(seL4_Word) */
            unsigned long num_leftover_bits = irq_cookie->num_irq_bitfields * sizeof(seL4_Word) -
                                              irq_cookie->max_irq_ids;
            unsigned long mask = MASK(num_leftover_bits);
            /* Reverse the mask, (bit 0 is the smallest ID of that bitfield) */
            mask = BSWAP_WORD(mask);

            unallocated_bitfield &= mask;
        }
        /* Check to avoid undefined behaviour of CTZL(0) */
        if (likely(unallocated_bitfield)) {
            return CTZL(unallocated_bitfield) + (i * sizeof(seL4_Word) * CHAR_BIT);
        }
    }
    return -1;
}

static ntfn_id_t find_free_ntfn_id(irq_cookie_t *irq_cookie)
{
    for (int i = 0; i < irq_cookie->num_ntfn_bitfields; i++) {
        unsigned long unallocated_bitfield = ~(irq_cookie->allocated_ntfn_bitfields[i]);
        if (i == irq_cookie->num_irq_bitfields - 1) {
            /* Hide the bits that cannot be allocated, i.e. max_irq_ids is
             * not a multiple of sizeof(seL4_Word) */
            unsigned long num_leftover_bits = irq_cookie->num_ntfn_bitfields * sizeof(seL4_Word) -
                                              irq_cookie->max_ntfn_ids;
            unsigned long mask = MASK(num_leftover_bits);
            /* Reverse the mask, (bit 0 is the smallest ID of that bitfield) */
            mask = BSWAP_WORD(mask);

            unallocated_bitfield &= mask;
        }
        /* Check to avoid undefined behaviour of CTZL(0) */
        if (likely(unallocated_bitfield)) {
            return CTZL(unallocated_bitfield) + (i * sizeof(seL4_Word) * CHAR_BIT);
        }
    }
    return -1;
}

static int find_free_ntfn_badge_index(ntfn_entry_t *ntfn_entry)
{
    unsigned long unallocated_bitfield = ~(ntfn_entry->status_bitfield);
    /* Mask the bits that we can use */
    unallocated_bitfield &= ntfn_entry->usable_mask;
    /* Check to avoid undefined behaviour of CTZL(0) */
    if (unlikely(!unallocated_bitfield)) {
        return -1;
    }
    return CTZL(unallocated_bitfield);
}

static int irq_set_ntfn_common(irq_cookie_t *irq_cookie, ntfn_id_t ntfn_id, irq_id_t irq_id,
                               seL4_Word *ret_badge)
{
    irq_entry_t *irq_entry = &(irq_cookie->irq_table[irq_id]);

    /* Check if the IRQ is already bound to something */
    if (irq_entry->paired_ntfn > UNPAIRED_ID) {
        return -EINVAL;
    }

    ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[ntfn_id]);

    /* Check if we have space to bound another IRQ to this notification */
    if (ntfn_entry->num_irqs_bound >= MAX_INTERRUPTS_TO_NOTIFICATIONS) {
        return -ENOSPC;
    }

    /* Find an empty space (unclaimed bit in the badge) for the IRQ */
    int badge_index = find_free_ntfn_badge_index(ntfn_entry);
    if (badge_index == -1) {
        return -ENOSPC;
    }

    /* Allocate a CSpace slot and mint the root notification object with badge */
    cspacepath_t mint_path = {0};
    int error = vka_cspace_alloc_path(irq_cookie->vka, &mint_path);
    if (error) {
        return -ENOMEM;
    }

    seL4_Word badge = BIT(badge_index);
    error = vka_cnode_mint(&mint_path, &(ntfn_entry->root_ntfn_path), seL4_AllRights, badge);
    if (error) {
        vka_cspace_free_path(irq_cookie->vka, mint_path);
        return -ENOMEM;
    }

    /* Bind the notification with the handler now */
    error = seL4_IRQHandler_SetNotification(irq_entry->handler_path.capPtr, mint_path.capPtr);
    if (error) {
        ZF_LOGE("Failed to set a notification with the IRQ handler");
        error = vka_cnode_delete(&mint_path);
        ZF_LOGF_IF(error, "Failed to cleanup after a failed IRQ set ntfn operation");
        vka_cspace_free_path(irq_cookie->vka, mint_path);
        return -EFAULT;
    }

    /* Acknowledge the handler so interrupts can arrive on the notification */
    error = seL4_IRQHandler_Ack(irq_entry->handler_path.capPtr);
    if (error) {
        ZF_LOGE("Failed to ack an IRQ handler");
        error = seL4_IRQHandler_Clear(irq_entry->handler_path.capPtr);
        ZF_LOGF_IF(error, "Failed to unpair a notification after a failed IRQ set ntfn operation");
        error = vka_cnode_delete(&mint_path);
        ZF_LOGF_IF(error, "Failed to cleanup after a failed IRQ set ntfn operation");
        vka_cspace_free_path(irq_cookie->vka, mint_path);
        return -EFAULT;
    }

    if (ret_badge) {
        *ret_badge = badge;
    }

    /* Fill in the bookkeeping information */
    ntfn_entry->num_irqs_bound++;
    ntfn_entry->status_bitfield |= badge;
    ntfn_entry->bound_irqs[badge_index] = irq_id;

    irq_entry->ntfn_path = mint_path;
    irq_entry->paired_ntfn = ntfn_id;
    irq_entry->allocated_badge_index = badge_index;

    return 0;
}

static irq_id_t irq_register_common(irq_cookie_t *irq_cookie, ps_irq_t irq, irq_callback_fn_t callback,
                                    void *callback_data)
{
    if (check_irq_id_all_allocated(irq_cookie)) {
        return -EMFILE;
    }

    if (!callback) {
        return -EINVAL;
    }

    irq_id_t free_id = find_free_irq_id(irq_cookie);
    if (free_id == -1) {
        /* Probably wouldn't get here, as we checked above already */
        ZF_LOGE("Failed to find a free IRQ id");
        return -EMFILE;
    }

    /* Allocate a path for the IRQ handler object */
    cspacepath_t irq_handler_path = {0};
    vka_cspace_alloc_path(irq_cookie->vka, &irq_handler_path);

    /* Create an IRQ handler object for this IRQ */
    int err = sel4platsupport_copy_irq_cap(irq_cookie->vka, irq_cookie->simple, &irq, &irq_handler_path);
    if (err) {
        /* Give a slightly ambigious message as we don't want to leak implementation details */
        ZF_LOGE("Failed to register an IRQ");
        vka_cspace_free_path(irq_cookie->vka, irq_handler_path);
        return -EFAULT;
    }

    irq_entry_t *irq_entry = &(irq_cookie->irq_table[free_id]);
    irq_entry->allocated = true;
    irq_entry->irq = irq;
    irq_entry->handler_path = irq_handler_path;
    irq_entry->irq_callback_fn = callback;
    irq_entry->callback_data = callback_data;

    irq_cookie->num_registered_irqs++;
    fill_bit_in_bitfield(irq_cookie->allocated_irq_bitfields, free_id);

    return free_id;
}

static void provide_ntfn_common(irq_cookie_t *irq_cookie, seL4_CPtr ntfn, seL4_Word usable_mask,
                                ntfn_id_t allocated_id)
{
    cspacepath_t ntfn_path = {0};
    vka_cspace_make_path(irq_cookie->vka, ntfn, &ntfn_path);

    /* Clear the notification entry and then fill in bookkeeping information */
    ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[allocated_id]);
    memset(ntfn_entry, 0, sizeof(ntfn_entry_t));
    ntfn_entry->allocated = true;
    ntfn_entry->root_ntfn_path = ntfn_path;
    ntfn_entry->usable_mask = usable_mask;

    irq_cookie->num_allocated_ntfns++;
    fill_bit_in_bitfield(irq_cookie->allocated_ntfn_bitfields, allocated_id);
}

static irq_cookie_t *new_irq_ops_common(vka_t *vka, simple_t *simple, irq_interface_config_t irq_config,
                                        ps_malloc_ops_t *malloc_ops, irq_iface_type_t iface_type)
{
    int err = 0;

    irq_cookie_t *cookie = 0;
    err = ps_calloc(malloc_ops, 1, sizeof(irq_cookie_t), (void **) &cookie);
    if (err) {
        ZF_LOGE("Failed to allocate %zu bytes for cookie", sizeof(irq_cookie_t));
        goto error;
    }

    /* Allocate the IRQ bookkeeping array, and set default values for some of the members */
    err = ps_calloc(malloc_ops, 1, sizeof(irq_entry_t) * irq_config.max_irq_ids, (void **) & (cookie->irq_table));
    if (err) {
        ZF_LOGE("Failed to allocate IRQ bookkeeping array");
        goto error;
    }
    for (int i = 0; i < irq_config.max_irq_ids; i++) {
        cookie->irq_table[i].paired_ntfn = UNPAIRED_ID;
        cookie->irq_table[i].allocated_badge_index = UNALLOCATED_BADGE_INDEX;
    }

    /* Allocate the notification bookkeeping array, and set default values for some of the members */
    err = ps_calloc(malloc_ops, 1, sizeof(ntfn_entry_t) * irq_config.max_ntfn_ids,
                    (void **) & (cookie->ntfn_table));
    if (err) {
        ZF_LOGE("Failed to allocate notification bookkeeping array");
        goto error;
    }
    for (int i = 0; i < irq_config.max_ntfn_ids; i++) {
        memset(cookie->ntfn_table[i].bound_irqs, UNPAIRED_ID, MAX_INTERRUPTS_TO_NOTIFICATIONS);
    }

    /* Figure out how many bitfields we need to keep track of the allocation status of the IDs */
    size_t bits_in_seL4_Word = sizeof(seL4_Word) * CHAR_BIT;
    size_t num_irq_bitfields = ALIGN_UP(irq_config.max_irq_ids, bits_in_seL4_Word) / sizeof(seL4_Word);
    size_t num_ntfn_bitfields = ALIGN_UP(irq_config.max_ntfn_ids, bits_in_seL4_Word) / sizeof(seL4_Word);
    err = ps_calloc(malloc_ops, 1, num_irq_bitfields * sizeof(seL4_Word),
                    (void **) & (cookie->allocated_irq_bitfields));
    if (err) {
        ZF_LOGE("Failed to allocate the IRQ bitfields");
        goto error;
    }
    err = ps_calloc(malloc_ops, 1, num_ntfn_bitfields * sizeof(seL4_Word),
                    (void **) & (cookie->allocated_ntfn_bitfields));
    if (err) {
        ZF_LOGE("Failed to allocate the notification bitfields");
        goto error;
    }

    cookie->iface_type = iface_type;
    cookie->simple = simple;
    cookie->vka = vka;
    cookie->malloc_ops = malloc_ops;
    cookie->max_irq_ids = irq_config.max_irq_ids;
    cookie->max_ntfn_ids = irq_config.max_ntfn_ids;
    cookie->num_irq_bitfields = num_irq_bitfields;
    cookie->num_ntfn_bitfields = num_ntfn_bitfields;

    return cookie;

error:
    if (cookie) {
        if (cookie->irq_table) {
            ps_free(malloc_ops, sizeof(irq_entry_t) * irq_config.max_irq_ids, cookie->irq_table);
        }

        if (cookie->ntfn_table) {
            ps_free(malloc_ops, sizeof(ntfn_entry_t) * irq_config.max_ntfn_ids,
                    cookie->ntfn_table);
        }

        if (cookie->allocated_irq_bitfields) {
            ps_free(malloc_ops, sizeof(seL4_Word) * num_irq_bitfields, cookie->allocated_irq_bitfields);
        }

        ps_free(malloc_ops, sizeof(irq_cookie_t), cookie);
    }

    return NULL;
}

static int sel4platsupport_irq_unregister(void *cookie, irq_id_t irq_id)
{
    irq_cookie_t *irq_cookie = cookie;

    if (!check_irq_id_is_valid(irq_cookie, irq_id)) {
        return -EINVAL;
    }

    if (!check_irq_id_is_allocated(irq_cookie, irq_id)) {
        return -EINVAL;
    }

    irq_entry_t *irq_entry = &(irq_cookie->irq_table[irq_id]);

    if (irq_entry->paired_ntfn > UNPAIRED_ID) {
        /* Clear the handler */
        int error = seL4_IRQHandler_Clear(irq_entry->handler_path.capPtr);
        if (error) {
            /* Give a slightly ambigious message as we don't want to leak implementation details */
            ZF_LOGE("Failed to unregister an IRQ");
            return -EFAULT;
        }

        /* Delete the notification */
        vka_cnode_delete(&(irq_entry->ntfn_path));
        vka_cspace_free_path(irq_cookie->vka, irq_entry->ntfn_path);

        /* Clear the necessary information in the notification array */
        ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[irq_entry->paired_ntfn]);
        ntfn_entry->status_bitfield &= ~BIT(irq_entry->allocated_badge_index);
        ntfn_entry->pending_bitfield &= ~BIT(irq_entry->allocated_badge_index);
        ntfn_entry->bound_irqs[irq_entry->allocated_badge_index] = UNPAIRED_ID;
        ntfn_entry->num_irqs_bound--;
    }

    /* Delete the handler */
    vka_cnode_delete(&(irq_entry->handler_path));
    vka_cspace_free_path(irq_cookie->vka, irq_entry->handler_path);

    /* Zero-out the entire entry */
    memset(irq_entry, 0, sizeof(irq_entry_t));
    /* Reset parts of the entry */
    irq_entry->paired_ntfn = UNPAIRED_ID;
    irq_entry->allocated_badge_index = UNALLOCATED_BADGE_INDEX;

    irq_cookie->num_registered_irqs--;
    unfill_bit_in_bitfield(irq_cookie->allocated_irq_bitfields, irq_id);

    return 0;
}

/* The register function for the standard IRQ interface */
static irq_id_t sel4platsupport_irq_register(void *cookie, ps_irq_t irq, irq_callback_fn_t callback,
                                             void *callback_data)
{
    irq_cookie_t *irq_cookie = cookie;

    return irq_register_common(irq_cookie, irq, callback, callback_data);
}

/* The register function for the mini IRQ interface */
static irq_id_t sel4platsupport_irq_register_mini(void *cookie, ps_irq_t irq, irq_callback_fn_t callback,
                                                  void *callback_data)
{
    irq_cookie_t *irq_cookie = cookie;

    irq_id_t assigned_id = irq_register_common(irq_cookie, irq, callback, callback_data);
    if (assigned_id < 0) {
        /* Contains the error code if < 0 */
        return assigned_id;
    }

    /* Pair this IRQ with the only notification */
    int error = irq_set_ntfn_common(irq_cookie, MINI_IRQ_INTERFACE_NTFN_ID, assigned_id, NULL);
    if (error) {
        ZF_LOGF_IF(sel4platsupport_irq_unregister(irq_cookie, assigned_id),
                   "Failed to clean-up a failed operation");
        return error;
    }

    return assigned_id;
}

static int sel4platsupport_irq_acknowledge(void *ack_data)
{
    if (!ack_data) {
        return -EINVAL;
    }

    int ret = 0;

    ack_data_t *data = ack_data;
    irq_cookie_t *irq_cookie = data->irq_cookie;
    irq_id_t irq_id = data->irq_id;

    if (!check_irq_id_is_valid(irq_cookie, irq_id)) {
        ret = -EINVAL;
        goto exit;
    }

    if (!check_irq_id_is_allocated(irq_cookie, irq_id)) {
        ret = -EINVAL;
        goto exit;
    }

    irq_entry_t *irq_entry = &(irq_cookie->irq_table[irq_id]);
    int error = seL4_IRQHandler_Ack(irq_entry->handler_path.capPtr);
    if (error) {
        ZF_LOGE("Failed to acknowledge IRQ");
        ret = -EFAULT;
        goto exit;
    }

exit:
    ps_free(irq_cookie->malloc_ops, sizeof(ack_data_t), data);

    return ret;
}

int sel4platsupport_new_irq_ops(ps_irq_ops_t *irq_ops, vka_t *vka, simple_t *simple,
                                irq_interface_config_t irq_config, ps_malloc_ops_t *malloc_ops)
{
    if (!irq_ops || !vka || !simple || !malloc_ops) {
        return -EINVAL;
    }

    if (irq_config.max_irq_ids == 0 || irq_config.max_ntfn_ids == 0) {
        return -EINVAL;
    }

    irq_cookie_t *cookie = new_irq_ops_common(vka, simple, irq_config, malloc_ops, STANDARD_IFACE);
    if (!cookie) {
        return -ENOMEM;
    }

    /* Fill in the actual IRQ ops structure now */
    irq_ops->cookie = (void *) cookie;
    irq_ops->irq_register_fn = sel4platsupport_irq_register;
    irq_ops->irq_unregister_fn = sel4platsupport_irq_unregister;

    return 0;
}

int sel4platsupport_new_mini_irq_ops(ps_irq_ops_t *irq_ops, vka_t *vka, simple_t *simple,
                                     ps_malloc_ops_t *malloc_ops, seL4_CPtr ntfn, seL4_Word usable_mask)
{
    if (!irq_ops || !vka || !simple || !malloc_ops || !usable_mask) {
        return -EINVAL;
    }

    if (ntfn == seL4_CapNull) {
        return -EINVAL;
    }

    /* Get the number of bits that we can use in the badge,
     * this is the amount of interrupts that can be registered at a given time */
    size_t bits_in_mask = POPCOUNTL(usable_mask);

    /* max_ntfn_ids is kinda irrelevant in the mini interface, but set it anyway */
    irq_interface_config_t irq_config = { .max_irq_ids = bits_in_mask, .max_ntfn_ids = 1 };

    irq_cookie_t *cookie = new_irq_ops_common(vka, simple, irq_config, malloc_ops, MINI_IFACE);
    if (!cookie) {
        return -ENOMEM;
    }

    /* Fill in the actual IRQ ops structure now */
    irq_ops->cookie = (void *) cookie;
    irq_ops->irq_register_fn = sel4platsupport_irq_register_mini;
    irq_ops->irq_unregister_fn = sel4platsupport_irq_unregister;

    /* Provide the ntfn */
    provide_ntfn_common(cookie, ntfn, usable_mask, MINI_IRQ_INTERFACE_NTFN_ID);

    return 0;
}

ntfn_id_t sel4platsupport_irq_provide_ntfn(ps_irq_ops_t *irq_ops, seL4_CPtr ntfn, seL4_Word usable_mask)
{
    if (!irq_ops || ntfn == seL4_CapNull || !usable_mask) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (irq_cookie->iface_type == MINI_IFACE) {
        ZF_LOGE("Trying to use %s with the mini IRQ Interface", __func__);
        return -EPERM;
    }

    if (check_ntfn_id_all_allocated(irq_cookie)) {
        return -EMFILE;
    }

    ntfn_id_t free_id = find_free_ntfn_id(irq_cookie);
    if (free_id == -1) {
        return -EMFILE;
    }

    provide_ntfn_common(irq_cookie, ntfn, usable_mask, free_id);

    return free_id;
}

int sel4platsupport_irq_provide_ntfn_with_id(ps_irq_ops_t *irq_ops, seL4_CPtr ntfn,
                                             seL4_Word usable_mask, ntfn_id_t id_hint)
{
    if (!irq_ops || ntfn == seL4_CapNull || !usable_mask) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (irq_cookie->iface_type == MINI_IFACE) {
        ZF_LOGE("Trying to use %s with the mini IRQ Interface", __func__);
        return -EPERM;
    }

    if (check_ntfn_id_all_allocated(irq_cookie)) {
        return -EMFILE;
    }

    if (irq_cookie->ntfn_table[id_hint].allocated) {
        return -EADDRINUSE;
    }

    provide_ntfn_common(irq_cookie, ntfn, usable_mask, id_hint);

    return 0;
}

int sel4platsupport_irq_return_ntfn(ps_irq_ops_t *irq_ops, ntfn_id_t ntfn_id,
                                    seL4_CPtr *ret_cptr)
{
    if (!irq_ops) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (irq_cookie->iface_type == MINI_IFACE) {
        ZF_LOGE("Trying to use %s with the mini IRQ Interface", __func__);
        return -EPERM;
    }

    if (!check_ntfn_id_is_valid(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    if (!check_ntfn_id_is_allocated(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[ntfn_id]);

    if (ntfn_entry->num_irqs_bound > 0) {
        unsigned long allocated_bits = ntfn_entry->status_bitfield;
        while (allocated_bits) {
            unsigned long index = CTZL(allocated_bits);
            irq_entry_t *irq_entry = &(irq_cookie->irq_table[ntfn_entry->bound_irqs[index]]);
            seL4_IRQHandler_Clear(irq_entry->handler_path.capPtr);
            int error = vka_cnode_delete(&(irq_entry->ntfn_path));
            ZF_LOGF_IF(error, "Failed to delete a minted notification");
            irq_entry->ntfn_path = (cspacepath_t) {
                0
            };
            irq_entry->paired_ntfn = UNPAIRED_ID;
            irq_entry->allocated_badge_index = UNALLOCATED_BADGE_INDEX;

            allocated_bits &= ~BIT(index);
        }
    }

    if (ret_cptr) {
        *ret_cptr = ntfn_entry->root_ntfn_path.capPtr;
    }

    /* Zero out the entire entry */
    memset(ntfn_entry, 0, sizeof(ntfn_entry_t));
    /* Reset the bound_irqs array for the entry */
    memset(ntfn_entry->bound_irqs, UNPAIRED_ID, MAX_INTERRUPTS_TO_NOTIFICATIONS);

    irq_cookie->num_allocated_ntfns--;
    unfill_bit_in_bitfield(irq_cookie->allocated_ntfn_bitfields, ntfn_id);

    return 0;
}

int sel4platsupport_irq_set_ntfn(ps_irq_ops_t *irq_ops, ntfn_id_t ntfn_id, irq_id_t irq_id, seL4_Word *ret_badge)
{
    if (!irq_ops) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (irq_cookie->iface_type == MINI_IFACE) {
        ZF_LOGE("Trying to use %s with the mini IRQ Interface", __func__);
        return -EPERM;
    }

    if (!check_ntfn_id_is_valid(irq_cookie, ntfn_id) ||
        !check_ntfn_id_is_allocated(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    if (!check_irq_id_is_valid(irq_cookie, irq_id) ||
        !check_irq_id_is_allocated(irq_cookie, irq_id)) {
        return -EINVAL;
    }

    return irq_set_ntfn_common(irq_cookie, ntfn_id, irq_id, ret_badge);
}

int sel4platsupport_irq_unset_ntfn(ps_irq_ops_t *irq_ops, irq_id_t irq_id)
{
    if (!irq_ops) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (irq_cookie->iface_type == MINI_IFACE) {
        ZF_LOGE("Trying to use %s with the mini IRQ Interface", __func__);
        return -EPERM;
    }

    if (!check_irq_id_is_valid(irq_cookie, irq_id) ||
        !check_irq_id_is_allocated(irq_cookie, irq_id)) {
        return -EINVAL;
    }

    irq_entry_t *irq_entry = &(irq_cookie->irq_table[irq_id]);

    /* Check if the IRQ is bound to a notification */
    if (irq_entry->paired_ntfn == UNPAIRED_ID) {
        return -EINVAL;
    }

    /* Unbind the notification from the handler */
    int error = seL4_IRQHandler_Clear(irq_entry->handler_path.capPtr);
    if (error) {
        ZF_LOGE("Failed to unpair a notification");
        return -EFAULT;
    }

    /* Delete the minted notification and free the path */
    vka_cnode_delete(&(irq_entry->ntfn_path));
    vka_cspace_free_path(irq_cookie->vka, irq_entry->ntfn_path);

    /* Free the allocated badge index and update the bookkeeping in the notification array and the irq array */
    ntfn_id_t paired_id = irq_entry->paired_ntfn;
    ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[paired_id]);
    ntfn_entry->status_bitfield &= ~BIT(irq_entry->allocated_badge_index);
    ntfn_entry->pending_bitfield &= ~BIT(irq_entry->allocated_badge_index);
    ntfn_entry->num_irqs_bound--;
    ntfn_entry->bound_irqs[irq_entry->allocated_badge_index] = UNPAIRED_ID;

    irq_entry->ntfn_path = (cspacepath_t) {
        0
    };
    irq_entry->paired_ntfn = UNPAIRED_ID;
    irq_entry->allocated_badge_index = UNALLOCATED_BADGE_INDEX;

    return 0;
}

static bool perform_callback(irq_cookie_t *irq_cookie, irq_id_t irq_id, unsigned long badge_bit)
{
    irq_entry_t *irq_entry = &(irq_cookie->irq_table[irq_id]);
    irq_callback_fn_t callback = irq_entry->irq_callback_fn;

    /* Check if callback was registered, if so, then run it */
    if (callback) {
        ack_data_t *ack_data = NULL;
        int error = ps_calloc(irq_cookie->malloc_ops, 1, sizeof(ack_data_t), (void **) &ack_data);
        ZF_LOGF_IF(error, "Failed to allocate memory for a cookie for the acknowledge function");
        *ack_data = (ack_data_t) {
            .irq_cookie = irq_cookie, .irq_id = irq_id
        };
        callback(irq_entry->callback_data,
                 sel4platsupport_irq_acknowledge, ack_data);
        return true;
    }
    return false;
}

int sel4platsupport_irq_handle(ps_irq_ops_t *irq_ops, ntfn_id_t ntfn_id, seL4_Word handle_mask)
{
    if (!irq_ops) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (!check_ntfn_id_is_valid(irq_cookie, ntfn_id) ||
        !check_ntfn_id_is_allocated(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[ntfn_id]);

    /* Just in case, but probably should throw an error at the user for passing in bits that
     * we dont' handle */
    unsigned long unchecked_bits = handle_mask & ntfn_entry->usable_mask;

    while (unchecked_bits) {
        unsigned long bit_index = CTZL(unchecked_bits);
        irq_id_t paired_irq_id = ntfn_entry->bound_irqs[bit_index];
        bool callback_called = perform_callback(irq_cookie, paired_irq_id, bit_index);
        if (callback_called && ntfn_entry->pending_bitfield & BIT(bit_index)) {
            /* Unset the bit, we've performed the callback for that interrupt */
            ntfn_entry->pending_bitfield & ~BIT(bit_index);
        }
        unchecked_bits &= ~BIT(bit_index);
    }

    return 0;
}

static void serve_irq(irq_cookie_t *irq_cookie, ntfn_id_t id, seL4_Word mask,
                      seL4_Word badge, seL4_Word *ret_leftover_bits)
{
    seL4_Word served_mask = 0;

    ntfn_entry_t *ntfn_entry = &(irq_cookie->ntfn_table[id]);

    /* Mask out the bits the are not relevant to us */
    unsigned long unchecked_bits = badge & ntfn_entry->usable_mask;
    /* Also check the interrupts that were leftover and not served */
    unchecked_bits |= ntfn_entry->pending_bitfield;

    while (unchecked_bits) {
        unsigned long bit_index = CTZL(unchecked_bits);

        if (likely(BIT(bit_index) & mask)) {
            irq_id_t paired_irq_id = ntfn_entry->bound_irqs[bit_index];
            if (perform_callback(irq_cookie, paired_irq_id, bit_index)) {
                /* Record that this particular IRQ was served */
                served_mask |= BIT(bit_index);
            }
        }

        unchecked_bits &= ~BIT(bit_index);
    }

    /* Record the IRQs that were not served but arrived, note that we don't want to
     * override the leftover IRQs still inside the pending bitfield */
    ntfn_entry->pending_bitfield ^= badge & ntfn_entry->usable_mask & ~(served_mask);

    /* Write bits that are leftover */
    if (ret_leftover_bits) {
        *ret_leftover_bits = badge & ~(served_mask);
    }
}

int sel4platsupport_irq_wait(ps_irq_ops_t *irq_ops, ntfn_id_t ntfn_id,
                             seL4_Word wait_mask,
                             seL4_Word *ret_leftover_bits)
{
    if (!irq_ops) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (!check_ntfn_id_is_valid(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    if (!check_ntfn_id_is_allocated(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    seL4_CPtr ntfn = irq_cookie->ntfn_table[ntfn_id].root_ntfn_path.capPtr;

    seL4_Word badge = 0;

    /* Wait on the notification object */
    seL4_Wait(ntfn, &badge);

    serve_irq(irq_cookie, ntfn_id, wait_mask, badge, ret_leftover_bits);

    return 0;

}

int sel4platsupport_irq_poll(ps_irq_ops_t *irq_ops, ntfn_id_t ntfn_id,
                             seL4_Word poll_mask,
                             seL4_Word *ret_leftover_bits)
{
    if (!irq_ops) {
        return -EINVAL;
    }

    irq_cookie_t *irq_cookie = irq_ops->cookie;

    if (!check_ntfn_id_is_valid(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    if (!check_ntfn_id_is_allocated(irq_cookie, ntfn_id)) {
        return -EINVAL;
    }

    seL4_CPtr ntfn = irq_cookie->ntfn_table[ntfn_id].root_ntfn_path.capPtr;

    seL4_Word badge = 0;

    /* Poll the notification object */
    seL4_Poll(ntfn, &badge);

    serve_irq(irq_cookie, ntfn_id, poll_mask, badge, ret_leftover_bits);

    return 0;
}
