diff --git a/libraries/openamp_arduino/src/device.c b/libraries/openamp_arduino/src/device.c index a3bc12caf..45e08eccd 100644 --- a/libraries/openamp_arduino/src/device.c +++ b/libraries/openamp_arduino/src/device.c @@ -5,9 +5,9 @@ */ #include -#include #include #include +#include #include #include #include @@ -43,11 +43,10 @@ int metal_bus_find(const char *name, struct metal_bus **result) metal_list_for_each(&_metal.common.bus_list, node) { bus = metal_container_of(node, struct metal_bus, node); - if (strcmp(bus->name, name) != 0) - continue; - if (result) + if (strcmp(bus->name, name) == 0 && result) { *result = bus; - return 0; + return 0; + } } return -ENOENT; } @@ -106,10 +105,10 @@ int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name, metal_list_for_each(&_metal.common.generic_device_list, node) { dev = metal_container_of(node, struct metal_device, node); - if (strcmp(dev->name, dev_name) != 0) - continue; - *device = dev; - return metal_generic_dev_sys_open(dev); + if (strcmp(dev->name, dev_name) == 0) { + *device = dev; + return metal_generic_dev_sys_open(dev); + } } return -ENODEV; @@ -122,9 +121,9 @@ int metal_generic_dev_dma_map(struct metal_bus *bus, int nents_in, struct metal_sg *sg_out) { + int i; (void)bus; (void)device; - int i; if (sg_out != sg_in) memcpy(sg_out, sg_in, nents_in*(sizeof(struct metal_sg))); @@ -144,10 +143,10 @@ void metal_generic_dev_dma_unmap(struct metal_bus *bus, struct metal_sg *sg, int nents) { + int i; (void)bus; (void)device; (void)dir; - int i; for (i = 0; i < nents; i++) { metal_cache_invalidate(sg[i].virt, sg[i].len); diff --git a/libraries/openamp_arduino/src/dma.c b/libraries/openamp_arduino/src/dma.c new file mode 100644 index 000000000..7edaa549c --- /dev/null +++ b/libraries/openamp_arduino/src/dma.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +int metal_dma_map(struct metal_device *dev, + uint32_t dir, + struct metal_sg *sg_in, + int nents_in, + struct metal_sg *sg_out) +{ + int nents_out; + + if (!dev || !sg_in || !sg_out) + return -EINVAL; + if (!dev->bus->ops.dev_dma_map) + return -ENODEV; + + /* memory barrier */ + if (dir == METAL_DMA_DEV_R) + /* If it is device read, apply memory write fence. */ + atomic_thread_fence(memory_order_release); + else + /* If it is device write or r/w, apply memory r/w fence. */ + atomic_thread_fence(memory_order_acq_rel); + nents_out = dev->bus->ops.dev_dma_map(dev->bus, + dev, dir, sg_in, nents_in, sg_out); + return nents_out; +} + +void metal_dma_unmap(struct metal_device *dev, + uint32_t dir, + struct metal_sg *sg, + int nents) +{ + /* memory barrier */ + if (dir == METAL_DMA_DEV_R) + /* If it is device read, apply memory write fence. */ + atomic_thread_fence(memory_order_release); + else + /*If it is device write or r/w, apply memory r/w fence */ + atomic_thread_fence(memory_order_acq_rel); + + if (!dev || !dev->bus->ops.dev_dma_unmap || !sg) + return; + dev->bus->ops.dev_dma_unmap(dev->bus, + dev, dir, sg, nents); +} diff --git a/libraries/openamp_arduino/src/generic_device.c b/libraries/openamp_arduino/src/generic_device.c index d01fd3cd7..ec6e53834 100644 --- a/libraries/openamp_arduino/src/generic_device.c +++ b/libraries/openamp_arduino/src/generic_device.c @@ -17,7 +17,7 @@ int metal_generic_dev_sys_open(struct metal_device *dev) { struct metal_io_region *io; - unsigned i; + unsigned int i; /* map I/O memory regions */ for (i = 0; i < dev->num_regions; i++) { diff --git a/libraries/openamp_arduino/src/generic_io.c b/libraries/openamp_arduino/src/generic_io.c index 670f239d5..966bfc561 100644 --- a/libraries/openamp_arduino/src/generic_io.c +++ b/libraries/openamp_arduino/src/generic_io.c @@ -17,8 +17,8 @@ void metal_sys_io_mem_map(struct metal_io_region *io) size_t psize; size_t *va; - va = (size_t *)io->virt; - psize = io->size; + va = io->virt; + psize = (size_t)io->size; if (psize) { if (psize >> io->page_shift) psize = (size_t)1 << io->page_shift; diff --git a/libraries/openamp_arduino/src/init.c b/libraries/openamp_arduino/src/init.c index 315217741..5a6a0063d 100644 --- a/libraries/openamp_arduino/src/init.c +++ b/libraries/openamp_arduino/src/init.c @@ -11,6 +11,9 @@ int metal_init(const struct metal_init_params *params) { int error = 0; + if (_metal.common.ref_count++ != 0) + return 0; + memset(&_metal, 0, sizeof(_metal)); _metal.common.log_handler = params->log_handler; @@ -24,11 +27,15 @@ int metal_init(const struct metal_init_params *params) if (error) return error; + ++_metal.common.ref_count; return error; } void metal_finish(void) { + if (--_metal.common.ref_count != 0) + return; + metal_sys_finish(); memset(&_metal, 0, sizeof(_metal)); } diff --git a/libraries/openamp_arduino/src/io.c b/libraries/openamp_arduino/src/io.c index fccf1100e..7faf40502 100644 --- a/libraries/openamp_arduino/src/io.c +++ b/libraries/openamp_arduino/src/io.c @@ -4,17 +4,19 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include #include +#include #include #include void metal_io_init(struct metal_io_region *io, void *virt, const metal_phys_addr_t *physmap, size_t size, - unsigned page_shift, unsigned int mem_flags, + unsigned int page_shift, unsigned int mem_flags, const struct metal_io_ops *ops) { - const struct metal_io_ops nops = {NULL, NULL, NULL, NULL, NULL, NULL}; + const struct metal_io_ops nops = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; io->virt = virt; io->physmap = physmap; @@ -37,7 +39,7 @@ int metal_io_block_read(struct metal_io_region *io, unsigned long offset, unsigned char *dest = dst; int retlen; - if (offset > io->size) + if (!ptr) return -ERANGE; if ((offset + len) > io->size) len = io->size - offset; @@ -74,7 +76,7 @@ int metal_io_block_write(struct metal_io_region *io, unsigned long offset, const unsigned char *source = src; int retlen; - if (offset > io->size) + if (!ptr) return -ERANGE; if ((offset + len) > io->size) len = io->size - offset; @@ -110,7 +112,7 @@ int metal_io_block_set(struct metal_io_region *io, unsigned long offset, unsigned char *ptr = metal_io_virt(io, offset); int retlen = len; - if (offset > io->size) + if (!ptr) return -ERANGE; if ((offset + len) > io->size) len = io->size - offset; @@ -123,7 +125,7 @@ int metal_io_block_set(struct metal_io_region *io, unsigned long offset, unsigned int i; for (i = 1; i < sizeof(int); i++) - cint |= ((unsigned int)value << (8 * i)); + cint |= ((unsigned int)value << (CHAR_BIT * i)); for (; len && ((uintptr_t)ptr % sizeof(int)); ptr++, len--) *(unsigned char *)ptr = (unsigned char) value; diff --git a/libraries/openamp_arduino/src/irq.c b/libraries/openamp_arduino/src/irq.c index e61bc7e83..c8578fa3c 100644 --- a/libraries/openamp_arduino/src/irq.c +++ b/libraries/openamp_arduino/src/irq.c @@ -1,279 +1,140 @@ /* - * Copyright (c) 2016 - 2017, Xilinx Inc. and Contributors. All rights reserved. + * Copyright (c) 2019, Xilinx Inc. and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -/* - * @file generic/irq.c - * @brief generic libmetal irq definitions. - */ - #include #include -#include -#include -#include +#include #include #include -#include - -/** IRQ handlers descriptor structure */ -struct metal_irq_hddesc { - metal_irq_handler hd; /**< irq handler */ - void *drv_id; /**< id to identify the driver - of the irq handler */ - struct metal_device *dev; /**< device identifier */ - struct metal_list node; /**< node on irq handlers list */ -}; - -/** IRQ descriptor structure */ -struct metal_irq_desc { - int irq; /**< interrupt number */ - struct metal_list hdls; /**< interrupt handlers */ - struct metal_list node; /**< node on irqs list */ -}; -/** IRQ state structure */ -struct metal_irqs_state { - struct metal_list irqs; /**< interrupt descriptors */ - metal_mutex_t irq_lock; /**< access lock */ -}; +/** List of registered IRQ controller */ +static METAL_DECLARE_LIST(irq_cntrs); -static struct metal_irqs_state _irqs = { - .irqs = METAL_INIT_LIST(_irqs.irqs), - .irq_lock = METAL_MUTEX_INIT(_irqs.irq_lock), -}; - -int metal_irq_register(int irq, - metal_irq_handler hd, - struct metal_device *dev, - void *drv_id) +static int metal_irq_allocate(int irq_base, int irq_num) { - struct metal_irq_desc *irq_p = NULL; - struct metal_irq_hddesc *hdl_p; struct metal_list *node; - unsigned int irq_flags_save; + struct metal_irq_controller *cntr; + int irq_tocheck = irq_base, irq_end_tocheck; - if (irq < 0) { - metal_log(METAL_LOG_ERROR, - "%s: irq %d need to be a positive number\n", - __func__, irq); - return -EINVAL; + if (irq_num == 0) { + return METAL_IRQ_ANY; } - - if ((drv_id == NULL) || (hd == NULL)) { - metal_log(METAL_LOG_ERROR, "%s: irq %d need drv_id and hd.\n", - __func__, irq); - return -EINVAL; + if (irq_tocheck == METAL_IRQ_ANY) { + irq_tocheck = 0; } - - /* Search for irq in list */ - metal_mutex_acquire(&_irqs.irq_lock); - metal_list_for_each(&_irqs.irqs, node) { - irq_p = metal_container_of(node, struct metal_irq_desc, node); - - if (irq_p->irq == irq) { - struct metal_list *h_node; - - /* Check if drv_id already exist */ - metal_list_for_each(&irq_p->hdls, h_node) { - hdl_p = metal_container_of(h_node, - struct metal_irq_hddesc, - node); - - /* if drv_id already exist reject */ - if ((hdl_p->drv_id == drv_id) && - ((dev == NULL) || (hdl_p->dev == dev))) { - metal_log(METAL_LOG_ERROR, - "%s: irq %d already registered." - "Will not register again.\n", - __func__, irq); - metal_mutex_release(&_irqs.irq_lock); - return -EINVAL; - } + irq_end_tocheck = irq_tocheck + irq_num; + + metal_list_for_each(&irq_cntrs, node) { + int cntr_irq_base, cntr_irq_end; + + cntr = metal_container_of(node, + struct metal_irq_controller, node); + cntr_irq_base = cntr->irq_base; + cntr_irq_end = cntr_irq_base + cntr->irq_num; + if (irq_tocheck < cntr_irq_end && + irq_end_tocheck > cntr_irq_base) { + if (irq_base != METAL_IRQ_ANY) { + /* IRQ has been allocated */ + return METAL_IRQ_ANY; } - /* irq found and drv_id not used, get out of metal_list_for_each */ - break; + irq_tocheck = cntr_irq_end; + irq_end_tocheck = irq_tocheck + irq_num; } } - - /* Either need to add handler to an existing list or to a new one */ - hdl_p = metal_allocate_memory(sizeof(struct metal_irq_hddesc)); - if (hdl_p == NULL) { - metal_log(METAL_LOG_ERROR, - "%s: irq %d cannot allocate mem for drv_id %d.\n", - __func__, irq, drv_id); - metal_mutex_release(&_irqs.irq_lock); - return -ENOMEM; - } - hdl_p->hd = hd; - hdl_p->drv_id = drv_id; - hdl_p->dev = dev; - - /* interrupt already registered, add handler to existing list*/ - if ((irq_p != NULL) && (irq_p->irq == irq)) { - irq_flags_save = metal_irq_save_disable(); - metal_list_add_tail(&irq_p->hdls, &hdl_p->node); - metal_irq_restore_enable(irq_flags_save); - - metal_log(METAL_LOG_DEBUG, "%s: success, irq %d add drv_id %p \n", - __func__, irq, drv_id); - metal_mutex_release(&_irqs.irq_lock); - return 0; - } - - /* interrupt was not already registered, add */ - irq_p = metal_allocate_memory(sizeof(struct metal_irq_desc)); - if (irq_p == NULL) { - metal_log(METAL_LOG_ERROR, "%s: irq %d cannot allocate mem.\n", - __func__, irq); - metal_mutex_release(&_irqs.irq_lock); - return -ENOMEM; - } - irq_p->irq = irq; - metal_list_init(&irq_p->hdls); - metal_list_add_tail(&irq_p->hdls, &hdl_p->node); - - irq_flags_save = metal_irq_save_disable(); - metal_list_add_tail(&_irqs.irqs, &irq_p->node); - metal_irq_restore_enable(irq_flags_save); - - metal_log(METAL_LOG_DEBUG, "%s: success, added irq %d\n", __func__, irq); - metal_mutex_release(&_irqs.irq_lock); - return 0; -} - -/* helper function for metal_irq_unregister() */ -static void metal_irq_delete_node(struct metal_list *node, void *p_to_free) -{ - unsigned int irq_flags_save; - - irq_flags_save=metal_irq_save_disable(); - metal_list_del(node); - metal_irq_restore_enable(irq_flags_save); - metal_free_memory(p_to_free); + return irq_tocheck; } -int metal_irq_unregister(int irq, - metal_irq_handler hd, - struct metal_device *dev, - void *drv_id) +int metal_irq_register_controller(struct metal_irq_controller *cntr) { - struct metal_irq_desc *irq_p; + int irq_base; struct metal_list *node; - if (irq < 0) { - metal_log(METAL_LOG_ERROR, "%s: irq %d need to be a positive number\n", - __func__, irq); + if (cntr == NULL) { return -EINVAL; } - - /* Search for irq in list */ - metal_mutex_acquire(&_irqs.irq_lock); - metal_list_for_each(&_irqs.irqs, node) { - - irq_p = metal_container_of(node, struct metal_irq_desc, node); - - if (irq_p->irq == irq) { - struct metal_list *h_node, *h_prenode; - struct metal_irq_hddesc *hdl_p; - unsigned int delete_count = 0; - - metal_log(METAL_LOG_DEBUG, "%s: found irq %d\n", - __func__, irq); - - /* Search through handlers */ - metal_list_for_each(&irq_p->hdls, h_node) { - hdl_p = metal_container_of(h_node, - struct metal_irq_hddesc, - node); - - if (((hd == NULL) || (hdl_p->hd == hd)) && - ((drv_id == NULL) || (hdl_p->drv_id == drv_id)) && - ((dev == NULL) || (hdl_p->dev == dev))) { - metal_log(METAL_LOG_DEBUG, - "%s: unregister hd=%p drv_id=%p dev=%p\n", - __func__, hdl_p->hd, hdl_p->drv_id, hdl_p->dev); - h_prenode = h_node->prev; - metal_irq_delete_node(h_node, hdl_p); - h_node = h_prenode; - delete_count++; - } - } - - /* we did not find any handler to delete */ - if (!delete_count) { - metal_log(METAL_LOG_DEBUG, "%s: No matching entry\n", - __func__); - metal_mutex_release(&_irqs.irq_lock); - return -ENOENT; - - } - - /* if interrupt handlers list is empty, unregister interrupt */ - if (metal_list_is_empty(&irq_p->hdls)) { - metal_log(METAL_LOG_DEBUG, - "%s: handlers list empty, unregister interrupt\n", - __func__); - metal_irq_delete_node(node, irq_p); - } - - metal_log(METAL_LOG_DEBUG, "%s: success\n", __func__); - - metal_mutex_release(&_irqs.irq_lock); + metal_list_for_each(&irq_cntrs, node) { + if (node == &cntr->node) { return 0; } } - metal_log(METAL_LOG_DEBUG, "%s: No matching IRQ entry\n", __func__); + /* + * Allocate IRQ numbers which are not yet used by any IRQ + * controllers. + */ + irq_base = metal_irq_allocate(cntr->irq_base, cntr->irq_num); + if (irq_base == METAL_IRQ_ANY) { + return -EINVAL; + } + cntr->irq_base = irq_base; - metal_mutex_release(&_irqs.irq_lock); - return -ENOENT; + metal_list_add_tail(&irq_cntrs, &cntr->node); + return 0; } -unsigned int metal_irq_save_disable(void) +static struct metal_irq_controller *metal_irq_get_controller(int irq) { - return sys_irq_save_disable(); + struct metal_list *node; + struct metal_irq_controller *cntr; + + metal_list_for_each(&irq_cntrs, node) { + int irq_base, irq_end; + + cntr = (struct metal_irq_controller *) + metal_container_of(node, struct metal_irq_controller, + node); + irq_base = cntr->irq_base; + irq_end = irq_base + cntr->irq_num; + if (irq >= irq_base && irq < irq_end) { + return cntr; + } + } + return NULL; } -void metal_irq_restore_enable(unsigned int flags) +static void _metal_irq_set_enable(int irq, unsigned int state) { - sys_irq_restore_enable(flags); + struct metal_irq_controller *cntr; + + cntr = metal_irq_get_controller(irq); + if (cntr == NULL) { + return; + } + cntr->irq_set_enable(cntr, irq, state); } -void metal_irq_enable(unsigned int vector) +int metal_irq_register(int irq, + metal_irq_handler irq_handler, + void *arg) { - sys_irq_enable(vector); + struct metal_irq_controller *cntr; + struct metal_irq *irq_data; + + cntr = metal_irq_get_controller(irq); + if (cntr == NULL) { + return -EINVAL; + } + if (cntr->irq_register != NULL) { + return cntr->irq_register(cntr, irq, irq_handler, arg); + } + if (cntr->irqs == NULL) { + return -EINVAL; + } + irq_data = &cntr->irqs[irq - cntr->irq_base]; + irq_data->hd = irq_handler; + irq_data->arg = arg; + return 0; } -void metal_irq_disable(unsigned int vector) +void metal_irq_enable(unsigned int vector) { - sys_irq_disable(vector); + _metal_irq_set_enable((int)vector, METAL_IRQ_ENABLE); } -/** - * @brief default handler - */ -void metal_irq_isr(unsigned int vector) +void metal_irq_disable(unsigned int vector) { - struct metal_list *node; - struct metal_irq_desc *irq_p; - - metal_list_for_each(&_irqs.irqs, node) { - irq_p = metal_container_of(node, struct metal_irq_desc, node); - - if ((unsigned int)irq_p->irq == vector) { - struct metal_list *h_node; - struct metal_irq_hddesc *hdl_p; - - metal_list_for_each(&irq_p->hdls, h_node) { - hdl_p = metal_container_of(h_node, - struct metal_irq_hddesc, - node); - - (hdl_p->hd)(vector, hdl_p->drv_id); - } - } - } + _metal_irq_set_enable((int)vector, METAL_IRQ_DISABLE); } diff --git a/libraries/openamp_arduino/src/log.c b/libraries/openamp_arduino/src/log.c index 719fbd82b..22c8b9bd5 100644 --- a/libraries/openamp_arduino/src/log.c +++ b/libraries/openamp_arduino/src/log.c @@ -10,15 +10,13 @@ #include #include -#define DEFAULT_LOGGER_ON - void metal_default_log_handler(enum metal_log_level level, const char *format, ...) { #ifdef DEFAULT_LOGGER_ON char msg[1024]; va_list args; - static const char *level_strs[] = { + static const char * const level_strs[] = { "metal: emergency: ", "metal: alert: ", "metal: critical: ", @@ -36,7 +34,7 @@ void metal_default_log_handler(enum metal_log_level level, if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG) level = METAL_LOG_EMERGENCY; - printf("%s%s", level_strs[level], msg); + fprintf(stderr, "%s%s", level_strs[level], msg); #else (void)level; (void)format; diff --git a/libraries/openamp_arduino/src/metal/alloc.h b/libraries/openamp_arduino/src/metal/alloc.h index b82a09af1..02f860b12 100755 --- a/libraries/openamp_arduino/src/metal/alloc.h +++ b/libraries/openamp_arduino/src/metal/alloc.h @@ -1,46 +1,53 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file alloc.h - * @brief Memory allocation handling primitives for libmetal. - */ - -#ifndef __METAL_ALLOC__H__ -#define __METAL_ALLOC__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup Memory Allocation Interfaces - * @{ */ - -/** - * @brief allocate requested memory size - * return a pointer to the allocated memory - * - * @param[in] size size in byte of requested memory - * @return memory pointer, or 0 if it failed to allocate - */ -static inline void *metal_allocate_memory(unsigned int size); - -/** - * @brief free the memory previously allocated - * - * @param[in] ptr pointer to memory - */ -static inline void metal_free_memory(void *ptr); - -#include - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_ALLOC__H__ */ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file alloc.h + * @brief Memory allocation handling primitives for libmetal. + */ + +#ifndef __METAL_ALLOC__H__ +#define __METAL_ALLOC__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Memory Allocation Interfaces + * @{ + */ + +/** + * @brief allocate requested memory size + * return a pointer to the allocated memory + * + * @param[in] size size in byte of requested memory + * @return memory pointer, or 0 if it failed to allocate + */ +static inline void *metal_allocate_memory(unsigned int size) +{ + return __metal_allocate_memory(size); +} + +/** + * @brief free the memory previously allocated + * + * @param[in] ptr pointer to memory + */ +static inline void metal_free_memory(void *ptr) +{ + __metal_free_memory(ptr); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_ALLOC__H__ */ diff --git a/libraries/openamp_arduino/src/metal/assert.h b/libraries/openamp_arduino/src/metal/assert.h index 8357fdf5b..4476b641a 100755 --- a/libraries/openamp_arduino/src/metal/assert.h +++ b/libraries/openamp_arduino/src/metal/assert.h @@ -1,26 +1,24 @@ -/* - * Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file assert.h - * @brief Assertion support. - */ - -#ifndef __METAL_ASSERT__H__ -#define __METAL_ASSERT__H__ - -//#include -//#include -#include - -/** - * @brief Assertion macro. - * @param cond Condition to test. - */ -#define metal_assert(cond) metal_sys_assert(cond) - -#endif /* __METAL_ASSERT_H__ */ - +/* + * Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file assert.h + * @brief Assertion support. + */ + +#ifndef __METAL_ASSERT__H__ +#define __METAL_ASSERT__H__ + +#include + +/** + * @brief Assertion macro. + * @param cond Condition to test. + */ +#define metal_assert(cond) metal_sys_assert(cond) + +#endif /* __METAL_ASSERT_H__ */ + diff --git a/libraries/openamp_arduino/src/metal/atomic.h b/libraries/openamp_arduino/src/metal/atomic.h index 14f771eb8..ce8595dbf 100755 --- a/libraries/openamp_arduino/src/metal/atomic.h +++ b/libraries/openamp_arduino/src/metal/atomic.h @@ -1,32 +1,113 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file atomic.h - * @brief Atomic primitives for libmetal. - */ - -#ifndef __METAL_ATOMIC__H__ -#define __METAL_ATOMIC__H__ - -#include - -#if defined(HAVE_STDATOMIC_H) && !defined (__CC_ARM) && \ - !defined(__STDC_NO_ATOMICS__) && !defined(__cplusplus) - -# include - -#ifndef atomic_thread_fence -#define atomic_thread_fence(order) -#endif - -#elif defined(__GNUC__) -# include -#else -# include -#endif - -#endif /* __METAL_ATOMIC__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file atomic.h + * @brief Atomic primitives for libmetal. + */ + +#ifndef __METAL_ATOMIC__H__ +#define __METAL_ATOMIC__H__ + +#include + +#if defined(__cplusplus) +# include + +/* + * has the same functionality as but all members are only + * accessible in the std namespace. As the rest of libmetal is pure C, it does + * not know about namespaces, even when compiled as part of a C++ file. So we + * just export the members of into the global namespace. + */ +# include +using std::atomic_flag; +using std::memory_order; +using std::memory_order_relaxed; +using std::memory_order_consume; +using std::memory_order_acquire; +using std::memory_order_release; +using std::memory_order_acq_rel; +using std::memory_order_seq_cst; + +using std::atomic_bool; +using std::atomic_char; +using std::atomic_schar; +using std::atomic_uchar; +using std::atomic_short; +using std::atomic_ushort; +using std::atomic_int; +using std::atomic_uint; +using std::atomic_long; +using std::atomic_ulong; +using std::atomic_llong; +using std::atomic_ullong; +using std::atomic_char16_t; +using std::atomic_char32_t; +using std::atomic_wchar_t; +using std::atomic_int_least8_t; +using std::atomic_uint_least8_t; +using std::atomic_int_least16_t; +using std::atomic_uint_least16_t; +using std::atomic_int_least32_t; +using std::atomic_uint_least32_t; +using std::atomic_int_least64_t; +using std::atomic_uint_least64_t; +using std::atomic_int_fast8_t; +using std::atomic_uint_fast8_t; +using std::atomic_int_fast16_t; +using std::atomic_uint_fast16_t; +using std::atomic_int_fast32_t; +using std::atomic_uint_fast32_t; +using std::atomic_int_fast64_t; +using std::atomic_uint_fast64_t; +using std::atomic_intptr_t; +using std::atomic_uintptr_t; +using std::atomic_size_t; +using std::atomic_ptrdiff_t; +using std::atomic_intmax_t; +using std::atomic_uintmax_t; + +using std::atomic_flag_test_and_set; +using std::atomic_flag_test_and_set_explicit; +using std::atomic_flag_clear; +using std::atomic_flag_clear_explicit; +using std::atomic_init; +using std::atomic_is_lock_free; +using std::atomic_store; +using std::atomic_store_explicit; +using std::atomic_load; +using std::atomic_load_explicit; +using std::atomic_exchange; +using std::atomic_exchange_explicit; +using std::atomic_compare_exchange_strong; +using std::atomic_compare_exchange_strong_explicit; +using std::atomic_compare_exchange_weak; +using std::atomic_compare_exchange_weak_explicit; +using std::atomic_fetch_add; +using std::atomic_fetch_add_explicit; +using std::atomic_fetch_sub; +using std::atomic_fetch_sub_explicit; +using std::atomic_fetch_or; +using std::atomic_fetch_or_explicit; +using std::atomic_fetch_xor; +using std::atomic_fetch_xor_explicit; +using std::atomic_fetch_and; +using std::atomic_fetch_and_explicit; +using std::atomic_thread_fence; +using std::atomic_signal_fence; + +#elif defined(HAVE_STDATOMIC_H) && !defined(__CC_ARM) && \ + !defined(__STDC_NO_ATOMICS__) +# include +# include +#elif defined(__GNUC__) +# include +#else +# include +#endif + +#endif /* __METAL_ATOMIC__H__ */ diff --git a/libraries/openamp_arduino/src/metal/cache.h b/libraries/openamp_arduino/src/metal/cache.h index 54a015594..02917b411 100755 --- a/libraries/openamp_arduino/src/metal/cache.h +++ b/libraries/openamp_arduino/src/metal/cache.h @@ -1,57 +1,57 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file cache.h - * @brief CACHE operation primitives for libmetal. - */ - -#ifndef __METAL_CACHE__H__ -#define __METAL_CACHE__H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/** \defgroup cache CACHE Interfaces - * @{ */ - -/** - * @brief flush specified data cache - * - * @param[in] addr start memory logical address - * @param[in] len length of memory - * If addr is NULL, and len is 0, - * It will flush the whole data cache. - */ -static inline void metal_cache_flush(void *addr, unsigned int len) -{ - __metal_cache_flush(addr, len); -} - -/** - * @brief invalidate specified data cache - * - * @param[in] addr start memory logical address - * @param[in] len length of memory - * If addr is NULL, and len is 0, - * It will invalidate the whole data cache. - */ -static inline void metal_cache_invalidate(void *addr, unsigned int len) -{ - __metal_cache_invalidate(addr, len); -} - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_CACHE__H__ */ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file cache.h + * @brief CACHE operation primitives for libmetal. + */ + +#ifndef __METAL_CACHE__H__ +#define __METAL_CACHE__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup cache CACHE Interfaces + * @{ + */ + +/** + * @brief flush specified data cache + * + * @param[in] addr start memory logical address + * @param[in] len length of memory + * If addr is NULL, and len is 0, + * It will flush the whole data cache. + */ +static inline void metal_cache_flush(void *addr, unsigned int len) +{ + __metal_cache_flush(addr, len); +} + +/** + * @brief invalidate specified data cache + * + * @param[in] addr start memory logical address + * @param[in] len length of memory + * If addr is NULL, and len is 0, + * It will invalidate the whole data cache. + */ +static inline void metal_cache_invalidate(void *addr, unsigned int len) +{ + __metal_cache_invalidate(addr, len); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_CACHE__H__ */ diff --git a/libraries/openamp_arduino/src/metal/compiler.h b/libraries/openamp_arduino/src/metal/compiler.h index ec4c67517..08c20943d 100755 --- a/libraries/openamp_arduino/src/metal/compiler.h +++ b/libraries/openamp_arduino/src/metal/compiler.h @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file compiler.h - * @brief Compiler specific primitives for libmetal. - */ - -#ifndef __METAL_COMPILER__H__ -#define __METAL_COMPILER__H__ - -#if defined(__GNUC__) -# include -#elif defined(__ICCARM__) -# include -#elif defined (__CC_ARM) -# error "MDK-ARM ARMCC compiler requires the GNU extentions to work correctly" -#else -# error "Missing compiler support" -#endif - -#endif /* __METAL_COMPILER__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file compiler.h + * @brief Compiler specific primitives for libmetal. + */ + +#ifndef __METAL_COMPILER__H__ +#define __METAL_COMPILER__H__ + +#if defined(__GNUC__) +# include +#elif defined(__ICCARM__) +# include +#elif defined(__CC_ARM) +# error "MDK-ARM ARMCC compiler requires the GNU extensions to work correctly" +#else +# error "Missing compiler support" +#endif + +#endif /* __METAL_COMPILER__H__ */ diff --git a/libraries/openamp_arduino/src/metal/condition.h b/libraries/openamp_arduino/src/metal/condition.h index 953293680..b5c7b2dbe 100755 --- a/libraries/openamp_arduino/src/metal/condition.h +++ b/libraries/openamp_arduino/src/metal/condition.h @@ -1,73 +1,74 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file condition.h - * @brief Condition variable for libmetal. - */ - -#ifndef __METAL_CONDITION__H__ -#define __METAL_CONDITION__H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup condition Condition Variable Interfaces - * @{ */ - -/** Opaque libmetal condition variable data structure. */ -struct metal_condition; - -/** - * @brief Initialize a libmetal condition variable. - * @param[in] cv condition variable to initialize. - */ -static inline void metal_condition_init(struct metal_condition *cv); - -/** - * @brief Notify one waiter. - * Before calling this function, the caller - * should have acquired the mutex. - * @param[in] cv condition variable - * @return zero on no errors, non-zero on errors - * @see metal_condition_wait, metal_condition_broadcast - */ -static inline int metal_condition_signal(struct metal_condition *cv); - -/** - * @brief Notify all waiters. - * Before calling this function, the caller - * should have acquired the mutex. - * @param[in] cv condition variable - * @return zero on no errors, non-zero on errors - * @see metal_condition_wait, metal_condition_signal - */ -static inline int metal_condition_broadcast(struct metal_condition *cv); - -/** - * @brief Block until the condition variable is notified. - * Before calling this function, the caller should - * have acquired the mutex. - * @param[in] cv condition variable - * @param[in] m mutex - * @return 0 on success, non-zero on failure. - * @see metal_condition_signal - */ -int metal_condition_wait(struct metal_condition *cv, metal_mutex_t *m); - -#include - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_CONDITION__H__ */ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file condition.h + * @brief Condition variable for libmetal. + */ + +#ifndef __METAL_CONDITION__H__ +#define __METAL_CONDITION__H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup condition Condition Variable Interfaces + * @{ + */ + +/** Opaque libmetal condition variable data structure. */ +struct metal_condition; + +/** + * @brief Initialize a libmetal condition variable. + * @param[in] cv condition variable to initialize. + */ +static inline void metal_condition_init(struct metal_condition *cv); + +/** + * @brief Notify one waiter. + * Before calling this function, the caller + * should have acquired the mutex. + * @param[in] cv condition variable + * @return zero on no errors, non-zero on errors + * @see metal_condition_wait, metal_condition_broadcast + */ +static inline int metal_condition_signal(struct metal_condition *cv); + +/** + * @brief Notify all waiters. + * Before calling this function, the caller + * should have acquired the mutex. + * @param[in] cv condition variable + * @return zero on no errors, non-zero on errors + * @see metal_condition_wait, metal_condition_signal + */ +static inline int metal_condition_broadcast(struct metal_condition *cv); + +/** + * @brief Block until the condition variable is notified. + * Before calling this function, the caller should + * have acquired the mutex. + * @param[in] cv condition variable + * @param[in] m mutex + * @return 0 on success, non-zero on failure. + * @see metal_condition_signal + */ +int metal_condition_wait(struct metal_condition *cv, metal_mutex_t *m); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* __METAL_CONDITION__H__ */ diff --git a/libraries/openamp_arduino/src/metal/config.h b/libraries/openamp_arduino/src/metal/config.h index ce08057fc..3de906067 100755 --- a/libraries/openamp_arduino/src/metal/config.h +++ b/libraries/openamp_arduino/src/metal/config.h @@ -20,13 +20,13 @@ extern "C" { #define METAL_VER_MAJOR 0 /** Library minor version number. */ -#define METAL_VER_MINOR 1 +#define METAL_VER_MINOR 5 /** Library patch level. */ #define METAL_VER_PATCH 0 /** Library version string. */ -#define METAL_VER "0.1.0" +#define METAL_VER "0.5.0" /** System type (linux, generic, ...). */ #define METAL_SYSTEM "generic" diff --git a/libraries/openamp_arduino/src/metal/cpu.h b/libraries/openamp_arduino/src/metal/cpu.h index 5537afba4..26dbaa2af 100755 --- a/libraries/openamp_arduino/src/metal/cpu.h +++ b/libraries/openamp_arduino/src/metal/cpu.h @@ -1,17 +1,17 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file cpu.h - * @brief CPU primitives for libmetal. - */ - -#ifndef __METAL_CPU__H__ -#define __METAL_CPU__H__ - -# include - -#endif /* __METAL_CPU__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file cpu.h + * @brief CPU primitives for libmetal. + */ + +#ifndef __METAL_CPU__H__ +#define __METAL_CPU__H__ + +# include + +#endif /* __METAL_CPU__H__ */ diff --git a/libraries/openamp_arduino/src/metal/device.h b/libraries/openamp_arduino/src/metal/device.h index c78b50dd1..fab1c147d 100755 --- a/libraries/openamp_arduino/src/metal/device.h +++ b/libraries/openamp_arduino/src/metal/device.h @@ -1,176 +1,177 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file device.h - * @brief Bus abstraction for libmetal. - */ - -#ifndef __METAL_BUS__H__ -#define __METAL_BUS__H__ - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup device Bus Abstraction - * @{ */ - -#ifndef METAL_MAX_DEVICE_REGIONS -#define METAL_MAX_DEVICE_REGIONS 32 -#endif - -struct metal_bus; -struct metal_device; - -/** Bus operations. */ -struct metal_bus_ops { - void (*bus_close)(struct metal_bus *bus); - int (*dev_open)(struct metal_bus *bus, - const char *dev_name, - struct metal_device **device); - void (*dev_close)(struct metal_bus *bus, - struct metal_device *device); - void (*dev_irq_ack)(struct metal_bus *bus, - struct metal_device *device, - int irq); - int (*dev_dma_map)(struct metal_bus *bus, - struct metal_device *device, - uint32_t dir, - struct metal_sg *sg_in, - int nents_in, - struct metal_sg *sg_out); - void (*dev_dma_unmap)(struct metal_bus *bus, - struct metal_device *device, - uint32_t dir, - struct metal_sg *sg, - int nents); -}; - -/** Libmetal bus structure. */ -struct metal_bus { - const char *name; - struct metal_bus_ops ops; - struct metal_list devices; - struct metal_list node; -}; - -/** Libmetal generic bus. */ -extern struct metal_bus metal_generic_bus; - -/** Libmetal device structure. */ -struct metal_device { - const char *name; /**< Device name */ - struct metal_bus *bus; /**< Bus that contains device */ - unsigned num_regions; /**< Number of I/O regions in - device */ - struct metal_io_region regions[METAL_MAX_DEVICE_REGIONS]; /**< Array of - I/O regions in device*/ - struct metal_list node; /**< Node on bus' list of devices */ - int irq_num; /**< Number of IRQs per device */ - void *irq_info; /**< IRQ ID */ -}; - -/** - * @brief Register a libmetal bus. - * @param[in] bus Pre-initialized bus structure. - * @return 0 on success, or -errno on failure. - */ -extern int metal_bus_register(struct metal_bus *bus); - -/** - * @brief Unregister a libmetal bus. - * @param[in] bus Pre-registered bus structure. - * @return 0 on success, or -errno on failure. - */ -extern int metal_bus_unregister(struct metal_bus *bus); - -/** - * @brief Find a libmetal bus by name. - * @param[in] name Bus name. - * @param[out] bus Returned bus handle. - * @return 0 on success, or -errno on failure. - */ -extern int metal_bus_find(const char *name, struct metal_bus **bus); - -/** - * @brief Statically register a generic libmetal device. - * - * In non-Linux systems, devices are always required to be statically - * registered at application initialization. - * In Linux system, devices can be dynamically opened via sysfs or libfdt based - * enumeration at runtime. - * This interface is used for static registration of devices. Subsequent calls - * to metal_device_open() look up in this list of pre-registered devices on the - * "generic" bus. - * "generic" bus is used on non-Linux system to group the memory mapped devices. - * - * @param[in] device Generic device. - * @return 0 on success, or -errno on failure. - */ -extern int metal_register_generic_device(struct metal_device *device); - -/** - * @brief Open a libmetal device by name. - * @param[in] bus_name Bus name. - * @param[in] dev_name Device name. - * @param[out] device Returned device handle. - * @return 0 on success, or -errno on failure. - */ -extern int metal_device_open(const char *bus_name, const char *dev_name, - struct metal_device **device); - -/** - * @brief Close a libmetal device. - * @param[in] device Device handle. - */ -extern void metal_device_close(struct metal_device *device); - -/** - * @brief Get an I/O region accessor for a device region. - * - * @param[in] device Device handle. - * @param[in] index Region index. - * @return I/O accessor handle, or NULL on failure. - */ -static inline struct metal_io_region * -metal_device_io_region(struct metal_device *device, unsigned index) -{ - return (index < device->num_regions - ? &device->regions[index] - : NULL); -} - -/** @} */ - -#ifdef METAL_INTERNAL -extern int metal_generic_dev_sys_open(struct metal_device *dev); -extern int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name, - struct metal_device **device); -extern int metal_generic_dev_dma_map(struct metal_bus *bus, - struct metal_device *device, - uint32_t dir, - struct metal_sg *sg_in, - int nents_in, - struct metal_sg *sg_out); -extern void metal_generic_dev_dma_unmap(struct metal_bus *bus, - struct metal_device *device, - uint32_t dir, - struct metal_sg *sg, - int nents); -#endif /* METAL_INTERNAL */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_BUS__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file device.h + * @brief Bus abstraction for libmetal. + */ + +#ifndef __METAL_BUS__H__ +#define __METAL_BUS__H__ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup device Bus Abstraction + * @{ + */ + +#ifndef METAL_MAX_DEVICE_REGIONS +#define METAL_MAX_DEVICE_REGIONS 32 +#endif + +struct metal_bus; +struct metal_device; + +/** Bus operations. */ +struct metal_bus_ops { + void (*bus_close)(struct metal_bus *bus); + int (*dev_open)(struct metal_bus *bus, + const char *dev_name, + struct metal_device **device); + void (*dev_close)(struct metal_bus *bus, + struct metal_device *device); + void (*dev_irq_ack)(struct metal_bus *bus, + struct metal_device *device, + int irq); + int (*dev_dma_map)(struct metal_bus *bus, + struct metal_device *device, + uint32_t dir, + struct metal_sg *sg_in, + int nents_in, + struct metal_sg *sg_out); + void (*dev_dma_unmap)(struct metal_bus *bus, + struct metal_device *device, + uint32_t dir, + struct metal_sg *sg, + int nents); +}; + +/** Libmetal bus structure. */ +struct metal_bus { + const char *name; + struct metal_bus_ops ops; + struct metal_list devices; + struct metal_list node; +}; + +/** Libmetal generic bus. */ +extern struct metal_bus metal_generic_bus; + +/** Libmetal device structure. */ +struct metal_device { + const char *name; /**< Device name */ + struct metal_bus *bus; /**< Bus that contains device */ + unsigned int num_regions; /**< Number of I/O regions in + device */ + struct metal_io_region regions[METAL_MAX_DEVICE_REGIONS]; /**< Array of + I/O regions in device*/ + struct metal_list node; /**< Node on bus' list of devices */ + int irq_num; /**< Number of IRQs per device */ + void *irq_info; /**< IRQ ID */ +}; + +/** + * @brief Register a libmetal bus. + * @param[in] bus Pre-initialized bus structure. + * @return 0 on success, or -errno on failure. + */ +extern int metal_bus_register(struct metal_bus *bus); + +/** + * @brief Unregister a libmetal bus. + * @param[in] bus Pre-registered bus structure. + * @return 0 on success, or -errno on failure. + */ +extern int metal_bus_unregister(struct metal_bus *bus); + +/** + * @brief Find a libmetal bus by name. + * @param[in] name Bus name. + * @param[out] bus Returned bus handle. + * @return 0 on success, or -errno on failure. + */ +extern int metal_bus_find(const char *name, struct metal_bus **bus); + +/** + * @brief Statically register a generic libmetal device. + * + * In non-Linux systems, devices are always required to be statically + * registered at application initialization. + * In Linux system, devices can be dynamically opened via sysfs or libfdt based + * enumeration at runtime. + * This interface is used for static registration of devices. Subsequent calls + * to metal_device_open() look up in this list of pre-registered devices on the + * "generic" bus. + * "generic" bus is used on non-Linux system to group the memory mapped devices. + * + * @param[in] device Generic device. + * @return 0 on success, or -errno on failure. + */ +extern int metal_register_generic_device(struct metal_device *device); + +/** + * @brief Open a libmetal device by name. + * @param[in] bus_name Bus name. + * @param[in] dev_name Device name. + * @param[out] device Returned device handle. + * @return 0 on success, or -errno on failure. + */ +extern int metal_device_open(const char *bus_name, const char *dev_name, + struct metal_device **device); + +/** + * @brief Close a libmetal device. + * @param[in] device Device handle. + */ +extern void metal_device_close(struct metal_device *device); + +/** + * @brief Get an I/O region accessor for a device region. + * + * @param[in] device Device handle. + * @param[in] index Region index. + * @return I/O accessor handle, or NULL on failure. + */ +static inline struct metal_io_region * +metal_device_io_region(struct metal_device *device, unsigned int index) +{ + return (index < device->num_regions + ? &device->regions[index] + : NULL); +} + +/** @} */ + +#ifdef METAL_INTERNAL +extern int metal_generic_dev_sys_open(struct metal_device *dev); +extern int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name, + struct metal_device **device); +extern int metal_generic_dev_dma_map(struct metal_bus *bus, + struct metal_device *device, + uint32_t dir, + struct metal_sg *sg_in, + int nents_in, + struct metal_sg *sg_out); +extern void metal_generic_dev_dma_unmap(struct metal_bus *bus, + struct metal_device *device, + uint32_t dir, + struct metal_sg *sg, + int nents); +#endif /* METAL_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_BUS__H__ */ diff --git a/libraries/openamp_arduino/src/metal/dma.h b/libraries/openamp_arduino/src/metal/dma.h index 1c8e8b11c..9bb7e54c8 100755 --- a/libraries/openamp_arduino/src/metal/dma.h +++ b/libraries/openamp_arduino/src/metal/dma.h @@ -1,79 +1,80 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file dma.h - * @brief DMA primitives for libmetal. - */ - -#ifndef __METAL_DMA__H__ -#define __METAL_DMA__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup dma DMA Interfaces - * @{ */ - -#include -#include - -#define METAL_DMA_DEV_R 1 /**< DMA direction, device read */ -#define METAL_DMA_DEV_W 2 /**< DMA direction, device write */ -#define METAL_DMA_DEV_WR 3 /**< DMA direction, device read/write */ - -/** - * @brief scatter/gather list element structure - */ -struct metal_sg { - void *virt; /**< CPU virtual address */ - struct metal_io_region *io; /**< IO region */ - int len; /**< length */ -}; - -struct metal_device; - -/** - * @brief Map memory for DMA transaction. - * After the memory is DMA mapped, the memory should be - * accessed by the DMA device but not the CPU. - * - * @param[in] dev DMA device - * @param[in] dir DMA direction - * @param[in] sg_in sg list of memory to map - * @param[in] nents_in number of sg list entries of memory to map - * @param[out] sg_out sg list of mapped memory - * @return number of mapped sg entries, -error on failure. - */ -int metal_dma_map(struct metal_device *dev, - uint32_t dir, - struct metal_sg *sg_in, - int nents_in, - struct metal_sg *sg_out); - -/** - * @brief Unmap DMA memory - * After the memory is DMA unmapped, the memory should - * be accessed by the CPU but not the DMA device. - * - * @param[in] dev DMA device - * @param[in] dir DMA direction - * @param[in] sg sg list of mapped DMA memory - * @param[in] nents number of sg list entries of DMA memory - */ -void metal_dma_unmap(struct metal_device *dev, - uint32_t dir, - struct metal_sg *sg, - int nents); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_DMA__H__ */ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file dma.h + * @brief DMA primitives for libmetal. + */ + +#ifndef __METAL_DMA__H__ +#define __METAL_DMA__H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup dma DMA Interfaces + * @{ + */ + +#define METAL_DMA_DEV_R 1 /**< DMA direction, device read */ +#define METAL_DMA_DEV_W 2 /**< DMA direction, device write */ +#define METAL_DMA_DEV_WR 3 /**< DMA direction, device read/write */ + +/** + * @brief scatter/gather list element structure + */ +struct metal_sg { + void *virt; /**< CPU virtual address */ + struct metal_io_region *io; /**< IO region */ + int len; /**< length */ +}; + +struct metal_device; + +/** + * @brief Map memory for DMA transaction. + * After the memory is DMA mapped, the memory should be + * accessed by the DMA device but not the CPU. + * + * @param[in] dev DMA device + * @param[in] dir DMA direction + * @param[in] sg_in sg list of memory to map + * @param[in] nents_in number of sg list entries of memory to map + * @param[out] sg_out sg list of mapped memory + * @return number of mapped sg entries, -error on failure. + */ +int metal_dma_map(struct metal_device *dev, + uint32_t dir, + struct metal_sg *sg_in, + int nents_in, + struct metal_sg *sg_out); + +/** + * @brief Unmap DMA memory + * After the memory is DMA unmapped, the memory should + * be accessed by the CPU but not the DMA device. + * + * @param[in] dev DMA device + * @param[in] dir DMA direction + * @param[in] sg sg list of mapped DMA memory + * @param[in] nents number of sg list entries of DMA memory + */ +void metal_dma_unmap(struct metal_device *dev, + uint32_t dir, + struct metal_sg *sg, + int nents); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_DMA__H__ */ diff --git a/libraries/openamp_arduino/src/metal/errno.h b/libraries/openamp_arduino/src/metal/errno.h index 2f200e8b7..e84a2bc7d 100755 --- a/libraries/openamp_arduino/src/metal/errno.h +++ b/libraries/openamp_arduino/src/metal/errno.h @@ -1,24 +1,23 @@ -/* - * * Copyright (c) 2019 STMicrolectonics , Xilinx Inc. and Contributors. All rights reserved. - * * - * * SPDX-License-Identifier: BSD-3-Clause - * */ - -/* - * * @file metal/errno.h - * * @brief error specific primitives for libmetal. - * */ - -#ifndef __METAL_ERRNO__H__ -#define __METAL_ERRNO__H__ - -#if defined (__CC_ARM) -# include -#elif defined (__ICCARM__) -# include -#else -#include -#endif - -#endif /* __METAL_ERRNO__H__ */ - +/* + * Copyright (c) 2020 STMicroelectronnics. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file metal/errno.h + * @brief error specific primitives for libmetal. + */ + +#ifndef __METAL_ERRNO__H__ +#define __METAL_ERRNO__H__ + +#if defined(__ICCARM__) +# include +#elif defined(__CC_ARM) +# include +#else +# include +#endif + +#endif /* __METAL_ERRNO__H__ */ diff --git a/libraries/openamp_arduino/src/metal/io.h b/libraries/openamp_arduino/src/metal/io.h index 95512d826..e534d1765 100755 --- a/libraries/openamp_arduino/src/metal/io.h +++ b/libraries/openamp_arduino/src/metal/io.h @@ -1,354 +1,374 @@ -/* - * Copyright (c) 2015 - 2017, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file io.h - * @brief I/O access primitives for libmetal. - */ - -#ifndef __METAL_IO__H__ -#define __METAL_IO__H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup io IO Interfaces - * @{ */ - -#ifdef __MICROBLAZE__ -#define NO_ATOMIC_64_SUPPORT -#endif - -struct metal_io_region; - -/** Generic I/O operations. */ -struct metal_io_ops { - uint64_t (*read)(struct metal_io_region *io, - unsigned long offset, - memory_order order, - int width); - void (*write)(struct metal_io_region *io, - unsigned long offset, - uint64_t value, - memory_order order, - int width); - int (*block_read)(struct metal_io_region *io, - unsigned long offset, - void *restrict dst, - memory_order order, - int len); - int (*block_write)(struct metal_io_region *io, - unsigned long offset, - const void *restrict src, - memory_order order, - int len); - void (*block_set)(struct metal_io_region *io, - unsigned long offset, - unsigned char value, - memory_order order, - int len); - void (*close)(struct metal_io_region *io); -}; - -/** Libmetal I/O region structure. */ -struct metal_io_region { - void *virt; /**< base virtual address */ - const metal_phys_addr_t *physmap; /**< table of base physical address - of each of the pages in the I/O - region */ - size_t size; /**< size of the I/O region */ - unsigned long page_shift; /**< page shift of I/O region */ - metal_phys_addr_t page_mask; /**< page mask of I/O region */ - unsigned int mem_flags; /**< memory attribute of the - I/O region */ - struct metal_io_ops ops; /**< I/O region operations */ -}; - -/** - * @brief Open a libmetal I/O region. - * - * @param[in, out] io I/O region handle. - * @param[in] virt Virtual address of region. - * @param[in] physmap Array of physical addresses per page. - * @param[in] size Size of region. - * @param[in] page_shift Log2 of page size (-1 for single page). - * @param[in] mem_flags Memory flags - * @param[in] ops ops - */ -void -metal_io_init(struct metal_io_region *io, void *virt, - const metal_phys_addr_t *physmap, size_t size, - unsigned page_shift, unsigned int mem_flags, - const struct metal_io_ops *ops); - -/** - * @brief Close a libmetal shared memory segment. - * @param[in] io I/O region handle. - */ -static inline void metal_io_finish(struct metal_io_region *io) -{ - if (io->ops.close) - (*io->ops.close)(io); - memset(io, 0, sizeof(*io)); -} - -/** - * @brief Get size of I/O region. - * - * @param[in] io I/O region handle. - * @return Size of I/O region. - */ -static inline size_t metal_io_region_size(struct metal_io_region *io) -{ - return io->size; -} - -/** - * @brief Get virtual address for a given offset into the I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into shared memory segment. - * @return NULL if offset is out of range, or pointer to offset. - */ -static inline void * -metal_io_virt(struct metal_io_region *io, unsigned long offset) -{ - return (io->virt != METAL_BAD_VA && offset <= io->size - ? (uint8_t *)io->virt + offset - : NULL); -} - -/** - * @brief Convert a virtual address to offset within I/O region. - * @param[in] io I/O region handle. - * @param[in] virt Virtual address within segment. - * @return METAL_BAD_OFFSET if out of range, or offset. - */ -static inline unsigned long -metal_io_virt_to_offset(struct metal_io_region *io, void *virt) -{ - size_t offset = (uint8_t *)virt - (uint8_t *)io->virt; - return (offset < io->size ? offset : METAL_BAD_OFFSET); -} - -/** - * @brief Get physical address for a given offset into the I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into shared memory segment. - * @return METAL_BAD_PHYS if offset is out of range, or physical address - * of offset. - */ -static inline metal_phys_addr_t -metal_io_phys(struct metal_io_region *io, unsigned long offset) -{ - unsigned long page = (io->page_shift >= - sizeof(offset) * CHAR_BIT ? - 0 : offset >> io->page_shift); - return (io->physmap != NULL && offset <= io->size - ? io->physmap[page] + (offset & io->page_mask) - : METAL_BAD_PHYS); -} - -/** - * @brief Convert a physical address to offset within I/O region. - * @param[in] io I/O region handle. - * @param[in] phys Physical address within segment. - * @return METAL_BAD_OFFSET if out of range, or offset. - */ -static inline unsigned long -metal_io_phys_to_offset(struct metal_io_region *io, metal_phys_addr_t phys) -{ - unsigned long offset = - (io->page_mask == (metal_phys_addr_t)(-1) ? - phys - io->physmap[0] : phys & io->page_mask); - do { - if (metal_io_phys(io, offset) == phys) - return offset; - offset += io->page_mask + 1; - } while (offset < io->size); - return METAL_BAD_OFFSET; -} - -/** - * @brief Convert a physical address to virtual address. - * @param[in] io Shared memory segment handle. - * @param[in] phys Physical address within segment. - * @return NULL if out of range, or corresponding virtual address. - */ -static inline void * -metal_io_phys_to_virt(struct metal_io_region *io, metal_phys_addr_t phys) -{ - return metal_io_virt(io, metal_io_phys_to_offset(io, phys)); -} - -/** - * @brief Convert a virtual address to physical address. - * @param[in] io Shared memory segment handle. - * @param[in] virt Virtual address within segment. - * @return METAL_BAD_PHYS if out of range, or corresponding - * physical address. - */ -static inline metal_phys_addr_t -metal_io_virt_to_phys(struct metal_io_region *io, void *virt) -{ - return metal_io_phys(io, metal_io_virt_to_offset(io, virt)); -} - -/** - * @brief Read a value from an I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into I/O region. - * @param[in] order Memory ordering. - * @param[in] width Width in bytes of datatype to read. This must be 1, 2, - * 4, or 8, and a compile time constant for this function - * to inline cleanly. - * @return Value. - */ -static inline uint64_t -metal_io_read(struct metal_io_region *io, unsigned long offset, - memory_order order, int width) -{ - void *ptr = metal_io_virt(io, offset); - - if (io->ops.read) - return (*io->ops.read)(io, offset, order, width); - else if (ptr && sizeof(atomic_uchar) == width) - return atomic_load_explicit((atomic_uchar *)ptr, order); - else if (ptr && sizeof(atomic_ushort) == width) - return atomic_load_explicit((atomic_ushort *)ptr, order); - else if (ptr && sizeof(atomic_uint) == width) - return atomic_load_explicit((atomic_uint *)ptr, order); - else if (ptr && sizeof(atomic_ulong) == width) - return atomic_load_explicit((atomic_ulong *)ptr, order); -#ifndef NO_ATOMIC_64_SUPPORT - else if (ptr && sizeof(atomic_ullong) == width) - return atomic_load_explicit((atomic_ullong *)ptr, order); -#endif - metal_assert(0); - return 0; /* quiet compiler */ -} - -/** - * @brief Write a value into an I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into I/O region. - * @param[in] value Value to write. - * @param[in] order Memory ordering. - * @param[in] width Width in bytes of datatype to read. This must be 1, 2, - * 4, or 8, and a compile time constant for this function - * to inline cleanly. - */ -static inline void -metal_io_write(struct metal_io_region *io, unsigned long offset, - uint64_t value, memory_order order, int width) -{ - void *ptr = metal_io_virt(io, offset); - if (io->ops.write) - (*io->ops.write)(io, offset, value, order, width); - else if (ptr && sizeof(atomic_uchar) == width) - atomic_store_explicit((atomic_uchar *)ptr, value, order); - else if (ptr && sizeof(atomic_ushort) == width) - atomic_store_explicit((atomic_ushort *)ptr, value, order); - else if (ptr && sizeof(atomic_uint) == width) - atomic_store_explicit((atomic_uint *)ptr, value, order); - else if (ptr && sizeof(atomic_ulong) == width) - atomic_store_explicit((atomic_ulong *)ptr, value, order); -#ifndef NO_ATOMIC_64_SUPPORT - else if (ptr && sizeof(atomic_ullong) == width) - atomic_store_explicit((atomic_ullong *)ptr, value, order); -#endif - else - metal_assert (0); -} - -#define metal_io_read8_explicit(_io, _ofs, _order) \ - metal_io_read((_io), (_ofs), (_order), 1) -#define metal_io_read8(_io, _ofs) \ - metal_io_read((_io), (_ofs), memory_order_seq_cst, 1) -#define metal_io_write8_explicit(_io, _ofs, _val, _order) \ - metal_io_write((_io), (_ofs), (_val), (_order), 1) -#define metal_io_write8(_io, _ofs, _val) \ - metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 1) - -#define metal_io_read16_explicit(_io, _ofs, _order) \ - metal_io_read((_io), (_ofs), (_order), 2) -#define metal_io_read16(_io, _ofs) \ - metal_io_read((_io), (_ofs), memory_order_seq_cst, 2) -#define metal_io_write16_explicit(_io, _ofs, _val, _order) \ - metal_io_write((_io), (_ofs), (_val), (_order), 2) -#define metal_io_write16(_io, _ofs, _val) \ - metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 2) - -#define metal_io_read32_explicit(_io, _ofs, _order) \ - metal_io_read((_io), (_ofs), (_order), 4) -#define metal_io_read32(_io, _ofs) \ - metal_io_read((_io), (_ofs), memory_order_seq_cst, 4) -#define metal_io_write32_explicit(_io, _ofs, _val, _order) \ - metal_io_write((_io), (_ofs), (_val), (_order), 4) -#define metal_io_write32(_io, _ofs, _val) \ - metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 4) - -#define metal_io_read64_explicit(_io, _ofs, _order) \ - metal_io_read((_io), (_ofs), (_order), 8) -#define metal_io_read64(_io, _ofs) \ - metal_io_read((_io), (_ofs), memory_order_seq_cst, 8) -#define metal_io_write64_explicit(_io, _ofs, _val, _order) \ - metal_io_write((_io), (_ofs), (_val), (_order), 8) -#define metal_io_write64(_io, _ofs, _val) \ - metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 8) - -/** - * @brief Read a block from an I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into I/O region. - * @param[in] dst destination to store the read data. - * @param[in] len length in bytes to read. - * @return On success, number of bytes read. On failure, negative value - */ -int metal_io_block_read(struct metal_io_region *io, unsigned long offset, - void *restrict dst, int len); - -/** - * @brief Write a block into an I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into I/O region. - * @param[in] src source to write. - * @param[in] len length in bytes to write. - * @return On success, number of bytes written. On failure, negative value - */ -int metal_io_block_write(struct metal_io_region *io, unsigned long offset, - const void *restrict src, int len); - -/** - * @brief fill a block of an I/O region. - * @param[in] io I/O region handle. - * @param[in] offset Offset into I/O region. - * @param[in] value value to fill into the block - * @param[in] len length in bytes to fill. - * @return On success, number of bytes filled. On failure, negative value - */ -int metal_io_block_set(struct metal_io_region *io, unsigned long offset, - unsigned char value, int len); - -#include - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_IO__H__ */ +/* + * Copyright (c) 2015 - 2017, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file io.h + * @brief I/O access primitives for libmetal. + */ + +#ifndef __METAL_IO__H__ +#define __METAL_IO__H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup io IO Interfaces + * @{ + */ + +#ifdef __MICROBLAZE__ +#define NO_ATOMIC_64_SUPPORT +#endif + +struct metal_io_region; + +/** Generic I/O operations. */ +struct metal_io_ops { + uint64_t (*read)(struct metal_io_region *io, + unsigned long offset, + memory_order order, + int width); + void (*write)(struct metal_io_region *io, + unsigned long offset, + uint64_t value, + memory_order order, + int width); + int (*block_read)(struct metal_io_region *io, + unsigned long offset, + void *restrict dst, + memory_order order, + int len); + int (*block_write)(struct metal_io_region *io, + unsigned long offset, + const void *restrict src, + memory_order order, + int len); + void (*block_set)(struct metal_io_region *io, + unsigned long offset, + unsigned char value, + memory_order order, + int len); + void (*close)(struct metal_io_region *io); + metal_phys_addr_t (*offset_to_phys)(struct metal_io_region *io, + unsigned long offset); + unsigned long (*phys_to_offset)(struct metal_io_region *io, + metal_phys_addr_t phys); +}; + +/** Libmetal I/O region structure. */ +struct metal_io_region { + void *virt; /**< base virtual address */ + const metal_phys_addr_t *physmap; /**< table of base physical address + of each of the pages in the I/O + region */ + size_t size; /**< size of the I/O region */ + unsigned long page_shift; /**< page shift of I/O region */ + metal_phys_addr_t page_mask; /**< page mask of I/O region */ + unsigned int mem_flags; /**< memory attribute of the + I/O region */ + struct metal_io_ops ops; /**< I/O region operations */ +}; + +/** + * @brief Open a libmetal I/O region. + * + * @param[in, out] io I/O region handle. + * @param[in] virt Virtual address of region. + * @param[in] physmap Array of physical addresses per page. + * @param[in] size Size of region. + * @param[in] page_shift Log2 of page size (-1 for single page). + * @param[in] mem_flags Memory flags + * @param[in] ops ops + */ +void +metal_io_init(struct metal_io_region *io, void *virt, + const metal_phys_addr_t *physmap, size_t size, + unsigned int page_shift, unsigned int mem_flags, + const struct metal_io_ops *ops); + +/** + * @brief Close a libmetal shared memory segment. + * @param[in] io I/O region handle. + */ +static inline void metal_io_finish(struct metal_io_region *io) +{ + if (io->ops.close) + (*io->ops.close)(io); + memset(io, 0, sizeof(*io)); +} + +/** + * @brief Get size of I/O region. + * + * @param[in] io I/O region handle. + * @return Size of I/O region. + */ +static inline size_t metal_io_region_size(struct metal_io_region *io) +{ + return io->size; +} + +/** + * @brief Get virtual address for a given offset into the I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into shared memory segment. + * @return NULL if offset is out of range, or pointer to offset. + */ +static inline void * +metal_io_virt(struct metal_io_region *io, unsigned long offset) +{ + return (io->virt != METAL_BAD_VA && offset < io->size + ? (void *)((uintptr_t)io->virt + offset) + : NULL); +} + +/** + * @brief Convert a virtual address to offset within I/O region. + * @param[in] io I/O region handle. + * @param[in] virt Virtual address within segment. + * @return METAL_BAD_OFFSET if out of range, or offset. + */ +static inline unsigned long +metal_io_virt_to_offset(struct metal_io_region *io, void *virt) +{ + size_t offset = (uintptr_t)virt - (uintptr_t)io->virt; + + return (offset < io->size ? offset : METAL_BAD_OFFSET); +} + +/** + * @brief Get physical address for a given offset into the I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into shared memory segment. + * @return METAL_BAD_PHYS if offset is out of range, or physical address + * of offset. + */ +static inline metal_phys_addr_t +metal_io_phys(struct metal_io_region *io, unsigned long offset) +{ + if (!io->ops.offset_to_phys) { + unsigned long page = (io->page_shift >= + sizeof(offset) * CHAR_BIT ? + 0 : offset >> io->page_shift); + return (io->physmap && offset < io->size + ? io->physmap[page] + (offset & io->page_mask) + : METAL_BAD_PHYS); + } + + return io->ops.offset_to_phys(io, offset); +} + +/** + * @brief Convert a physical address to offset within I/O region. + * @param[in] io I/O region handle. + * @param[in] phys Physical address within segment. + * @return METAL_BAD_OFFSET if out of range, or offset. + */ +static inline unsigned long +metal_io_phys_to_offset(struct metal_io_region *io, metal_phys_addr_t phys) +{ + if (!io->ops.phys_to_offset) { + unsigned long offset = + (io->page_mask == (metal_phys_addr_t)(-1) ? + phys - io->physmap[0] : phys & io->page_mask); + do { + if (metal_io_phys(io, offset) == phys) + return offset; + offset += io->page_mask + 1; + } while (offset < io->size); + return METAL_BAD_OFFSET; + } + + return (*io->ops.phys_to_offset)(io, phys); +} + +/** + * @brief Convert a physical address to virtual address. + * @param[in] io Shared memory segment handle. + * @param[in] phys Physical address within segment. + * @return NULL if out of range, or corresponding virtual address. + */ +static inline void * +metal_io_phys_to_virt(struct metal_io_region *io, metal_phys_addr_t phys) +{ + return metal_io_virt(io, metal_io_phys_to_offset(io, phys)); +} + +/** + * @brief Convert a virtual address to physical address. + * @param[in] io Shared memory segment handle. + * @param[in] virt Virtual address within segment. + * @return METAL_BAD_PHYS if out of range, or corresponding + * physical address. + */ +static inline metal_phys_addr_t +metal_io_virt_to_phys(struct metal_io_region *io, void *virt) +{ + return metal_io_phys(io, metal_io_virt_to_offset(io, virt)); +} + +/** + * @brief Read a value from an I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into I/O region. + * @param[in] order Memory ordering. + * @param[in] width Width in bytes of datatype to read. This must be 1, 2, + * 4, or 8, and a compile time constant for this function + * to inline cleanly. + * @return Value. + */ +static inline uint64_t +metal_io_read(struct metal_io_region *io, unsigned long offset, + memory_order order, int width) +{ + void *ptr = metal_io_virt(io, offset); + + if (io->ops.read) + return (*io->ops.read)(io, offset, order, width); + else if (ptr && sizeof(atomic_uchar) == width) + return atomic_load_explicit((atomic_uchar *)ptr, order); + else if (ptr && sizeof(atomic_ushort) == width) + return atomic_load_explicit((atomic_ushort *)ptr, order); + else if (ptr && sizeof(atomic_uint) == width) + return atomic_load_explicit((atomic_uint *)ptr, order); + else if (ptr && sizeof(atomic_ulong) == width) + return atomic_load_explicit((atomic_ulong *)ptr, order); +#ifndef NO_ATOMIC_64_SUPPORT + else if (ptr && sizeof(atomic_ullong) == width) + return atomic_load_explicit((atomic_ullong *)ptr, order); +#endif + metal_assert(0); + return 0; /* quiet compiler */ +} + +/** + * @brief Write a value into an I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into I/O region. + * @param[in] value Value to write. + * @param[in] order Memory ordering. + * @param[in] width Width in bytes of datatype to read. This must be 1, 2, + * 4, or 8, and a compile time constant for this function + * to inline cleanly. + */ +static inline void +metal_io_write(struct metal_io_region *io, unsigned long offset, + uint64_t value, memory_order order, int width) +{ + void *ptr = metal_io_virt(io, offset); + + if (io->ops.write) + (*io->ops.write)(io, offset, value, order, width); + else if (ptr && sizeof(atomic_uchar) == width) + atomic_store_explicit((atomic_uchar *)ptr, (unsigned char)value, + order); + else if (ptr && sizeof(atomic_ushort) == width) + atomic_store_explicit((atomic_ushort *)ptr, + (unsigned short)value, order); + else if (ptr && sizeof(atomic_uint) == width) + atomic_store_explicit((atomic_uint *)ptr, (unsigned int)value, + order); + else if (ptr && sizeof(atomic_ulong) == width) + atomic_store_explicit((atomic_ulong *)ptr, (unsigned long)value, + order); +#ifndef NO_ATOMIC_64_SUPPORT + else if (ptr && sizeof(atomic_ullong) == width) + atomic_store_explicit((atomic_ullong *)ptr, + (unsigned long long)value, order); +#endif + else + metal_assert(0); +} + +#define metal_io_read8_explicit(_io, _ofs, _order) \ + metal_io_read((_io), (_ofs), (_order), 1) +#define metal_io_read8(_io, _ofs) \ + metal_io_read((_io), (_ofs), memory_order_seq_cst, 1) +#define metal_io_write8_explicit(_io, _ofs, _val, _order) \ + metal_io_write((_io), (_ofs), (_val), (_order), 1) +#define metal_io_write8(_io, _ofs, _val) \ + metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 1) + +#define metal_io_read16_explicit(_io, _ofs, _order) \ + metal_io_read((_io), (_ofs), (_order), 2) +#define metal_io_read16(_io, _ofs) \ + metal_io_read((_io), (_ofs), memory_order_seq_cst, 2) +#define metal_io_write16_explicit(_io, _ofs, _val, _order) \ + metal_io_write((_io), (_ofs), (_val), (_order), 2) +#define metal_io_write16(_io, _ofs, _val) \ + metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 2) + +#define metal_io_read32_explicit(_io, _ofs, _order) \ + metal_io_read((_io), (_ofs), (_order), 4) +#define metal_io_read32(_io, _ofs) \ + metal_io_read((_io), (_ofs), memory_order_seq_cst, 4) +#define metal_io_write32_explicit(_io, _ofs, _val, _order) \ + metal_io_write((_io), (_ofs), (_val), (_order), 4) +#define metal_io_write32(_io, _ofs, _val) \ + metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 4) + +#define metal_io_read64_explicit(_io, _ofs, _order) \ + metal_io_read((_io), (_ofs), (_order), 8) +#define metal_io_read64(_io, _ofs) \ + metal_io_read((_io), (_ofs), memory_order_seq_cst, 8) +#define metal_io_write64_explicit(_io, _ofs, _val, _order) \ + metal_io_write((_io), (_ofs), (_val), (_order), 8) +#define metal_io_write64(_io, _ofs, _val) \ + metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 8) + +/** + * @brief Read a block from an I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into I/O region. + * @param[in] dst destination to store the read data. + * @param[in] len length in bytes to read. + * @return On success, number of bytes read. On failure, negative value + */ +int metal_io_block_read(struct metal_io_region *io, unsigned long offset, + void *restrict dst, int len); + +/** + * @brief Write a block into an I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into I/O region. + * @param[in] src source to write. + * @param[in] len length in bytes to write. + * @return On success, number of bytes written. On failure, negative value + */ +int metal_io_block_write(struct metal_io_region *io, unsigned long offset, + const void *restrict src, int len); + +/** + * @brief fill a block of an I/O region. + * @param[in] io I/O region handle. + * @param[in] offset Offset into I/O region. + * @param[in] value value to fill into the block + * @param[in] len length in bytes to fill. + * @return On success, number of bytes filled. On failure, negative value + */ +int metal_io_block_set(struct metal_io_region *io, unsigned long offset, + unsigned char value, int len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* __METAL_IO__H__ */ diff --git a/libraries/openamp_arduino/src/metal/irq.h b/libraries/openamp_arduino/src/metal/irq.h index 9f0344e7f..43562abe1 100755 --- a/libraries/openamp_arduino/src/metal/irq.h +++ b/libraries/openamp_arduino/src/metal/irq.h @@ -1,116 +1,104 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file irq.h - * @brief Interrupt handling primitives for libmetal. - */ - -#ifndef __METAL_IRQ__H__ -#define __METAL_IRQ__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup irq Interrupt Handling Interfaces - * @{ */ - -#include - -/** IRQ handled status */ -#define METAL_IRQ_NOT_HANDLED 0 -#define METAL_IRQ_HANDLED 1 - -/** - * @brief type of interrupt handler - * @param[in] irq interrupt id - * @param[in] priv private data - * @return irq handled status - */ -typedef int (*metal_irq_handler) (int irq, void *priv); - -struct metal_device; - -/** - * @brief Register interrupt handler for driver ID/device. - * - * @param[in] irq interrupt id - * @param[in] irq_handler interrupt handler - * @param[in] dev metal device this irq belongs to (can be NULL). - * @param[in] drv_id driver id is a unique interrupt handler identifier. - * It can also be used for driver data. - * @return 0 for success, non-zero on failure - */ -int metal_irq_register(int irq, - metal_irq_handler irq_handler, - struct metal_device *dev, - void *drv_id); - -/** - * @brief Unregister interrupt handler for driver ID and/or device. - * - * If interrupt handler (hd), driver ID (drv_id) and device (dev) - * are NULL, unregister all handlers for this interrupt. - * - * If interrupt handler (hd), device (dev) or driver ID (drv_id), - * are not NULL, unregister handlers matching non NULL criterias. - * e.g: when call is made with drv_id and dev non NULL, - * all handlers matching both are unregistered. - * - * If interrupt is not found, or other criterias not matching, - * return -ENOENT - * - * @param[in] irq interrupt id - * @param[in] irq_handler interrupt handler - * @param[in] dev metal device this irq belongs to - * @param[in] drv_id driver id. It can be used for driver data. - * @return 0 for success, non-zero on failure - */ -int metal_irq_unregister(int irq, - metal_irq_handler irq_handler, - struct metal_device *dev, - void *drv_id); - -/** - * @brief disable interrupts - * @return interrupts state - */ -unsigned int metal_irq_save_disable(void); - -/** - * @brief restore interrupts to their previous state - * @param[in] flags previous interrupts state - */ -void metal_irq_restore_enable(unsigned int flags); - -/** - * @brief metal_irq_enable - * - * Enables the given interrupt - * - * @param vector - interrupt vector number - */ -void metal_irq_enable(unsigned int vector); - -/** - * @brief metal_irq_disable - * - * Disables the given interrupt - * - * @param vector - interrupt vector number - */ -void metal_irq_disable(unsigned int vector); - -#include - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_IRQ__H__ */ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file irq.h + * @brief Interrupt handling primitives for libmetal. + */ + +#ifndef __METAL_IRQ__H__ +#define __METAL_IRQ__H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup irq Interrupt Handling Interfaces + * @{ + */ + +/** IRQ handled status */ +#define METAL_IRQ_NOT_HANDLED 0 +#define METAL_IRQ_HANDLED 1 + +/** + * @brief type of interrupt handler + * @param[in] irq interrupt id + * @param[in] arg argument to pass to the handler + * @return irq handled status + */ +typedef int (*metal_irq_handler) (int irq, void *arg); + +/** + * @brief Register interrupt handler for interrupt. + * Only allow single interrupt handler for a interrupt. + * + * If irq_handler is NULL, it will unregister interrupt + * handler from interrupt + * + * @param[in] irq interrupt id + * @param[in] irq_handler interrupt handler + * @param[in] arg arg is the argument pointing to the data which + * will be passed to the interrupt handler. + * @return 0 for success, non-zero on failure + */ +int metal_irq_register(int irq, + metal_irq_handler irq_handler, + void *arg); + +/** + * @brief Unregister interrupt handler for interrupt. + * + * @param[in] irq interrupt id + */ +static inline +void metal_irq_unregister(int irq) +{ + metal_irq_register(irq, 0, NULL); +} + +/** + * @brief disable interrupts + * @return interrupts state + */ +unsigned int metal_irq_save_disable(void); + +/** + * @brief restore interrupts to their previous state + * @param[in] flags previous interrupts state + */ +void metal_irq_restore_enable(unsigned int flags); + +/** + * @brief metal_irq_enable + * + * Enables the given interrupt + * + * @param vector - interrupt vector number + */ +void metal_irq_enable(unsigned int vector); + +/** + * @brief metal_irq_disable + * + * Disables the given interrupt + * + * @param vector - interrupt vector number + */ +void metal_irq_disable(unsigned int vector); + +#include + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_IRQ__H__ */ diff --git a/libraries/openamp_arduino/src/metal/irq_controller.h b/libraries/openamp_arduino/src/metal/irq_controller.h new file mode 100644 index 000000000..c821ef48c --- /dev/null +++ b/libraries/openamp_arduino/src/metal/irq_controller.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file irq.h + * @brief Interrupt handling primitives for libmetal. + */ + +#ifndef __METAL_IRQ_CONTROLLER__H__ +#define __METAL_IRQ_CONTROLLER__H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup irq Interrupt Handling Interfaces + * @{ + */ + +#include +#include +#include + +/** IRQ ANY ID */ +#define METAL_IRQ_ANY (-1) + +/** IRQ state macro which will be passed to metal irq set state function + * to indicate which state the caller want the IRQ to change to. + */ +#define METAL_IRQ_DISABLE 0U +#define METAL_IRQ_ENABLE 1U + +struct metal_irq_controller; + +/** + * @brief type of interrupt controller to set irq enable + * @param[in] irq_cntr pointer to interrupt controller + * @param[in] irq interrupt id + * @param[in] enable IRQ state + */ +typedef void (*metal_irq_set_enable) (struct metal_irq_controller *irq_cntr, + int irq, unsigned int enable); + +/** + * @brief type of controller specific registering interrupt function + * @param[in] irq_cntr pointer to interrupt controller + * @param[in] irq interrupt id + * @param[in] hd interrupt handler + * @param[in] arg argument which will be passed to the interrupt handler + * @return 0 for success, negative value for failure + */ +typedef int (*metal_cntr_irq_register) (struct metal_irq_controller *irq_cntr, + int irq, metal_irq_handler hd, + void *arg); + +/** Libmetal interrupt structure */ +struct metal_irq { + metal_irq_handler hd; /**< Interrupt handler */ + void *arg; /**< Argument to pass to the interrupt handler */ +}; + +/** Libmetal interrupt controller structure */ +struct metal_irq_controller { + int irq_base; /**< Start of IRQ number of the range managed by + * the IRQ controller + */ + int irq_num; /**< Number of IRQs managed by the IRQ controller */ + void *arg; /**< Argument to pass to interrupt controller function */ + metal_irq_set_enable irq_set_enable; /**< function to set IRQ enable */ + metal_cntr_irq_register irq_register; /**< function to register IRQ + * handler + */ + struct metal_list node; /**< list node */ + struct metal_irq *irqs; /**< Array of IRQs managed by the controller */ +}; + +#define METAL_IRQ_CONTROLLER_DECLARE(_irq_controller, \ + _irq_base, _irq_num, \ + _arg, \ + _irq_set_enable, \ + _irq_register, \ + _irqs) \ + struct metal_irq_controller _irq_controller = { \ + .irq_base = _irq_base, \ + .irq_num = _irq_num, \ + .arg = _arg, \ + .irq_set_enable = _irq_set_enable, \ + .irq_register = _irq_register, \ + .irqs = _irqs,\ + } + +/** + * @brief metal_irq_register_controller + * + * Register IRQ controller + * This function will allocate IRQ ids if it was + * not predefined in the irq controller. There is no + * locking in the function, it is not supposed to be + * called by multiple threads. + * + * @param[in] cntr Interrupt controller to register + * @return 0 on success, or negative value for failure. + */ +int metal_irq_register_controller(struct metal_irq_controller *cntr); + +/** + * @brief metal_irq_handle + * + * Call registered IRQ handler + * + * @param[in] irq_data metal IRQ structure + * @param[in] irq IRQ id which will be passed to handler + * @return IRQ handler status + */ +static inline +int metal_irq_handle(struct metal_irq *irq_data, int irq) +{ + if (irq_data && irq_data->hd) { + return irq_data->hd(irq, irq_data->arg); + } else { + return METAL_IRQ_NOT_HANDLED; + } +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_IRQ__H__ */ diff --git a/libraries/openamp_arduino/src/metal/list.h b/libraries/openamp_arduino/src/metal/list.h index a9395ba77..eb0e7b339 100755 --- a/libraries/openamp_arduino/src/metal/list.h +++ b/libraries/openamp_arduino/src/metal/list.h @@ -1,102 +1,118 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file list.h - * @brief List primitives for libmetal. - */ - -#ifndef __METAL_LIST__H__ -#define __METAL_LIST__H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup list List Primitives - * @{ */ - -struct metal_list { - struct metal_list *next, *prev; -}; - -/* - * METAL_INIT_LIST - used for initializing an list elmenet in a static struct - * or global - */ -#define METAL_INIT_LIST(name) { .next = &name, .prev = &name } -/* - * METAL_DECLARE_LIST - used for defining and initializing a global or - * static singleton list - */ -#define METAL_DECLARE_LIST(name) \ - struct metal_list name = METAL_INIT_LIST(name) - -static inline void metal_list_init(struct metal_list *list) -{ - list->next = list->prev = list; -} - -static inline void metal_list_add_before(struct metal_list *node, - struct metal_list *new_node) -{ - new_node->prev = node->prev; - new_node->next = node; - new_node->next->prev = new_node; - new_node->prev->next = new_node; -} - -static inline void metal_list_add_after(struct metal_list *node, - struct metal_list *new_node) -{ - new_node->prev = node; - new_node->next = node->next; - new_node->next->prev = new_node; - new_node->prev->next = new_node; -} - -static inline void metal_list_add_head(struct metal_list *list, - struct metal_list *node) -{ - metal_list_add_after(list, node); -} - -static inline void metal_list_add_tail(struct metal_list *list, - struct metal_list *node) -{ - metal_list_add_before(list, node); -} - -static inline int metal_list_is_empty(struct metal_list *list) -{ - return list->next == list; -} - -static inline void metal_list_del(struct metal_list *node) -{ - node->next->prev = node->prev; - node->prev->next = node->next; - node->next = node->prev = node; -} - -static inline struct metal_list *metal_list_first(struct metal_list *list) -{ - return metal_list_is_empty(list) ? NULL : list->next; -} - -#define metal_list_for_each(list, node) \ - for ((node) = (list)->next; \ - (node) != (list); \ - (node) = (node)->next) -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_LIST__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file list.h + * @brief List primitives for libmetal. + */ + +#ifndef __METAL_LIST__H__ +#define __METAL_LIST__H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup list List Primitives + * @{ + */ + +struct metal_list { + struct metal_list *next, *prev; +}; + +/* + * METAL_INIT_LIST - used for initializing an list element in a static struct + * or global + */ +#define METAL_INIT_LIST(name) { .next = &name, .prev = &name } +/* + * METAL_DECLARE_LIST - used for defining and initializing a global or + * static singleton list + */ +#define METAL_DECLARE_LIST(name) \ + struct metal_list name = METAL_INIT_LIST(name) + +static inline void metal_list_init(struct metal_list *list) +{ + list->prev = list; + list->next = list; +} + +static inline void metal_list_add_before(struct metal_list *node, + struct metal_list *new_node) +{ + new_node->prev = node->prev; + new_node->next = node; + new_node->next->prev = new_node; + new_node->prev->next = new_node; +} + +static inline void metal_list_add_after(struct metal_list *node, + struct metal_list *new_node) +{ + new_node->prev = node; + new_node->next = node->next; + new_node->next->prev = new_node; + new_node->prev->next = new_node; +} + +static inline void metal_list_add_head(struct metal_list *list, + struct metal_list *node) +{ + metal_list_add_after(list, node); +} + +static inline void metal_list_add_tail(struct metal_list *list, + struct metal_list *node) +{ + metal_list_add_before(list, node); +} + +static inline int metal_list_is_empty(struct metal_list *list) +{ + return list->next == list; +} + +static inline void metal_list_del(struct metal_list *node) +{ + node->next->prev = node->prev; + node->prev->next = node->next; + node->prev = node; + node->next = node; +} + +static inline struct metal_list *metal_list_first(struct metal_list *list) +{ + return metal_list_is_empty(list) ? NULL : list->next; +} + +#define metal_list_for_each(list, node) \ + for ((node) = (list)->next; \ + (node) != (list); \ + (node) = (node)->next) + +static inline bool metal_list_find_node(struct metal_list *list, + struct metal_list *node) +{ + struct metal_list *n; + + metal_list_for_each(list, n) { + if (n == node) + return true; + } + return false; +} +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_LIST__H__ */ diff --git a/libraries/openamp_arduino/src/metal/log.h b/libraries/openamp_arduino/src/metal/log.h index d439ef8f4..528e4c6b0 100755 --- a/libraries/openamp_arduino/src/metal/log.h +++ b/libraries/openamp_arduino/src/metal/log.h @@ -1,93 +1,116 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file log.h - * @brief Logging support for libmetal. - */ - -#ifndef __METAL_METAL_LOG__H__ -#define __METAL_METAL_LOG__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup logging Library Logging Interfaces - * @{ */ - -/** Log message priority levels for libmetal. */ -enum metal_log_level { - METAL_LOG_EMERGENCY, /**< system is unusable. */ - METAL_LOG_ALERT, /**< action must be taken immediately. */ - METAL_LOG_CRITICAL, /**< critical conditions. */ - METAL_LOG_ERROR, /**< error conditions. */ - METAL_LOG_WARNING, /**< warning conditions. */ - METAL_LOG_NOTICE, /**< normal but significant condition. */ - METAL_LOG_INFO, /**< informational messages. */ - METAL_LOG_DEBUG, /**< debug-level messages. */ -}; - -/** Log message handler type. */ -typedef void (*metal_log_handler)(enum metal_log_level level, - const char *format, ...); - -/** - * @brief Set libmetal log handler. - * @param[in] handler log message handler. - * @return 0 on success, or -errno on failure. - */ -extern void metal_set_log_handler(metal_log_handler handler); - -/** - * @brief Get the current libmetal log handler. - * @return Current log handler. - */ -extern metal_log_handler metal_get_log_handler(void); - -/** - * @brief Set the level for libmetal logging. - * @param[in] level log message level. - */ -extern void metal_set_log_level(enum metal_log_level level); - -/** - * @brief Get the current level for libmetal logging. - * @return Current log level. - */ -extern enum metal_log_level metal_get_log_level(void); - -/** - * @brief Default libmetal log handler. This handler prints libmetal log - * mesages to stderr. - * @param[in] level log message level. - * @param[in] format log message format string. - * @return 0 on success, or -errno on failure. - */ -extern void metal_default_log_handler(enum metal_log_level level, - const char *format, ...); - - -/** - * Emit a log message if the log level permits. - * - * @param level Log level. - * @param ... Format string and arguments. - */ -#define metal_log(level, ...) \ - ((level <= _metal.common.log_level && _metal.common.log_handler) \ - ? (void)_metal.common.log_handler(level, __VA_ARGS__) \ - : (void)0) - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#include - -#endif /* __METAL_METAL_LOG__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file log.h + * @brief Logging support for libmetal. + */ + +#ifndef __METAL_METAL_LOG__H__ +#define __METAL_METAL_LOG__H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup logging Library Logging Interfaces + * @{ + */ + +/** Log message priority levels for libmetal. */ +enum metal_log_level { + METAL_LOG_EMERGENCY, /**< system is unusable. */ + METAL_LOG_ALERT, /**< action must be taken immediately. */ + METAL_LOG_CRITICAL, /**< critical conditions. */ + METAL_LOG_ERROR, /**< error conditions. */ + METAL_LOG_WARNING, /**< warning conditions. */ + METAL_LOG_NOTICE, /**< normal but significant condition. */ + METAL_LOG_INFO, /**< informational messages. */ + METAL_LOG_DEBUG, /**< debug-level messages. */ +}; + +/** Log message handler type. */ +typedef void (*metal_log_handler)(enum metal_log_level level, + const char *format, ...); + +/** + * @brief Set libmetal log handler. + * @param[in] handler log message handler. + * @return 0 on success, or -errno on failure. + */ +extern void metal_set_log_handler(metal_log_handler handler); + +/** + * @brief Get the current libmetal log handler. + * @return Current log handler. + */ +extern metal_log_handler metal_get_log_handler(void); + +/** + * @brief Set the level for libmetal logging. + * @param[in] level log message level. + */ +extern void metal_set_log_level(enum metal_log_level level); + +/** + * @brief Get the current level for libmetal logging. + * @return Current log level. + */ +extern enum metal_log_level metal_get_log_level(void); + +/** + * @brief Default libmetal log handler. This handler prints libmetal log + * messages to stderr. + * @param[in] level log message level. + * @param[in] format log message format string. + * @return 0 on success, or -errno on failure. + */ +extern void metal_default_log_handler(enum metal_log_level level, + const char *format, ...); + +/** + * @internal + * + * @brief used by the metal_log() macro to update the format string + * + * If ML_FUNC_LINE is defined this macro generates a unified format + * string for metal_log() and its convenience metal_*() macros, i.e. it + * adds function-name:line-number prefix to all log messages. + * + * @param[in] fmt format string passed from the metal_log() macro + */ +#if defined(ML_FUNC_LINE) +#define metal_fmt(fmt) "%s:%u " fmt, __func__, __LINE__ +#else /* ML_FUNC_LINE */ +#define metal_fmt(fmt) fmt +#endif /* ML_FUNC_LINE */ + +/** + * @brief Emit a log message if the log level permits. + * + * @param level Log level. + * @param fmt Format string. + * @param args... Variable number of arguments. + */ +#define metal_log(level, fmt, args...) ({ \ + if (_metal.common.log_handler && level <= _metal.common.log_level) \ + _metal.common.log_handler(level, metal_fmt(fmt), ##args); \ +}) + +#define metal_err(fmt, args...) metal_log(METAL_LOG_ERROR, fmt, ##args) +#define metal_warn(fmt, args...) metal_log(METAL_LOG_WARNING, fmt, ##args) +#define metal_info(fmt, args...) metal_log(METAL_LOG_INFO, fmt, ##args) +#define metal_dbg(fmt, args...) metal_log(METAL_LOG_DEBUG, fmt, ##args) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* __METAL_METAL_LOG__H__ */ diff --git a/libraries/openamp_arduino/src/metal/mutex.h b/libraries/openamp_arduino/src/metal/mutex.h index c241bd0db..71d9eaa21 100755 --- a/libraries/openamp_arduino/src/metal/mutex.h +++ b/libraries/openamp_arduino/src/metal/mutex.h @@ -1,87 +1,88 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file mutex.h - * @brief Mutex primitives for libmetal. - */ - -#ifndef __METAL_MUTEX__H__ -#define __METAL_MUTEX__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup mutex Mutex Interfaces - * @{ */ - -#include - -/** - * @brief Initialize a libmetal mutex. - * @param[in] mutex Mutex to initialize. - */ -static inline void metal_mutex_init(metal_mutex_t *mutex) -{ - __metal_mutex_init(mutex); -} - -/** - * @brief Deinitialize a libmetal mutex. - * @param[in] mutex Mutex to deinitialize. - */ -static inline void metal_mutex_deinit(metal_mutex_t *mutex) -{ - __metal_mutex_deinit(mutex); -} - -/** - * @brief Try to acquire a mutex - * @param[in] mutex Mutex to mutex. - * @return 0 on failure to acquire, non-zero on success. - */ -static inline int metal_mutex_try_acquire(metal_mutex_t *mutex) -{ - return __metal_mutex_try_acquire(mutex); -} - -/** - * @brief Acquire a mutex - * @param[in] mutex Mutex to mutex. - */ -static inline void metal_mutex_acquire(metal_mutex_t *mutex) -{ - __metal_mutex_acquire(mutex); -} - -/** - * @brief Release a previously acquired mutex. - * @param[in] mutex Mutex to mutex. - * @see metal_mutex_try_acquire, metal_mutex_acquire - */ -static inline void metal_mutex_release(metal_mutex_t *mutex) -{ - __metal_mutex_release(mutex); -} - -/** - * @brief Checked if a mutex has been acquired. - * @param[in] mutex mutex to check. - * @see metal_mutex_try_acquire, metal_mutex_acquire - */ -static inline int metal_mutex_is_acquired(metal_mutex_t *mutex) -{ - return __metal_mutex_is_acquired(mutex); -} - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_MUTEX__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file mutex.h + * @brief Mutex primitives for libmetal. + */ + +#ifndef __METAL_MUTEX__H__ +#define __METAL_MUTEX__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup mutex Mutex Interfaces + * @{ + */ + +/** + * @brief Initialize a libmetal mutex. + * @param[in] mutex Mutex to initialize. + */ +static inline void metal_mutex_init(metal_mutex_t *mutex) +{ + __metal_mutex_init(mutex); +} + +/** + * @brief Deinitialize a libmetal mutex. + * @param[in] mutex Mutex to deinitialize. + */ +static inline void metal_mutex_deinit(metal_mutex_t *mutex) +{ + __metal_mutex_deinit(mutex); +} + +/** + * @brief Try to acquire a mutex + * @param[in] mutex Mutex to mutex. + * @return 0 on failure to acquire, non-zero on success. + */ +static inline int metal_mutex_try_acquire(metal_mutex_t *mutex) +{ + return __metal_mutex_try_acquire(mutex); +} + +/** + * @brief Acquire a mutex + * @param[in] mutex Mutex to mutex. + */ +static inline void metal_mutex_acquire(metal_mutex_t *mutex) +{ + __metal_mutex_acquire(mutex); +} + +/** + * @brief Release a previously acquired mutex. + * @param[in] mutex Mutex to mutex. + * @see metal_mutex_try_acquire, metal_mutex_acquire + */ +static inline void metal_mutex_release(metal_mutex_t *mutex) +{ + __metal_mutex_release(mutex); +} + +/** + * @brief Checked if a mutex has been acquired. + * @param[in] mutex mutex to check. + * @see metal_mutex_try_acquire, metal_mutex_acquire + */ +static inline int metal_mutex_is_acquired(metal_mutex_t *mutex) +{ + return __metal_mutex_is_acquired(mutex); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_MUTEX__H__ */ diff --git a/libraries/openamp_arduino/src/metal/processor/arm/atomic.h b/libraries/openamp_arduino/src/metal/processor/arm/atomic.h index c5e25cdfb..ab5ee4060 100755 --- a/libraries/openamp_arduino/src/metal/processor/arm/atomic.h +++ b/libraries/openamp_arduino/src/metal/processor/arm/atomic.h @@ -1,15 +1,15 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file arm/atomic.h - * @brief ARM specific atomic primitives for libmetal. - */ - -#ifndef __METAL_ARM_ATOMIC__H__ -#define __METAL_ARM_ATOMIC__H__ - -#endif /* __METAL_ARM_ATOMIC__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file arm/atomic.h + * @brief Arm specific atomic primitives for libmetal. + */ + +#ifndef __METAL_ARM_ATOMIC__H__ +#define __METAL_ARM_ATOMIC__H__ + +#endif /* __METAL_ARM_ATOMIC__H__ */ diff --git a/libraries/openamp_arduino/src/metal/processor/arm/cpu.h b/libraries/openamp_arduino/src/metal/processor/arm/cpu.h index 3e4f8483b..0ea96102a 100755 --- a/libraries/openamp_arduino/src/metal/processor/arm/cpu.h +++ b/libraries/openamp_arduino/src/metal/processor/arm/cpu.h @@ -1,17 +1,17 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file cpu.h - * @brief CPU specific primatives - */ - -#ifndef __METAL_ARM_CPU__H__ -#define __METAL_ARM_CPU__H__ - -#define metal_cpu_yield() - -#endif /* __METAL_ARM_CPU__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file cpu.h + * @brief CPU specific primitives + */ + +#ifndef __METAL_ARM_CPU__H__ +#define __METAL_ARM_CPU__H__ + +#define metal_cpu_yield() + +#endif /* __METAL_ARM_CPU__H__ */ diff --git a/libraries/openamp_arduino/src/metal/shmem.h b/libraries/openamp_arduino/src/metal/shmem.h index 19f282caf..561a2c85d 100755 --- a/libraries/openamp_arduino/src/metal/shmem.h +++ b/libraries/openamp_arduino/src/metal/shmem.h @@ -1,83 +1,84 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file shmem.h - * @brief Shared memory primitives for libmetal. - */ - -#ifndef __METAL_SHMEM__H__ -#define __METAL_SHMEM__H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup shmem Shared Memory Interfaces - * @{ */ - -/** Generic shared memory data structure. */ -struct metal_generic_shmem { - const char *name; - struct metal_io_region io; - struct metal_list node; -}; - -/** - * @brief Open a libmetal shared memory segment. - * - * Open a shared memory segment. - * - * @param[in] name Name of segment to open. - * @param[in] size Size of segment. - * @param[out] io I/O region handle, if successful. - * @return 0 on success, or -errno on failure. - * - * @see metal_shmem_create - */ -extern int metal_shmem_open(const char *name, size_t size, - struct metal_io_region **io); - -/** - * @brief Statically register a generic shared memory region. - * - * Shared memory regions may be statically registered at application - * initialization, or may be dynamically opened. This interface is used for - * static registration of regions. Subsequent calls to metal_shmem_open() look - * up in this list of pre-registered regions. - * - * @param[in] shmem Generic shmem structure. - * @return 0 on success, or -errno on failure. - */ -extern int metal_shmem_register_generic(struct metal_generic_shmem *shmem); - -#ifdef METAL_INTERNAL - -/** - * @brief Open a statically registered shmem segment. - * - * This interface is meant for internal libmetal use within system specific - * shmem implementations. - * - * @param[in] name Name of segment to open. - * @param[in] size Size of segment. - * @param[out] io I/O region handle, if successful. - * @return 0 on success, or -errno on failure. - */ -int metal_shmem_open_generic(const char *name, size_t size, - struct metal_io_region **result); - -#endif - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_SHMEM__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file shmem.h + * @brief Shared memory primitives for libmetal. + */ + +#ifndef __METAL_SHMEM__H__ +#define __METAL_SHMEM__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup shmem Shared Memory Interfaces + * @{ + */ + +/** Generic shared memory data structure. */ +struct metal_generic_shmem { + const char *name; + struct metal_io_region io; + struct metal_list node; +}; + +/** + * @brief Open a libmetal shared memory segment. + * + * Open a shared memory segment. + * + * @param[in] name Name of segment to open. + * @param[in] size Size of segment. + * @param[out] io I/O region handle, if successful. + * @return 0 on success, or -errno on failure. + * + * @see metal_shmem_create + */ +extern int metal_shmem_open(const char *name, size_t size, + struct metal_io_region **io); + +/** + * @brief Statically register a generic shared memory region. + * + * Shared memory regions may be statically registered at application + * initialization, or may be dynamically opened. This interface is used for + * static registration of regions. Subsequent calls to metal_shmem_open() look + * up in this list of pre-registered regions. + * + * @param[in] shmem Generic shmem structure. + * @return 0 on success, or -errno on failure. + */ +extern int metal_shmem_register_generic(struct metal_generic_shmem *shmem); + +#ifdef METAL_INTERNAL + +/** + * @brief Open a statically registered shmem segment. + * + * This interface is meant for internal libmetal use within system specific + * shmem implementations. + * + * @param[in] name Name of segment to open. + * @param[in] size Size of segment. + * @param[out] io I/O region handle, if successful. + * @return 0 on success, or -errno on failure. + */ +int metal_shmem_open_generic(const char *name, size_t size, + struct metal_io_region **result); + +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_SHMEM__H__ */ diff --git a/libraries/openamp_arduino/src/metal/sleep.h b/libraries/openamp_arduino/src/metal/sleep.h index 0dad40129..b366ee5b1 100755 --- a/libraries/openamp_arduino/src/metal/sleep.h +++ b/libraries/openamp_arduino/src/metal/sleep.h @@ -1,44 +1,45 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file sleep.h - * @brief Sleep primitives for libmetal. - */ - -#ifndef __METAL_SLEEP__H__ -#define __METAL_SLEEP__H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup sleep Sleep Interfaces - * @{ */ - -/** - * @brief delay in microseconds - * delay the next execution in the calling thread - * fo usec microseconds. - * - * @param[in] usec microsecond intervals - * @return 0 on success, non-zero for failures - */ -static inline int metal_sleep_usec(unsigned int usec) -{ - return __metal_sleep_usec(usec); -} - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_SLEEP__H__ */ - +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file sleep.h + * @brief Sleep primitives for libmetal. + */ + +#ifndef __METAL_SLEEP__H__ +#define __METAL_SLEEP__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup sleep Sleep Interfaces + * @{ + */ + +/** + * @brief delay in microseconds + * delay the next execution in the calling thread + * fo usec microseconds. + * + * @param[in] usec microsecond intervals + * @return 0 on success, non-zero for failures + */ +static inline int metal_sleep_usec(unsigned int usec) +{ + return __metal_sleep_usec(usec); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_SLEEP__H__ */ + diff --git a/libraries/openamp_arduino/src/metal/softirq.h b/libraries/openamp_arduino/src/metal/softirq.h new file mode 100644 index 000000000..52ea00f18 --- /dev/null +++ b/libraries/openamp_arduino/src/metal/softirq.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file softirq.h + * @brief Soft Interrupt handling primitives for libmetal. + */ + +#ifndef __METAL_SOFTIRQ__H__ +#define __METAL_SOFTIRQ__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup soft irq Interrupt Handling Interfaces + * @{ + */ + +/** + * @brief metal_softirq_init + * + * Initialize libmetal soft IRQs controller + * + * @return 0 on success, or negative value for failure + */ +int metal_softirq_init(void); + +/** + * @brief metal_softirq_dispatch + * + * Dispatch the pending soft IRQs + */ +void metal_softirq_dispatch(void); + +/** + * @brief metal_softirq_allocate + * + * Allocate soft IRQs + * + * This function doesn't have any locking, it is not supposed + * to be called by multiple threads. + * + * @param[in] num number of soft irqs requested + * @return soft irq base for success, or negative value for failure + */ +int metal_softirq_allocate(int num); + +/** + * @brief metal_softirq_set + * + * Set soft IRQ to pending + * + * @param[in] irq soft IRQ ID to set + */ +void metal_softirq_set(int irq); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_SOFTIRQ__H__ */ diff --git a/libraries/openamp_arduino/src/metal/spinlock.h b/libraries/openamp_arduino/src/metal/spinlock.h index f6a711eb7..6992267e6 100755 --- a/libraries/openamp_arduino/src/metal/spinlock.h +++ b/libraries/openamp_arduino/src/metal/spinlock.h @@ -1,71 +1,70 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file spinlock.h - * @brief Spinlock primitives for libmetal. - */ - -#ifndef __METAL_SPINLOCK__H__ -#define __METAL_SPINLOCK__H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup spinlock Spinlock Interfaces - * @{ */ -struct metal_spinlock { - union{ - atomic_int v; - atomic_flag w; - }; -}; - -/** Static metal spinlock initialization. */ -#define METAL_SPINLOCK_INIT {ATOMIC_VAR_INIT(0)} - -/** - * @brief Initialize a libmetal spinlock. - * @param[in] slock Spinlock to initialize. - */ -static inline void metal_spinlock_init(struct metal_spinlock *slock) -{ - atomic_store(&slock->v, 0); -} - -/** - * @brief Acquire a spinlock. - * @param[in] slock Spinlock to acquire. - * @see metal_spinlock_release - */ -static inline void metal_spinlock_acquire(struct metal_spinlock *slock) -{ - while (atomic_flag_test_and_set(&slock->w)) { - metal_cpu_yield(); - } -} - -/** - * @brief Release a previously acquired spinlock. - * @param[in] slock Spinlock to release. - * @see metal_spinlock_acquire - */ -static inline void metal_spinlock_release(struct metal_spinlock *slock) -{ - atomic_flag_clear(&slock->w); -} - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_SPINLOCK__H__ */ +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file spinlock.h + * @brief Spinlock primitives for libmetal. + */ + +#ifndef __METAL_SPINLOCK__H__ +#define __METAL_SPINLOCK__H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup spinlock Spinlock Interfaces + * @{ + */ + +struct metal_spinlock { + atomic_flag v; +}; + +/** Static metal spinlock initialization. */ +#define METAL_SPINLOCK_INIT {ATOMIC_FLAG_INIT} + +/** + * @brief Initialize a libmetal spinlock. + * @param[in] slock Spinlock to initialize. + */ +static inline void metal_spinlock_init(struct metal_spinlock *slock) +{ + atomic_flag_clear(&slock->v); +} + +/** + * @brief Acquire a spinlock. + * @param[in] slock Spinlock to acquire. + * @see metal_spinlock_release + */ +static inline void metal_spinlock_acquire(struct metal_spinlock *slock) +{ + while (atomic_flag_test_and_set(&slock->v)) { + metal_cpu_yield(); + } +} + +/** + * @brief Release a previously acquired spinlock. + * @param[in] slock Spinlock to release. + * @see metal_spinlock_acquire + */ +static inline void metal_spinlock_release(struct metal_spinlock *slock) +{ + atomic_flag_clear(&slock->v); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_SPINLOCK__H__ */ diff --git a/libraries/openamp_arduino/src/metal/sys.h b/libraries/openamp_arduino/src/metal/sys.h index 12f7f6995..24822ca14 100755 --- a/libraries/openamp_arduino/src/metal/sys.h +++ b/libraries/openamp_arduino/src/metal/sys.h @@ -1,148 +1,152 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file sys.h - * @brief System primitives for libmetal. - * @brief Top level include internal to libmetal library code. - */ - -#ifndef __METAL_SYS__H__ -#define __METAL_SYS__H__ - -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup system Top Level Interfaces - * @{ */ - -/** Physical address type. */ -typedef unsigned long metal_phys_addr_t; - -/** Interrupt request number. */ -typedef int metal_irq_t; - -/** Bad offset into shared memory or I/O region. */ -#define METAL_BAD_OFFSET ((unsigned long)-1) - -/** Bad physical address value. */ -#define METAL_BAD_PHYS ((metal_phys_addr_t)-1) - -/** Bad virtual address value. */ -#define METAL_BAD_VA ((void *)-1) - -/** Bad IRQ. */ -#define METAL_BAD_IRQ ((metal_irq_t)-1) - -/** - * Initialization configuration for libmetal. - */ -struct metal_init_params { - - /** log message handler (defaults to stderr). */ - metal_log_handler log_handler; - - /** default log message level (defaults to emergency). */ - enum metal_log_level log_level; -}; - -/** - * System independent runtime state for libmetal. This is part of a system - * specific singleton data structure (@see _metal). - */ -struct metal_common_state { - /** Current log level. */ - enum metal_log_level log_level; - - /** Current log handler (null for none). */ - metal_log_handler log_handler; - - /** List of registered buses. */ - struct metal_list bus_list; - - /** Generic statically defined shared memory segments. */ - struct metal_list generic_shmem_list; - - /** Generic statically defined devices. */ - struct metal_list generic_device_list; -}; - -struct metal_state; - -#include - -#ifndef METAL_INIT_DEFAULTS -#define METAL_INIT_DEFAULTS \ -{ \ - .log_handler = metal_default_log_handler, \ - .log_level = METAL_LOG_INFO, \ -} -#endif - -/** System specific runtime data. */ -extern struct metal_state _metal; - -/** - * @brief Initialize libmetal. - * - * Initialize the libmetal library. - * - * @param[in] params Initialization params (@see metal_init_params). - * - * @return 0 on success, or -errno on failure. - * - * @see metal_finish - */ -extern int metal_init(const struct metal_init_params *params); - -/** - * @brief Shutdown libmetal. - * - * Shutdown the libmetal library, and release all reserved resources. - * - * @see metal_init - */ -extern void metal_finish(void); - -#ifdef METAL_INTERNAL - -/** - * @brief libmetal system initialization. - * - * This function initializes libmetal on Linux or Generic platforms. This - * involves obtaining necessary pieces of system information (sysfs mount path, - * page size, etc.). - * - * @param[in] params Initialization parameters (@see metal_init_params). - * @return 0 on success, or -errno on failure. - */ -extern int metal_sys_init(const struct metal_init_params *params); - -/** - * @brief libmetal system shutdown. - * - * This function shuts down and releases resources held by libmetal Linux or - * Generic platform layers. - * - * @see metal_sys_init - */ -extern void metal_sys_finish(void); - -#endif - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_SYS__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file sys.h + * @brief System primitives for libmetal. + * @brief Top level include internal to libmetal library code. + */ + +#ifndef __METAL_SYS__H__ +#define __METAL_SYS__H__ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup system Top Level Interfaces + * @{ + */ + +/** Physical address type. */ +typedef unsigned long metal_phys_addr_t; + +/** Interrupt request number. */ +typedef int metal_irq_t; + +/** Bad offset into shared memory or I/O region. */ +#define METAL_BAD_OFFSET ((unsigned long)-1) + +/** Bad physical address value. */ +#define METAL_BAD_PHYS ((metal_phys_addr_t)-1) + +/** Bad virtual address value. */ +#define METAL_BAD_VA ((void *)-1) + +/** Bad IRQ. */ +#define METAL_BAD_IRQ ((metal_irq_t)-1) + +/** + * Initialization configuration for libmetal. + */ +struct metal_init_params { + + /** log message handler (defaults to stderr). */ + metal_log_handler log_handler; + + /** default log message level (defaults to emergency). */ + enum metal_log_level log_level; +}; + +/** + * System independent runtime state for libmetal. This is part of a system + * specific singleton data structure (@see _metal). + */ +struct metal_common_state { + /** reference count to track metal_init/metal_finish. */ + int ref_count; + + /** Current log level. */ + enum metal_log_level log_level; + + /** Current log handler (null for none). */ + metal_log_handler log_handler; + + /** List of registered buses. */ + struct metal_list bus_list; + + /** Generic statically defined shared memory segments. */ + struct metal_list generic_shmem_list; + + /** Generic statically defined devices. */ + struct metal_list generic_device_list; +}; + +struct metal_state; + +#include + +#ifndef METAL_INIT_DEFAULTS +#define METAL_INIT_DEFAULTS \ +{ \ + .log_handler = metal_default_log_handler, \ + .log_level = METAL_LOG_INFO, \ +} +#endif + +/** System specific runtime data. */ +extern struct metal_state _metal; + +/** + * @brief Initialize libmetal. + * + * Initialize the libmetal library. + * + * @param[in] params Initialization params (@see metal_init_params). + * + * @return 0 on success, or -errno on failure. + * + * @see metal_finish + */ +extern int metal_init(const struct metal_init_params *params); + +/** + * @brief Shutdown libmetal. + * + * Shutdown the libmetal library, and release all reserved resources. + * + * @see metal_init + */ +extern void metal_finish(void); + +#ifdef METAL_INTERNAL + +/** + * @brief libmetal system initialization. + * + * This function initializes libmetal on Linux or Generic platforms. This + * involves obtaining necessary pieces of system information (sysfs mount path, + * page size, etc.). + * + * @param[in] params Initialization parameters (@see metal_init_params). + * @return 0 on success, or -errno on failure. + */ +extern int metal_sys_init(const struct metal_init_params *params); + +/** + * @brief libmetal system shutdown. + * + * This function shuts down and releases resources held by libmetal Linux or + * Generic platform layers. + * + * @see metal_sys_init + */ +extern void metal_sys_finish(void); + +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_SYS__H__ */ diff --git a/libraries/openamp_arduino/src/metal/system/generic/alloc.h b/libraries/openamp_arduino/src/metal/system/generic/alloc.h index 5338dd7de..6dc767fa1 100755 --- a/libraries/openamp_arduino/src/metal/system/generic/alloc.h +++ b/libraries/openamp_arduino/src/metal/system/generic/alloc.h @@ -22,12 +22,12 @@ extern "C" { #endif -static inline void *metal_allocate_memory(unsigned int size) +static inline void *__metal_allocate_memory(unsigned int size) { return (malloc(size)); } -static inline void metal_free_memory(void *ptr) +static inline void __metal_free_memory(void *ptr) { free(ptr); } diff --git a/libraries/openamp_arduino/src/metal/system/generic/cortexm/sys.h b/libraries/openamp_arduino/src/metal/system/generic/cortexm/sys.h deleted file mode 100755 index 35597d616..000000000 --- a/libraries/openamp_arduino/src/metal/system/generic/cortexm/sys.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Xilinx nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * @file generic/mp1_m4/sys.h - * @brief generic mp1_m4 system primitives for libmetal. - */ - -#ifndef __METAL_GENERIC_SYS__H__ -#error "Include metal/sys.h instead of metal/generic/cortexm/sys.h" -#endif - -#ifndef __METAL_GENERIC_MP1_M4_SYS__H__ -#define __METAL_GENERIC_MP1_M4_SYS__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MAX_IRQS) -#define MAX_IRQS 8 /**< maximum number of irqs */ -#endif - -static inline void sys_irq_enable(unsigned int vector) -{ - (void)vector; -} - -static inline void sys_irq_disable(unsigned int vector) -{ - (void)vector; -} - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_GENERIC_MP1_M4_SYS__H__ */ diff --git a/libraries/openamp_arduino/src/metal/system/generic/sys.h b/libraries/openamp_arduino/src/metal/system/generic/sys.h index f5a236852..0a19b2362 100755 --- a/libraries/openamp_arduino/src/metal/system/generic/sys.h +++ b/libraries/openamp_arduino/src/metal/system/generic/sys.h @@ -25,8 +25,6 @@ #include #include -#include "./cortexm/sys.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/libraries/openamp_arduino/src/metal/time.h b/libraries/openamp_arduino/src/metal/time.h index b05e6794a..bc24e6134 100755 --- a/libraries/openamp_arduino/src/metal/time.h +++ b/libraries/openamp_arduino/src/metal/time.h @@ -1,41 +1,42 @@ -/* - * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file time.h - * @brief Time primitives for libmetal. - */ - -#ifndef __METAL_TIME__H__ -#define __METAL_TIME__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup time TIME Interfaces - * @{ */ - -#include -#include - -/** - * @brief get timestamp - * This function returns the timestampe as unsigned long long - * value. - * - * @return timestamp - */ -unsigned long long metal_get_timestamp(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_TIME__H__ */ - +/* + * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file time.h + * @brief Time primitives for libmetal. + */ + +#ifndef __METAL_TIME__H__ +#define __METAL_TIME__H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup time TIME Interfaces + * @{ + */ + +/** + * @brief get timestamp + * This function returns the timestampe as unsigned long long + * value. + * + * @return timestamp + */ +unsigned long long metal_get_timestamp(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_TIME__H__ */ + diff --git a/libraries/openamp_arduino/src/metal/utilities.h b/libraries/openamp_arduino/src/metal/utilities.h index 95a6670a9..6b592e017 100755 --- a/libraries/openamp_arduino/src/metal/utilities.h +++ b/libraries/openamp_arduino/src/metal/utilities.h @@ -1,152 +1,165 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file utilities.h - * @brief Utility routines for libmetal. - */ - -#ifndef __METAL_UTILITIES__H__ -#define __METAL_UTILITIES__H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup utilities Simple Utilities - * @{ */ - -/** Marker for unused function arguments/variables. */ -#define metal_unused(x) do { (x) = (x); } while (0) - -/** Figure out number of elements in an array. */ -#define metal_dim(x) (sizeof(x) / sizeof(x[0])) - -/** Minimum of two numbers (warning: multiple evaluation!). */ -#define metal_min(x, y) ((x) < (y) ? (x) : (y)) - -/** Maximum of two numbers (warning: multiple evaluation!). */ -#define metal_max(x, y) ((x) > (y) ? (x) : (y)) - -/** Sign of a number [-1, 0, or 1] (warning: multiple evaluation!). */ -#define metal_sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0)) - -/** Align 'size' down to a multiple of 'align' (must be a power of two). */ -#define metal_align_down(size, align) \ - ((size) & ~((align) - 1)) - -/** Align 'size' up to a multiple of 'align' (must be a power of two). */ -#define metal_align_up(size, align) \ - metal_align_down((size) + (align) - 1, align) - -/** Divide (and round down). */ -#define metal_div_round_down(num, den) \ - ((num) / (den)) - -/** Divide (and round up). */ -#define metal_div_round_up(num, den) \ - metal_div_round_down((num) + (den) - 1, (den)) - -/** Align 'ptr' down to a multiple of 'align' (must be a power of two). */ -#define metal_ptr_align_down(ptr, align) \ - (void *)(metal_align_down((uintptr_t)(ptr), (uintptr_t)(align))) - -/** Align 'ptr' up to a multiple of 'align' (must be a power of two). */ -#define metal_ptr_align_up(ptr, align) \ - (void *)(metal_align_up((uintptr_t)(ptr), (uintptr_t)(align))) - -/** Compute offset of a field within a structure. */ -#define metal_offset_of(structure, member) \ - ((uintptr_t) &(((structure *) 0)->member)) - -/** Compute pointer to a structure given a pointer to one of its fields. */ -#define metal_container_of(ptr, structure, member) \ - (void *)((uintptr_t)(ptr) - metal_offset_of(structure, member)) - -#define METAL_BITS_PER_ULONG (8 * sizeof(unsigned long)) - -#define metal_bit(bit) (1UL << (bit)) - -#define metal_bitmap_longs(x) metal_div_round_up((x), METAL_BITS_PER_ULONG) - -static inline void metal_bitmap_set_bit(unsigned long *bitmap, int bit) -{ - bitmap[bit / METAL_BITS_PER_ULONG] |= - metal_bit(bit & (METAL_BITS_PER_ULONG - 1)); -} - -static inline int metal_bitmap_is_bit_set(unsigned long *bitmap, int bit) -{ - return bitmap[bit / METAL_BITS_PER_ULONG] & - metal_bit(bit & (METAL_BITS_PER_ULONG - 1)); -} - -static inline void metal_bitmap_clear_bit(unsigned long *bitmap, int bit) -{ - bitmap[bit / METAL_BITS_PER_ULONG] &= - ~metal_bit(bit & (METAL_BITS_PER_ULONG - 1)); -} - -static inline int metal_bitmap_is_bit_clear(unsigned long *bitmap, int bit) -{ - return !metal_bitmap_is_bit_set(bitmap, bit); -} - -static inline unsigned int -metal_bitmap_next_set_bit(unsigned long *bitmap, unsigned int start, - unsigned int max) -{ - unsigned int bit; - for (bit = start; - bit < max && !metal_bitmap_is_bit_set(bitmap, bit); - bit ++) - ; - return bit; -} - -#define metal_bitmap_for_each_set_bit(bitmap, bit, max) \ - for ((bit) = metal_bitmap_next_set_bit((bitmap), 0, (max)); \ - (bit) < (max); \ - (bit) = metal_bitmap_next_set_bit((bitmap), (bit), (max))) - -static inline unsigned int -metal_bitmap_next_clear_bit(unsigned long *bitmap, unsigned int start, - unsigned int max) -{ - unsigned int bit; - for (bit = start; - bit < max && !metal_bitmap_is_bit_clear(bitmap, bit); - bit ++) - ; - return bit; -} - -#define metal_bitmap_for_each_clear_bit(bitmap, bit, max) \ - for ((bit) = metal_bitmap_next_clear_bit((bitmap), 0, (max)); \ - (bit) < (max); \ - (bit) = metal_bitmap_next_clear_bit((bitmap), (bit), (max))) - -static inline unsigned long metal_log2(unsigned long in) -{ - unsigned long result; - - metal_assert((in & (in - 1)) == 0); - - for (result = 0; (1UL << result) < in; result ++) - ; - return result; -} - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_UTILITIES__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file utilities.h + * @brief Utility routines for libmetal. + */ + +#ifndef __METAL_UTILITIES__H__ +#define __METAL_UTILITIES__H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup utilities Simple Utilities + * @{ + */ + +#ifndef MB +#define MB (1024UL << 10UL) +#endif + +#ifndef GB +#define GB (MB << 10UL) +#endif + +/** Marker for unused function arguments/variables. */ +#define metal_unused(x) do { (x) = (x); } while (0) + +/** Figure out number of elements in an array. */ +#define metal_dim(x) (sizeof(x) / sizeof(x[0])) + +/** Minimum of two numbers (warning: multiple evaluation!). */ +#define metal_min(x, y) ((x) < (y) ? (x) : (y)) + +/** Maximum of two numbers (warning: multiple evaluation!). */ +#define metal_max(x, y) ((x) > (y) ? (x) : (y)) + +/** Sign of a number [-1, 0, or 1] (warning: multiple evaluation!). */ +#define metal_sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0)) + +/** Align 'size' down to a multiple of 'align' (must be a power of two). */ +#define metal_align_down(size, align) \ + ((size) & ~((align) - 1)) + +/** Align 'size' up to a multiple of 'align' (must be a power of two). */ +#define metal_align_up(size, align) \ + metal_align_down((size) + (align) - 1, align) + +/** Divide (and round down). */ +#define metal_div_round_down(num, den) \ + ((num) / (den)) + +/** Divide (and round up). */ +#define metal_div_round_up(num, den) \ + metal_div_round_down((num) + (den) - 1, (den)) + +/** Align 'ptr' down to a multiple of 'align' (must be a power of two). */ +#define metal_ptr_align_down(ptr, align) \ + (void *)(metal_align_down((uintptr_t)(ptr), (uintptr_t)(align))) + +/** Align 'ptr' up to a multiple of 'align' (must be a power of two). */ +#define metal_ptr_align_up(ptr, align) \ + (void *)(metal_align_up((uintptr_t)(ptr), (uintptr_t)(align))) + +/** Compute offset of a field within a structure. */ +#define metal_offset_of(structure, member) \ + ((uintptr_t)&(((structure *)0)->member)) + +/** Compute pointer to a structure given a pointer to one of its fields. */ +#define metal_container_of(ptr, structure, member) \ + (void *)((uintptr_t)(ptr) - metal_offset_of(structure, member)) + +#define METAL_BITS_PER_ULONG (CHAR_BIT * sizeof(unsigned long)) + +#define metal_bit(bit) (1UL << (bit)) + +#define metal_bitmap_longs(x) metal_div_round_up((x), METAL_BITS_PER_ULONG) + +static inline void metal_bitmap_set_bit(unsigned long *bitmap, int bit) +{ + bitmap[bit / METAL_BITS_PER_ULONG] |= + metal_bit(bit & (METAL_BITS_PER_ULONG - 1)); +} + +static inline int metal_bitmap_is_bit_set(unsigned long *bitmap, int bit) +{ + return ((bitmap[bit / METAL_BITS_PER_ULONG] & + metal_bit(bit & (METAL_BITS_PER_ULONG - 1))) == 0) ? 0 : 1; +} + +static inline void metal_bitmap_clear_bit(unsigned long *bitmap, int bit) +{ + bitmap[bit / METAL_BITS_PER_ULONG] &= + ~metal_bit(bit & (METAL_BITS_PER_ULONG - 1)); +} + +static inline int metal_bitmap_is_bit_clear(unsigned long *bitmap, int bit) +{ + return !metal_bitmap_is_bit_set(bitmap, bit); +} + +static inline unsigned int +metal_bitmap_next_set_bit(unsigned long *bitmap, unsigned int start, + unsigned int max) +{ + unsigned int bit; + + for (bit = start; + bit < max && !metal_bitmap_is_bit_set(bitmap, bit); + bit++) + ; + return bit; +} + +#define metal_bitmap_for_each_set_bit(bitmap, bit, max) \ + for ((bit) = metal_bitmap_next_set_bit((bitmap), 0, (max)); \ + (bit) < (max); \ + (bit) = metal_bitmap_next_set_bit((bitmap), (bit + 1), (max))) + +static inline unsigned int +metal_bitmap_next_clear_bit(unsigned long *bitmap, unsigned int start, + unsigned int max) +{ + unsigned int bit; + + for (bit = start; + bit < max && !metal_bitmap_is_bit_clear(bitmap, bit); + bit++) + ; + return bit; +} + +#define metal_bitmap_for_each_clear_bit(bitmap, bit, max) \ + for ((bit) = metal_bitmap_next_clear_bit((bitmap), 0, (max)); \ + (bit) < (max); \ + (bit) = metal_bitmap_next_clear_bit((bitmap), (bit + 1), (max))) + +static inline unsigned long metal_log2(unsigned long in) +{ + unsigned long result; + + metal_assert((in & (in - 1)) == 0); + + for (result = 0; (1UL << result) < in; result++) + ; + return result; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_UTILITIES__H__ */ diff --git a/libraries/openamp_arduino/src/metal/version.h b/libraries/openamp_arduino/src/metal/version.h index 96666b3aa..32be7ae69 100755 --- a/libraries/openamp_arduino/src/metal/version.h +++ b/libraries/openamp_arduino/src/metal/version.h @@ -1,76 +1,77 @@ -/* - * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * @file version.h - * @brief Library version information for libmetal. - */ - -#ifndef __METAL_VERSION__H__ -#define __METAL_VERSION__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup versions Library Version Interfaces - * @{ */ - -/** - * @brief Library major version number. - * - * Return the major version number of the library linked into the application. - * This is required to match the value of METAL_VER_MAJOR, which is the major - * version of the library that the application was compiled against. - * - * @return Library major version number. - * @see METAL_VER_MAJOR - */ -extern int metal_ver_major(void); - -/** - * @brief Library minor version number. - * - * Return the minor version number of the library linked into the application. - * This could differ from the value of METAL_VER_MINOR, which is the minor - * version of the library that the application was compiled against. - * - * @return Library minor version number. - * @see METAL_VER_MINOR - */ -extern int metal_ver_minor(void); - -/** - * @brief Library patch level. - * - * Return the patch level of the library linked into the application. This - * could differ from the value of METAL_VER_PATCH, which is the patch level of - * the library that the application was compiled against. - * - * @return Library patch level. - * @see METAL_VER_PATCH - */ -extern int metal_ver_patch(void); - -/** - * @brief Library version string. - * - * Return the version string of the library linked into the application. This - * could differ from the value of METAL_VER, which is the version string of - * the library that the application was compiled against. - * - * @return Library version string. - * @see METAL_VER - */ -extern const char *metal_ver(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __METAL_VERSION__H__ */ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * @file version.h + * @brief Library version information for libmetal. + */ + +#ifndef __METAL_VERSION__H__ +#define __METAL_VERSION__H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup versions Library Version Interfaces + * @{ + */ + +/** + * @brief Library major version number. + * + * Return the major version number of the library linked into the application. + * This is required to match the value of METAL_VER_MAJOR, which is the major + * version of the library that the application was compiled against. + * + * @return Library major version number. + * @see METAL_VER_MAJOR + */ +extern int metal_ver_major(void); + +/** + * @brief Library minor version number. + * + * Return the minor version number of the library linked into the application. + * This could differ from the value of METAL_VER_MINOR, which is the minor + * version of the library that the application was compiled against. + * + * @return Library minor version number. + * @see METAL_VER_MINOR + */ +extern int metal_ver_minor(void); + +/** + * @brief Library patch level. + * + * Return the patch level of the library linked into the application. This + * could differ from the value of METAL_VER_PATCH, which is the patch level of + * the library that the application was compiled against. + * + * @return Library patch level. + * @see METAL_VER_PATCH + */ +extern int metal_ver_patch(void); + +/** + * @brief Library version string. + * + * Return the version string of the library linked into the application. This + * could differ from the value of METAL_VER, which is the version string of + * the library that the application was compiled against. + * + * @return Library version string. + * @see METAL_VER + */ +extern const char *metal_ver(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __METAL_VERSION__H__ */ diff --git a/libraries/openamp_arduino/src/shmem.c b/libraries/openamp_arduino/src/shmem.c index 5ead8e755..0ded4ec4a 100644 --- a/libraries/openamp_arduino/src/shmem.c +++ b/libraries/openamp_arduino/src/shmem.c @@ -9,8 +9,8 @@ * @brief Generic libmetal shared memory handling. */ -#include #include +#include #include #include #include @@ -38,10 +38,10 @@ int metal_shmem_open_generic(const char *name, size_t size, shmem = metal_container_of(node, struct metal_generic_shmem, node); if (strcmp(shmem->name, name) != 0) continue; - if (size > metal_io_region_size(&shmem->io)) - continue; - *result = &shmem->io; - return 0; + if (size <= metal_io_region_size(&shmem->io)) { + *result = &shmem->io; + return 0; + } } return -ENOENT; diff --git a/libraries/openamp_arduino/src/softirq.c b/libraries/openamp_arduino/src/softirq.c new file mode 100644 index 000000000..4ba745fa1 --- /dev/null +++ b/libraries/openamp_arduino/src/softirq.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2019, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define METAL_SOFTIRQ_NUM 64 + +#define METAL_SOFTIRQ_ARRAY_DECLARE(num) \ + static const int metal_softirq_num = num; \ + static struct metal_irq metal_softirqs[num]; \ + static atomic_char metal_softirq_pending[num]; \ + static atomic_char metal_softirq_enabled[num]; + +static int metal_softirq_avail; +METAL_SOFTIRQ_ARRAY_DECLARE(METAL_SOFTIRQ_NUM) + +static void metal_softirq_set_enable(struct metal_irq_controller *cntr, + int irq, unsigned int enable) +{ + if (irq < cntr->irq_base || + irq >= (cntr->irq_base + cntr->irq_num)) { + return; + } + + irq -= cntr->irq_base; + if (enable == METAL_IRQ_ENABLE) { + atomic_store(&metal_softirq_enabled[irq], 1); + } else { + atomic_store(&metal_softirq_enabled[irq], 0); + } +} + +static METAL_IRQ_CONTROLLER_DECLARE(metal_softirq_cntr, + METAL_IRQ_ANY, METAL_SOFTIRQ_NUM, + NULL, + metal_softirq_set_enable, NULL, + metal_softirqs); + +void metal_softirq_set(int irq) +{ + struct metal_irq_controller *cntr; + + cntr = &metal_softirq_cntr; + + if (irq < cntr->irq_base || + irq >= (cntr->irq_base + cntr->irq_num)) { + return; + } + + irq -= cntr->irq_base; + atomic_store(&metal_softirq_pending[irq], 1); +} + +int metal_softirq_init(void) +{ + return metal_irq_register_controller(&metal_softirq_cntr); +} + +int metal_softirq_allocate(int num) +{ + int irq_base; + + if ((metal_softirq_avail + num) >= metal_softirq_num) { + metal_log(METAL_LOG_ERROR, "No %d available soft irqs.\r\n", + num); + return -EINVAL; + } + irq_base = metal_softirq_avail; + irq_base += metal_softirq_cntr.irq_base; + metal_softirq_avail += num; + return irq_base; +} + +void metal_softirq_dispatch(void) +{ + int i; + + for (i = 0; i < metal_softirq_num; i++) { + struct metal_irq *irq; + char is_pending = 1; + + if (atomic_load(&metal_softirq_enabled[i]) != 0 && + atomic_compare_exchange_strong(&metal_softirq_pending[i], + &is_pending, 0)) { + irq = &metal_softirqs[i]; + (void)metal_irq_handle(irq, + i + metal_softirq_cntr.irq_base); + } + } +} diff --git a/libraries/openamp_arduino/src/version.c b/libraries/openamp_arduino/src/version.c new file mode 100644 index 000000000..bc23ee480 --- /dev/null +++ b/libraries/openamp_arduino/src/version.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +int metal_ver_major(void) +{ + return METAL_VER_MAJOR; +} + +int metal_ver_minor(void) +{ + return METAL_VER_MINOR; +} + +int metal_ver_patch(void) +{ + return METAL_VER_PATCH; +} + +const char *metal_ver(void) +{ + return METAL_VER; +}