blob: 999124334c5a2bcdfb53648fafe8c7bbea0aab16 [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/*- import 'helpers/error.c' as error with context -*/
#include <assert.h>
#include <camkes/error.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <sel4/sel4.h>
#include <camkes/io.h>
#include <utils/attribute.h>
#include <platsupport/io.h>
/*? macros.show_includes(me.instance.type.includes) ?*/
/*- set ioport = [] -*/
/*- set attr = configuration[me.parent.to_instance.name].get('%s_attributes' % me.parent.to_interface.name) -*/
/*- set port_range = [] -*/
/*- if attr is not none -*/
/*- set start, end = attr.strip('"').split(':') -*/
/*- set start = int(start, 0) -*/
/*- set end = int(end, 0) -*/
/*- do port_range.extend([start, end]) -*/
/*- do ioport.append(alloc('ioport', seL4_IA32_IOPort, start_port=start, end_port=end + 1)) -*/
int /*? me.interface.name ?*/_in_range(unsigned port) {
return port >= /*? start ?*/ && port <= /*? end ?*/;
}
/*- endif -*/
/* Interface-specific error handling */
/*- set error_handler = '%s_error_handler' % me.parent.to_interface.name -*/
/*? error.make_error_handler(me.interface.name, error_handler) ?*/
static char *interface_name = "/*? me.parent.to_interface ?*/";
/* Expose the IO port region */
static ioport_region_t /*? me.interface.name ?*/_region = {
.start = /*? start ?*/,
.end = /*? end ?*/,
.cap = /*? ioport[0] ?*/,
.error_handler = /*? error_handler ?*/,
.interface_name = &interface_name,
};
USED SECTION("_ioport_regions")
ioport_region_t * /*? me.interface.name ?*/_region_ptr = &/*? me.interface.name ?*/_region;
static ps_io_port_ops_t ops;
static bool ops_inited = false;
static inline int init_io_port_ops(void)
{
assert(camkes_io_port_ops(&ops) == 0);
ops_inited = true;
return 0;
}
uint8_t /*? me.interface.name ?*/_in8_offset(uint16_t offset)
{
if (!ops_inited) {
init_io_port_ops();
}
assert(/*? me.interface.name ?*/_in_range(/*? port_range[0] ?*/ + offset));
uint32_t result = 0;
int ret = ps_io_port_in(&ops, /*? port_range[0] ?*/ + offset, IOSIZE_8, &result);
if (ret) {
return 0;
}
return (uint8_t) result;
}
uint16_t /*? me.interface.name ?*/_in16_offset(uint16_t offset)
{
if (!ops_inited) {
init_io_port_ops();
}
assert(/*? me.interface.name ?*/_in_range(/*? port_range[0] ?*/ + offset));
uint32_t result = 0;
int ret = ps_io_port_in(&ops, /*? port_range[0] ?*/ + offset, IOSIZE_16, &result);
if (ret) {
return 0;
}
return (uint16_t) result;
}
uint32_t /*? me.interface.name ?*/_in32_offset(uint16_t offset)
{
if (!ops_inited) {
init_io_port_ops();
}
assert(/*? me.interface.name ?*/_in_range(/*? port_range[0] ?*/ + offset));
uint32_t result = 0;
int ret = ps_io_port_in(&ops, /*? port_range[0] ?*/ + offset, IOSIZE_32, &result);
if (ret) {
return 0;
}
return (uint32_t) result;
}
void /*? me.interface.name ?*/_out8_offset(uint16_t offset, uint8_t value)
{
if (!ops_inited) {
init_io_port_ops();
}
assert(/*? me.interface.name ?*/_in_range(/*? port_range[0] ?*/ + offset));
/* Ignore the return value */
ps_io_port_out(&ops, /*? port_range[0] ?*/ + offset, IOSIZE_8, value);
}
void /*? me.interface.name ?*/_out16_offset(uint16_t offset, uint16_t value)
{
if (!ops_inited) {
init_io_port_ops();
}
assert(/*? me.interface.name ?*/_in_range(/*? port_range[0] ?*/ + offset));
/* Ignore the return value */
ps_io_port_out(&ops, /*? port_range[0] ?*/ + offset, IOSIZE_16, value);
}
void /*? me.interface.name ?*/_out32_offset(uint16_t offset, uint32_t value)
{
if (!ops_inited) {
init_io_port_ops();
}
assert(/*? me.interface.name ?*/_in_range(/*? port_range[0] ?*/ + offset));
/* Ignore the return value */
ps_io_port_out(&ops, /*? port_range[0] ?*/ + offset, IOSIZE_32, value);
}