From a57cc2c988482010061b9e68344fdf1969889763 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 12 Jan 2016 14:06:54 -0800 Subject: initial commit, FreeRTOS_BSP_1.0.0_iMX7D --- middleware/multicore/open-amp/common/shm/sh_mem.c | 230 ++++++++++++++++++++++ middleware/multicore/open-amp/common/shm/sh_mem.h | 89 +++++++++ 2 files changed, 319 insertions(+) create mode 100644 middleware/multicore/open-amp/common/shm/sh_mem.c create mode 100644 middleware/multicore/open-amp/common/shm/sh_mem.h (limited to 'middleware/multicore/open-amp/common/shm') 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_ */ -- cgit v1.2.3