summaryrefslogtreecommitdiff
path: root/middleware/multicore/open-amp/common/shm
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2016-01-12 14:06:54 -0800
committerStefan Agner <stefan.agner@toradex.com>2016-01-12 14:06:54 -0800
commita57cc2c988482010061b9e68344fdf1969889763 (patch)
tree5c050337492ce27c09b47421b123980b5a79f8d9 /middleware/multicore/open-amp/common/shm
initial commit, FreeRTOS_BSP_1.0.0_iMX7D
Diffstat (limited to 'middleware/multicore/open-amp/common/shm')
-rw-r--r--middleware/multicore/open-amp/common/shm/sh_mem.c230
-rw-r--r--middleware/multicore/open-amp/common/shm/sh_mem.h89
2 files changed, 319 insertions, 0 deletions
diff --git a/middleware/multicore/open-amp/common/shm/sh_mem.c b/middleware/multicore/open-amp/common/shm/sh_mem.c
new file mode 100644
index 0000000..6a290a4
--- /dev/null
+++ b/middleware/multicore/open-amp/common/shm/sh_mem.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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
+ *
+ * sh_mem.c
+ *
+ * COMPONENT
+ *
+ * OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ * Source file for fixed buffer size memory management service. Currently
+ * it is only being used to manage shared memory.
+ *
+ **************************************************************************/
+#include "sh_mem.h"
+
+/**
+ * sh_mem_create_pool
+ *
+ * Creates new memory pool with the given parameters.
+ *
+ * @param start_addr - start address of the memory region
+ * @param size - size of the memory
+ * @param buff_size - fixed buffer size
+ *
+ * @return - pointer to memory pool
+ *
+ */
+struct sh_mem_pool * sh_mem_create_pool(void *start_addr, unsigned int size,
+ unsigned int buff_size) {
+ struct sh_mem_pool *mem_pool;
+ int status, pool_size;
+ int num_buffs, bmp_size;
+
+ if (!start_addr || !size || !buff_size)
+ return NULL;
+
+ /* Word align the buffer size */
+ buff_size = WORD_ALIGN(buff_size);
+
+ /* Get number of buffers. */
+ num_buffs = (size / buff_size) + ((size % buff_size) == 0 ? 0 : 1);
+
+ /*
+ * Size of the bitmap required to maintain buffers info. One word(32 bit) can
+ * keep track of 32 buffers.
+ */
+ bmp_size = (num_buffs / BITMAP_WORD_SIZE)
+ + ((num_buffs % BITMAP_WORD_SIZE) == 0 ? 0 : 1);
+
+ /* Total size required for pool control block. */
+ pool_size = sizeof(struct sh_mem_pool) + WORD_SIZE * bmp_size;
+
+ /* Create pool control block. */
+ mem_pool = env_allocate_memory(pool_size);
+
+ if (mem_pool) {
+ /* Initialize pool parameters */
+ env_memset(mem_pool, 0x00, pool_size);
+ status = env_create_mutex(&mem_pool->lock , 1);
+ if (status){
+ env_free_memory(mem_pool);
+ return NULL;
+ }
+ mem_pool->start_addr = start_addr;
+ mem_pool->buff_size = buff_size;
+ mem_pool->bmp_size = bmp_size;
+ mem_pool->total_buffs = num_buffs;
+ }
+
+ return mem_pool;
+}
+
+/**
+ * sh_mem_get_buffer
+ *
+ * Allocates fixed size buffer from the given memory pool.
+ *
+ * @param pool - pointer to memory pool
+ *
+ * @return - pointer to allocated buffer
+ *
+ */
+void * sh_mem_get_buffer(struct sh_mem_pool *pool) {
+ void *buff = NULL;
+ int idx, bit_idx;
+
+ if (!pool)
+ return NULL;
+
+ env_lock_mutex(pool->lock);
+
+ if (pool->used_buffs >= pool->total_buffs) {
+ env_unlock_mutex(pool->lock);
+ return NULL;
+ }
+
+ for (idx = 0; idx < pool->bmp_size; idx++) {
+ /*
+ * Find the first 0 bit in the buffers bitmap. The 0th bit
+ * represents a free buffer.
+ */
+ bit_idx = get_first_zero_bit(pool->bitmap[idx]);
+ if (bit_idx < 32) {
+ /* Set bit to mark it as consumed. */
+ pool->bitmap[idx] |= (1 << bit_idx);
+ buff = (char *) pool->start_addr +
+ pool->buff_size * (idx * BITMAP_WORD_SIZE + bit_idx);
+ pool->used_buffs++;
+ break;
+ }
+ }
+
+ env_unlock_mutex(pool->lock);
+
+ return buff;
+}
+
+/**
+ * sh_mem_free_buffer
+ *
+ * Frees the given buffer.
+ *
+ * @param pool - pointer to memory pool
+ * @param buff - pointer to buffer
+ *
+ * @return - none
+ */
+void sh_mem_free_buffer(void *buff, struct sh_mem_pool *pool) {
+ unsigned long *bitmask;
+ int bmp_idx, bit_idx, buff_idx;
+
+ if (!pool || !buff)
+ return;
+
+ /* Acquire the pool lock */
+ env_lock_mutex(pool->lock);
+
+ /* Map the buffer address to its index. */
+ buff_idx = ((char *) buff - (char*) pool->start_addr) / pool->buff_size;
+
+ /* Translate the buffer index to bitmap index. */
+ bmp_idx = buff_idx / BITMAP_WORD_SIZE;
+ bit_idx = buff_idx % BITMAP_WORD_SIZE;
+ bitmask = &pool->bitmap[bmp_idx];
+
+ /* Mark the buffer as free */
+ *bitmask ^= (1 << bit_idx);
+
+ pool->used_buffs--;
+
+ /* Release the pool lock. */
+ env_unlock_mutex(pool->lock);
+
+}
+
+/**
+ * sh_mem_delete_pool
+ *
+ * Deletes the given memory pool.
+ *
+ * @param pool - pointer to memory pool
+ *
+ * @return - none
+ */
+void sh_mem_delete_pool(struct sh_mem_pool *pool) {
+
+ if (pool) {
+ env_delete_mutex(pool->lock);
+ env_free_memory(pool);
+ }
+}
+
+/**
+ * get_first_zero_bit
+ *
+ * Provides position of first 0 bit in a 32 bit value
+ *
+ * @param value - given value
+ *
+ * @return - 0th bit position
+ */
+unsigned int get_first_zero_bit(unsigned long value) {
+ unsigned int idx;
+ unsigned int tmp32;
+
+ /* Invert value */
+ value = ~value;
+
+ /* (~value) & (2's complement of value) */
+ value = (value & (-value)) - 1;
+
+ /* log2(value) */
+
+ tmp32 = value - ((value >> 1) & 033333333333)
+ - ((value >> 2) & 011111111111);
+
+ idx = ((tmp32 + (tmp32 >> 3)) & 030707070707) % 63;
+
+ return idx;
+}
diff --git a/middleware/multicore/open-amp/common/shm/sh_mem.h b/middleware/multicore/open-amp/common/shm/sh_mem.h
new file mode 100644
index 0000000..4ba830b
--- /dev/null
+++ b/middleware/multicore/open-amp/common/shm/sh_mem.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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
+ *
+ * sh_mem.c
+ *
+ * COMPONENT
+ *
+ * IPC Stack for uAMP systems.
+ *
+ * DESCRIPTION
+ *
+ * Header file for fixed buffer size memory management service. Currently
+ * it is being used to manage shared memory.
+ *
+ **************************************************************************/
+#ifndef SH_MEM_H_
+#define SH_MEM_H_
+
+#include "../../porting/env/env.h"
+
+
+/* Macros */
+#define BITMAP_WORD_SIZE 32
+#define WORD_SIZE sizeof(unsigned long)
+#define WORD_ALIGN(a) (((a) & (WORD_SIZE-1)) != 0)? \
+ (((a) & (~(WORD_SIZE-1))) + 4):(a)
+/*
+ * This structure represents a shared memory pool.
+ *
+ * @start_addr - start address of shared memory region
+ * @lock - lock to ensure exclusive access
+ * @size - size of shared memory*
+ * @buff_size - size of each buffer
+ * @total_buffs - total number of buffers in shared memory region
+ * @used_buffs - number of used buffers
+ * @bmp_size - size of bitmap array
+ * @bitmap - array to keep record of free and used blocks
+ *
+ */
+
+struct sh_mem_pool {
+ void *start_addr;
+ LOCK *lock;
+ int size;
+ int buff_size;
+ int total_buffs;
+ int used_buffs;
+ int bmp_size;
+ unsigned long bitmap[0];
+};
+
+/* APIs */
+struct sh_mem_pool *sh_mem_create_pool(void *start_addr, unsigned int size,
+ unsigned int buff_size);
+void sh_mem_delete_pool(struct sh_mem_pool *pool);
+void *sh_mem_get_buffer(struct sh_mem_pool *pool);
+void sh_mem_free_buffer(void *ptr, struct sh_mem_pool *pool);
+unsigned int get_first_zero_bit(unsigned long value);
+
+#endif /* SH_MEM_H_ */