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

#include <assert.h>
#include <camkes/dataport.h>
#include <camkes/irq.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <platsupport/io.h>
#include <platsupport/irq.h>
#include <utils/util.h>
#include <sel4/sel4.h>

/*- import 'dtb-query-common.template.c' as dtb_macros with context -*/

/*# Grab the DTB object made from the previous stages of the parsing #*/
/*- set configuration_name = '%s.%s' % (me.instance.name, me.interface.name) -*/
/*- set dtb_config = configuration[configuration_name].get('dtb') -*/
/*- if dtb_config is none -*/
    /*# DTB query hasn't been made, raise a fault #*/
    /*? raise(TemplateError('Missing DTB attribute, create a DTB query to attribute %s.dtb.' % (me.interface.name))) ?*/
/*- endif -*/
/*- set dtb_query = dtb_config.get('query')  -*/
/*- if dtb_query is none -*/
    /*# DTB path hasn't been passed, raise a fault #*/
    /*? raise(TemplateError('Missing DTB query, assign a DTB path to attribute %s.dtb.' % (me.interface.name))) ?*/
/*- endif -*/
/*- if len(dtb_query) != 1 -*/
    /*? raise(TemplateError('Invalid number of DTB paths, assign a single DTB path to attribute %s.dtb.' % (me.interface.name))) ?*/
/*- endif -*/
/*- if dtb_query[0] is none -*/
    /*? raise(TemplateError('Missing DTB path, assign a single DTB path to attribute %s.dtb.' % (me.interface.name))) ?*/
/*- endif -*/
/*- set dtb = dtb_query[0]  -*/

/*# Check if we want interrupts #*/
/*- set generate_interrupts = configuration[configuration_name].get('generate_interrupts', none) -*/

/*# ================ #*/
/*# Register section #*/
/*# ================ #*/

/*? dtb_macros.parse_dtb_node_reg(dtb) ?*/
/*- set reg_set = pop('reg_set') -*/
/*- set cached = configuration[configuration_name].get('hardware_cached', False) -*/

/*- for paddr, size in reg_set -*/

        /*# Get the next multiple of 4K that can fit the register #*/
        /*- set size = macros.next_page_multiple(size, options.architecture) -*/
        /*- set page_size = macros.get_page_size(size, options.architecture) -*/
        /*- set page_size_bits = int(math.log(page_size, 2)) -*/

        /*- set dataport_symbol_name = "from_%d_%s_data" % (loop.index0, me.interface.name) -*/
        struct {
            char content[ROUND_UP_UNSAFE(/*? size ?*/,
                SIZE_BITS_TO_BYTES(/*? page_size_bits ?*/))];
        } /*? dataport_symbol_name ?*/
                ALIGN(/*? page_size ?*/)
                SECTION("align_/*? page_size_bits ?*/bit")
                VISIBLE
                USED;

        /*- set reg_interface_name = '%s_%d' % (me.interface.name, loop.index0) -*/

        /*- set frame_caps = [] -*/
        /*? register_shared_variable('%s_data' % reg_interface_name, dataport_symbol_name, size, frame_size=page_size, perm='RW', paddr=paddr, cached=cached, with_mapping_caps=frame_caps) ?*/

        /*# Assign a name for this particular set of registers #*/
        volatile void * /*? reg_interface_name ?*/ =
            (volatile void *) & /*? dataport_symbol_name ?*/;

        /*- set id = composition.connections.index(me.parent) -*/

        __attribute__((used)) __attribute__((section("_dataport_frames")))
        dataport_frame_t /*? reg_interface_name ?*/_frames[] = {

        /*- for cap in frame_caps -*/
            {
                .paddr = /*? paddr + loop.index0 * page_size ?*/,
                .cap = /*? cap ?*/,
                .size = /*? page_size ?*/,
                .vaddr = (uintptr_t)&(/*? dataport_symbol_name ?*/.content[/*? loop.index0 * page_size ?*/]),
            },
        /*- endfor -*/
        };
        /*# We only pull frame_caps from the stash. This is because only one caller of register_shared_variable
            should pass a frames parameter. By not stashing the frame_objs we ensure that only the original
            creator passed the frames, and everyone else will still have a None here #*/


        /* Flush data corresponding to the dataport-relative address range from the CPU cache */
        int /*? reg_interface_name ?*/_flush_cache(size_t start_offset UNUSED, size_t size UNUSED, dma_cache_op_t cache_op UNUSED) {
            return camkes_dataport_flush_cache(start_offset, size,
                                               (uintptr_t) &/*? dataport_symbol_name ?*/.content,
                                               /*? size ?*/, cache_op);
        }

/*- endfor -*/

/*# ================== #*/
/*# Interrupts section #*/
/*# ================== #*/

/*- if generate_interrupts -*/

    /*- set ntfn_obj = alloc_obj('%s_ntfn' % me.interface.name, seL4_NotificationObject) -*/
    /*- set root_ntfn = alloc_cap('%s_root_ntfn' % me.interface.name, ntfn_obj, read=True, write=True) -*/

    /*- set irq_handler_pairs = [] -*/

    /*- set interrupt_struct_prefix = '%s_irq' % (me.interface.name) -*/

    /*# CAmkES has a maximum limit of 28 bits for badges, #*/
    /*# highly unlikely a device has greater than 28 #*/
    /*? dtb_macros.parse_dtb_node_interrupts(dtb, 28) ?*/
    /*- set badges =  macros.global_endpoint_badges(composition, me, configuration) -*/
    /*- set irq_set = pop('irq_set') -*/
    /*- set name = '%s_global_endpoint' % me.instance.name -*/
/*- set stash_name = "%s_global_notification" % (name) -*/

  /*# Check the global stash for our endpoint #*/
  /*- set maybe_notification = _pop(stash_name) -*/

  /*# Create the endpoint if we need to #*/
  /*- if maybe_notification is none -*/
          /*- set notification_owner = me.instance.name -*/
          /*- set notification_object = alloc_obj(name, seL4_NotificationObject, label=notification_owner) -*/
  /*- else -*/
      /*- set notification_object, notification_owner = maybe_notification -*/
  /*- endif -*/

  /*# Put it back into the stash #*/
  /*- do _stash(stash_name, (notification_object, notification_owner)) -*/

  /*# Create the badged endpoint #*/

    /*- for i,irq_node in enumerate(irq_set) -*/
        /*- set _irq = irq_node['irq'] -*/

        /*- set interrupt_ntfn = alloc_cap('%s_%s_%d_notification_object_cap' % (name, badges[i], False), notification_object, read=False, write=True) -*/
        /*- do cap_space.cnode[interrupt_ntfn].set_badge(badges[i]) -*/

        /*- set irq = alloc('%s_irq_%d' % (me.interface.name, i), seL4_IRQHandler, number=_irq, notification=cap_space.cnode[interrupt_ntfn]) -*/

        /*# Add the interrupt number to the IRQ num list for later #*/
        /*- do irq_handler_pairs.append((_irq, irq)) -*/

        /*- set interrupt_interface_name = '%s_%d' % (me.interface.name, i) -*/

        /*# Add an entry to the allocated_irqs ELF section #*/
        static allocated_irq_t /*? interrupt_struct_prefix ?*/_/*? i ?*/ = {
            .irq_handler = /*? irq ?*/,
            .irq = { .type = PS_INTERRUPT, .irq = { .number = /*? _irq ?*/ }},
            .is_allocated = false,
            .callback_fn = NULL,
            .callback_data = NULL
        };
        USED SECTION("_allocated_irqs")
        allocated_irq_t * /*? interrupt_struct_prefix ?*/_/*? i ?*/_ptr = &/*? interrupt_struct_prefix ?*/_/*? i ?*/;

        static int /*? me.interface.name ?*/_acknowledge_cb_/*? i ?*/(UNUSED void* cookie) {
            return seL4_IRQHandler_Ack(/*? irq ?*/);
        }

        /*# Add an entry to the global_notification_irqs ELF section #*/
        /*- set irq_handler_struct_name = '%s_irq_handler_%d' % (me.interface.name, i) -*/
        static global_notification_irq_handler_t /*? irq_handler_struct_name ?*/ = {
            .badge = /*? badges[i] ?*/,
            .ack_fun = /*? me.interface.name ?*/_acknowledge_cb_/*? i ?*/,
            .allocated_ref = &/*? interrupt_struct_prefix ?*/_/*? i ?*/,
        };

        USED SECTION("_global_notification_irqs")
        global_notification_irq_handler_t * /*? irq_handler_struct_name ?*/_ptr = &/*? irq_handler_struct_name ?*/;

    /*- endfor -*/

/*- endif -*/
