extern IMG_RESULT SYSMEMKM_AddIONMemory(SYSDEVU_sInfo *sysdev, SYS_eMemPool *peMemPool)
{
	static SYS_eMemPool memPool;
	static IMG_BOOL initialized = IMG_FALSE;

	/* Only one system heap is allowed to be inserted - obviously - */
	if(initialized)
		return memPool;

	SYSMEMU_AddMemoryHeap(&ion_ops, sysdev, IMG_FALSE, IMG_NULL, &memPool);

	initialized = IMG_TRUE;

	*peMemPool = memPool;

	return IMG_SUCCESS;
}
IMG_RESULT SYSMEMKM_AddCarveoutMemory(
    IMG_UINTPTR     vstart,
    IMG_PHYSADDR    pstart,
    IMG_UINT32      size,
    SYS_eMemPool *  peMemPool
)
{
    IMG_RESULT ui32Result;
    struct priv_params *prv;
    struct gen_pool *pool = gen_pool_create(12, -1);

    prv = (struct priv_params *)IMG_MALLOC(sizeof(*prv));
    IMG_ASSERT(prv != IMG_NULL);
    if(IMG_NULL == prv)
    {
        ui32Result = IMG_ERROR_OUT_OF_MEMORY;
        goto error_priv_alloc;
    }
    IMG_MEMSET((void *)prv, 0, sizeof(*prv));

    IMG_ASSERT(pool != IMG_NULL);
    IMG_ASSERT(size != 0);
    IMG_ASSERT((vstart & (HOST_MMU_PAGE_SIZE-1)) == 0);
    gen_pool_add_virt(pool, (unsigned long)vstart, (unsigned long)pstart, size, -1);

    prv->pool = pool;
    prv->pstart = pstart;
    prv->size = size;
    prv->vstart = vstart;

    ui32Result = SYSMEMU_AddMemoryHeap(&carveout_ops, IMG_TRUE, (IMG_VOID *)prv, peMemPool);
    IMG_ASSERT(IMG_SUCCESS == ui32Result);
    if(IMG_SUCCESS != ui32Result)
    {
        goto error_heap_add;
    }

    return IMG_SUCCESS;

error_heap_add:
    IMG_FREE(prv);
error_priv_alloc:
    gen_pool_destroy(pool);

    return ui32Result;
}
IMG_RESULT SYSMEMKM_AddDevIFMemory(
	SYSDEVU_sInfo	*sysdev,
    IMG_UINTPTR     vstart,
    IMG_PHYSADDR    pstart,
    IMG_UINT32      size,
    SYS_eMemPool *  peMemPool
)
{
    IMG_RESULT ui32Result;
    struct priv_params *prv;

    IMG_ASSERT(size != 0);
    IMG_ASSERT((vstart & (HOST_MMU_PAGE_SIZE - 1)) == 0);
    if((0 == size) ||
       (0 != (vstart & (HOST_MMU_PAGE_SIZE - 1))))
    {
        return IMG_ERROR_INVALID_PARAMETERS;
    }

    prv = (struct priv_params *)IMG_MALLOC(sizeof(*prv));
    IMG_ASSERT(IMG_NULL != prv);
    if (IMG_NULL == prv)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    IMG_MEMSET((void *)prv, 0, sizeof(*prv));

    IMG_ASSERT(size != 0);
    IMG_ASSERT((((IMG_UINTPTR)vstart) & (HOST_MMU_PAGE_SIZE-1)) == 0);

    // not allowed to use kmalloc for this size of buffer in the kernel.
    prv->npages = (size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE;

    prv->alloc_pool = IMG_BIGALLOC(prv->npages);
    IMG_ASSERT(prv->alloc_pool != IMG_NULL);
    if(IMG_NULL == prv->alloc_pool)
    {
        ui32Result = IMG_ERROR_OUT_OF_MEMORY;
        goto error_pool_alloc;
    }
    IMG_MEMSET(prv->alloc_pool, 0, prv->npages);

    prv->pstart = pstart;
    prv->size = size;
    prv->vstart = vstart;

    ui32Result = SYSMEMU_AddMemoryHeap(&devif_ops, sysdev, IMG_TRUE, (IMG_VOID *)prv, peMemPool);
    IMG_ASSERT(IMG_SUCCESS == ui32Result);
    if(IMG_SUCCESS != ui32Result)
    {
        goto error_heap_add;
    }

    return IMG_SUCCESS;

    /* Error handling. */
error_heap_add:
    IMG_BIGFREE(prv->alloc_pool);
error_pool_alloc:
    IMG_FREE(prv);

    return ui32Result;
}