#include <ppcboot.h>
#include <commproc.h>

#ifdef CFG_ALLOC_DPRAM

void dpram_init(void)
{
    /* Pointer to initial global data area */
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);

    /* Reclaim the DP memory for our use. */
    idata->dp_alloc_base = CPM_DATAONLY_BASE ;
    idata->dp_alloc_top  = idata->dp_alloc_base + CPM_DATAONLY_SIZE ;
}

/* Allocate some memory from the dual ported ram.  We may want to
 * enforce alignment restrictions, but right now everyone is a good
 * citizen.
 */
uint dpram_alloc(uint size)
{
    /* Pointer to initial global data area */
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
    uint	addr = idata->dp_alloc_base ;

    if ((idata->dp_alloc_base + size) >= idata->dp_alloc_top)
	return(CPM_DP_NOSPACE);

    idata->dp_alloc_base += size;

    return addr;
}

uint dpram_base(void)
{
    /* Pointer to initial global data area */
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
    return idata->dp_alloc_base ;
}

/* Allocate some memory from the dual ported ram.  We may want to
 * enforce alignment restrictions, but right now everyone is a good
 * citizen.
 */
uint dpram_alloc_align(uint size, uint align)
{
    /* Pointer to initial global data area */
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
    uint	addr, mask = align -1 ;

    addr = (idata->dp_alloc_base + mask) & ~mask;

    if ((addr + size) >= idata->dp_alloc_top)
	return(CPM_DP_NOSPACE);

    idata->dp_alloc_base = addr + size;

    return addr;
}

uint dpram_base_align(uint align)
{
    /* Pointer to initial global data area */
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
    uint mask = align-1 ;

    return (idata->dp_alloc_base + mask) & ~mask;
}

#endif	/* CFG_ALLOC_DPRAM */
