blob: 9ca3bef59026fea0e91601c1a104cc17f22a1c73 [file] [log] [blame] [edit]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <camkes/dataport.h>
#include <camkes/error.h>
#include <stdint.h>
#include <stdlib.h>
#include <utils/util.h>
#include <platsupport/io.h>
#include <platsupport/irq.h>
/*? macros.show_includes(me.type.includes) ?*/
/*- for i in me.type.uses -*/
/*? macros.show_includes(i.type.includes) ?*/
/*- endfor -*/
/*- for i in me.type.provides -*/
/*? macros.show_includes(i.type.includes) ?*/
/*- endfor -*/
const char *get_instance_name(void);
/* Attributes */
// This macro allows using attributes as "rvalues" e.g. in the array size
// declarations. Unfortunately, the C language (in contrast to C++) does not
// support using "lvalues" in this case, even if declared as const.
#define CAMKES_CONST_ATTR(attr) attr##_DEF
/*- set myconf = configuration[me.name] -*/
/*? macros.print_type_definitions(me.type.attributes, myconf) ?*/
/*- for a in me.type.attributes -*/
/*- set value = myconf.get(a.name) -*/
/*- if value is not none -*/
#define /*? a.name ?*/_DEF /*? macros.show_attribute_value(a, value) ?*/
/*- endif -*/
extern const /*? macros.show_type(a.type) ?*/ /*? a.name ?*/ /*- if a.array -*/ [/*?len(value)?*/] /*- endif -*/;
/*- endfor -*/
/*- for u in me.type.uses + me.type.provides -*/
/*- for m in u.type.methods -*/
/*- if m.return_type is not none -*/
/*- if m.return_type == 'string' -*/
char *
/*- else -*/
/*? macros.show_type(m.return_type) ?*/
/*- endif -*/
/*- else -*/
void
/*- endif -*/
/*? u.name ?*/_/*? m.name ?*/(
/*- for p in m.parameters -*/
/*- if p.direction == 'in' -*/
/*- if p.array -*/
size_t /*? p.name ?*/_sz,
/*- if p.type == 'string' -*/
char **
/*- else -*/
const /*? macros.show_type(p.type) ?*/ *
/*- endif -*/
/*- elif p.type == 'string' -*/
const char *
/*- else -*/
/*? macros.show_type(p.type) ?*/
/*- endif -*/
/*? p.name ?*/
/*- else -*/
/*? assert(p.direction in ['refin', 'out', 'inout']) ?*/
/*- if p.array -*/
/*- if p.direction == 'refin' -*/
const
/*- endif -*/
size_t * /*? p.name ?*/_sz,
/*- if p.type == 'string' -*/
char ***
/*- else -*/
/*? macros.show_type(p.type) ?*/ **
/*- endif -*/
/*- elif p.type == 'string' -*/
char **
/*- else -*/
/*- if p.direction == 'refin' -*/
const
/*- endif -*/
/*? macros.show_type(p.type) ?*/ *
/*- endif -*/
/*? p.name ?*/
/*- endif -*/
/*- if not loop.last -*/
,
/*- endif -*/
/*- endfor -*/
/*- if len(m.parameters) == 0 -*/
void
/*- endif -*/
) NONNULL_ALL /*- if isinstance(u, camkes.ast.Uses) and u.optional -*/ WEAK /*- endif -*/;
/*- endfor -*/
/*- endfor -*/
/*- for c in me.type.consumes -*/
/*# HACK: Connection-specific check here to just be nice to the user and
*# trigger a compile-time warning if they try to use functions that aren't
*# implemented.
#*/
/*- set irq = [False] -*/
/*- set dtb_connector = [False] -*/
/*- for conn in composition.connections -*/
/*- if conn.type.name == 'seL4HardwareInterrupt' and id(conn.to_ends[0].interface) == id(c) -*/
/*- do irq.__setitem__(0, True) -*/
/*- break -*/
/*- endif -*/
/*- if conn.type.name == 'seL4DTBHardware' -*/
/*# We need to loop over ends as there may be multiple 'consumes' devices connected to
*# the same dummy source, e.g.
*# emits Dummy dummy_source;
*# consumes Dummy pwm_timer_1;
*# consumes Dummy pwm_timer_2;
*# ...
*# connection seL4DTBHardware pwm_conn_1(from dummy_source, to pwm_timer_1);
*# connection seL4DTBHardware pwm_conn_2(from dummy_source, to pwm_timer_2);
*# the whole connection becomes:
*# component.pwm_conn_1.component.pwm_conn_2
#*/
/*- for end in conn.to_ends -*/
/*- if id(end.interface) == id(c) -*/
/*- do irq.__setitem__(0, True) -*/
/*- do dtb_connector.__setitem__(0, True) -*/
/*- break -*/
/*- endif -*/
/*- endfor -*/
/*- if irq[0] -*/
/*- break -*/
/*- endif -*/
/*- endif -*/
/*- endfor -*/
void /*? c.name ?*/_wait(void)
/*- if c.optional -*/ WEAK /*- endif -*/
/*- if irq[0] -*/ WARNING("/*? c.name ?*/_wait is not provided by "
"seL4HardwareInterrupt or seL4DTBHardware") /*- endif -*/
;
int /*? c.name ?*/_poll(void) WARN_UNUSED_RESULT
/*- if c.optional -*/ WEAK /*- endif -*/
/*- if irq[0] -*/ WARNING("/*? c.name ?*/_poll is not provided by "
"seL4HardwareInterrupt or seL4DTBHardware") /*- endif -*/
;
int /*? c.name ?*/_reg_callback(void (*callback)(void*), void *arg) WARN_UNUSED_RESULT
/*- if c.optional -*/ WEAK /*- endif -*/
/*- if irq[0] -*/ WARNING("/*? c.name ?*/_reg_callback is not provided "
"by seL4HardwareInterrupt or seL4DTBHardware") /*- endif -*/
;
/*- if dtb_connector[0] -*/
/*# Since the interfaces of the seL4DTBHardware connector are 'consumes', we
*# have to declare the buffers here, and not inside the dataport block
#*/
/*- set config_name = '%s.%s' % (me.name, c) -*/
/*- set dtb_config = configuration[config_name]['dtb'] -*/
/*- if dtb_config is none -*/
/*? raise(TemplateError('Couldn\'t grab the DTB for the %s seL4DTBHardware connection.' % config_name)) ?*/
/*- endif -*/
/*- set dtb_query = dtb_config.get('query') -*/
/*- if dtb_query is none -*/
/*? raise(TemplateError('Couldn\'t grab the DTB query for the %s seL4DTBHardware connection.' % config_name)) ?*/
/*- endif -*/
/*- if len(dtb_query) != 1 -*/
/*? raise(TemplateError('Invalid number of DTB paths for the %s seL4DTBHardware connection.' % config_name)) ?*/
/*- endif -*/
/*- if dtb_query[0] is none -*/
/*? raise(TemplateError('Missing DTB path for the %s seL4DTBHardware connection.' % config_name)) ?*/
/*- endif -*/
/*- set dtb = dtb_query[0] -*/
/*- set num_registers = len(dtb['reg']) // (dtb['this_address_cells'][0] + dtb['this_size_cells'][0]) -*/
/*# Declare all the initialised buffers #*/
/*- for i in range(0, num_registers) -*/
extern void * /*? c ?*/_/*? i ?*/;
/*- endfor -*/
/*- endif -*/
/*- if irq[0] and dtb_connector[0] -*/
int /*? c.name ?*/_irq_acknowledge(ps_irq_t *irq) WARN_UNUSED_RESULT;
/* Implemented by user code or substituted for the IRQ interface. */
void /*? c.name ?*/_irq_handle(ps_irq_t *irq) WEAK;
/*- else -*/
int /*? c.name ?*/_acknowledge(void) WARN_UNUSED_RESULT
/*- if c.optional -*/ WEAK /*- endif -*/;
/* Implemented by user code or substituted for the IRQ interface. */
void /*? c.name ?*/_handle(void) WEAK;
/*- endif -*/
/*- endfor -*/
/*- for e in me.type.emits -*/
void /*? e.name ?*/_emit(void);
/*- endfor -*/
/*- for d in me.type.dataports -*/
extern /*? macros.dataport_type(d.type) ?*/ * /*? d.name ?*/
/*- if d.optional -*/
WEAK
/*- endif -*/;
int /*? d.name ?*/_cache_op(size_t start_offset, size_t size, dma_cache_op_t cache_op)
/*- if d.optional -*/
__attribute__((weak))
/*- endif -*/;
#define /*? d.name ?*/_release() COMPILER_MEMORY_RELEASE()
#define /*? d.name ?*/_acquire() COMPILER_MEMORY_ACQUIRE()
#define /*? d.name ?*/_size /*? macros.dataport_size(d.type) ?*/
static inline size_t /*? d.name ?*/_get_size(void) {
return /*? macros.dataport_size(d.type) ?*/;
}
/*- endfor -*/
/*- for m in me.type.mutexes -*/
int /*? m.name ?*/_lock(void) WARN_UNUSED_RESULT;
int /*? m.name ?*/_unlock(void) WARN_UNUSED_RESULT;
/*- endfor -*/
/*- for s in me.type.semaphores -*/
int /*? s.name ?*/_wait(void) WARN_UNUSED_RESULT;
int /*? s.name ?*/_trywait(void) WARN_UNUSED_RESULT;
int /*? s.name ?*/_post(void) WARN_UNUSED_RESULT;
/*- endfor -*/
/*- for b in me.type.binary_semaphores -*/
int /*? b.name ?*/_wait(void) WARN_UNUSED_RESULT;
int /*? b.name ?*/_post(void) WARN_UNUSED_RESULT;
/*- endfor -*/
/* Entry point expected to be provided by the user. */
int run(void);
/*- set all_interfaces = me.type.provides + me.type.uses + me.type.emits + me.type.consumes + me.type.dataports -*/
/* Optional init functions provided by the user. */
void pre_init(void) WEAK;
void post_init(void) WEAK;
/*- for i in all_interfaces -*/
void /*? i.name ?*/__init(void) WEAK;
void /*? i.name ?*/_timing_get_points(char ***points, size_t *size);
uint64_t /*? i.name ?*/_timing_get_entry(unsigned iteration, char *point);
void /*? i.name ?*/_timing_reset(void);
/*- endfor -*/
void set_putchar(void (*putchar)(int c));
/*- for i in all_interfaces -*/
camkes_error_handler_t /*? i.name ?*/_register_error_handler(
camkes_error_handler_t handler);
/*- endfor -*/