/******************************************************************************* * Copyright (C) 2018 Cadence Design Systems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to use this Software with Cadence processor cores only and * not with any other processors and platforms, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ /******************************************************************************* * xf-mem.h * * System-specific memory allocator * *******************************************************************************/ #ifndef __XF_H #error "xf-mem.h mustn't be included directly" #endif /******************************************************************************* * System specific memory pools ******************************************************************************/ #if XF_CFG_CORES_NUM > 1 /* ...shared memory pool for communication within DSP-cluster */ extern xf_mm_pool_t xf_dsp_shmem_pool; #endif /******************************************************************************* * Platform-specific SHMEM allocation registering functions ******************************************************************************/ /* ...register shmem allocation address */ static inline void xf_shmem_alloc_addref(u32 core, xf_message_t *m) { } /* ...unregister shmem allocation address */ static inline void xf_shmem_alloc_rmref(u32 core, xf_message_t *m) { } /******************************************************************************* * API functions ******************************************************************************/ /* ...allocate aligned memory on particular core specifying if it is shared */ static inline void * xf_mem_alloc(u32 size, u32 align, u32 core, u32 shared) { #if XF_CFG_CORES_NUM > 1 if (shared) { /* ...if memory is shared, core is dropped */ return xf_mm_alloc(&xf_dsp_shmem_pool, size); } #endif /* ...select local memory pool basing on core specification */ return xf_mm_alloc(&XF_CORE_DATA(core)->local_pool, size); } #ifdef XAF_ENABLE_NON_HIKEY /* ...redefine macro to add bugchecks */ #define xf_mem_alloc(size, align, core, shared) \ ({ \ void *__data; \ /* ...size must be properly aligned */ \ BUG(!XF_MM_ALIGNED(size), _x("Bad size: %u"), size); \ __data = (xf_mem_alloc)(size, align, core, shared); \ TRACE(1, _b("alloc-%u: %p[%u] (shared=%u)"), core, __data, size, shared); \ __data; \ }) #endif /* ...release allocated memory */ static inline void xf_mem_free(void *p, u32 size, u32 core, u32 shared) { #if XF_CFG_CORES_NUM > 1 if (shared) { /* ...if memory is shared, core is dropped */ xf_mm_free(&xf_dsp_shmem_pool, p, size); return; } #endif /* ...select proper pool basing on core specification */ xf_mm_free(&XF_CORE_DATA(core)->local_pool, p, size); } #ifdef XAF_ENABLE_NON_HIKEY /* ...redefine macro to add bugchecks */ #define xf_mem_free(p, size, core, shared) \ ({ \ void *__data = (p); \ /* ...size must be properly aligned */ \ BUG(!XF_MM_ALIGNED(size), _x("Bad size: %u"), size); \ TRACE(1, _b("free-%u: %p[%u] (shared=%u)"), core, __data, size, shared); \ (xf_mem_free)(__data, size, core, shared); \ }) #endif /* ...allocate AP-DSP shared memory */ static inline int xf_shmem_alloc(u32 core, xf_message_t *m) { xf_mm_pool_t *pool = &XF_CORE_DATA(core)->shared_pool; /* ...length is always cache-line aligned */ if ((m->buffer = xf_mm_alloc(pool, XF_ALIGNED(m->length))) != NULL) { /* ...register allocation address */ xf_shmem_alloc_addref(core, m); return 0; } else { return -ENOMEM; } } /* ...free AP-DSP shared memory */ static inline void xf_shmem_free(u32 core, xf_message_t *m) { xf_mm_pool_t *pool = &XF_CORE_DATA(core)->shared_pool; /* ...length is always cache-line aligned */ xf_mm_free(pool, m->buffer, XF_ALIGNED(m->length)); /* ...unregister allocation address */ xf_shmem_alloc_rmref(core, m); } /******************************************************************************* * Scratch memory management ******************************************************************************/ static inline void * xf_scratch_mem_init(u32 core) { /* ...allocate scratch memory from local DSP memory */ return xf_mem_alloc(XF_CFG_CODEC_SCRATCHMEM_SIZE, XF_CFG_CODEC_SCRATCHMEM_ALIGN, core, 0); } /******************************************************************************* * Helpers - hmm; they are platform-independent - tbd ******************************************************************************/ /* ...allocate local buffer */ static inline int xf_mm_alloc_buffer(u32 size, u32 align, u32 core, xf_mm_buffer_t *b) { /* ...allocate memory from proper local pool */ if ((size = XF_MM(size)) != 0) XF_CHK_ERR(b->addr = xf_mem_alloc(size, align, core, 0), -ENOMEM); else b->addr = NULL; /* ...save address */ b->size = size; return 0; } /* ...free local buffer */ static inline void xf_mm_free_buffer(xf_mm_buffer_t *b, u32 core) { if (b->addr) { xf_mem_free(b->addr, b->size, core, 0); } }