/*
 * Copyright 2017, 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 <autoconf.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) {
                ltimer_handle_irq(&timer->ltimer, &timer->to.irqs[i].irq);
                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 %"PRIuPTR,
                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);
    }
    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, &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, &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");
            }
        }
    }

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