summaryrefslogtreecommitdiff
path: root/middleware/multicore/open-amp/porting/env/freertos/rpmsg_porting.c
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/multicore/open-amp/porting/env/freertos/rpmsg_porting.c')
-rw-r--r--middleware/multicore/open-amp/porting/env/freertos/rpmsg_porting.c640
1 files changed, 640 insertions, 0 deletions
diff --git a/middleware/multicore/open-amp/porting/env/freertos/rpmsg_porting.c b/middleware/multicore/open-amp/porting/env/freertos/rpmsg_porting.c
new file mode 100644
index 0000000..54c8054
--- /dev/null
+++ b/middleware/multicore/open-amp/porting/env/freertos/rpmsg_porting.c
@@ -0,0 +1,640 @@
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2015 Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2015 Freescale Semiconductor, Inc. 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 Mentor Graphics Corporation 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 NAME
+ *
+ * freertos_env.c
+ *
+ *
+ * DESCRIPTION
+ *
+ * This file is FreeRTOS Implementation of env layer for OpenAMP.
+ *
+ *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "porting/env/env.h"
+#include "porting/config/config.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+#include "platform.h"
+
+#if (defined(__CC_ARM))
+#define MEM_BARRIER() __schedule_barrier()
+#elif (defined(__GNUC__))
+#define MEM_BARRIER() asm volatile("" ::: "memory")
+#else
+#define MEM_BARRIER()
+#endif
+
+static int env_init_counter = 0;
+static struct isr_info isr_table[ISR_COUNT];
+
+
+/**
+ * env_in_isr
+ *
+ * @returns - true, if currently in ISR
+ *
+ */
+int env_in_isr(void)
+{
+ return platform_in_isr();
+}
+
+/**
+ * env_init
+ *
+ * Initializes environment.
+ *
+ */
+int env_init() {
+ // verify 'env_init_counter'
+ assert(env_init_counter >= 0);
+ if (env_init_counter < 0)
+ return -1;
+ env_init_counter++;
+ // multiple call of 'env_init' - return ok
+ if (1 < env_init_counter)
+ return 0;
+ // first call
+ memset(isr_table, 0, sizeof(isr_table));
+ return platform_init();
+}
+
+/**
+ * env_deinit
+ *
+ * Uninitializes environment.
+ *
+ * @returns - execution status
+ */
+int env_deinit() {
+ // verify 'env_init_counter'
+ assert(env_init_counter > 0);
+ if (env_init_counter <= 0)
+ return -1;
+ // counter on zero - call platform deinit
+ env_init_counter--;
+ // multiple call of 'env_deinit' - return ok
+ if (0 < env_init_counter)
+ return 0;
+ // last call
+ memset(isr_table, 0, sizeof(isr_table));
+ return platform_deinit();
+}
+/**
+ * env_allocate_memory - implementation
+ *
+ * @param size
+ */
+void *env_allocate_memory(unsigned int size)
+{
+ return (pvPortMalloc(size));
+}
+
+/**
+ * env_free_memory - implementation
+ *
+ * @param ptr
+ */
+void env_free_memory(void *ptr)
+{
+ vPortFree(ptr);
+}
+
+/**
+ *
+ * env_memset - implementation
+ *
+ * @param ptr
+ * @param value
+ * @param size
+ */
+void env_memset(void *ptr, int value, unsigned long size)
+{
+ memset(ptr, value, size);
+}
+
+/**
+ *
+ * env_memcpy - implementation
+ *
+ * @param dst
+ * @param src
+ * @param len
+ */
+void env_memcpy(void *dst, void const * src, unsigned long len) {
+ memcpy(dst,src,len);
+}
+
+/**
+ *
+ * env_strcmp - implementation
+ *
+ * @param dst
+ * @param src
+ */
+
+int env_strcmp(const char *dst, const char *src){
+ return (strcmp(dst, src));
+}
+
+/**
+ *
+ * env_strncpy - implementation
+ *
+ * @param dest
+ * @param src
+ * @param len
+ */
+void env_strncpy(char * dest, const char *src, unsigned long len)
+{
+ strncpy(dest, src, len);
+}
+
+/**
+ *
+ * env_strncmp - implementation
+ *
+ * @param dest
+ * @param src
+ * @param len
+ */
+int env_strncmp(char * dest, const char *src, unsigned long len)
+{
+ return (strncmp(dest, src, len));
+}
+
+/**
+ *
+ * env_mb - implementation
+ *
+ */
+void env_mb()
+{
+ MEM_BARRIER();
+}
+
+/**
+ * osalr_mb - implementation
+ */
+void env_rmb()
+{
+ MEM_BARRIER();
+}
+
+/**
+ * env_wmb - implementation
+ */
+void env_wmb()
+{
+ MEM_BARRIER();
+}
+
+/**
+ * env_map_vatopa - implementation
+ *
+ * @param address
+ */
+unsigned long env_map_vatopa(void *address)
+{
+ return platform_vatopa(address);
+}
+
+/**
+ * env_map_patova - implementation
+ *
+ * @param address
+ */
+void *env_map_patova(unsigned long address)
+{
+ return platform_patova(address);
+}
+
+/**
+ * env_create_mutex
+ *
+ * Creates a mutex with the given initial count.
+ *
+ */
+int env_create_mutex(void **lock, int count)
+{
+ *lock = xSemaphoreCreateCounting(10, count);
+ if(*lock)
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+/**
+ * env_delete_mutex
+ *
+ * Deletes the given lock
+ *
+ */
+void env_delete_mutex(void *lock)
+{
+ vSemaphoreDelete(lock);
+}
+
+/**
+ * env_lock_mutex
+ *
+ * Tries to acquire the lock, if lock is not available then call to
+ * this function will suspend.
+ */
+void env_lock_mutex(void *lock)
+{
+ SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)lock;
+ if(!env_in_isr())
+ {
+ xSemaphoreTake( xSemaphore, portMAX_DELAY);
+ platform_interrupt_disable_all();
+ }
+}
+
+/**
+ * env_unlock_mutex
+ *
+ * Releases the given lock.
+ */
+void env_unlock_mutex(void *lock)
+{
+ SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)lock;
+ if(!env_in_isr())
+ {
+ platform_interrupt_enable_all();
+ xSemaphoreGive( xSemaphore);
+ }
+}
+
+
+/**
+ * env_create_sync_lock
+ *
+ * Creates a synchronization lock primitive. It is used
+ * when signal has to be sent from the interrupt context to main
+ * thread context.
+ */
+int env_create_sync_lock(void **lock , int state) {
+ return env_create_mutex(lock, state); /* state=1 .. initially free */
+}
+
+/**
+ * env_delete_sync_lock
+ *
+ * Deletes the given lock
+ *
+ */
+void env_delete_sync_lock(void *lock){
+ if(lock)
+ env_delete_mutex(lock);
+}
+
+/**
+ * env_acquire_sync_lock
+ *
+ * Tries to acquire the lock, if lock is not available then call to
+ * this function waits for lock to become available.
+ */
+void env_acquire_sync_lock(void *lock)
+{
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)lock;
+ if(env_in_isr())
+ {
+ xSemaphoreTakeFromISR(xSemaphore, &xTaskWokenByReceive);
+ portEND_SWITCHING_ISR( xTaskWokenByReceive );
+ }
+ else
+ {
+ xSemaphoreTake( xSemaphore, portMAX_DELAY);
+ }
+}
+
+/**
+ * env_release_sync_lock
+ *
+ * Releases the given lock.
+ */
+void env_release_sync_lock(void *lock)
+{
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)lock;
+ if(env_in_isr())
+ {
+ xSemaphoreGiveFromISR(xSemaphore, &xTaskWokenByReceive);
+ portEND_SWITCHING_ISR( xTaskWokenByReceive );
+ }
+ else
+ {
+ xSemaphoreGive( xSemaphore);
+ }
+}
+
+/**
+ * env_sleep_msec
+ *
+ * Suspends the calling thread for given time , in msecs.
+ */
+void env_sleep_msec(int num_msec)
+{
+ vTaskDelay(num_msec / portTICK_PERIOD_MS);
+}
+
+/**
+ * env_disable_interrupts
+ *
+ * Disables system interrupts
+ *
+ */
+void env_disable_interrupts()
+{
+ platform_interrupt_disable_all();
+}
+
+/**
+ * env_restore_interrupts
+ *
+ * Enables system interrupts
+ *
+ */
+void env_restore_interrupts()
+{
+ platform_interrupt_enable_all();
+}
+
+/**
+ * env_register_isr
+ *
+ * Registers interrupt handler for the given interrupt vector.
+ *
+ * @param vector - interrupt vector number
+ * @param isr - interrupt handler
+ */
+void env_register_isr(int vector , void *data ,
+ void (*isr)(int vector , void *data))
+{
+ assert(vector < ISR_COUNT);
+ if(vector < ISR_COUNT)
+ {
+ /* Save interrupt data */
+ isr_table[vector].data = data;
+ isr_table[vector].isr = isr;
+ }
+}
+
+void env_update_isr(int vector , void *data ,
+ void (*isr)(int vector , void *data))
+{
+ assert(vector < ISR_COUNT);
+ if(vector < ISR_COUNT)
+ {
+ isr_table[vector].data = data;
+ isr_table[vector].isr = isr;
+ }
+}
+
+/**
+ * env_enable_interrupt
+ *
+ * Enables the given interrupt
+ *
+ * @param vector - interrupt vector number
+ * @param priority - interrupt priority
+ * @param polarity - interrupt polarity
+ */
+
+void env_enable_interrupt(unsigned int vector , unsigned int priority ,
+ unsigned int polarity)
+{
+ assert(vector < ISR_COUNT);
+ if (vector < ISR_COUNT)
+ {
+ isr_table[vector].priority = priority;
+ isr_table[vector].type = polarity;
+ platform_interrupt_enable(vector, polarity, priority);
+ }
+}
+
+/**
+ * env_disable_interrupt
+ *
+ * Disables the given interrupt
+ *
+ * @param vector - interrupt vector number
+ */
+
+void env_disable_interrupt(unsigned int vector)
+{
+ platform_interrupt_disable(vector);
+}
+
+/**
+ * env_map_memory
+ *
+ * Enables memory mapping for given memory region.
+ *
+ * @param pa - physical address of memory
+ * @param va - logical address of memory
+ * @param size - memory size
+ * param flags - flags for cache/uncached and access type
+ */
+
+void env_map_memory(unsigned int pa, unsigned int va, unsigned int size,
+ unsigned int flags) {
+ platform_map_mem_region(va, pa, size, flags);
+}
+
+/**
+ * env_disable_cache
+ *
+ * Disables system caches.
+ *
+ */
+
+void env_disable_cache() {
+ platform_cache_all_flush_invalidate();
+ platform_cache_disable();
+}
+
+/**
+ *
+ * env_get_timestamp
+ *
+ * Returns a 64 bit time stamp.
+ *
+ *
+ */
+unsigned long long env_get_timestamp(void) {
+ if(env_in_isr())
+ {
+ return (unsigned long long) xTaskGetTickCountFromISR();
+ }
+ else
+ {
+ return (unsigned long long) xTaskGetTickCount();
+ }
+}
+
+/*========================================================= */
+/* Util data / functions */
+
+void env_isr(int vector) {
+ struct isr_info *info;
+
+ assert(vector < ISR_COUNT);
+ if (vector < ISR_COUNT)
+ {
+ info = &isr_table[vector];
+ assert(NULL != info->isr);
+ if (NULL != info->isr)
+ {
+ env_disable_interrupt(vector);
+ info->isr(vector, info->data);
+ env_enable_interrupt(vector, info->priority, info->type);
+ }
+ }
+}
+
+/*
+ * env_create_queue
+ *
+ * Creates a message queue.
+ *
+ * @param queue - pointer to created queue
+ * @param length - maximum number of elements in the queue
+ * @param item_size - queue element size in bytes
+ *
+ * @return - status of function execution
+ */
+int env_create_queue(void **queue, int length , int element_size)
+{
+ *queue = xQueueCreate(length, element_size);
+ if(*queue)
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+/**
+ * env_delete_queue
+ *
+ * Deletes the message queue.
+ *
+ * @param queue - queue to delete
+ */
+
+void env_delete_queue(void *queue)
+{
+ vQueueDelete(queue);
+}
+
+/**
+ * env_put_queue
+ *
+ * Put an element in a queue.
+ *
+ * @param queue - queue to put element in
+ * @param msg - pointer to the message to be put into the queue
+ * @param timeout_ms - timeout in ms
+ *
+ * @return - status of function execution
+ */
+
+int env_put_queue(void *queue, void* msg, int timeout_ms)
+{
+ BaseType_t xHigherPriorityTaskWoken;
+ if(env_in_isr())
+ {
+ if(xQueueSendFromISR(queue, msg, &xHigherPriorityTaskWoken) == pdPASS)
+ {
+ portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
+ return 1;
+ }
+ }
+ else
+ {
+ if(xQueueSend(queue, msg, ((portMAX_DELAY == timeout_ms) ? portMAX_DELAY : timeout_ms / portTICK_PERIOD_MS)) == pdPASS)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * env_get_queue
+ *
+ * Get an element out of a queue.
+ *
+ * @param queue - queue to get element from
+ * @param msg - pointer to a memory to save the message
+ * @param timeout_ms - timeout in ms
+ *
+ * @return - status of function execution
+ */
+
+int env_get_queue(void *queue, void* msg, int timeout_ms)
+{
+ BaseType_t xHigherPriorityTaskWoken;
+ if(env_in_isr())
+ {
+ if(xQueueReceiveFromISR(queue, msg, &xHigherPriorityTaskWoken) == pdPASS)
+ {
+ portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
+ return 1;
+ }
+ }
+ else
+ {
+ if(xQueueReceive(queue, msg, ((portMAX_DELAY == timeout_ms) ? portMAX_DELAY : timeout_ms / portTICK_PERIOD_MS)) == pdPASS)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}