/*   ======================================================================
 *   Copyright (c) Texas Instruments Inc , 2012
 *
 *   Use of this software is controlled by the terms and conditions found
 *   in the license agreement under which this software has been supplied
 *   provided
 *   ==========================================================================
*/
#ifndef _VCOP_MEMMAP_H
#define _VCOP_MEMMAP_H

#include <vcop/vcop.h> /* from ARP32 cgtools include */

#define VCOP_MEM_IBUFLA_ADDR        (0x40050000)
#define VCOP_MEM_IBUFHA_ADDR        (0x40054000)

#define VCOP_MEM_IBUFLB_ADDR        (0x40070000)
#define VCOP_MEM_IBUFHB_ADDR        (0x40074000)

#define VCOP_MEM_WBUF_ADDR          (0x40040000)

#define VCOP_MEM_IBUFL_SIZE         (0x4000)
#define VCOP_MEM_IBUFH_SIZE         (0x4000)
#define VCOP_MEM_WBUF_SIZE          (0x8000)

/*
 * Utility APIs and data structures to alloc from VCOP internal memory in
 * a linear manner
 *
 * This is not a dynamic heap allocator
 * Allocs happens linearly.
 * There is no "free" API
 * Reset heap to free all allocate memory
 */
#define VCOP_MAX_HEAPS              (5)

typedef struct {

    unsigned char *heapAddr[VCOP_MAX_HEAPS];
    unsigned int  heapSize[VCOP_MAX_HEAPS];
    unsigned int  allocIdx[VCOP_MAX_HEAPS];

} VCOP_HEAP_INFO;

static inline void vcop_heap_reset(VCOP_HEAP_INFO *pInfo)
{
    pInfo->heapAddr[VCOP_IBUFLA] = (unsigned char*)VCOP_MEM_IBUFLA_ADDR;
    pInfo->heapAddr[VCOP_IBUFLB] = (unsigned char*)VCOP_MEM_IBUFLB_ADDR;
    pInfo->heapAddr[VCOP_IBUFHA] = (unsigned char*)VCOP_MEM_IBUFHA_ADDR;
    pInfo->heapAddr[VCOP_IBUFHB] = (unsigned char*)VCOP_MEM_IBUFHB_ADDR;
    pInfo->heapAddr[VCOP_WMEM]   = (unsigned char*)VCOP_MEM_WBUF_ADDR;

    pInfo->heapSize[VCOP_IBUFLA] = VCOP_MEM_IBUFL_SIZE;
    pInfo->heapSize[VCOP_IBUFLB] = VCOP_MEM_IBUFL_SIZE;
    pInfo->heapSize[VCOP_IBUFHA] = VCOP_MEM_IBUFH_SIZE;
    pInfo->heapSize[VCOP_IBUFHB] = VCOP_MEM_IBUFH_SIZE;
    pInfo->heapSize[VCOP_WMEM]   = VCOP_MEM_WBUF_SIZE;

    pInfo->allocIdx[VCOP_IBUFLA] = 0;
    pInfo->allocIdx[VCOP_IBUFLB] = 0;
    pInfo->allocIdx[VCOP_IBUFHA] = 0;
    pInfo->allocIdx[VCOP_IBUFHB] = 0;
    pInfo->allocIdx[VCOP_WMEM]   = 0;
}

static inline void *vcop_heap_alloc (VCOP_HEAP_INFO *pInfo, VCOP_MEMHEAP heap, int size)
{
    void *addr;

    if(heap>=VCOP_MAX_HEAPS)
        return NULL;

    if(pInfo->allocIdx[heap]+size > pInfo->heapSize[heap])
        return NULL;

    addr = (void*)(pInfo->heapAddr[heap] + pInfo->allocIdx[heap]);

    pInfo->allocIdx[heap] += size;

    return addr;
}

#endif /* _VCOP_MEMMAP_H */


