/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <autoconf.h>
#include <sel4platsupport/gen_config.h>
#include <vka/object.h>
#include <vka/vka.h>
#include <vka/capops.h>
#include <sel4platsupport/timer.h>
#include <platsupport/ltimer.h>
#include <sel4platsupport/device.h>
#include <sel4platsupport/io.h>
#include <utils/util.h>

static void cleanup_timer_irq(vka_t *vka, sel4ps_irq_t *irq)
{
    seL4_IRQHandler_Clear(irq->handler_path.capPtr);
    /* clear the cslots */
    vka_cnode_delete(&irq->badged_ntfn_path);
    vka_cnode_delete(&irq->handler_path);
    /* free the cslots */
    vka_cspace_free(vka, irq->badged_ntfn_path.capPtr);
    vka_cspace_free(vka, irq->handler_path.capPtr);
}


void sel4platsupport_destroy_timer(seL4_timer_t *timer, vka_t *vka)
{
    ltimer_destroy(&timer->ltimer);
    assert(timer->to.nirqs < MAX_IRQS);
    for (size_t i = 0; i < timer->to.nirqs; i++) {
        cleanup_timer_irq(vka, &timer->to.irqs[i]);
    }

    assert(timer->to.nobjs < MAX_OBJS);
    for (size_t i = 0; i < timer->to.nobjs; i++) {
        vka_free_object(vka, &timer->to.objs[i].obj);
    }
}

void sel4platsupport_handle_timer_irq(seL4_timer_t *timer, seL4_Word badge)
{
    assert(timer->to.nirqs < MAX_IRQS);
    /* check which bits are set to find which irq to handle */
    for (unsigned long i = 0; badge && i < timer->to.nirqs; i++) {
        /* invert the bit: we take the top badge bits to identify timers */
        long irq = seL4_BadgeBits - i - 1;
        if (badge & BIT(irq)) {
            /* mask the bit out of the badge */
            badge &= ~BIT(irq);
            if (timer->to.irqs[i].irq.type != PS_NONE) {
                int error = seL4_IRQHandler_Ack(timer->to.irqs[i].handler_path.capPtr);
                if (error) {
                    ZF_LOGE("Failed to ack irq %lu, error %d", irq, error);
                }
            }
        }
    }
}

static int setup_irq(vka_t *vka, sel4ps_irq_t *irq, seL4_Word badge, seL4_CPtr ntfn)
{
    int error = vka_cspace_alloc_path(vka, &irq->badged_ntfn_path);
    cspacepath_t path;
    vka_cspace_make_path(vka, ntfn, &path);
    if (!error) {
        /* badge it */
        error = vka_cnode_mint(&irq->badged_ntfn_path, &path, seL4_AllRights, badge);
    }
    if (!error) {
        /* set notification *before* acking any pending IRQ to ensure there is no race where
         * we lose an IRQ */
        error =  seL4_IRQHandler_SetNotification(irq->handler_path.capPtr, irq->badged_ntfn_path.capPtr);
    }
    if (!error) {
        error = seL4_IRQHandler_Ack(irq->handler_path.capPtr);
    }
    return error;
}

static int get_nth_pmem(vka_t *vka, ltimer_t *ltimer, sel4ps_pmem_t *obj, int n)
{
    int error = ltimer_get_nth_pmem(ltimer, n, &obj->region);
    if (!error && obj->region.length > PAGE_SIZE_4K) {
        ZF_LOGE("Support for timers with anything but 4K pages unimplemented! length %zu",
                (size_t) obj->region.length);
        return ENOSYS;
    }

    obj->region.length = PAGE_SIZE_4K;
    if (!error) {
        error = vka_alloc_untyped_at(vka, seL4_PageBits, obj->region.base_addr,
                                     &obj->obj);
    }
    obj->obj.size_bits = seL4_PageBits;
    if (error) {
        ZF_LOGF("Failed to obtain device-ut cap for default timer.");
    }
    return error;
}

static inline size_t get_nirqs(ltimer_t *ltimer)
{
    size_t nirqs = ltimer_get_num_irqs(ltimer);
    if (nirqs > MAX_IRQS) {
        ZF_LOGE("MAX_IRQS insufficient for timer");
        return -1;
    }

    return nirqs;
}

static int init_timer_internal(vka_t *vka, simple_t *simple, seL4_CPtr ntfn,
                               seL4_timer_t *timer, size_t nirqs)
{

    /* set up the irq caps the timer needs */
    timer->to.nirqs = 0;
    for (size_t i = 0; i < nirqs; i++) {
        assert(timer->to.irqs[i].irq.type != PS_NONE);
        int error = sel4platsupport_copy_irq_cap(vka, simple, &timer->to.irqs[i].irq,
                                                 &timer->to.irqs[i].handler_path);
        if (!error) {
            error = setup_irq(vka, &timer->to.irqs[i], BIT(seL4_BadgeBits - i - 1), ntfn);
        }
        if (error) {
            sel4platsupport_destroy_timer(timer, vka);
            return error;
        }
        /* increment as we go to aid destruction */
        timer->to.nirqs++;
    }

    timer->to.nobjs = 0;
    return 0;
}

int sel4platsupport_init_default_timer_ops(vka_t *vka, UNUSED vspace_t *vspace, simple_t *simple,
                                           ps_io_ops_t ops, seL4_CPtr ntfn, seL4_timer_t *timer)
{
    int error;
    if (timer == NULL) {
        return EINVAL;
    }

    error = ltimer_default_describe(&timer->ltimer, ops);

    if (!error) {
        size_t nirqs = get_nirqs(&timer->ltimer);
        for (size_t i = 0; i < nirqs; i++) {
            error = ltimer_get_nth_irq(&timer->ltimer, i, &timer->to.irqs[i].irq);
            if (error) {
                return error;
            }
        }
        error = init_timer_internal(vka, simple, ntfn, timer, nirqs);
    }

    if (!error)  {
        error = ltimer_default_init(&timer->ltimer, ops, NULL, NULL);
    }
    return error;
}

int sel4platsupport_init_default_timer(vka_t *vka, vspace_t *vspace, simple_t *simple,
                                       seL4_CPtr ntfn, seL4_timer_t *timer)
{
    int error;

    /* initialise io ops */
    ps_io_ops_t ops;
    memset(&ops, 0, sizeof(ops));
    error = sel4platsupport_new_io_ops(vspace, vka, simple, &ops);
    if (!error) {
        /* we have no way of storing the fact that we allocated these io ops so we'll just leak
         * them forever */
        return sel4platsupport_init_default_timer_ops(vka, vspace, simple, ops, ntfn, timer);
    }
    return error;
}

int sel4platsupport_init_timer_irqs(vka_t *vka, simple_t *simple,
                                    seL4_CPtr ntfn, seL4_timer_t *timer, timer_objects_t *to)
{
    if (timer == NULL) {
        return EINVAL;
    }

    /* copy the timer objects */
    timer->to = *to;
    return init_timer_internal(vka, simple, ntfn, timer, to->nirqs);
}


int sel4platsupport_init_default_timer_caps(vka_t *vka, vspace_t *vspace, simple_t *simple,
                                            timer_objects_t *timer_objects)
{
    /* initialise io ops */
    ps_io_ops_t ops;
    memset(&ops, 0, sizeof(ops));
    int error = sel4platsupport_new_io_ops(vspace, vka, simple, &ops);
    if (error) {
        ZF_LOGE("Failed to get io ops");
        return error;;
    }

    /* Allocate timer irqs. */
    ltimer_t ltimer;
    error = ltimer_default_describe(&ltimer, ops);
    if (error) {
        ZF_LOGE("Failed to describe default timer");
        return error;
    }

    /* set up the irq caps the timer needs */
    size_t nirqs = get_nirqs(&ltimer);
    for (size_t i = 0; i < nirqs; i++) {
        error = ltimer_get_nth_irq(&ltimer, i, &timer_objects->irqs[i].irq);
        assert(timer_objects->irqs[i].irq.type != PS_NONE);
        if (!error) {
            error =  sel4platsupport_copy_irq_cap(vka, simple, &timer_objects->irqs[i].irq,
                                                  &timer_objects->irqs[i].handler_path);
        }
        if (error) {
            ZF_LOGE("Failed to get irq cap %zu", i);
            return error;
        }
        timer_objects->nirqs++;
    }

    /* Obtain untyped frame caps for PS default ltimer.
     * currently this code assumes all timers need a 4k frame.
     */
    size_t nobjs = ltimer_get_num_pmems(&ltimer);
    if (nobjs > MAX_OBJS) {
        ZF_LOGE("MAX_OBJS insufficient for timer");
        return -1;
    }

    for (size_t i = 0; i < nobjs; i++) {
        error = get_nth_pmem(vka, &ltimer, &timer_objects->objs[i], i);
        timer_objects->objs[i].obj.size_bits = seL4_PageBits;
        if (error) {
            ZF_LOGE("Failed to get nth pmem");
            return error;
        }
        /* increment as we go to aid destruction */
        timer_objects->nobjs++;
    }

    return error;
}

seL4_CPtr sel4platsupport_timer_objs_get_irq_cap(timer_objects_t *to, int id, irq_type_t type)
{
    for (size_t i = 0; i < to->nirqs; i++) {
        if (to->irqs[i].irq.type == type) {
            switch (type) {
            case PS_MSI:
                if (to->irqs[i].irq.msi.vector == id) {
                    return to->irqs[i].handler_path.capPtr;
                }
                break;
            case PS_IOAPIC:
                if (to->irqs[i].irq.ioapic.pin == id) {
                    return to->irqs[i].handler_path.capPtr;
                }
                break;
            case PS_INTERRUPT:
                if (to->irqs[i].irq.irq.number == id) {
                    return to->irqs[i].handler_path.capPtr;
                }
                break;
            case PS_TRIGGER:
                if (to->irqs[i].irq.trigger.number == id) {
                    return to->irqs[i].handler_path.capPtr;
                }
                break;
            case PS_NONE:
                ZF_LOGE("Invalid irq type");
                break;
            default:
                ZF_LOGE("Unsupported irq type");
            }
        }
    }

    ZF_LOGE("Could not find irq");
    return seL4_CapNull;
}
