// +FHDR------------------------------------------------------------
//                 Copyright (c) 2020 PicocomTech.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : ucp_pcie_mem.c
// Author        : xianfeng.du
// Created On    : 2022-06-27
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

#include <stddef.h>
#include <string.h>
#include "mem_sections.h"
#include "ucp_pcie_traffic.h"
#include "ucp_printf.h"
#include "ucp_utility.h"
#include "ucp_tick.h"

UcpPcieEpMemInfo_t* gUcpPcieMemInfoPtr;//im section

UcpPcieEpMemInfo_t* get_ucp_pcie_mem_info(void)
{
    return gUcpPcieMemInfoPtr;
}

static inline void set_ucp_pcie_mem_info(uint8_t* buf)
{
    gUcpPcieMemInfoPtr = (UcpPcieEpMemInfo_t *)buf;
}

void pcie_ep_mem_init(void)
{
	UCP_PRINT_LOG("start initializing memory");

	uint8_t *ptr = NULL;
	uint32_t k = 0;
	uint32_t i = 0;

	MEM_SECTION_INFO* pMemSection = GetRfmDm0Section();
	memset((void *)pMemSection->baseAddr,0,pMemSection->maxSize);

    //pcie ep的对象描述符
	ptr = (uint8_t *)memSectionAlloc(pMemSection, sizeof(UcpPcieEpMemInfo_t), MEM_ALIGNED_4BYTES, "gUcpPcieMemInfoPtr");
	set_ucp_pcie_mem_info(ptr);
	UcpPcieEpMemInfo_t* pUcpPcieMemInfo = (UcpPcieEpMemInfo_t *)ptr;

	//alloc mem buffer	DMA 描述符	
	pUcpPcieMemInfo->pDmaDesc = (DwPcieDmaLinkListNode_t *)memSectionAlloc(pMemSection, 2*MAX_CH_NUM_DW_DMA*MAX_NODE_NUM_DMA_CHAIN*sizeof(DwPcieDmaLinkListNode_t), MEM_ALIGNED_4BYTES, "pDmaDesc");
    //DMA通道状态描述，下行
	ptr = (uint8_t *)memSectionAlloc(pMemSection, MAX_CH_NUM_UCP_DMA*sizeof_aligned_4bytes(UcpPcieDmaCh_t), MEM_ALIGNED_4BYTES, "pDmaDlCh");
    for (k = 0; k < MAX_CH_NUM_UCP_DMA; k++) {
        pUcpPcieMemInfo->pDmaDlCh[k] = (UcpPcieDmaCh_t *)(ptr + k * sizeof_aligned_4bytes(UcpPcieDmaCh_t));
    }
     //DMA通道状态描述，上行
	ptr = (uint8_t *)memSectionAlloc(pMemSection, MAX_CH_NUM_UCP_DMA*sizeof_aligned_4bytes(UcpPcieDmaCh_t), MEM_ALIGNED_4BYTES, "pDmaUlCh");
    for (k = 0; k < MAX_CH_NUM_UCP_DMA; k++) {
        pUcpPcieMemInfo->pDmaUlCh[k] = (UcpPcieDmaCh_t *)(ptr + k * sizeof_aligned_4bytes(UcpPcieDmaCh_t));
    }
    //DMA通道数据包的描述符，读
	ptr = (uint8_t *)memSectionAlloc(pMemSection, MAX_CH_NUM_UCP_DMA*sizeof_aligned_4bytes(PcieDmaBuffer_t), MEM_ALIGNED_4BYTES, "pRdmaChains");
    for (k = 0; k < MAX_CH_NUM_UCP_DMA; k++) {
        pUcpPcieMemInfo->pRdmaChains[k] = (PcieDmaBuffer_t *)(ptr + k * sizeof_aligned_4bytes(PcieDmaBuffer_t));
        pUcpPcieMemInfo->pRdmaChains[k]->buffer = (void *)((uint8_t *)pUcpPcieMemInfo->pDmaDesc + k * (MAX_NODE_NUM_DMA_CHAIN)* sizeof(DwPcieDmaLinkListNode_t));	
		//此处需要把rfm dm0的内存地址转换为PCIE可以识别的SOC地址
		pUcpPcieMemInfo->pRdmaChains[k]->bufByPcie = pUcpPcieMemInfo->pRdmaChains[k]->buffer + RFM_DM0_SOC_ADDR;//(0x8720000 - 0x200000);
        //pUcpPcieMemInfo->pRdmaChains[k]->bufByPcie = pUcpPcieMemInfo->pRdmaChains[k]->buffer;
		//pUcpPcieMemInfo->pRdmaChains[k]->size = MAX_NODE_NUM_DMA_CHAIN * sizeof_aligned(DwPcieDmaLinkListNode_t);	
	    //pUcpPcieMemInfo->pRdmaChains[k]->used = 0;			
    }
     //DMA通道数据包的描述符，写
	ptr = (uint8_t *)memSectionAlloc(pMemSection, MAX_CH_NUM_UCP_DMA*sizeof_aligned_4bytes(PcieDmaBuffer_t), MEM_ALIGNED_4BYTES, "pWdmaChains");
    for (k = 0; k < MAX_CH_NUM_UCP_DMA; k++) {
        pUcpPcieMemInfo->pWdmaChains[k] = (PcieDmaBuffer_t *)(ptr + k * sizeof_aligned_4bytes(PcieDmaBuffer_t));		
		pUcpPcieMemInfo->pWdmaChains[k]->buffer = (void *)((uint8_t *)pUcpPcieMemInfo->pDmaDesc + (k + MAX_CH_NUM_UCP_DMA) * (MAX_NODE_NUM_DMA_CHAIN) * sizeof(DwPcieDmaLinkListNode_t));	
		//此处需要把rfm dm0的内存地址转换为PCIE可以识别的SOC地址
		pUcpPcieMemInfo->pWdmaChains[k]->bufByPcie = pUcpPcieMemInfo->pWdmaChains[k]->buffer + RFM_DM0_SOC_ADDR;//(0x8720000 - 0x200000);
        //pUcpPcieMemInfo->pWdmaChains[k]->bufByPcie = pUcpPcieMemInfo->pWdmaChains[k]->buffer;	
	    //pUcpPcieMemInfo->pWdmaChains[k]->size = MAX_NODE_NUM_DMA_CHAIN * sizeof(DwPcieDmaLinkListNode_t);	
	    ///pUcpPcieMemInfo->pWdmaChains[k]->used = 0;			
    }
    //跟RC通信的线程， 读
	ptr = (uint8_t *)memSectionAlloc(pMemSection, MAX_INSTANCE_NUM*MAX_Q_NUM_DL_TRAFFIC*sizeof_aligned_4bytes(UcpExtTraffic_t), MEM_ALIGNED_4BYTES, "pExtDlTraffic");	
	for(k = 0; k < MAX_INSTANCE_NUM; k++)
	{
	    for (i = 0; i < MAX_Q_NUM_DL_TRAFFIC; i++) 
		{
	        pUcpPcieMemInfo->pExtDlTraffic[k][i] = (UcpExtTraffic_t *)(ptr + (k*MAX_Q_NUM_DL_TRAFFIC+i)* sizeof_aligned_4bytes(UcpExtTraffic_t));
			UCP_PRINT_LOG("pUcpPcieMemInfo->pExtDlTraffic[%d][%d] = 0x%lx\n",k,i, (uint32_t)pUcpPcieMemInfo->pExtDlTraffic[k][i]);
	    }
	}
    //跟应用通信的描述符，写
	ptr = (uint8_t *)memSectionAlloc(pMemSection, MAX_INSTANCE_NUM*MAX_Q_NUM_UL_TRAFFIC*sizeof_aligned_4bytes(UcpExtTraffic_t), MEM_ALIGNED_4BYTES, "pExtUlTraffic");
	for(k = 0; k < MAX_INSTANCE_NUM; k++)
	{
    	for (i = 0; i < MAX_Q_NUM_UL_TRAFFIC; i++) 
		{
        	pUcpPcieMemInfo->pExtUlTraffic[k][i] = (UcpExtTraffic_t *)(ptr + (k*MAX_Q_NUM_DL_TRAFFIC+i)*sizeof_aligned_4bytes(UcpExtTraffic_t));
			/*UCP_PRINT_LOG("pUcpPcieMemInfo->pExtUlTraffic[%d][%d] = 0x%lx",k,i, (uint_t)pUcpPcieMemInfo->pExtUlTraffic[k][i]);*/
    	}
	}
	//alloc bar buffer，bar空间
	pMemSection = GetRfmDm1Section();
	memset((void *)pMemSection->baseAddr,0,pMemSection->maxSize);	
	//sizeof(PcieEpMemBarStruct_t) must be less than MAX_MEM_BAR_SIZE
	pUcpPcieMemInfo->pUcpMemBar = (PcieEpMemBarStruct_t *)memSectionAlloc(pMemSection, MAX_MEM_BAR_SIZE, MEM_ALIGNED_4BYTES, "pUcpMemBar");
	return;
}

