// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : mem_section.c
// Author        : xianfeng.du
// Created On    : 2022-06-25
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

#include "mem_sections.h"
#include "ucp_printf.h"

MEM_SECTION_INFO SECTION_ALIGNED PetSram = {
    .baseAddr = (PET_SRAM_BASE_ADDR + 0x0),
    .currAddr = (PET_SRAM_BASE_ADDR + 0x0),
    .maxSize = PET_SRAM_SIZE,
    .memSectionName = "PET_SRAM"
};

MEM_SECTION_INFO SECTION_ALIGNED EcsSram = {
    .baseAddr = (ECS_SRAM_BASE_ADDR + 0x0),
    .currAddr = (ECS_SRAM_BASE_ADDR + 0x0),
    .maxSize = ECS_SRAM_SIZE,
    .memSectionName = "ECS_SRAM"
};

MEM_SECTION_INFO SECTION_ALIGNED RfmDm0 = {
    .baseAddr = (RFM_DM0_BASE_ADDR + 0x0),
    .currAddr = (RFM_DM0_BASE_ADDR + 0x0),
    .maxSize = RFM_SPU_DM_SIZE,
    .memSectionName = "RFM_DM0"
};

MEM_SECTION_INFO SECTION_ALIGNED RfmDm1 = {
    .baseAddr = (RFM_DM1_BASE_ADDR + 0x0),
    .currAddr = (RFM_DM1_BASE_ADDR + 0x0),
    .maxSize = RFM_SPU_DM_SIZE,
    .memSectionName = "RFM_DM1"
};


MEM_SECTION_INFO SECTION_ALIGNED MsgDdrMem = {
    .baseAddr = (UCP_MSG_MEM_BASE_ADDR + 0x0),
    .currAddr = (UCP_MSG_MEM_BASE_ADDR + 0x0),
    .maxSize = UCP_MSG_MEM_SIZE,
    .memSectionName = "MSG_DDR_MEM"
};


void memSectionInit(MEM_SECTION_INFO* memSecInfo, uint32_t baseAddr, uint32_t maxSize, char* memSectionName)
{
	UCP_PRINT_LOG("[memSectionInit]: 0x%08x, 0x%08x, 0x%08x, %s", (uint32_t)memSecInfo, baseAddr, maxSize, memSectionName);

    memSecInfo->baseAddr = baseAddr;
    memSecInfo->maxSize = maxSize;
    memSecInfo->memSectionName = memSectionName;

    memSecInfo->currAddr = baseAddr;
}

void memSectionReset(MEM_SECTION_INFO* memSecInfo)
{
    memSecInfo->currAddr = memSecInfo->baseAddr;
}

#if 0
void memSectionAllocPrint(MEM_SECTION_INFO* memSecInfo, uint32_t allocSize, char* varString)
{
    char* pMemSectionName = (char*)&memSecInfo->memSectionName[0];

    UCP_PRINT_LOG("Memory Section - [%s]: Base Address: [0x%08x]; Maximum Size: [%8u]\n",
        pMemSectionName,
        memSecInfo->baseAddr,
        memSecInfo->maxSize);
    UCP_PRINT_LOG("Memory Section - [%s]: Variable Name: [%s]; Allocated Address: [0x%08x]; Allocated Size: [%6u]\n",
        pMemSectionName,
        varString,
        memSecInfo->currAddr,
        allocSize);
}
#endif

void* memSectionAlloc(MEM_SECTION_INFO* memSecInfo, uint32_t allocSize, uint32_t allocAlign, char* varString)
{
    void* ret;

    uint32_t baseAddr = memSecInfo->baseAddr;
    uint32_t currAddr = ((memSecInfo->currAddr + (allocAlign - 1)) / allocAlign) * allocAlign;
    uint32_t maxSize = memSecInfo->maxSize;

    uint8_t* p = (uint8_t*)baseAddr;
    uint32_t offset = currAddr - baseAddr;

    if ((offset + allocSize) <= maxSize) {
        ret = (void*)&p[offset];

        memSecInfo->currAddr = currAddr;

        /* disable as default since it cost much time. Could be enabled when needed. */
        //memSectionAllocPrint(memSecInfo, allocSize, varString);

        memSecInfo->currAddr = currAddr + allocSize;
    } else {
        UCP_PRINT_EMPTY("Memory Section - [%s]: Base Address: [0x%08x]; Maximum Size: [0x%08x]",
            memSecInfo->memSectionName,
            baseAddr,
            maxSize);

        UCP_PRINT_EMPTY("Memory Section - [%s]: Variable Name: [%s]; Allocated Address: [0x%08x]; Allocated Size: [0x%08x]",
            memSecInfo->memSectionName,
            varString,
            currAddr,
            allocSize);

        UCP_PRINT_EMPTY("Can't allocate 0x%08x bytes in Memory Section - [%s] for Variable - [%s]!", allocSize, memSecInfo->memSectionName, varString);
        ret = NULL;
    }

    return ret;
}

MEM_SECTION_INFO* GetPetSramSection()
{
    return (MEM_SECTION_INFO*)&PetSram;
}

MEM_SECTION_INFO* GetEcsSramSection()
{
    return (MEM_SECTION_INFO*)&EcsSram;
}

MEM_SECTION_INFO* GetRfmDm0Section()
{
    return (MEM_SECTION_INFO*)&RfmDm0;
}

MEM_SECTION_INFO* GetRfmDm1Section()
{
    return (MEM_SECTION_INFO*)&RfmDm1;
}

MEM_SECTION_INFO* GetMsgDdrSection()
{
    return (MEM_SECTION_INFO*)&MsgDdrMem;
}


