1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#pragma once 14 15#include <camkes/dataport.h> 16#include <camkes/error.h> 17#include <stdint.h> 18#include <stdlib.h> 19#include <utils/util.h> 20#include <platsupport/io.h> 21#include <platsupport/irq.h> 22 23/*? macros.show_includes(me.type.includes) ?*/ 24/*- for i in me.type.uses -*/ 25 /*? macros.show_includes(i.type.includes) ?*/ 26/*- endfor -*/ 27/*- for i in me.type.provides -*/ 28 /*? macros.show_includes(i.type.includes) ?*/ 29/*- endfor -*/ 30 31const char *get_instance_name(void); 32 33/* Attributes */ 34 35// This macro allows using attributes as "rvalues" e.g. in the array size 36// declarations. Unfortunately, the C language (in contrast to C++) does not 37// support using "lvalues" in this case, even if declared as const. 38#define CAMKES_CONST_ATTR(attr) attr##_DEF 39 40/*- set myconf = configuration[me.name] -*/ 41/*? macros.print_type_definitions(me.type.attributes, myconf) ?*/ 42/*- for a in me.type.attributes -*/ 43 /*- set value = myconf.get(a.name) -*/ 44 /*- if value is not none -*/ 45 #define /*? a.name ?*/_DEF /*? macros.show_attribute_value(a, value) ?*/ 46 /*- endif -*/ 47 48 extern const /*? macros.show_type(a.type) ?*/ /*? a.name ?*/ /*- if a.array -*/ [/*?len(value)?*/] /*- endif -*/; 49/*- endfor -*/ 50 51/*- for u in me.type.uses + me.type.provides -*/ 52 /*- for m in u.type.methods -*/ 53 /*- if m.return_type is not none -*/ 54 /*- if m.return_type == 'string' -*/ 55 char * 56 /*- else -*/ 57 /*? macros.show_type(m.return_type) ?*/ 58 /*- endif -*/ 59 /*- else -*/ 60 void 61 /*- endif -*/ 62 /*? u.name ?*/_/*? m.name ?*/( 63 /*- for p in m.parameters -*/ 64 /*- if p.direction == 'in' -*/ 65 /*- if p.array -*/ 66 size_t /*? p.name ?*/_sz, 67 /*- if p.type == 'string' -*/ 68 char ** 69 /*- else -*/ 70 const /*? macros.show_type(p.type) ?*/ * 71 /*- endif -*/ 72 /*- elif p.type == 'string' -*/ 73 const char * 74 /*- else -*/ 75 /*? macros.show_type(p.type) ?*/ 76 /*- endif -*/ 77 /*? p.name ?*/ 78 /*- else -*/ 79 /*? assert(p.direction in ['refin', 'out', 'inout']) ?*/ 80 /*- if p.array -*/ 81 /*- if p.direction == 'refin' -*/ 82 const 83 /*- endif -*/ 84 size_t * /*? p.name ?*/_sz, 85 /*- if p.type == 'string' -*/ 86 char *** 87 /*- else -*/ 88 /*? macros.show_type(p.type) ?*/ ** 89 /*- endif -*/ 90 /*- elif p.type == 'string' -*/ 91 char ** 92 /*- else -*/ 93 /*- if p.direction == 'refin' -*/ 94 const 95 /*- endif -*/ 96 /*? macros.show_type(p.type) ?*/ * 97 /*- endif -*/ 98 /*? p.name ?*/ 99 /*- endif -*/ 100 /*- if not loop.last -*/ 101 , 102 /*- endif -*/ 103 /*- endfor -*/ 104 /*- if len(m.parameters) == 0 -*/ 105 void 106 /*- endif -*/ 107 ) NONNULL_ALL /*- if isinstance(u, camkes.ast.Uses) and u.optional -*/ WEAK /*- endif -*/; 108 /*- endfor -*/ 109/*- endfor -*/ 110 111/*- for c in me.type.consumes -*/ 112 /*# HACK: Connection-specific check here to just be nice to the user and 113 *# trigger a compile-time warning if they try to use functions that aren't 114 *# implemented. 115 #*/ 116 /*- set irq = [False] -*/ 117 /*- set dtb_connector = [False] -*/ 118 /*- for conn in composition.connections -*/ 119 /*- if conn.type.name == 'seL4HardwareInterrupt' and id(conn.to_ends[0].interface) == id(c) -*/ 120 /*- do irq.__setitem__(0, True) -*/ 121 /*- break -*/ 122 /*- endif -*/ 123 /*- if conn.type.name == 'seL4DTBHardware' -*/ 124 /*# We need to loop over ends as there may be multiple 'consumes' devices connected to 125 *# the same dummy source, e.g. 126 *# emits Dummy dummy_source; 127 *# consumes Dummy pwm_timer_1; 128 *# consumes Dummy pwm_timer_2; 129 *# ... 130 *# connection seL4DTBHardware pwm_conn_1(from dummy_source, to pwm_timer_1); 131 *# connection seL4DTBHardware pwm_conn_2(from dummy_source, to pwm_timer_2); 132 *# the whole connection becomes: 133 *# component.pwm_conn_1.component.pwm_conn_2 134 #*/ 135 /*- for end in conn.to_ends -*/ 136 /*- if id(end.interface) == id(c) -*/ 137 /*- do irq.__setitem__(0, True) -*/ 138 /*- do dtb_connector.__setitem__(0, True) -*/ 139 /*- break -*/ 140 /*- endif -*/ 141 /*- endfor -*/ 142 /*- if irq[0] -*/ 143 /*- break -*/ 144 /*- endif -*/ 145 /*- endif -*/ 146 /*- endfor -*/ 147 void /*? c.name ?*/_wait(void) 148 /*- if c.optional -*/ WEAK /*- endif -*/ 149 /*- if irq[0] -*/ WARNING("/*? c.name ?*/_wait is not provided by " 150 "seL4HardwareInterrupt or seL4DTBHardware") /*- endif -*/ 151 ; 152 int /*? c.name ?*/_poll(void) WARN_UNUSED_RESULT 153 /*- if c.optional -*/ WEAK /*- endif -*/ 154 /*- if irq[0] -*/ WARNING("/*? c.name ?*/_poll is not provided by " 155 "seL4HardwareInterrupt or seL4DTBHardware") /*- endif -*/ 156 ; 157 int /*? c.name ?*/_reg_callback(void (*callback)(void*), void *arg) WARN_UNUSED_RESULT 158 /*- if c.optional -*/ WEAK /*- endif -*/ 159 /*- if irq[0] -*/ WARNING("/*? c.name ?*/_reg_callback is not provided " 160 "by seL4HardwareInterrupt or seL4DTBHardware") /*- endif -*/ 161 ; 162 /*- if dtb_connector[0] -*/ 163 /*# Since the interfaces of the seL4DTBHardware connector are 'consumes', we 164 *# have to declare the buffers here, and not inside the dataport block 165 #*/ 166 /*- set config_name = '%s.%s' % (me.name, c) -*/ 167 /*- set dtb_config = configuration[config_name]['dtb'] -*/ 168 /*- if dtb_config is none -*/ 169 /*? raise(TemplateError('Couldn\'t grab the DTB for the %s seL4DTBHardware connection.' % config_name)) ?*/ 170 /*- endif -*/ 171 /*- set dtb_query = dtb_config.get('query') -*/ 172 /*- if dtb_query is none -*/ 173 /*? raise(TemplateError('Couldn\'t grab the DTB query for the %s seL4DTBHardware connection.' % config_name)) ?*/ 174 /*- endif -*/ 175 /*- if len(dtb_query) != 1 -*/ 176 /*? raise(TemplateError('Invalid number of DTB paths for the %s seL4DTBHardware connection.' % config_name)) ?*/ 177 /*- endif -*/ 178 /*- if dtb_query[0] is none -*/ 179 /*? raise(TemplateError('Missing DTB path for the %s seL4DTBHardware connection.' % config_name)) ?*/ 180 /*- endif -*/ 181 /*- set dtb = dtb_query[0] -*/ 182 /*- set num_registers = len(dtb['reg']) // (dtb['this_address_cells'][0] + dtb['this_size_cells'][0]) -*/ 183 /*# Declare all the initialised buffers #*/ 184 /*- for i in range(0, num_registers) -*/ 185 extern void * /*? c ?*/_/*? i ?*/; 186 /*- endfor -*/ 187 /*- endif -*/ 188 /*- if irq[0] and dtb_connector[0] -*/ 189 int /*? c.name ?*/_irq_acknowledge(ps_irq_t *irq) WARN_UNUSED_RESULT; 190 /* Implemented by user code or substituted for the IRQ interface. */ 191 void /*? c.name ?*/_irq_handle(ps_irq_t *irq) WEAK; 192 /*- else -*/ 193 int /*? c.name ?*/_acknowledge(void) WARN_UNUSED_RESULT 194 /*- if c.optional -*/ WEAK /*- endif -*/; 195 /* Implemented by user code or substituted for the IRQ interface. */ 196 void /*? c.name ?*/_handle(void) WEAK; 197 /*- endif -*/ 198/*- endfor -*/ 199 200/*- for e in me.type.emits -*/ 201 void /*? e.name ?*/_emit(void); 202/*- endfor -*/ 203 204/*- for d in me.type.dataports -*/ 205 extern /*? macros.dataport_type(d.type) ?*/ * /*? d.name ?*/ 206 /*- if d.optional -*/ 207 WEAK 208 /*- endif -*/; 209 int /*? d.name ?*/_cache_op(size_t start_offset, size_t size, dma_cache_op_t cache_op) 210 /*- if d.optional -*/ 211 __attribute__((weak)) 212 /*- endif -*/; 213 #define /*? d.name ?*/_release() COMPILER_MEMORY_RELEASE() 214 #define /*? d.name ?*/_acquire() COMPILER_MEMORY_ACQUIRE() 215 216/*- endfor -*/ 217 218/*- for m in me.type.mutexes -*/ 219 int /*? m.name ?*/_lock(void) WARN_UNUSED_RESULT; 220 int /*? m.name ?*/_unlock(void) WARN_UNUSED_RESULT; 221/*- endfor -*/ 222 223/*- for s in me.type.semaphores -*/ 224 int /*? s.name ?*/_wait(void) WARN_UNUSED_RESULT; 225 int /*? s.name ?*/_trywait(void) WARN_UNUSED_RESULT; 226 int /*? s.name ?*/_post(void) WARN_UNUSED_RESULT; 227/*- endfor -*/ 228 229/*- for b in me.type.binary_semaphores -*/ 230 int /*? b.name ?*/_wait(void) WARN_UNUSED_RESULT; 231 int /*? b.name ?*/_post(void) WARN_UNUSED_RESULT; 232/*- endfor -*/ 233 234/* Entry point expected to be provided by the user. */ 235int run(void); 236 237/*- set all_interfaces = me.type.provides + me.type.uses + me.type.emits + me.type.consumes + me.type.dataports -*/ 238 239/* Optional init functions provided by the user. */ 240void pre_init(void) WEAK; 241void post_init(void) WEAK; 242/*- for i in all_interfaces -*/ 243 void /*? i.name ?*/__init(void) WEAK; 244 245 void /*? i.name ?*/_timing_get_points(char ***points, size_t *size); 246 uint64_t /*? i.name ?*/_timing_get_entry(unsigned iteration, char *point); 247 void /*? i.name ?*/_timing_reset(void); 248/*- endfor -*/ 249 250void set_putchar(void (*putchar)(int c)); 251 252/*- for i in all_interfaces -*/ 253 camkes_error_handler_t /*? i.name ?*/_register_error_handler( 254 camkes_error_handler_t handler); 255/*- endfor -*/ 256 257@CMAKE_INTERFACE_INCLUDES@ 258