Commit 3289c89f authored by witcomm's avatar witcomm

fpga_ldpc decode Ok, but encode not

parent f3ea3104
......@@ -23,6 +23,7 @@
#ifndef __NRLDPC_DEFS__H__
#define __NRLDPC_DEFS__H__
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#include "openair1/PHY/NR_TRANSPORT/ldpc_fpga_entx.h"
/**
\brief LDPC encoder
\param 1 input
......@@ -46,6 +47,10 @@ typedef struct {
}encoder_implemparams_t;
#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL}
typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*);
// typedef int(*LDPC_FPGA_EnTx_Test)(int , int);
typedef int(*LDPC_FPGA_HugePage_Init)(int);
typedef int(*LDPC_FPGA_EnTx)( EncodeInHeadStruct *pHeader, unsigned char * pSrc, unsigned char * pDst );
typedef int(*LDPC_FPGA_DeTx)( DecodeInHeadStruct *pHeader, unsigned char * pSrc, unsigned char * pDst, unsigned char * pCRC );
//============================================================================================================================
// decoder interface
/**
......
......@@ -23,6 +23,10 @@
#ifdef LDPC_LOADER
nrLDPC_decoderfunc_t nrLDPC_decoder;
nrLDPC_encoderfunc_t nrLDPC_encoder;
// LDPC_FPGA_EnTx_Test add;
LDPC_FPGA_HugePage_Init HugePage_Init;
LDPC_FPGA_EnTx encoder_load;
LDPC_FPGA_DeTx decoder_load;
#else
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
extern int load_nrLDPClib(void) ;
......@@ -30,6 +34,10 @@ extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_en
/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
extern nrLDPC_decoderfunc_t nrLDPC_decoder;
extern nrLDPC_encoderfunc_t nrLDPC_encoder;
// extern LDPC_FPGA_EnTx_Test add;
extern LDPC_FPGA_HugePage_Init HugePage_Init;
extern LDPC_FPGA_EnTx encoder_load;
extern LDPC_FPGA_DeTx decoder_load;
// inline functions:
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
#endif
\ No newline at end of file
......@@ -39,6 +39,18 @@
#include "PHY/CODING/nrLDPC_extern.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <hugetlbfs.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <dlfcn.h>
#include "openair1/PHY/NR_TRANSPORT/time_measure_diff.h"
/* function description array, to be used when loading the encoding/decoding shared lib */
......@@ -46,6 +58,28 @@ static loader_shlibfunc_t shlib_fdesc[2];
char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"};
#if 0
//nr_ulsch_unscrambling_optim_fpga_ldpc测解扰个别时间
double unscramble_llr128_gettime_cur, unscramble_llr8_gettime_cur;
struct timespec unscramble_llr128_start, unscramble_llr8_start;
struct timespec unscramble_llr128_stop, unscramble_llr8_stop;
//nr_ulsch_decoding_fpga_ldpc测fpga时间
double decode_clock_gettime_cur;
struct timespec decode_start;
struct timespec decode_stop;
//nr_ulsch_procedures_fpga_ldpc测解扰和译码时间
double unscrambing_gettime_cur,decoding_gettime_cur;
struct timespec unscrambing_start,decoding_start;
struct timespec unscrambing_stop,decoding_stop;
//phy_procedures_gNB_uespec_RX测总时间
double ulsch_clock_gettime_cur;
struct timespec ulsch_start;
struct timespec ulsch_stop;
#endif
int load_nrLDPClib(void) {
char *ptr = (char*)config_get_if();
if ( ptr==NULL ) {// phy simulators, config module possibly not loaded
......@@ -58,6 +92,47 @@ int load_nrLDPClib(void) {
AssertFatal( (ret >= 0),"Error loading ldpc decoder");
nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr;
nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr;
//手动加载指定位置的so动态库
void *handle = dlopen("/home/witcomm/work/yihz_5gran/ran/yihz/FecDemo/cDemo2/ldpc_fpga_encode.so", RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
if(!handle){
printf("open ldpc_fpga_encode error!\n");
return -1;
}
//根据动态链接库操作句柄与符号,返回符号对应的地址
// add = (LDPC_FPGA_EnTx_Test) dlsym(handle, "add");
// if(!add){
// printf("FPGA loading add error!\n");
// dlclose(handle);
// return -1;
// }
#if 1
HugePage_Init = (LDPC_FPGA_HugePage_Init) dlsym(handle, "HugePage_Init");
if(!HugePage_Init){
printf("FPGA loading HugePage_Init error!\n");
dlclose(handle);
return -1;
}
int HP = HugePage_Init(1);
if(HP != 0){
printf("HugePage_Init error!\n");
}
LOG_D(PHY,"load_nrLDPClib \n");
encoder_load = (LDPC_FPGA_EnTx) dlsym(handle, "encoder_load");
if(!encoder_load){
printf("FPGA loading encoder_load error!\n");
dlclose(handle);
return -1;
}
decoder_load = (LDPC_FPGA_DeTx) dlsym(handle, "decoder_load");
if(!decoder_load){
printf("FPGA loading decoder_load error!\n");
dlclose(handle);
return -1;
}
#endif
return 0;
}
......
//FPGA LDPC加速接口头部定义
typedef struct{
/*Word 0*/
uint32_t pktType :8; //0x12
uint32_t rsv0 :8; //空
uint32_t chkCode :16; //0xFAFA
/*Word 1*/
uint32_t pktLen :21; //Byte,pktLen=encoder header(32byte)+ tbszie (byte),并且32Byte对齐,是32的整数倍
uint32_t rsv1 :11;
/*Word 2*/
uint32_t rsv2 :28;
uint32_t sectorId :2; //=0表示单小区
uint32_t rsv3 :2;
/*Word 3*/
uint32_t sfn :10; //每次都不一样
uint32_t rsv4 :2;
uint32_t subfn :4; //=slotNum/2
uint32_t slotNum :5;
uint32_t pduIdx :9; //=0表示第一个码字,总共一个码字
uint32_t rev5 :2;
/*Word 4*/
uint32_t tbSizeB :18;
uint32_t rev6 :2;
uint32_t lastTb :1; //=1表示本slot只有一个TB
uint32_t firstTb :1; //=1表示本slot只有一个TB
uint32_t rev7 :2;
uint32_t cbNum :8;
/*Word 5*/
uint32_t qm :3; //规定是BPSK qm=0,QPSK qm=1,其他floor(调制阶数/2)
uint32_t rev8 :1;
uint32_t fillbit :14;
uint32_t rev9 :2;
uint32_t kpInByte :11; //encode的单位是Byte
uint32_t rev10 :1;
/*Word 6*/
uint32_t gamma :8;
uint32_t codeRate :6; //For LDPC base graph 1, a matrix of has 46 rows ,For LDPC base graph 2, a matrix of has 42 rows(看bg)
uint32_t rev11 :2;
uint32_t rvIdx :2;
uint32_t rev12 :6;
uint32_t lfSizeIx :3; //由lfSizeIx(列)和iLs(行)找到Zc
uint32_t rev13 :1;
uint32_t iLs :3;
uint32_t bg :1; //规定选择协议base grape1 bg=0; base grape2 bg=1
/*Word 7*/
uint32_t e1 :16;
uint32_t e0 :16;
}EncodeInHeadStruct;
typedef struct
{
/*Word 0*/
uint32_t pktType :8;
uint32_t rsv0 :8;
uint32_t chkCode :16;
/*Word 1*/
uint32_t pktLen :21; /*包含header + DDRheader + CB DATA的长度,单位是byte*/
uint32_t rsv1 :11;
/*Word 2*/
uint32_t pktTpTmp :4;
uint32_t pduSize :24; /*包含header + DDRheader + CB DATA的长度,单位是Word*/
uint32_t sectorId :2;
uint32_t rsv2 :2;
/*Word 3*/
uint32_t sfn :10;
uint32_t rsv3 :2;
uint32_t subfn :4;
uint32_t slotNum :5;
uint32_t pduIdx :9;
uint32_t rev4 :2;
/*Word 4*/
uint32_t tbSizeB :18; /*tbsize的大小,单位byte*/
uint32_t rev5 :2;
uint32_t lastTb :1;
uint32_t firstTb :1;
uint32_t rev6 :2;
uint32_t cbNum :8; /*码块数*/
/*Word 5*/
uint32_t qm :3;
uint32_t rev7 :1;
uint32_t fillbit :14;
uint32_t kpInByte :14; /* 被均分后每个cb块的长度,单位bit */
/*Word 6*/
uint32_t gamma :8;
uint32_t maxRowNm :6; //填成46
uint32_t maxRvIdx :2;
uint32_t rvIdx :2;
uint32_t ndi :1;
uint32_t flush :1;
uint32_t maxIter :4;
uint32_t lfSizeIx :3;
uint32_t rev10 :1;
uint32_t iLs :3;
uint32_t bg :1;
/*Word 7*/
uint32_t e1 :16;
uint32_t e0 :16;
}DecodeInHeadStruct;
typedef struct
{
/*word 0*/
uint32_t pktType :8; /* FEC RX 类型: 0x11*/
uint32_t rsv0 :8;
uint32_t chkCode :16; /* 数据校验 :0xFAFA*/
/*word 1*/
uint32_t pktLen :21; /* 包括 FPGA_ALIGN(header+ FPGA_ALIGN4B(tbsizeB)+4byte) */
uint32_t rsv1 :11;
/*word 2*/
uint32_t pktTpTmp :4;
uint32_t pduSize :20; /* pktLen长度除以4 单位 word*/
uint32_t rsv2 :4;
uint32_t sectorId :2;
uint32_t rsv3 :2;
/*word 3*/
uint32_t sfn :10; /* 帧号 */
uint32_t rsv4 :2;
uint32_t subfn :4; /* 子帧号 */
uint32_t slotNum :5; /* 时隙号 */
uint32_t pduIdx :9;
uint32_t rsv5 :2;
/*Word 4*/
uint32_t tbSizeB :18; /* tbsize 的大小,单位byte*/
uint32_t rsv6 :2;
uint32_t lastTb :1;
uint32_t firstTb :1;
uint32_t rsv7 :2;
uint32_t cbNum :8;
/*Word 5*/
uint32_t rsv8 :32;
/*Word 6*/
uint32_t rsv9 :32;
/*Word 7*/
uint32_t rsv10 :32;
}DecodeOutHeadStruct;
......@@ -54,3 +54,25 @@ uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r) {
return E;
}
void nr_get_E0_E1(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r, uint32_t *E0, uint32_t *E1) {
uint8_t Cprime = C; //assume CBGTI not present
AssertFatal(Nl>0,"Nl is 0\n");
AssertFatal(Qm>0,"Qm is 0\n");
LOG_D(PHY,"nr_get_E_ldpc_high_speed : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r);
LOG_D(PHY,"nr_get_E : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r);
*E0 = Nl*Qm*(G/(Nl*Qm*Cprime));
*E1 = Nl*Qm*((G+(Nl*Qm*Cprime-1))/(Nl*Qm*Cprime));
// if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
// {
// *E0 = Nl*Qm*(G/(Nl*Qm*Cprime));
// }
// else
// {
// *E1 = Nl*Qm*((G+(Nl*Qm*Cprime-1))/(Nl*Qm*Cprime));
// }
}
......@@ -80,4 +80,6 @@ void init_nr_prach_tables(int N_ZC);
/**@}*/
void init_pucch2_luts(void);
void nr_get_E0_E1(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r, uint32_t *E0, uint32_t *E1);
#endif
......@@ -197,3 +197,47 @@ NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch) {
return(stats);
}
void nr_ulsch_unscrambling_optim_fpga_ldpc(int16_t* llr,int8_t* llr8,
uint32_t size,
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI) {
#if defined(__x86_64__) || defined(__i386__)
uint32_t x1, x2, s=0;
x2 = (n_RNTI<<15) + Nid;
uint8_t *s8=(uint8_t *)&s;
__m128i *llr128 = (__m128i*)llr;
int j=0;
s = lte_gold_generic(&x1, &x2, 1);
for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++,j+=4) {
llr128[j] = _mm_mullo_epi16(llr128[j],byte2m128i[s8[0]]);
llr128[j+1] = _mm_mullo_epi16(llr128[j+1],byte2m128i[s8[1]]);
llr128[j+2] = _mm_mullo_epi16(llr128[j+2],byte2m128i[s8[2]]);
llr128[j+3] = _mm_mullo_epi16(llr128[j+3],byte2m128i[s8[3]]);
s = lte_gold_generic(&x1, &x2, 0);
}
//为FPGA加速调整格式,调整成+-32以内
for (int i = 0; i < size; i++)
{
if(llr[i] > 31)
llr8[i] = 31;
else if(llr[i] < -31)
llr8[i] = -31;
else
llr8[i] = llr[i];
}
#else
nr_ulsch_unscrambling(llr,
size,
q,
Nid,
n_RNTI);
#endif
}
\ No newline at end of file
......@@ -94,3 +94,28 @@ void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
void clear_pusch_stats(PHY_VARS_gNB *gNB);
NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
uint32_t nr_ulsch_decoding_fpga_ldpc(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
int8_t *ul_llr8,
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_pusch_pdu_t *pusch_pdu,
uint32_t frame,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint32_t G);
void nr_ulsch_unscrambling_optim_fpga_ldpc(int16_t* llr,int8_t* llr8,
uint32_t size,
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI);
void nr_ulsch_procedures_fpga_ldpc(PHY_VARS_gNB *gNB,
int frame_rx,
int slot_rx,
int UE_id,
uint8_t harq_pid);
void ul_find_iLS_lsIndex(unsigned int *LDPC_lifting_size, uint32_t *iLS_out, uint32_t *lsIndex_out);
\ No newline at end of file
......@@ -46,6 +46,8 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
#include <syscall.h>
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_TRANSPORT/time_measure_diff.h"
//#define DEBUG_ULSCH_DECODING
//#define gNB_DEBUG_TRACE
......@@ -652,3 +654,219 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
return 1;
}
uint32_t nr_ulsch_decoding_fpga_ldpc(PHY_VARS_gNB *phy_vars_gNB,
uint8_t ULSCH_id,
short *ulsch_llr,
int8_t *ul_llr8,
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_pusch_pdu_t *pusch_pdu,
uint32_t frame,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint32_t G) {
uint32_t A;
uint32_t r = 0;
#ifdef PRINT_CRC_CHECK
prnt_crc_cnt++;
#endif
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[ULSCH_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
if (!harq_process) {
LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
return 1;
}
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
phy_vars_gNB->nbDecode = 0;
harq_process->processedSegments = 0;
double Coderate = 0.0;
// ------------------------------------------------------------------
uint16_t nb_rb = pusch_pdu->rb_size;
uint8_t Qm = pusch_pdu->qam_mod_order;
uint16_t R = pusch_pdu->target_code_rate;
uint8_t mcs = pusch_pdu->mcs_index;
uint8_t n_layers = pusch_pdu->nrOfLayers;
// ------------------------------------------------------------------
uint32_t iLS, lsIndex = 0;
uint32_t E0, E1 = 0;
DecodeInHeadStruct DecodeHead;
uint8_t *pDeDataIn = NULL;
uint8_t *pDeDataOut = NULL;
uint8_t *pcrc = NULL;
pDeDataIn = (uint8_t *)ul_llr8;
pDeDataOut = harq_process->b;
pcrc = (unsigned char *)malloc(4);
if (!ulsch_llr) {
LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
return 1;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
harq_process->round = nr_rv_round_map[pusch_pdu->pusch_data.rv_index];
A = (harq_process->TBS)<<3;
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
if (R<1024)
Coderate = (float) R /(float) 1024;
else
Coderate = (float) R /(float) 2048;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
p_decParams->BG = 2;
if (Coderate < 0.3333) {
p_decParams->R = 15;
}
else if (Coderate <0.6667) {
p_decParams->R = 13;
}
else {
p_decParams->R = 23;
}
} else {
p_decParams->BG = 1;
if (Coderate < 0.6667) {
p_decParams->R = 13;
}
else if (Coderate <0.8889) {
p_decParams->R = 23;
}
else {
p_decParams->R = 89;
}
}
if (A > 3824)
harq_process->B = A+24;
else
harq_process->B = A+16;
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
nr_segmentation(NULL,
NULL,
harq_process->B,
&harq_process->C,
&harq_process->K,
&harq_process->Z, // [hna] Z is Zc
&harq_process->F,
p_decParams->BG);
//FPGA头部参数
DecodeHead.cbNum = harq_process->C;
LOG_D(PHY,"cbnum = %d\n", DecodeHead.cbNum);
DecodeHead.tbSizeB = A>>3;
DecodeHead.pktLen = 32+((DecodeHead.cbNum+7)/8)*32+((G+32-1)/32)*32;//Byte,pktLen=decoder header(32byte)+ DDR Header + tbszie (byte),并且32Byte对齐,是32的整数倍
LOG_D(PHY,"pktLen = %d\n", DecodeHead.pktLen);
DecodeHead.pduSize = DecodeHead.pktLen/4; //word
DecodeHead.qm = Qm/2;//规定是BPSK qm=0,QPSK qm=1,其他floor(调制阶数/2);OAI的Qm为2/4/6/8
DecodeHead.sfn = frame;
DecodeHead.slotNum = nr_tti_rx;
DecodeHead.subfn = DecodeHead.slotNum/2;
DecodeHead.fillbit = harq_process->F;
DecodeHead.bg = p_decParams->BG-1; //规定选择协议base grape1 bg=0; base grape2 bg=1;OAI的BG大了1
ul_find_iLS_lsIndex(&harq_process->Z, &iLS, &lsIndex);
DecodeHead.iLs = iLS;
DecodeHead.lfSizeIx = lsIndex;
if(DecodeHead.bg == 0){
DecodeHead.maxRowNm = 46;
}
else{
DecodeHead.maxRowNm = 42;
}
if(DecodeHead.cbNum == 1){
DecodeHead.kpInByte = ((harq_process->B)/DecodeHead.cbNum); //decode的kpInByte应该用bit,encode用的Byte
}
else{
DecodeHead.kpInByte = ((harq_process->B+((DecodeHead.cbNum)*24))/DecodeHead.cbNum);
}
nr_get_E0_E1(G, harq_process->C, Qm, n_layers, r, &E0, &E1);
DecodeHead.e0 = E0;
DecodeHead.e1 = E1;
DecodeHead.rvIdx = pusch_pdu->pusch_data.rv_index;
DecodeHead.ndi = 1; //1表示新传,0表示重传
DecodeHead.flush = 0;
DecodeHead.maxIter = 4; //最大迭代次数
DecodeHead.maxRvIdx = 0;
DecodeHead.pktType = 0x10;
DecodeHead.chkCode = 0xFAFA;
DecodeHead.pktTpTmp = 0;
DecodeHead.sectorId = 0; //=0表示单小区
DecodeHead.pduIdx = 0; //=0表示第一个码字,总共一个码字
DecodeHead.lastTb = 1;
DecodeHead.firstTb = 1; //=1表示本slot只有一个TB
DecodeHead.gamma = DecodeHead.cbNum - (G/(n_layers*(2*DecodeHead.qm)))%DecodeHead.cbNum; //E0的CB个数
//调用FPGA的decode,并输出CRC
// clock_gettime( CLOCK_REALTIME, &decode_start );
decoder_load( &DecodeHead, pDeDataIn, pDeDataOut, pcrc );
// clock_gettime( CLOCK_REALTIME, &decode_stop );
if (*pcrc == 1) {
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n",
phy_vars_gNB->Mod_id,harq_process->slot,harq_process->TBS);
harq_process->status = SCH_IDLE;
harq_process->round = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
LOG_D(PHY, "ULSCH received ok \n");
nr_fill_indication(phy_vars_gNB,harq_process->frame, harq_process->slot, ULSCH_id, harq_pid, 0);
} else {
LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) r %d\n",
phy_vars_gNB->Mod_id, harq_process->frame, harq_process->slot,
harq_pid,harq_process->status, harq_process->round,harq_process->TBS,r);
if (harq_process->round >= ulsch->Mlimit) {
harq_process->status = SCH_IDLE;
harq_process->round = 0;
harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
}
harq_process->handled = 1;
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
nr_fill_indication(phy_vars_gNB,harq_process->frame, harq_process->slot, ULSCH_id, harq_pid, 1);
}
free(pcrc);
return 1;
}
void ul_find_iLS_lsIndex(unsigned int *LDPC_lifting_size, uint32_t *iLS_out, uint32_t *lsIndex_out)
{
unsigned int Set_of_LDPC_lifting_size[8][8] = {
{2,4,8,16,32,64,128,256},
{3,6,12,24,48,96,192,384},
{5,10,20,40,80,160,320},
{7,14,28,56,112,224},
{9,18,36,72,144,288},
{11,22,44,88,176,352},
{13,26,52,104,208},
{15,30,60,120,240}};
uint32_t iLS,lsIndex;
for(iLS = 0; iLS < 8; iLS++) {
for(lsIndex = 0; lsIndex < 8; lsIndex++){
if(*LDPC_lifting_size == Set_of_LDPC_lifting_size[iLS][lsIndex]){
*iLS_out = iLS;
*lsIndex_out = lsIndex;
}
}
}
}
\ No newline at end of file
#include <time.h>
//测时间函数
extern struct timespec nr_t[];
#define NR_TIMESPEC_TO_DOUBLE_US( nr_t ) ( ( (double)nr_t.tv_sec * 1000000 ) + ( (double)nr_t.tv_nsec / 1000 ) )
extern struct timespec nr_get_timespec_diff(
struct timespec *start,
struct timespec *stop );
//--------------------------------------------------------------------------------------------------------
#if 0
//nr_ulsch_unscrambling_optim_fpga_ldpc测时间
extern double unscramble_llr128_gettime_cur, unscramble_llr8_gettime_cur;
extern struct timespec unscramble_llr128_start, unscramble_llr8_start;
extern struct timespec unscramble_llr128_stop, unscramble_llr8_stop;
//nr_ulsch_decoding_fpga_ldpc测时间
extern double decode_clock_gettime_cur;
extern struct timespec decode_start;
extern struct timespec decode_stop;
//nr_ulsch_procedures_fpga_ldpc测时间
extern double unscrambing_gettime_cur,decoding_gettime_cur;
extern struct timespec unscrambing_start,decoding_start;
extern struct timespec unscrambing_stop,decoding_stop;
//phy_procedures_gNB_uespec_RX测总时间
extern double ulsch_clock_gettime_cur;
extern struct timespec ulsch_start;
extern struct timespec ulsch_stop;
#endif
extern int8_t ul_de_llr8[];
......@@ -50,12 +50,15 @@
#include "intertask_interface.h"
#include "PHY/NR_TRANSPORT/time_measure_diff.h"
//#define DEBUG_RXDATA
uint8_t SSB_Table[38]={0,2,4,6,8,10,12,14,254,254,16,18,20,22,24,26,28,30,254,254,32,34,36,38,40,42,44,46,254,254,48,50,52,54,56,58,60,62};
extern uint8_t nfapi_mode;
int8_t ul_de_llr8[0x40000];
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp) {
uint8_t sco = 0;
......@@ -696,6 +699,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
//LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,1);
nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
// nr_ulsch_procedures_fpga_ldpc(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); //上面是OAI的代码,pga_ldpc的decode切换到该行即可
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,0);
break;
}
......@@ -715,3 +719,73 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
return 0;
}
void nr_ulsch_procedures_fpga_ldpc(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu;
uint8_t l, number_dmrs_symbols = 0;
uint32_t G;
uint16_t start_symbol, number_symbols, nb_re_dmrs;
start_symbol = pusch_pdu->start_symbol_index;
number_symbols = pusch_pdu->nr_of_symbols;
for (l = start_symbol; l < start_symbol + number_symbols; l++)
number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
if (pusch_pdu->dmrs_config_type==pusch_dmrs_type1)
nb_re_dmrs = 6*pusch_pdu->num_dmrs_cdm_grps_no_data;
else
nb_re_dmrs = 4*pusch_pdu->num_dmrs_cdm_grps_no_data;
G = nr_get_G(pusch_pdu->rb_size,
number_symbols,
nb_re_dmrs,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
AssertFatal(G>0,"G is 0 : rb_size %u, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %u, nrOfLayer %u\n",
pusch_pdu->rb_size,
number_symbols,
nb_re_dmrs,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
LOG_D(PHY,"rb_size %d, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %d, nrOfLayer %d\n",
pusch_pdu->rb_size,
number_symbols,
nb_re_dmrs,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
//----------------------------------------------------------
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_unscrambling_stats);
nr_ulsch_unscrambling_optim_fpga_ldpc(gNB->pusch_vars[ULSCH_id]->llr, ul_de_llr8,
G,
0,
pusch_pdu->data_scrambling_id,
pusch_pdu->rnti);
stop_meas(&gNB->ulsch_unscrambling_stats);
//----------------------------------------------------------
//--------------------- ULSCH decoding ---------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_decoding_stats);
nr_ulsch_decoding_fpga_ldpc(gNB,
ULSCH_id,
gNB->pusch_vars[ULSCH_id]->llr,
ul_de_llr8,
frame_parms,
pusch_pdu,
frame_rx,
slot_rx,
harq_pid,
G);
stop_meas(&gNB->ulsch_decoding_stats);
}
\ No newline at end of file
PREGCC=
TARGET=FFTest
GCC=$(PREGCC)gcc
SYS_INC=/usr/local/include/dev2.0
INCLUDE_DIR := -I$(SYS_INC)
INCLUDE_DIR += -I$(SYS_INC)/9371base
INCLUDE_DIR += -I$(SYS_INC)/ecpriBase
INCLUDE_DIR += -I$(SYS_INC)/fr9371
INCLUDE_DIR += -I$(SYS_INC)/frecpri
INCLUDE_DIR += -I$(SYS_INC)/wi9371
INCLUDE_DIR += -I$(SYS_INC)/wiecpri
LIB_DIR = -lpthread -lhugetlbfs
LIB_DIR1 = -lhugetlbfs
LIB_DIR2 = -ldev2.0
CURDIR:=$(shell pwd)
SRCDIR2 := $(CURDIR)
SRCS := $(wildcard *.c)
OBJS = $(SRCS:%.c=%.o)
CCFLAGS := -g -O2 $(INCLUDE_DIR)
$(TARGET):$(OBJS)
$(GCC) $(CCFLAGS) $(OBJS) -o $@ $(LIB_DIR) $(LIB_DIR2)
%.o: %.c
$(GCC) $(INCLUDE_DIR) $(CCFLAGS) -c $< -o $@
clean:
rm -rf $(OBJS) $(TARGET)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "logger_wrapper.h"
#include "ff_define.h"
int getBinDataFromFile(unsigned char *pData, int *len,char *fname)
{
int fileSize,ret;
FILE *fp;
int i,j,count;
int tempData;
fp=fopen(fname,"rb");
if(fp==NULL){
printf("This %s file is open failed.\n",fname);
}
fseek(fp,0,SEEK_END);
fileSize=ftell(fp);
rewind(fp);
printf("fileSize=0x%x\n",fileSize);
ret=fread(pData,1,fileSize,fp);
*len=fileSize;
//printf("ret=0x%x\n",ret);
fclose(fp);
return 1;
}
//
//
//
////////////////////////////////
void saveBinDataTofile(unsigned char *pData,int len,char * fname)
{
int i,fileSize,ret;
FILE *fp;
fp=fopen(fname,"wb+");
if(fp==NULL){
printf("This %s file is open failed.\n",fname);
}
ret=fwrite(pData,1,len,fp);
//printf("ret=0x%x\n",ret);
fclose(fp);
}
char tempData[512];
char saveDataDirDe[]="/tmp/saveData/de";
char saveDataDirEn[]="/tmp/saveData/en";
static int count1=0,count2=0,loop_count_de=0,loop_count_en=0;
void saveBinData(unsigned char *pData, int type)
{
int i;
DataHeadInfo *pDataHeadInfo;
DataHeadInfo TempDataHead;
unsigned char *pDataHead;
char fname[64];
pDataHeadInfo=(DataHeadInfo *)pData;
if(type==FEC_DECODE_DATA){
loop_count_de++;
if(loop_count_de>=100000){
sprintf(fname,"%s/decode_%08d.bin",saveDataDirDe,count2++);
saveBinDataTofile(pData, pDataHeadInfo->pktLen, fname);
loop_count_de=0;
}
}else if(type==FEC_ENCODE_DATA){
loop_count_en++;
if(loop_count_en>=200000){
sprintf(fname,"%s/encode_%08d.bin",saveDataDirEn,count1++);
saveBinDataTofile(pData, pDataHeadInfo->pktLen, fname);
loop_count_en=0;
}
}
//zLog(PHY_LOG_INFO,"rec header: len=%x---[DRV_LOG]",pDataHeadInfo->pktLen);
}
//
//
//
//
////////////////////////////////////////////
void load_expect_data(unsigned char *pData, char *fname)
{
int len;
getBinDataFromFile(pData, &len, fname);
}
//
//
//
//
////////////////////////////////////////////
int compare_data(unsigned char *pDst1, unsigned char *pDst2, int len)
{
int ret=0;
//ret=memcmp(pDst1,pDst2,len);
return ret;
}
#ifndef __DEV2_DATA_FILE__
#define __DEV2_DATA_FILE__
//
int getBinDataFromFile(unsigned char *pData,int *len, char * fname);
//
void saveBinDataTofile(unsigned char *pData,int len, char *fname);
//
void saveBinData(unsigned char *pData, int type);
//
int compare_data(unsigned char *pDst1, unsigned char *pDst2, int len);
//
void load_expect_data(unsigned char *pData, char *fname);
#endif //__DEV2_DATA_FILE__
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef __FF_DEMO_DEFINE__
#define __FF_DEMO_DEFINE__
#define FPGA_FRONTHAUL 0
#define FPGA_FEC 1
#define FPGA_NUM 2
#define IS_FREE 0
#define IS_BUSY 1
#define IS_FULL 2
#define IS_INVAL 3
#define MILLION 1000000
#define THOUSAND 1000
#define FEC_DECODE_DATA 0x01
#define FEC_ENCODE_DATA 0x02
// log mask
#define ZLOG_DRIVER_DM_TX (1<<20)
#define ZLOG_DRIVER_DM_RX (1<<21)
#define ZLOG_DRIVER_DM_FEC (1<<22)
#define ZLOG_DRIVER_DM_STATUS (1<<23)
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
typedef int int32_t;
typedef long int int64_t;
typedef short int int16_t;
#include "fec_c_if.h"
/*
typedef struct __DescriptorAddrRingStruct
{
uint32_t nRingBufferPoolIndex;
HugepageTblStruct RxFhRingBuffer;
HugepageTblStruct RxEnCodeRingBuffer;
HugepageTblStruct RxDeCodeRingBuffer;
HugepageTblStruct SyncFhRingBuffer;
HugepageTblStruct TxFhRingBuffer;
HugepageTblStruct TxEnCodeRingBuffer;
HugepageTblStruct TxDeCodeRingBuffer;
uint64_t BaseAddress;
}DescriptorAddrRingStruct;
typedef struct __DmaDescInfo
{
uint32_t nAddressHigh;
uint32_t nAddressLow;
uint32_t nAddressLen;
uint32_t rsvrd;
}DescInfo;
typedef struct __DmaDescChainInfo
{
volatile uint32_t nDescriptorStatus[127];
volatile uint32_t nTotalDescriptorStatus;
DescInfo sDescriptor[127];
}DescChainInfo;
typedef struct __HugepageInfo
{
void* pHugepages;
uint32_t nHugePage;
uint32_t nSegment;
uint32_t nHugePagePerSegment;
uint64_t nHugePageSize;
}HugepageInfo;
typedef struct __HugepageTbl
{
void *pPageVirtAddr;
uint64_t nPagePhyAddr;
uint8_t nIsAllocated:1;
HugepageInfo info;
}HugepageTblStruct;
typedef struct __DmaDescDataInfo
{
uint64_t nPhysicalAddr;
void * nVirtAddr;
void * pBarVirtAddr;
uint32_t dataLen;
}DescDataInfo;
typedef struct __DataHeadStruct
{
unsigned int pktType :8;
unsigned int rsv0 :8;
unsigned int chkCode :16;
unsigned int pktLen :21;
unsigned int rsv1:11;
unsigned int rsv2;
unsigned int rsv3;
unsigned int rsv4;
unsigned int rsv5;
unsigned int rsv6;
unsigned int rsv7;
}DataHeadInfo;
*/
typedef struct __MemorySegment
{
void *pSegment;
uint64_t nPhysicalAddr;
uint32_t nSize;
uint8_t nReferences;
}MemorySegmentStruct;
typedef union
{
uint32_t nAll;
struct
{
uint32_t nSlotIdx : 5;
uint32_t nSubFrameIdx : 6;
uint32_t nFrameIdx : 10;
uint32_t nSymbolIdx : 4;
uint32_t nReservd : 7;
} bit;
}TimeStempIndUnion;
#endif // __FF_DEMO_DEFINE__
#!/bin/bash
echo "Insmod NR_Drv"
NR_DRV=./
lsmod | grep nr_drv >& /dev/null
if [ $? -eq 0 ]; then
rmmod nr_drv
rm -rf /dev/nr_cdev0
rm -rf /dev/nr_cdev1
rm -rf /dev/nr_sys
fi
insmod ${NR_DRV}/nr_drv.ko
mknod /dev/nr_sys c 200 0
mknod /dev/nr_cdev0 c 201 0
mknod /dev/nr_cdev1 c 202 0
mkdir -p /tmp/saveData/en
mkdir -p /tmp/saveData/de
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <hugetlbfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include "logger_wrapper.h"
#include "ff_define.h"
#include "mem.h"
#include "dataFile.h"
#include "fec_c_if.h"
int32_t zlogMask=0xF00000; //driver log all open
char FecDeDataFileName[]="decode_data_0.bin";
char FecEnDataFileName[]="encode_data_0.bin";
char saveDataFileName[]="save_data.bin";
//
//
//
//
////////////////////////////////////////////////////////
void dm_time_rec_add(struct timespec *t)
{
clock_gettime(CLOCK_MONOTONIC, t);
}
uint64_t dm_time_rec_diff(struct timespec* now, struct timespec* old) {
uint64_t diff_time = 0;
diff_time = MILLION * (now->tv_sec - old->tv_sec) + (now->tv_nsec - old->tv_nsec) / THOUSAND;
return diff_time;
}
volatile TimeStempIndUnion gTxTimeIndex;
volatile uint64_t *pTxTimeIndex = NULL;
volatile int32_t newSlotIdx,oldSlotIdx;
volatile uint32_t tti_loop_count=0;
volatile uint64_t loopCountEn=0,loopCountDe=0;
volatile uint64_t DeAllTime=0, EnAllTime=0;
volatile uint64_t DeAllLen=0, EnAllLen=0;
int32_t lstSlotIdx =0;
#define DE_RESULT_DATA_MAX 0x100000
#define EN_RESULT_DATA_MAX 0x10000
unsigned char DeDataResult[DE_RESULT_DATA_MAX];
unsigned char EnDataResult[EN_RESULT_DATA_MAX];
char DeResultFileName[]="decode_00.bin";
char EnResultFileName[]="encode_00.bin";
//
//
//
//
////////////////////////////////////////////////////////
int main(int argc,char *argv[])
{
int32_t retVal,i;
uint64_t DmaBaseVirAddr,DmaBasePhyAddr, TtiPhyAddr;
uint8_t *pTtiVirAddr;
MemorySegmentStruct *pFecSegentInfo;
HugepageTblStruct *pFecHugepageTbl;
DescriptorAddrRingStruct DescRingAddr={0};
uint64_t time_dis = 0;
uint32_t fpgaData1,fpgaData2;
DescDataInfo EnDataTx, EnDataRx;
DescDataInfo DeDataTx, DeDataRx;
DataHeadInfo *pDataHeadInfo;
struct timespec deRxEndNew;
struct timespec deRxEndOld;
struct timespec deTxEndNew;
struct timespec deTxEndOld;
struct timespec enRxEndNew;
struct timespec enRxEndOld;
struct timespec enTxEndNew;
struct timespec enTxEndOld;
struct timespec deTxStartRec;
struct timespec deTxStartNew;
struct timespec deRxStartRec;
struct timespec deRxStartNew;
struct timespec enTxStartRec;
struct timespec enTxStartNew;
struct timespec enRxStartRec;
struct timespec enRxStartNew;
volatile uint32_t k;
mm_huge_table_init(&pFecHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
printf( "%s>>>---pFecHugepageTbl->nPagePhyAddr=0x%lx\n",__FUNCTION__,(uint64_t)pFecHugepageTbl->nPagePhyAddr );
mm_segment_init(&pFecSegentInfo, pFecHugepageTbl);
printf("%s>>> pFecSegentInfo->pSegment=0x%lx, pFecSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFecSegentInfo->pSegment, pFecSegentInfo->nPhysicalAddr);
mm_regist_addr_to_ring(&DescRingAddr, pFecSegentInfo);
//log init
GLOBAL_FRLOG_INIT("/tmp/usrp/l1/", "l1", 2, 3);
//
dev2_init_fec();
//
dev2_register_mem_addr(&DescRingAddr);
// malloc memory for rx/tx data
get_data_addr_len(&DescRingAddr, &EnDataTx, &EnDataRx, &DeDataTx, &DeDataRx);
// date init
dm_time_rec_add(&enTxStartNew);
dm_time_rec_add(&enRxStartNew);
dm_time_rec_add(&deTxEndNew);
dm_time_rec_add(&deRxEndNew);
// test data load
getBinDataFromFile((unsigned char *)DeDataTx.nVirtAddr, &DeDataTx.dataLen, FecDeDataFileName);
getBinDataFromFile((unsigned char *)EnDataTx.nVirtAddr, &EnDataTx.dataLen, FecEnDataFileName);
//load_expect_data(DeDataResult,DeResultFileName);
//load_expect_data(EnDataResult,EnResultFileName);
pDataHeadInfo=(DataHeadInfo *)DeDataRx.nVirtAddr;
// main loop !!!
while(1)
{
// Fec Encode Ring
if( fec_en_tx_release() )
{
// release encode data buffer
}
if( fec_en_rx_release() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
dm_time_rec_add(&enRxEndNew);
time_dis = dm_time_rec_diff(&enRxEndNew, &enTxStartNew);
EnAllTime+=time_dis;
EnAllLen+=EnDataTx.dataLen;
loopCountEn++;
if(loopCountEn>=10000){
EnAllTime/=1000;
zLog(PHY_LOG_INFO,"[FecEnRxRing] data throughput=%dMbps current time=%dus EnDataTx.dataLen=%d ---[DRV_LOG]", 8*EnAllLen/EnAllTime/1024,time_dis,EnDataTx.dataLen);
//zLog(PHY_LOG_INFO,"[FecEnRxRing] EnAllTime=%d EnAllLen=%d ---[DRV_LOG]", EnAllTime, EnAllLen);
loopCountEn=0;
EnAllTime=0;
EnAllLen=0;
}
}
saveBinData((unsigned char *)EnDataRx.nVirtAddr, FEC_ENCODE_DATA);
}
// Fec Decode Ring
if( fec_de_tx_release() )
{
// release decode data buffer
}
if( fec_de_rx_release() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
dm_time_rec_add(&deRxEndNew);
time_dis = dm_time_rec_diff(&deRxEndNew, &deTxStartNew);
DeAllTime+=time_dis;
DeAllLen+=pDataHeadInfo->pktLen;
loopCountDe++;
if(loopCountDe>=10000){
DeAllTime/=1000;
zLog(PHY_LOG_INFO,"[FecDeRxRing] data throughput=%dMbps ,current time=%dus,pDataHeadInfo->pktLen=%d ---[DRV_LOG]", 8*DeAllLen/DeAllTime/1024, time_dis, pDataHeadInfo->pktLen);
//zLog(PHY_LOG_INFO,"[FecDeRxRing] DeAllTime=%d DeAllLen=%d ----[DRV_LOG]", DeAllTime, DeAllLen);
loopCountDe=0;
DeAllTime=0;
DeAllLen=0;
}
}
//compare_data();
saveBinData((unsigned char *)DeDataRx.nVirtAddr, FEC_DECODE_DATA);
}
//FEC Encode
if( fec_en_tx_require() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
dm_time_rec_add(&enTxStartNew);
}
dev2_send_en_data(&EnDataTx);
}
if( fec_en_rx_require() )
{
dev2_recv_en_data(&EnDataRx);
}
// FEC Decode
if( fec_de_tx_require() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
dm_time_rec_add(&deTxStartNew);
}
dev2_send_de_data(&DeDataTx);
}
if( fec_de_rx_require() )
{
dev2_recv_de_data(&DeDataRx);
}
}
return 0;
}
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "logger_wrapper.h"
#include "ff_define.h"
#include "mem.h"
#define ADDR (void *)(0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
#define PROTECTION (PROT_READ | PROT_WRITE)
//
//
//
//
////////////////////////////////////////////////////////
int get_hugepage_size(uint64_t* hugepage_size)
{
if (!hugepage_size) {
return -1;
}
if (gethugepagesizes ((int64_t *)hugepage_size, 1) == -1) {
printf("get huge size failed\n");
return -1;
}
return 0;
}
//
//
//
//
////////////////////////////////////////////////////////
int cpa_bb_mm_virttophys (void * pVirtAddr, uint64_t * pPhysAddr)
{
int32_t nMapFd;
uint64_t nPage;
uint32_t nPageSize;
uint64_t nVirtualPageNumber;
nMapFd = open ("/proc/self/pagemap", O_RDONLY);
if (nMapFd < 0)
{
printf("ERROR: Could't open pagemap file\n");
return 0;
}
/*get standard page size */
nPageSize = (uint32_t) getpagesize ();
nVirtualPageNumber = (uint64_t) pVirtAddr / nPageSize;
lseek (nMapFd, nVirtualPageNumber * sizeof (uint64_t), SEEK_SET);
if (read (nMapFd, &nPage, sizeof (uint64_t)) < 0)
{
close (nMapFd);
printf("ERROR: Could't read pagemap file\n");
return 0;
}
*pPhysAddr = ((nPage & 0x007fffffffffffffULL) * nPageSize);
printf("nVirtualPageNumber=0x%lx, nPage=0x%lx, nPageSize=0x%x PhysAddr=0x%lx\n", nVirtualPageNumber, nPage, nPageSize, *pPhysAddr);
close (nMapFd);
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
uint64_t q_partition (HugepageTblStruct * pHugepageTbl, uint64_t nLow, uint64_t nHigh)
{
uint64_t nLowIndex = 0;
uint64_t nHiIndex = 0;
nLowIndex = nLow + 1;
nHiIndex = nHigh;
HugepageTblStruct sTemp;
while (nHiIndex >= nLowIndex)
{
while ((nLowIndex <= nHiIndex) &&
(pHugepageTbl[nLowIndex].nPagePhyAddr < pHugepageTbl[nLow].nPagePhyAddr))
{
nLowIndex++;
}
while ((nHiIndex >= nLowIndex) &&
(pHugepageTbl[nHiIndex].nPagePhyAddr > pHugepageTbl[nLow].nPagePhyAddr))
{
nHiIndex--;
}
if (nHiIndex > nLowIndex)
{
memcpy (&sTemp, &pHugepageTbl[nHiIndex], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nHiIndex], &pHugepageTbl[nLowIndex],
sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nLowIndex], &sTemp, sizeof (HugepageTblStruct));
}
}
memcpy (&sTemp, &pHugepageTbl[nLow], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nLow], &pHugepageTbl[nHiIndex], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nHiIndex], &sTemp, sizeof (HugepageTblStruct));
return nHiIndex;
}
//
//
//
//
////////////////////////////////////////////////////////
int is_flat (uint64_t nPhysAddr1, uint64_t nPhysAddr2, uint64_t nHugePageSize)
{
if (nPhysAddr1 > nPhysAddr2)
{
return 0;
}
else
{
return ((nPhysAddr1 + nHugePageSize) == nPhysAddr2) ? 1 : 0;
}
}
//
//
//
//
////////////////////////////////////////////////////////
int is_contiguous (HugepageTblStruct * pHugepageTbl,
uint32_t nTblOffset,
uint32_t nHugePagePerSegment,
uint64_t nHugePageSize)
{
uint32_t nCount;
for (nCount = 1; nCount < nHugePagePerSegment; nCount++)
{
/*Check current page and next page are contiguous */
if (is_flat (pHugepageTbl[nTblOffset + nCount - 1].nPagePhyAddr,
pHugepageTbl[nTblOffset + nCount].nPagePhyAddr,
nHugePageSize) == 0)
{
return 0;
}
}
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
int check_no_of_segments (HugepageTblStruct * pHugepageTbl,
uint32_t nHugePage, uint32_t nSegment,
uint32_t nHugePagePerSegment,
uint64_t nHugePageSize, uint32_t * segmentCount)
{
uint32_t nCount = 0;
*segmentCount = 0;
if (nHugePagePerSegment == 1)
{
*segmentCount = nSegment;
return 0;
}
do
{
if (is_contiguous (pHugepageTbl, nCount, nHugePagePerSegment, nHugePageSize))
{
nCount += nHugePagePerSegment;
(*segmentCount)++;
}
else
{
nCount++;
}
}
while (nCount <= (nHugePage - nHugePagePerSegment));
printf("INFO: required segment %d segments formed %d\n",
nSegment,
*segmentCount);
printf("INFO: percentage of segment got %f\n",
(((float) *segmentCount / nSegment) * 100));
return (*segmentCount < nSegment) ? -1 : 0;
}
//
//
//
//
////////////////////////////////////////////////////////
int mm_huge_table_init(HugepageTblStruct **pHugepageTbl, uint64_t memSize)
{
uint64_t nHugePageSize;
uint64_t nMemorySize, nMemorySegmentSize;
uint32_t nHugePagePerSegment = 0;
uint32_t nSegmentCount = 0;
uint32_t nHugePage = 0;
uint32_t nSegment = 0;
void *VirtAddr = NULL;
uint64_t PhyAddr;
uint32_t nCount = 0;
uint32_t * pSegmentCount;
uint32_t SegmentCount;
HugepageTblStruct *pHT;
if (get_hugepage_size(&nHugePageSize) != 0) {
return -1;
}
nMemorySize=memSize;
nMemorySegmentSize=SW_FPGA_SEGMENT_BUFFER_LEN;
/*Calculate number of segment */
nSegment = DIV_ROUND_OFF (nMemorySize, nMemorySegmentSize);
/*Calculate number of hugepsges per segment */
nHugePagePerSegment = DIV_ROUND_OFF (nMemorySegmentSize, nHugePageSize);
/* calculate total number of hugepages */
nHugePage = nSegment * nHugePagePerSegment;
pHT = (HugepageTblStruct *) malloc (sizeof (HugepageTblStruct) * nHugePage);
if (pHT == NULL)
{
printf("ERROR: HugepageTblStruct memory allocation failed cause: %s\n", strerror(errno));
return 0;
}
//printf("nHugePageSize=0x%lx, nSegment=%d, nHugePagePerSegment=%d, nHugePage=%d\n", nHugePageSize, nSegment, nHugePagePerSegment, nHugePage);
/*Allocate required number of pages to sort */
VirtAddr = mmap (ADDR, (nHugePage * nHugePageSize), PROTECTION, FLAGS, 0, 0);
if (VirtAddr == MAP_FAILED)
{
printf("ERROR: mmap was failed cause: %s\n", strerror(errno));
free(pHT);
return 0;
}
for(nCount = 0; nCount < nHugePage; nCount++)
{
pHT[nCount].pPageVirtAddr = (uint8_t *) VirtAddr + (nCount * nHugePageSize);
/*Creating dummy page fault in process for each page inorder to get pagemap */
*(uint8_t *) pHT[nCount].pPageVirtAddr = 1;
cpa_bb_mm_virttophys(pHT[nCount].pPageVirtAddr, &pHT[nCount].nPagePhyAddr);
//printf("VirtAddr=0x%lx PhyAddr=0x%lx\n", (uint64_t)(uint64_t *)pHT[nCount].pPageVirtAddr, pHT[nCount].nPagePhyAddr);
}
*pHugepageTbl=pHT;
printf(">>> mm_huge_table_init is ok.\n");
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
int mm_segment_init(MemorySegmentStruct **pSegInfo, HugepageTblStruct *pHugepageTbl)
{
uint32_t nCount = 0;
MemorySegmentStruct *pSegment = NULL;
int32_t nDevFd = 0;
void *VirtAddr = NULL;
//segment calloc
pSegment = (MemorySegmentStruct *)malloc (sizeof (MemorySegmentStruct) );
if (pSegment == NULL)
{
printf("ERROR: No sufficient memory to store segment info\n");
return -3;
}
*pSegInfo=pSegment;
pSegment->nPhysicalAddr=pHugepageTbl[0].nPagePhyAddr;
pSegment->pSegment=pHugepageTbl[0].pPageVirtAddr;
//
return 0;
}
//
//
//
//
////////////////////////////////////////////////////////
void mm_regist_addr_to_ring(DescriptorAddrRingStruct *pDescRing, MemorySegmentStruct *pFecSegInfo)
{
pDescRing->TxEnCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment;
pDescRing->TxEnCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr;
pDescRing->RxEnCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x20;
pDescRing->RxEnCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x20;
pDescRing->TxDeCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x40;
pDescRing->TxDeCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x40;
pDescRing->RxDeCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x60;
pDescRing->RxDeCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x60;
}
//
//
//
////////////////////////////////////////////////////////
void get_data_addr_len(DescriptorAddrRingStruct *pDescRingAddr, DescDataInfo *pEnDataTx, DescDataInfo *pEnDataRx, DescDataInfo *pDeDataTx, DescDataInfo *pDeDataRx)
{
uint64_t phyAddr;
//encode tx
phyAddr=pDescRingAddr->TxEnCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pEnDataTx->nPhysicalAddr=phyAddr;
pEnDataTx->nVirtAddr=pDescRingAddr->TxEnCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataTx->dataLen=0;
//rx
phyAddr=pDescRingAddr->RxEnCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pEnDataRx->nPhysicalAddr=phyAddr;
pEnDataRx->nVirtAddr=pDescRingAddr->RxEnCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataRx->dataLen=0;
//decode tx
phyAddr=pDescRingAddr->TxDeCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pDeDataTx->nPhysicalAddr=phyAddr;
pDeDataTx->nVirtAddr=pDescRingAddr->TxDeCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pDeDataTx->dataLen=0;
//rx
phyAddr=pDescRingAddr->RxDeCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pDeDataRx->nPhysicalAddr=phyAddr;
pDeDataRx->nVirtAddr=pDescRingAddr->RxDeCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataRx->dataLen=0;
}
#ifndef __DEV2_FF_DEMO_MEM__
#define __DEV2_FF_DEMO_MEM__
/*DMA CONTROL REG*/
#define CTRL_MODE_CFG_REG 0
#define STATUS_HADDR_REG 1
#define STATUS_LADDR_REG 2
#define VALID_DES_NUM_REG 3
#define DESC_RING_HADDR_REG 4
#define DESC_RING_LADDR_REG 5
#define BAR_MODE_READ_DESC 0x0 /*2'b00'*/
#define BAR_MODE_READ_MEM 0x2 /*2'b10'*/
#define BAR_MODE_NOTIFY_EACH 0x0 /*2'b00'*/
#define BAR_MODE_NOTIFY_ALL 0x1 /*2'b01'*/
/* hugepage setting */
#define SW_FPGA_TOTAL_BUFFER_LEN 4LL*1024*1024*1024
#define SW_FPGA_SEGMENT_BUFFER_LEN 1LL*1024*1024*1024
#define SW_FPGA_FH_TOTAL_BUFFER_LEN 1LL*1024*1024*1024
#define DIV_ROUND_OFF(X,Y) ( X/Y + ((X%Y)?1:0) )
#define DEVICE_NAME "/dev/nr_cdev"
#define FTH_MEM_SIZE (0x100000)
#define FEC_MEM_SIZE (0x100000)
#define RING_MEM_SIZE (0x10000)
#define SHIFTBITS_32 (32)
#define IS_DESC_DONE(desc) (0xFF&desc)
//
int mm_huge_table_init(HugepageTblStruct **pHugepageTbl, uint64_t memSize);
//
int mm_segment_init(MemorySegmentStruct **pFecSegInfo, HugepageTblStruct *pHugepageTbl);
//
void mm_regist_addr_to_ring(DescriptorAddrRingStruct *pDescRing, MemorySegmentStruct *pFecSegInfo);
//
//
void get_data_addr_len(DescriptorAddrRingStruct *pDescRingAddr, DescDataInfo *pEnDataTx, DescDataInfo *pEnDataRx, DescDataInfo *pDeDataTx, DescDataInfo *pDeDataRx);
#endif //__DEV2_FF_DEMO_MEM__
PREGCC=
TARGET=FFTest
GCC=$(PREGCC)gcc
SYS_INC=/usr/local/include/dev2.0
INCLUDE_DIR := -I$(SYS_INC)
INCLUDE_DIR += -I$(SYS_INC)/9371base
INCLUDE_DIR += -I$(SYS_INC)/ecpriBase
INCLUDE_DIR += -I$(SYS_INC)/fr9371
INCLUDE_DIR += -I$(SYS_INC)/frecpri
INCLUDE_DIR += -I$(SYS_INC)/wi9371
INCLUDE_DIR += -I$(SYS_INC)/wiecpri
LIB_DIR = -lpthread -lhugetlbfs
LIB_DIR1 = -lhugetlbfs
LIB_DIR2 = -ldev2.0
CURDIR:=$(shell pwd)
SRCDIR2 := $(CURDIR)
SRCS := $(wildcard *.c)
OBJS = $(SRCS:%.c=%.o)
CCFLAGS := -g -O2 $(INCLUDE_DIR)
$(TARGET):$(OBJS)
$(GCC) $(CCFLAGS) $(OBJS) -o $@ $(LIB_DIR) $(LIB_DIR2)
%.o: %.c
$(GCC) $(INCLUDE_DIR) $(CCFLAGS) -c $< -o $@
clean:
rm -rf $(OBJS) $(TARGET)
gcc main.c dataFile.c mem.c -fPIC -lpthread -shared -lhugetlbfs -ldev2.0 -o ldpc_fpga_encode.so
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#if 1
#include <dev2.0/logger_wrapper.h>
#include "ff_define.h"
int getBinDataFromFile(unsigned char *pData, int *len,char *fname)
{
int fileSize,ret;
FILE *fp;
int i,j,count;
int tempData;
fp=fopen(fname,"rb");
if(fp==NULL){
printf("This %s file is open failed.\n",fname);
}
fseek(fp,0,SEEK_END);
fileSize=ftell(fp);
rewind(fp);
printf("fileSize=0x%x\n",fileSize);
ret=fread(pData,1,fileSize,fp);
*len=fileSize;
//printf("ret=0x%x\n",ret);
fclose(fp);
return 1;
}
//
//
//
////////////////////////////////
void saveBinDataTofile(unsigned char *pData,int len,char * fname)
{
int i,fileSize,ret;
FILE *fp;
fp=fopen(fname,"wb+");
if(fp==NULL){
printf("This %s file is open failed.\n",fname);
}
ret=fwrite(pData,1,len,fp);
//printf("ret=0x%x\n",ret);
fclose(fp);
}
char tempData[512];
char saveDataDirDe[]="/tmp/saveData/de";
char saveDataDirEn[]="/tmp/saveData/en";
static int count1=0,count2=0,loop_count_de=0,loop_count_en=0;
void saveBinData(unsigned char *pData, int type)
{
int i;
DataHeadInfo *pDataHeadInfo;
DataHeadInfo TempDataHead;
unsigned char *pDataHead;
char fname[64];
pDataHeadInfo=(DataHeadInfo *)pData;
if(type==FEC_DECODE_DATA){
loop_count_de++;
if(loop_count_de>=10000){
sprintf(fname,"%s/decode_%08d.bin",saveDataDirDe,count2++);
saveBinDataTofile(pData, pDataHeadInfo->pktLen+16, fname);
loop_count_de=0;
}
}else if(type==FEC_ENCODE_DATA){
loop_count_en++;
if(loop_count_en>=100000){
sprintf(fname,"%s/encode_%08d.bin",saveDataDirEn,count1++);
saveBinDataTofile(pData, pDataHeadInfo->pktLen+16, fname);
loop_count_en=0;
}
}
//zLog(PHY_LOG_INFO,"rec header: len=%x---[DRV_LOG]",pDataHeadInfo->pktLen);
}
//
//
//
//
////////////////////////////////////////////
void load_expect_data(unsigned char *pData, char *fname)
{
int len;
getBinDataFromFile(pData, &len, fname);
}
//
//
//
//
////////////////////////////////////////////
int compare_data(unsigned char *pDst1, unsigned char *pDst2, int len)
{
int ret=0;
//ret=memcmp(pDst1,pDst2,len);
return ret;
}
#endif
#include "dataFile.h"
int add(int x, int y)
{
printf("dataFile x+y = %d\n", x+y);
return(x+y);
}
#ifndef __DEV2_DATA_FILE__
#define __DEV2_DATA_FILE__
#if 1
//
int getBinDataFromFile(unsigned char *pData,int *len, char * fname);
//
void saveBinDataTofile(unsigned char *pData,int len, char *fname);
//
void saveBinData(unsigned char *pData, int type);
//
int compare_data(unsigned char *pDst1, unsigned char *pDst2, int len);
//
void load_expect_data(unsigned char *pData, char *fname);
#endif
int add(int x, int y);
#endif //__DEV2_DATA_FILE__
#ifndef __FF_DEMO_DEFINE__
#define __FF_DEMO_DEFINE__
#define FPGA_FRONTHAUL 0
#define FPGA_FEC 1
#define FPGA_NUM 2
#define IS_FREE 0
#define IS_BUSY 1
#define IS_FULL 2
#define IS_INVAL 3
#define MILLION 1000000
#define THOUSAND 1000
#define FEC_DECODE_DATA 0x01
#define FEC_ENCODE_DATA 0x02
// log mask
#define ZLOG_DRIVER_DM_TX (1<<20)
#define ZLOG_DRIVER_DM_RX (1<<21)
#define ZLOG_DRIVER_DM_FEC (1<<22)
#define ZLOG_DRIVER_DM_STATUS (1<<23)
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
typedef int int32_t;
typedef long int int64_t;
typedef short int int16_t;
#include <dev2.0/fec_c_if.h>
typedef struct
{
/*Word 0*/
uint32_t pktType :8;
uint32_t rsv0 :8;
uint32_t chkCode :16;
/*Word 1*/
uint32_t pktLen :21; /*按照byte计算,header+tbsize 按照byte对齐后的长度*/
uint32_t rsv1 :11;
/*Word 2*/
uint32_t rsv2 :28;
uint32_t sectorId :2;
uint32_t rsv3 :2;
/*Word 3*/
uint32_t sfn :10;
uint32_t rsv4 :2;
uint32_t subfn :4;
uint32_t slotNum :5;
uint32_t pduIdx :9;
uint32_t rev5 :2;
/*Word 4*/
uint32_t tbSizeB :18;
uint32_t rev6 :2;
uint32_t lastTb :1;
uint32_t firstTb :1;
uint32_t rev7 :2;
uint32_t cbNum :8;
/*Word 5*/
uint32_t qm :3;
uint32_t rev8 :1;
uint32_t fillbit :14;
uint32_t rev9 :2;
uint32_t kpInByte :11;
uint32_t rev10 :1;
/*Word 6*/
uint32_t gamma :8;
uint32_t codeRate :6;
uint32_t rev11 :2;
uint32_t rvIdx :2;
uint32_t rev12 :6;
uint32_t lfSizeIx :3;
uint32_t rev13 :1;
uint32_t iLs :3;
uint32_t bg :1;
/*Word 7*/
uint32_t e1 :16;
uint32_t e0 :16;
}EncodeInHeaderStruct;
typedef struct
{
uint32_t pktType :8;
uint32_t rsv0 :8;
uint32_t chkCode :16;
uint32_t pduSize :21;
uint32_t rsv1 :11;
uint32_t rsv2 :28;
uint32_t sectorId :2;
uint32_t rsv3 :2;
uint32_t sfn :10;
uint32_t rsv4 :2;
uint32_t subfn :4;
uint32_t slotNum :5;
uint32_t pduIdx :9;
uint32_t rev5 :2;
uint32_t tbSizeB :18;
uint32_t rev6 :2;
uint32_t lastTb :1;
uint32_t firstTb :1;
uint32_t rev7 :2;
uint32_t cbNum :8;
uint32_t qm :3;
uint32_t rev8 :1;
uint32_t fillbit :14;
uint32_t rev9 :2;
uint32_t kpInByte :11;
uint32_t rev10 :1;
uint32_t gamma :8;
uint32_t codeRate :6;
uint32_t rev11 :2;
uint32_t rvIdx :2;
uint32_t rev12 :6;
uint32_t lfSizeIx :3;
uint32_t rev13 :1;
uint32_t iLs :3;
uint32_t bg :1;
uint32_t e1 :16;
uint32_t e0 :16;
}EncodeOutHeaderStruct;
typedef struct
{
/*Word 0*/
uint32_t pktType :8;
uint32_t rsv0 :8;
uint32_t chkCode :16;
/*Word 1*/
uint32_t pktLen :21; /*包含header + DDRheader + CB DATA的长度,单位是byte*/
uint32_t rsv1 :11;
/*Word 2*/
uint32_t pktTpTmp :4;
uint32_t pduSize :24; /*包含header + DDRheader + CB DATA的长度,单位是Word*/
uint32_t sectorId :2;
uint32_t rsv2 :2;
/*Word 3*/
uint32_t sfn :10;
uint32_t rsv3 :2;
uint32_t subfn :4;
uint32_t slotNum :5;
uint32_t pduIdx :9;
uint32_t rev4 :2;
/*Word 4*/
uint32_t tbSizeB :18; /*tbsize的大小,单位byte*/
uint32_t rev5 :2;
uint32_t lastTb :1;
uint32_t firstTb :1;
uint32_t rev6 :2;
uint32_t cbNum :8; /*码块数*/
/*Word 5*/
uint32_t qm :3;
uint32_t rev7 :1;
uint32_t fillbit :14;
uint32_t kpInByte :14; /* 被均分后每个cb块的长度,单位bit */
/*Word 6*/
uint32_t gamma :8;
uint32_t maxRowNm :6; //填成46
uint32_t maxRvIdx :2;
uint32_t rvIdx :2;
uint32_t ndi :1;
uint32_t flush :1;
uint32_t maxIter :4;
uint32_t lfSizeIx :3;
uint32_t rev10 :1;
uint32_t iLs :3;
uint32_t bg :1;
/*Word 7*/
uint32_t e1 :16;
uint32_t e0 :16;
}DecodeInHeaderStruct;
typedef struct
{
/*word 0*/
uint32_t pktType :8; /* FEC RX 类型: 0x11*/
uint32_t rsv0 :8;
uint32_t chkCode :16; /* 数据校验 :0xFAFA*/
/*word 1*/
uint32_t pktLen :21; /* 包括 FPGA_ALIGN(header+ FPGA_ALIGN4B(tbsizeB)+4byte) */
uint32_t rsv1 :11;
/*word 2*/
uint32_t pktTpTmp :4;
uint32_t pduSize :20; /* pktLen长度除以4 单位 word*/
uint32_t rsv2 :4;
uint32_t sectorId :2;
uint32_t rsv3 :2;
/*word 3*/
uint32_t sfn :10; /* 帧号 */
uint32_t rsv4 :2;
uint32_t subfn :4; /* 子帧号 */
uint32_t slotNum :5; /* 时隙号 */
uint32_t pduIdx :9;
uint32_t rsv5 :2;
/*Word 4*/
uint32_t tbSizeB :18; /* tbsize 的大小,单位byte*/
uint32_t rsv6 :2;
uint32_t lastTb :1;
uint32_t firstTb :1;
uint32_t rsv7 :2;
uint32_t cbNum :8;
/*Word 5*/
uint32_t rsv8 :32;
/*Word 6*/
uint32_t rsv9 :32;
/*Word 7*/
uint32_t rsv10 :32;
}DecodeOutHeaderStruct;
typedef struct __MemorySegment
{
void *pSegment;
uint64_t nPhysicalAddr;
uint32_t nSize;
uint8_t nReferences;
}MemorySegmentStruct;
typedef union
{
uint32_t nAll;
struct
{
uint32_t nSlotIdx : 5;
uint32_t nSubFrameIdx : 6;
uint32_t nFrameIdx : 10;
uint32_t nSymbolIdx : 4;
uint32_t nReservd : 7;
} bit;
}TimeStempIndUnion;
#endif // __FF_DEMO_DEFINE__
#!/bin/bash
echo "Insmod NR_Drv"
NR_DRV=./
lsmod | grep nr_drv >& /dev/null
if [ $? -eq 0 ]; then
rmmod nr_drv
rm -rf /dev/nr_cdev0
rm -rf /dev/nr_cdev1
rm -rf /dev/nr_sys
fi
insmod ${NR_DRV}/nr_drv.ko
mknod /dev/nr_sys c 200 0
mknod /dev/nr_cdev0 c 201 0
mknod /dev/nr_cdev1 c 202 0
mkdir -p /tmp/saveData/en
mkdir -p /tmp/saveData/de
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <hugetlbfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
//#include "logger_wrapper.h"
#include <dev2.0/logger_wrapper.h>
#include "ff_define.h"
#include "mem.h"
#include "dataFile.h"
//#include "fec_c_if.h"
#include <dev2.0/fec_c_if.h>
int32_t zlogMask=0xF00000; //driver log all open
static int demo_count = 0;
char FecDeDataFileName[]="rx_decode0608.bin";
// char FecDeDataFileName[]="rx_decode_matlab.bin";
// char FecDeDataFileName[]="decode_fpga.bin";
char FecEnDataFileName[]="oai_encode_data_0.bin";
char saveDataFileName[]="save_data.bin";
//
//
//
//
////////////////////////////////////////////////////////
void dm_time_rec_add(struct timespec *t)
{
clock_gettime(CLOCK_MONOTONIC, t);
}
uint64_t dm_time_rec_diff(struct timespec* now, struct timespec* old) {
uint64_t diff_time = 0;
diff_time = MILLION * (now->tv_sec - old->tv_sec) + (now->tv_nsec - old->tv_nsec) / THOUSAND;
return diff_time;
}
volatile uint64_t loopCountEn=0,loopCountDe=0;
volatile uint64_t DeAllTime=0, EnAllTime=0;
volatile uint64_t DeAllLen=0, EnAllLen=0;
int32_t lstSlotIdx =0;
#define DEFAULT_EN_DATA_LEN 0x400000
#define DEFAULT_DE_DATA_LEN 0x400000
char DeResultFileName[]="decode_00.bin";
char EnResultFileName[]="encode_00.bin";
char HeadDataFileName[]="head_data.bin";
DescDataInfo EnDataTx,EnDataRx;
DescDataInfo DeDataTx,DeDataRx;
int step1=0,step2=0,step3=0,step4=0;
//
//
//
//
////////////////////////////////////////////////////////
int encoder_load( EncodeInHeaderStruct *pHeader, unsigned char * pSrc, unsigned char * pDst )
{
EncodeInHeaderStruct *pDataHeadInfo;
// if(demo_count > 1)
// {
// return 1;
// }
//while(1)
//{
// Fec Encode Ring
while(1){
//FEC Encode
if( fec_en_tx_require() )
{
memcpy( (unsigned char *)EnDataTx.nVirtAddr, pHeader, sizeof(EncodeInHeaderStruct));
memcpy( (unsigned char *)EnDataTx.nVirtAddr+sizeof(EncodeInHeaderStruct), pSrc, pHeader->pktLen);
EnDataTx.dataLen=pHeader->pktLen;
dev2_send_en_data(&EnDataTx);
//zLog(PHY_LOG_INFO," encoder_load:<1> ---[DRV_LOG]");
break;
}
}
while(1){
if( fec_en_rx_require() )
{
//printf("fec_en_rx_require_start\n");
dev2_recv_en_data(&EnDataRx);
//zLog(PHY_LOG_INFO," encoder_load:<2> ---[DRV_LOG]");
// printf("fec_en_rx_require_end\n");
break;
}
//usleep(2);
}
while(1){
if( fec_en_tx_release() )
{
// release encode data buffer
//zLog(PHY_LOG_INFO," encoder_load:<3> ---[DRV_LOG]");
// printf("fec_en_tx_release\n");
break;
}
}
while(1){
if( fec_en_rx_release() )
{
//zLog(PHY_LOG_INFO," encoder_load:<3.5> ---[DRV_LOG]");
// printf("fec_en_rx_release_start\n");
pDataHeadInfo=(EncodeOutHeaderStruct *)EnDataRx.nVirtAddr;
// memcpy(pDst, (unsigned char *)(EnDataRx.nVirtAddr), (pDataHeadInfo->pktLen));
memcpy(pDst, (unsigned char *)(EnDataRx.nVirtAddr+32), (pDataHeadInfo->pktLen-32));
//zLog(PHY_LOG_INFO," encoder_load:<4> ---[DRV_LOG]");
// printf("fec_en_rx_release\n");
return 1;
}
}
//}
}
int decoder_load( DecodeInHeaderStruct *pHeader, unsigned char * pSrc, unsigned char * pDst, unsigned char * pCRC )
{
DecodeInHeaderStruct *pDataHeadInfo;
int InHeaderLength = sizeof(DecodeInHeaderStruct);
int DDRHeaderLength = ((pHeader->cbNum+7)/8)*32;
// if(demo_count > 1)
// {
// return 1;
// }
//while(1)
//{
// Fec Decode Ring
while(1){
//FEC Decode
if( fec_de_tx_require() )
{
memcpy( (unsigned char *)DeDataTx.nVirtAddr, pHeader, InHeaderLength);
memcpy( (unsigned char *)DeDataTx.nVirtAddr+InHeaderLength+DDRHeaderLength, pSrc, pHeader->pktLen-InHeaderLength-DDRHeaderLength);
DeDataTx.dataLen=pHeader->pktLen;
dev2_send_de_data(&DeDataTx);
zLog(PHY_LOG_INFO," decoder_load:<1> ---[DRV_LOG]");
break;
}
}
while(1){
if( fec_de_rx_require() )
{
//printf("fec_de_rx_require_start\n");
dev2_recv_de_data(&DeDataRx);
zLog(PHY_LOG_INFO," decoder_load:<2> ---[DRV_LOG]");
// printf("fec_de_rx_require_end\n");
break;
}
//usleep(2);
}
while(1){
if( fec_de_tx_release() )
{
// release decode data buffer
zLog(PHY_LOG_INFO," decoder_load:<3> ---[DRV_LOG]");
// printf("fec_de_tx_release\n");
break;
}
}
while(1){
if( fec_de_rx_release() )
{
zLog(PHY_LOG_INFO," decoder_load:<3.5> ---[DRV_LOG]");
// printf("fec_de_rx_release_start\n");
pDataHeadInfo=(DecodeOutHeaderStruct *)DeDataRx.nVirtAddr;
// memcpy(pDst, (unsigned char *)(DeDataRx.nVirtAddr), (pDataHeadInfo->tbSizeB));
memcpy(pDst, (unsigned char *)(DeDataRx.nVirtAddr+32), (pDataHeadInfo->tbSizeB));
memcpy(pCRC, (unsigned char *)( DeDataRx.nVirtAddr+32 + (pDataHeadInfo->tbSizeB+(4-pDataHeadInfo->tbSizeB%4)%4) ), (4));
if(*pCRC == 1)
{
zLog(PHY_LOG_INFO," decoder_load: crc correct!");
// memcpy(pDst, (unsigned char *)(DeDataRx.nVirtAddr+32), (pDataHeadInfo->tbSizeB-32));
}
zLog(PHY_LOG_INFO," decoder_load:<4> ---[DRV_LOG]");
// printf("fec_de_rx_release\n");
return 1;
}
}
//}
}
void encode_tx_head( EncodeInHeaderStruct *pHD )
{
//word 0
pHD->pktType=0x12;
pHD->rsv0=0x00;
pHD->chkCode=0xFAFA;
//word 1
pHD->pktLen=0x1000;
pHD->rsv1=0x0000;
//word 2
pHD->rsv2=0x0;
pHD->sectorId=0x0;
pHD->rsv3=0x0;
//word 3
pHD->sfn=0x13c;
pHD->rsv4=0x0;
pHD->subfn=0x1;
pHD->slotNum=0x2;
pHD->pduIdx=0x0;
pHD->rev5=0x0;
//word 4
pHD->tbSizeB=0x0fc1;
pHD->rev6=0x0;
pHD->lastTb=0x1;
pHD->firstTb=0x1;
pHD->rev7=0x0;
pHD->cbNum=0x04;
//word 5
pHD->qm=0x3;
pHD->rev8=0x0;
pHD->fillbit=0x160;
pHD->rev9=0x0;
pHD->kpInByte=0x3f4;
pHD->rev10=0x0;
//word 6
pHD->gamma=0x02;
pHD->codeRate=0x2e;
pHD->rev11=0x0;
pHD->rvIdx=0x0;
pHD->rev12=0x0;
pHD->lfSizeIx=0x7;
pHD->rev13=0x0;
pHD->iLs=0x1;
pHD->bg=0x0;
//word 7
pHD->e1=0x44be;
pHD->e0=0x44b8;
}
void decode_tx_head( DecodeInHeaderStruct *pHD )
{
#if 0 //最先测试的头部参数,对应rx_decode_matlab
//word 0
pHD->pktType=0x10;
pHD->rsv0=0x00;
pHD->chkCode=0xFAFA;
//word 1
pHD->pktLen=0x68A0;
pHD->rsv1=0x0000;
//word 2
pHD->pktTpTmp=0x0;
pHD->pduSize=0x1A28;
pHD->sectorId=0x0;
pHD->rsv2=0x0;
//word 3
pHD->sfn=0x121;
pHD->rsv3=0x0;
pHD->subfn=0x04;
pHD->slotNum=0x08;
pHD->pduIdx=0x0;
pHD->rev4=0x0;
//word 4
pHD->tbSizeB=0x8C1;
pHD->rev5=0x0;
pHD->lastTb=0x1;
pHD->firstTb=0x1;
pHD->rev6=0x0;
pHD->cbNum=0x03;
//word 5
pHD->qm=0x01;
pHD->rev7=0x0;
pHD->fillbit=0x148;
pHD->kpInByte=0x1778;
//word 6
pHD->gamma=0x03;
pHD->maxRowNm=0x2E;
pHD->maxRvIdx=0x0;
pHD->rvIdx=0x0;
pHD->ndi=0x01;
pHD->flush=0x0;
pHD->maxIter=0x04;
pHD->lfSizeIx=0x05;
pHD->rev10=0x0;
pHD->iLs=0x04;
pHD->bg=0x0;
//word 7
pHD->e1=0x22C8;
pHD->e0=0x22C8;
#endif
#if 1 //最新测试的头部参数,对应rx_decode0608
//word 0
pHD->pktType=16;
pHD->rsv0=0x00;
pHD->chkCode=64250;
//word 1
pHD->pktLen=38464;
pHD->rsv1=0x0000;
//word 2
pHD->pktTpTmp=0;
pHD->pduSize=9616;
pHD->sectorId=0;
pHD->rsv2=0x0;
//word 3
pHD->sfn=199;
pHD->rsv3=0x0;
pHD->subfn=4;
pHD->slotNum=8;
pHD->pduIdx=0;
pHD->rev4=0x0;
//word 4
pHD->tbSizeB=1761;
pHD->rev5=0x0;
pHD->lastTb=1;
pHD->firstTb=1;
pHD->rev6=0x0;
pHD->cbNum=2;
//word 5
pHD->qm=2;
pHD->rev7=0x0;
pHD->fillbit=664;
pHD->kpInByte=7080;
//word 6
pHD->gamma=2;
pHD->maxRowNm=46;
pHD->maxRvIdx=0;
pHD->rvIdx=0;
pHD->ndi=1;
pHD->flush=0;
pHD->maxIter=4;
pHD->lfSizeIx=5;
pHD->rev10=0x0;
pHD->iLs=5;
pHD->bg=0;
//word 7
pHD->e1=19200;
pHD->e0=19200;
#endif
}
//
//
//
//
////////////////////////////////////////////////////////
#if 0 //encode的demo的main
int main(int argc,char *argv[])
{
volatile uint32_t k;
int32_t retVal,i;
MemorySegmentStruct *pFecSegentInfo;
HugepageTblStruct *pFecHugepageTbl;
DescriptorAddrRingStruct DescRingAddr={0};
uint64_t time_dis =0;
struct timespec deEndTime,deStartTime;
struct timespec enEndTime,enStartTime;
EncodeInHeaderStruct EncodeHeadData;
// DecodeInHeaderStruct DecodeHeadData;
unsigned char *pEnDataSrc,*pEnDataDst;
// unsigned char *pDeDataSrc,*pDeDataDst;
int dataLen=0;
mm_huge_table_init(&pFecHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
printf( "%s>>>---pFecHugepageTbl->nPagePhyAddr=0x%lx\n",__FUNCTION__,(uint64_t)pFecHugepageTbl->nPagePhyAddr );
mm_segment_init(&pFecSegentInfo, pFecHugepageTbl);
printf("%s>>> pFecSegentInfo->pSegment=0x%lx, pFecSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFecSegentInfo->pSegment, pFecSegentInfo->nPhysicalAddr);
mm_regist_addr_to_ring(&DescRingAddr, pFecSegentInfo);
//log init
GLOBAL_FRLOG_INIT("/tmp/usrp/l1/", "l1", 2, 3);
dev2_init_fec();
dev2_register_mem_addr(&DescRingAddr);
get_data_addr_len(&DescRingAddr, &EnDataTx, &EnDataRx, &DeDataTx, &DeDataRx);
// malloc memory for rx/tx data
pEnDataSrc=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
pEnDataDst=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
// pDeDataSrc=(unsigned char *)malloc(DEFAULT_DE_DATA_LEN);
// pDeDataDst=(unsigned char *)malloc(DEFAULT_DE_DATA_LEN);
// test data load
getBinDataFromFile( pEnDataSrc, &dataLen, FecEnDataFileName );
// getBinDataFromFile( pDeDataSrc, &dataLen, FecDeDataFileName );
//create head;
encode_tx_head(&EncodeHeadData);
// decode_tx_head(&DecodeHeadData);
//saveBinDataTofile(&EncodeHeadData, sizeof(EncodeInHeaderStruct), HeadDataFileName);
//printf("head data file save.\n");
//sleep(100);
// main loop !!!
//while( loopCountEn<3 )
// while( 1 )
// {
// Fec Encode
dm_time_rec_add(&enStartTime);
// dm_time_rec_add(&deStartTime);
encoder_load( &EncodeHeadData, pEnDataSrc, pEnDataDst );
// decoder_load( &DecodeHeadData, pDeDataSrc, pDeDataDst );
dm_time_rec_add(&enEndTime);
// dm_time_rec_add(&deEndTime);
time_dis = dm_time_rec_diff(&enEndTime, &enStartTime);
// time_dis = dm_time_rec_diff(&deEndTime, &deStartTime);
EnAllTime+=time_dis;
EnAllLen+=dataLen;
loopCountEn++;
if(loopCountEn>=10000)
{
EnAllTime/=1000;
zLog(PHY_LOG_INFO,"[FecEnRxRing] data throughput=%dMbps current time=%dus dataLen=%d ---[DRV_LOG]", 8*EnAllLen/EnAllTime/1000,time_dis, dataLen);
loopCountEn=0;
EnAllTime=0;
EnAllLen=0;
}
// DeAllTime+=time_dis;
// DeAllLen+=dataLen;
// loopCountDe++;
// if(loopCountDe>=10000)
// {
// DeAllTime/=1000;
// //zLog(PHY_LOG_INFO,"[FecEnRxRing] data throughput=%dMbps current time=%dus dataLen=%d ---[DRV_LOG]", 8*EnAllLen/EnAllTime/1000,time_dis, dataLen);
// loopCountDe=0;
// DeAllTime=0;
// DeAllLen=0;
// }
printf("---end---\n");
// for(i=0; i<10;i++){
// printf("%d\n",i);
// }
for(i=0; i<30; i++)
{
printf("pEnDataDst+%d = %d\n", i, *(pEnDataDst+i));
}
saveBinData(pEnDataDst, FEC_ENCODE_DATA);
// saveBinData(pDeDataDst, FEC_DECODE_DATA);
// }
// printf("---end---\n");
// sleep(1);
return 0;
}
#endif
#if 1 //decode的demo的main
int main(int argc,char *argv[])
{
volatile uint32_t k;
int32_t retVal,i;
MemorySegmentStruct *pFecSegentInfo;
HugepageTblStruct *pFecHugepageTbl;
DescriptorAddrRingStruct DescRingAddr={0};
uint64_t time_dis =0;
struct timespec deEndTime,deStartTime;
struct timespec enEndTime,enStartTime;
EncodeInHeaderStruct EncodeHeadData;
DecodeInHeaderStruct DecodeHeadData;
unsigned char *pEnDataSrc,*pEnDataDst;
char *pDeDataSrc;
unsigned char *pDeDataDst;
int dataLen=0;
unsigned char *pcrc;
mm_huge_table_init(&pFecHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
printf( "%s>>>---pFecHugepageTbl->nPagePhyAddr=0x%lx\n",__FUNCTION__,(uint64_t)pFecHugepageTbl->nPagePhyAddr );
mm_segment_init(&pFecSegentInfo, pFecHugepageTbl);
printf("%s>>> pFecSegentInfo->pSegment=0x%lx, pFecSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFecSegentInfo->pSegment, pFecSegentInfo->nPhysicalAddr);
mm_regist_addr_to_ring(&DescRingAddr, pFecSegentInfo);
//log init
GLOBAL_FRLOG_INIT("/tmp/usrp/l1/", "l1", 2, 3);
dev2_init_fec();
dev2_register_mem_addr(&DescRingAddr);
get_data_addr_len(&DescRingAddr, &EnDataTx, &EnDataRx, &DeDataTx, &DeDataRx);
// malloc memory for rx/tx data
// pEnDataSrc=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
// pEnDataDst=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
pDeDataSrc=(char *)malloc(DEFAULT_DE_DATA_LEN);
pDeDataDst=(unsigned char *)malloc(DEFAULT_DE_DATA_LEN);
pcrc = (unsigned char *)malloc(4);
// test data load
getBinDataFromFile( pDeDataSrc, &dataLen, FecDeDataFileName );
//create head;
// encode_tx_head(&EncodeHeadData);
decode_tx_head(&DecodeHeadData);
//saveBinDataTofile(&EncodeHeadData, sizeof(EncodeInHeaderStruct), HeadDataFileName);
//printf("head data file save.\n");
//sleep(100);
// main loop !!!
//while( loopCountEn<3 )
// while( 1 )
// {
// Fec Encode
dm_time_rec_add(&deStartTime);
// encoder_load( &EncodeHeadData, pEnDataSrc, pEnDataDst );
//测试的demo中pDeDataSrc包含了32Byte的头,应该去掉。
// decoder_load( &DecodeHeadData, pDeDataSrc, pDeDataDst );
decoder_load( &DecodeHeadData, pDeDataSrc+64, pDeDataDst, pcrc );
dm_time_rec_add(&deEndTime);
time_dis = dm_time_rec_diff(&deEndTime, &deStartTime);
DeAllTime+=time_dis;
DeAllLen+=dataLen;
loopCountDe++;
if(loopCountDe>=10000)
{
DeAllTime/=1000;
zLog(PHY_LOG_INFO,"[FecDeRxRing] data throughput=%dMbps current time=%dus dataLen=%d ---[DRV_LOG]", 8*DeAllLen/DeAllTime/1000,time_dis, dataLen);
loopCountDe=0;
DeAllTime=0;
DeAllLen=0;
}
printf("---end---\n");
// for(i=0; i<10;i++){
// printf("%d\n",i);
// }
for(i=0; i<100; i++)
{
printf("pDeDataSrc+%d = %d\n", i, *(pDeDataSrc+i));
}
printf("--------------------------------------\n");
// for(i=0; i<DecodeHeadData.tbSizeB+8; i++)
// {
// printf("pDeDataDst+%d = %u\n", i, *(pDeDataDst+i));
// }
for(i=0; i<200; i++)
{
printf("pDeDataDst+%d = %u\n", i, *(pDeDataDst+i));
}
for(i=0; i<4; i++)
{
printf("pcrc+%d = %u\n", i, *(pcrc+i));
}
if(*pcrc == 1)
{
printf("decode correct!\n");
}
saveBinData(pDeDataDst, FEC_DECODE_DATA);
// }
// printf("---end---\n");
// sleep(1);
return 0;
}
#endif
int HugePage_Init(int bbb)
{
// demo_count++;
// if(demo_count > 1)
// {
// return 0;
// }
volatile uint32_t k;
int32_t retVal,i;
MemorySegmentStruct *pFecSegentInfo;
HugepageTblStruct *pFecHugepageTbl;
DescriptorAddrRingStruct DescRingAddr={0};
uint64_t time_dis =0;
struct timespec deEndTime,deStartTime;
struct timespec enEndTime,enStartTime;
EncodeInHeaderStruct EncodeHeadData;
unsigned char *pEnDataSrc,*pEnDataDst;
int dataLen=0;
mm_huge_table_init(&pFecHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
printf( "%s>>>---pFecHugepageTbl->nPagePhyAddr=0x%lx\n",__FUNCTION__,(uint64_t)pFecHugepageTbl->nPagePhyAddr );
mm_segment_init(&pFecSegentInfo, pFecHugepageTbl);
printf("%s>>> pFecSegentInfo->pSegment=0x%lx, pFecSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFecSegentInfo->pSegment, pFecSegentInfo->nPhysicalAddr);
mm_regist_addr_to_ring(&DescRingAddr, pFecSegentInfo);
//log init
GLOBAL_FRLOG_INIT("/tmp/usrp/l1/", "l1", 2, 3);
dev2_init_fec();
dev2_register_mem_addr(&DescRingAddr);
get_data_addr_len(&DescRingAddr, &EnDataTx, &EnDataRx, &DeDataTx, &DeDataRx);
#if 0
// malloc memory for rx/tx data
pEnDataSrc=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
pEnDataDst=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
// test data load
getBinDataFromFile( pEnDataSrc, &dataLen, FecEnDataFileName );
// int dl_encode_i;
// for(dl_encode_i = 0; dl_encode_i<4096; dl_encode_i++){
// pEnDataSrc[dl_encode_i] = dl_encode_i;
// }
//create head;
encode_tx_head(&EncodeHeadData);
#endif
//saveBinDataTofile(&EncodeHeadData, sizeof(EncodeInHeaderStruct), HeadDataFileName);
//printf("head data file save.\n");
//sleep(100);
// main loop !!!
//while( loopCountEn<3 )
#if 0
while( 1 )
{
// Fec Encode
dm_time_rec_add(&enStartTime);
encoder_load( &EncodeHeadData, pEnDataSrc, pEnDataDst );
dm_time_rec_add(&enEndTime);
time_dis = dm_time_rec_diff(&enEndTime, &enStartTime);
EnAllTime+=time_dis;
EnAllLen+=dataLen;
loopCountEn++;
if(loopCountEn>=10000)
{
EnAllTime/=1000;
zLog(PHY_LOG_INFO,"[FecEnRxRing] data throughput=%dMbps current time=%dus dataLen=%d ---[DRV_LOG]", 8*EnAllLen/EnAllTime/1000,time_dis, dataLen);
loopCountEn=0;
EnAllTime=0;
EnAllLen=0;
}
printf("---end---\n");
// for(i=0; i<10;i++){
// printf("%d\n",i);
// }
saveBinData(pEnDataDst, FEC_ENCODE_DATA);
}
// printf("---end---\n");
sleep(1);
#endif
return 0;
}
int main234(int aaa)
{
volatile uint32_t k;
int32_t retVal,i;
MemorySegmentStruct *pFecSegentInfo;
HugepageTblStruct *pFecHugepageTbl;
DescriptorAddrRingStruct DescRingAddr={0};
uint64_t time_dis =0;
struct timespec deEndTime,deStartTime;
struct timespec enEndTime,enStartTime;
EncodeInHeaderStruct EncodeHeadData;
DecodeInHeaderStruct DecodeHeadData;
unsigned char *pEnDataSrc,*pEnDataDst;
char *pDeDataSrc;
unsigned char *pDeDataDst;
int dataLen=0;
unsigned char *pcrc;
mm_huge_table_init(&pFecHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
printf( "%s>>>---pFecHugepageTbl->nPagePhyAddr=0x%lx\n",__FUNCTION__,(uint64_t)pFecHugepageTbl->nPagePhyAddr );
mm_segment_init(&pFecSegentInfo, pFecHugepageTbl);
printf("%s>>> pFecSegentInfo->pSegment=0x%lx, pFecSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFecSegentInfo->pSegment, pFecSegentInfo->nPhysicalAddr);
mm_regist_addr_to_ring(&DescRingAddr, pFecSegentInfo);
//log init
GLOBAL_FRLOG_INIT("/tmp/usrp/l1/", "l1", 2, 3);
dev2_init_fec();
dev2_register_mem_addr(&DescRingAddr);
get_data_addr_len(&DescRingAddr, &EnDataTx, &EnDataRx, &DeDataTx, &DeDataRx);
// malloc memory for rx/tx data
// pEnDataSrc=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
// pEnDataDst=(unsigned char *)malloc(DEFAULT_EN_DATA_LEN);
pDeDataSrc=(char *)malloc(DEFAULT_DE_DATA_LEN);
pDeDataDst=(unsigned char *)malloc(DEFAULT_DE_DATA_LEN);
pcrc = (unsigned char *)malloc(4);
// test data load
getBinDataFromFile( pDeDataSrc, &dataLen, FecDeDataFileName );
//create head;
// encode_tx_head(&EncodeHeadData);
decode_tx_head(&DecodeHeadData);
//saveBinDataTofile(&EncodeHeadData, sizeof(EncodeInHeaderStruct), HeadDataFileName);
//printf("head data file save.\n");
//sleep(100);
// main loop !!!
//while( loopCountEn<3 )
// while( 1 )
// {
// Fec Encode
dm_time_rec_add(&deStartTime);
// encoder_load( &EncodeHeadData, pEnDataSrc, pEnDataDst );
//测试的demo中pDeDataSrc包含了32Byte的头,应该去掉。
// decoder_load( &DecodeHeadData, pDeDataSrc, pDeDataDst );
decoder_load( &DecodeHeadData, pDeDataSrc+32, pDeDataDst, pcrc );
dm_time_rec_add(&deEndTime);
time_dis = dm_time_rec_diff(&deEndTime, &deStartTime);
DeAllTime+=time_dis;
DeAllLen+=dataLen;
loopCountDe++;
if(loopCountDe>=10000)
{
DeAllTime/=1000;
zLog(PHY_LOG_INFO,"[FecDeRxRing] data throughput=%dMbps current time=%dus dataLen=%d ---[DRV_LOG]", 8*DeAllLen/DeAllTime/1000,time_dis, dataLen);
loopCountDe=0;
DeAllTime=0;
DeAllLen=0;
}
printf("---end---\n");
// for(i=0; i<10;i++){
// printf("%d\n",i);
// }
for(i=0; i<100; i++)
{
printf("pDeDataSrc+%d = %d\n", i, *(pDeDataSrc+i));
}
printf("--------------------------------------\n");
// for(i=0; i<DecodeHeadData.tbSizeB+8; i++)
// {
// printf("pDeDataDst+%d = %u\n", i, *(pDeDataDst+i));
// }
for(i=0; i<200; i++)
{
printf("pDeDataDst+%d = %u\n", i, *(pDeDataDst+i));
}
for(i=0; i<4; i++)
{
printf("pcrc+%d = %u\n", i, *(pcrc+i));
}
if(*pcrc == 1)
{
printf("decode correct!\n");
}
saveBinData(pDeDataDst, FEC_DECODE_DATA);
// }
// printf("---end---\n");
// sleep(1);
return 0;
}
\ No newline at end of file
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <hugetlbfs.h>
#include <dev2.0/logger_wrapper.h>
#include "ff_define.h"
#include "mem.h"
#define ADDR (void *)(0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
#define PROTECTION (PROT_READ | PROT_WRITE)
//
//
//
//
////////////////////////////////////////////////////////
int get_hugepage_size(uint64_t* hugepage_size)
{
if (!hugepage_size) {
return -1;
}
// printf("get_hugepage_size!!!!\n ");
// if (gethugepagesizes != NULL)
// {
// printf("gethugepagesizes %p %p\n ",gethugepagesizes,&gethugepagesizes);
// }
// else
// {
// printf("gethugepagesizes is NULL\n ");
// }
if (gethugepagesizes ((int64_t *)hugepage_size, 1) == -1) {
printf("get huge size failed\n");
return -1;
}
return 0;
}
//
//
//
//
////////////////////////////////////////////////////////
int cpa_bb_mm_virttophys (void * pVirtAddr, uint64_t * pPhysAddr)
{
int32_t nMapFd;
uint64_t nPage;
uint32_t nPageSize;
uint64_t nVirtualPageNumber;
nMapFd = open ("/proc/self/pagemap", O_RDONLY);
if (nMapFd < 0)
{
printf("ERROR: Could't open pagemap file\n");
return 0;
}
/*get standard page size */
nPageSize = (uint32_t) getpagesize ();
nVirtualPageNumber = (uint64_t) pVirtAddr / nPageSize;
lseek (nMapFd, nVirtualPageNumber * sizeof (uint64_t), SEEK_SET);
if (read (nMapFd, &nPage, sizeof (uint64_t)) < 0)
{
close (nMapFd);
printf("ERROR: Could't read pagemap file\n");
return 0;
}
*pPhysAddr = ((nPage & 0x007fffffffffffffULL) * nPageSize);
printf("nVirtualPageNumber=0x%lx, nPage=0x%lx, nPageSize=0x%x PhysAddr=0x%lx\n", nVirtualPageNumber, nPage, nPageSize, *pPhysAddr);
close (nMapFd);
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
uint64_t q_partition (HugepageTblStruct * pHugepageTbl, uint64_t nLow, uint64_t nHigh)
{
uint64_t nLowIndex = 0;
uint64_t nHiIndex = 0;
nLowIndex = nLow + 1;
nHiIndex = nHigh;
HugepageTblStruct sTemp;
while (nHiIndex >= nLowIndex)
{
while ((nLowIndex <= nHiIndex) &&
(pHugepageTbl[nLowIndex].nPagePhyAddr < pHugepageTbl[nLow].nPagePhyAddr))
{
nLowIndex++;
}
while ((nHiIndex >= nLowIndex) &&
(pHugepageTbl[nHiIndex].nPagePhyAddr > pHugepageTbl[nLow].nPagePhyAddr))
{
nHiIndex--;
}
if (nHiIndex > nLowIndex)
{
memcpy (&sTemp, &pHugepageTbl[nHiIndex], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nHiIndex], &pHugepageTbl[nLowIndex],
sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nLowIndex], &sTemp, sizeof (HugepageTblStruct));
}
}
memcpy (&sTemp, &pHugepageTbl[nLow], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nLow], &pHugepageTbl[nHiIndex], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nHiIndex], &sTemp, sizeof (HugepageTblStruct));
return nHiIndex;
}
//
//
//
//
////////////////////////////////////////////////////////
int is_flat (uint64_t nPhysAddr1, uint64_t nPhysAddr2, uint64_t nHugePageSize)
{
if (nPhysAddr1 > nPhysAddr2)
{
return 0;
}
else
{
return ((nPhysAddr1 + nHugePageSize) == nPhysAddr2) ? 1 : 0;
}
}
//
//
//
//
////////////////////////////////////////////////////////
int is_contiguous (HugepageTblStruct * pHugepageTbl,
uint32_t nTblOffset,
uint32_t nHugePagePerSegment,
uint64_t nHugePageSize)
{
uint32_t nCount;
for (nCount = 1; nCount < nHugePagePerSegment; nCount++)
{
/*Check current page and next page are contiguous */
if (is_flat (pHugepageTbl[nTblOffset + nCount - 1].nPagePhyAddr,
pHugepageTbl[nTblOffset + nCount].nPagePhyAddr,
nHugePageSize) == 0)
{
return 0;
}
}
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
int check_no_of_segments (HugepageTblStruct * pHugepageTbl,
uint32_t nHugePage, uint32_t nSegment,
uint32_t nHugePagePerSegment,
uint64_t nHugePageSize, uint32_t * segmentCount)
{
uint32_t nCount = 0;
*segmentCount = 0;
if (nHugePagePerSegment == 1)
{
*segmentCount = nSegment;
return 0;
}
do
{
if (is_contiguous (pHugepageTbl, nCount, nHugePagePerSegment, nHugePageSize))
{
nCount += nHugePagePerSegment;
(*segmentCount)++;
}
else
{
nCount++;
}
}
while (nCount <= (nHugePage - nHugePagePerSegment));
printf("INFO: required segment %d segments formed %d\n",
nSegment,
*segmentCount);
printf("INFO: percentage of segment got %f\n",
(((float) *segmentCount / nSegment) * 100));
return (*segmentCount < nSegment) ? -1 : 0;
}
//
//
//
//
////////////////////////////////////////////////////////
int mm_huge_table_init(HugepageTblStruct **pHugepageTbl, uint64_t memSize)
{
uint64_t nHugePageSize;
uint64_t nMemorySize, nMemorySegmentSize;
uint32_t nHugePagePerSegment = 0;
uint32_t nSegmentCount = 0;
uint32_t nHugePage = 0;
uint32_t nSegment = 0;
void *VirtAddr = NULL;
uint64_t PhyAddr;
uint32_t nCount = 0;
uint32_t * pSegmentCount;
uint32_t SegmentCount;
HugepageTblStruct *pHT;
if (get_hugepage_size(&nHugePageSize) != 0) {
return -1;
}
nMemorySize=memSize;
nMemorySegmentSize=SW_FPGA_SEGMENT_BUFFER_LEN;
/*Calculate number of segment */
nSegment = DIV_ROUND_OFF (nMemorySize, nMemorySegmentSize);
/*Calculate number of hugepsges per segment */
nHugePagePerSegment = DIV_ROUND_OFF (nMemorySegmentSize, nHugePageSize);
/* calculate total number of hugepages */
nHugePage = nSegment * nHugePagePerSegment;
pHT = (HugepageTblStruct *) malloc (sizeof (HugepageTblStruct) * nHugePage);
if (pHT == NULL)
{
printf("ERROR: HugepageTblStruct memory allocation failed cause: %s\n", strerror(errno));
return 0;
}
//printf("nHugePageSize=0x%lx, nSegment=%d, nHugePagePerSegment=%d, nHugePage=%d\n", nHugePageSize, nSegment, nHugePagePerSegment, nHugePage);
/*Allocate required number of pages to sort */
VirtAddr = mmap (ADDR, (nHugePage * nHugePageSize), PROTECTION, FLAGS, 0, 0);
if (VirtAddr == MAP_FAILED)
{
printf("ERROR: mmap was failed cause: %s\n", strerror(errno));
free(pHT);
return 0;
}
for(nCount = 0; nCount < nHugePage; nCount++)
{
pHT[nCount].pPageVirtAddr = (uint8_t *) VirtAddr + (nCount * nHugePageSize);
/*Creating dummy page fault in process for each page inorder to get pagemap */
*(uint8_t *) pHT[nCount].pPageVirtAddr = 1;
cpa_bb_mm_virttophys(pHT[nCount].pPageVirtAddr, &pHT[nCount].nPagePhyAddr);
//printf("VirtAddr=0x%lx PhyAddr=0x%lx\n", (uint64_t)(uint64_t *)pHT[nCount].pPageVirtAddr, pHT[nCount].nPagePhyAddr);
}
*pHugepageTbl=pHT;
printf(">>> mm_huge_table_init is ok.\n");
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
int mm_segment_init(MemorySegmentStruct **pSegInfo, HugepageTblStruct *pHugepageTbl)
{
uint32_t nCount = 0;
MemorySegmentStruct *pSegment = NULL;
int32_t nDevFd = 0;
void *VirtAddr = NULL;
//segment calloc
pSegment = (MemorySegmentStruct *)malloc (sizeof (MemorySegmentStruct) );
if (pSegment == NULL)
{
printf("ERROR: No sufficient memory to store segment info\n");
return -3;
}
*pSegInfo=pSegment;
pSegment->nPhysicalAddr=pHugepageTbl[0].nPagePhyAddr;
pSegment->pSegment=pHugepageTbl[0].pPageVirtAddr;
//
return 0;
}
//
//
//
//
////////////////////////////////////////////////////////
void mm_regist_addr_to_ring(DescriptorAddrRingStruct *pDescRing, MemorySegmentStruct *pFecSegInfo)
{
pDescRing->TxEnCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment;
pDescRing->TxEnCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr;
pDescRing->RxEnCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x20;
pDescRing->RxEnCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x20;
pDescRing->TxDeCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x40;
pDescRing->TxDeCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x40;
pDescRing->RxDeCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x60;
pDescRing->RxDeCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x60;
}
//
//
//
////////////////////////////////////////////////////////
void get_data_addr_len(DescriptorAddrRingStruct *pDescRingAddr, DescDataInfo *pEnDataTx, DescDataInfo *pEnDataRx, DescDataInfo *pDeDataTx, DescDataInfo *pDeDataRx)
{
uint64_t phyAddr;
//encode tx
phyAddr=pDescRingAddr->TxEnCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pEnDataTx->nPhysicalAddr=phyAddr;
pEnDataTx->nVirtAddr=pDescRingAddr->TxEnCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataTx->dataLen=0;
//rx
phyAddr=pDescRingAddr->RxEnCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pEnDataRx->nPhysicalAddr=phyAddr;
pEnDataRx->nVirtAddr=pDescRingAddr->RxEnCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataRx->dataLen=0;
//decode tx
phyAddr=pDescRingAddr->TxDeCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pDeDataTx->nPhysicalAddr=phyAddr;
pDeDataTx->nVirtAddr=pDescRingAddr->TxDeCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pDeDataTx->dataLen=0;
//rx
phyAddr=pDescRingAddr->RxDeCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pDeDataRx->nPhysicalAddr=phyAddr;
pDeDataRx->nVirtAddr=pDescRingAddr->RxDeCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataRx->dataLen=0;
}
#ifndef __DEV2_FF_DEMO_MEM__
#define __DEV2_FF_DEMO_MEM__
/*DMA CONTROL REG*/
#define CTRL_MODE_CFG_REG 0
#define STATUS_HADDR_REG 1
#define STATUS_LADDR_REG 2
#define VALID_DES_NUM_REG 3
#define DESC_RING_HADDR_REG 4
#define DESC_RING_LADDR_REG 5
#define BAR_MODE_READ_DESC 0x0 /*2'b00'*/
#define BAR_MODE_READ_MEM 0x2 /*2'b10'*/
#define BAR_MODE_NOTIFY_EACH 0x0 /*2'b00'*/
#define BAR_MODE_NOTIFY_ALL 0x1 /*2'b01'*/
/* hugepage setting */
#define SW_FPGA_TOTAL_BUFFER_LEN 4LL*1024*1024*1024
#define SW_FPGA_SEGMENT_BUFFER_LEN 1LL*1024*1024*1024
#define SW_FPGA_FH_TOTAL_BUFFER_LEN 1LL*1024*1024*1024
#define DIV_ROUND_OFF(X,Y) ( X/Y + ((X%Y)?1:0) )
#define DEVICE_NAME "/dev/nr_cdev"
#define FTH_MEM_SIZE (0x100000)
#define FEC_MEM_SIZE (0x100000)
#define RING_MEM_SIZE (0x10000)
#define SHIFTBITS_32 (32)
#define IS_DESC_DONE(desc) (0xFF&desc)
//
int mm_huge_table_init(HugepageTblStruct **pHugepageTbl, uint64_t memSize);
//
int mm_segment_init(MemorySegmentStruct **pFecSegInfo, HugepageTblStruct *pHugepageTbl);
//
void mm_regist_addr_to_ring(DescriptorAddrRingStruct *pDescRing, MemorySegmentStruct *pFecSegInfo);
//
//
void get_data_addr_len(DescriptorAddrRingStruct *pDescRingAddr, DescDataInfo *pEnDataTx, DescDataInfo *pEnDataRx, DescDataInfo *pDeDataTx, DescDataInfo *pDeDataRx);
#endif //__DEV2_FF_DEMO_MEM__
PREGCC=
TARGET=FFTest
GCC=$(PREGCC)g++
SYS_INC=/usr/local/include/dev2.0
INCLUDE_DIR := -I$(SYS_INC)
INCLUDE_DIR += -I$(SYS_INC)/9371base
INCLUDE_DIR += -I$(SYS_INC)/ecpriBase
INCLUDE_DIR += -I$(SYS_INC)/fr9371
INCLUDE_DIR += -I$(SYS_INC)/frecpri
INCLUDE_DIR += -I$(SYS_INC)/wi9371
INCLUDE_DIR += -I$(SYS_INC)/wiecpri
LIB_DIR = -lpthread -lhugetlbfs
LIB_DIR1 = -lhugetlbfs
LIB_DIR2 = -ldev2.0
CURDIR:=$(shell pwd)
SRCDIR2 := $(CURDIR)
SRCS := $(wildcard *.cpp)
OBJS = $(SRCS:%.cpp=%.o)
CCFLAGS := -std=c++11 -g -O2 $(INCLUDE_DIR)
$(TARGET):$(OBJS)
$(GCC) $(CCFLAGS) $(OBJS) -o $@ $(LIB_DIR) $(LIB_DIR2)
%.o: %.cpp
$(GCC) $(INCLUDE_DIR) $(CCFLAGS) -c $< -o $@
clean:
rm -rf $(OBJS) $(TARGET)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <iostream>
#include <string>
#include <sstream>
#include <cstdint>
#include "logger_wrapper.h"
#include "ff_define.h"
//using namespace std;
int getBinDataFromFile(unsigned char *pData, int *len,char *fname)
{
int fileSize,ret;
FILE *fp;
int i,j,count;
int tempData;
fp=fopen(fname,"rb");
if(fp==NULL){
printf("This %s file is open failed.\n",fname);
}
fseek(fp,0,SEEK_END);
fileSize=ftell(fp);
rewind(fp);
printf("fileSize=0x%x\n",fileSize);
ret=fread(pData,1,fileSize,fp);
*len=fileSize;
//printf("ret=0x%x\n",ret);
fclose(fp);
/*
count=ret/32;
for(j=0;j<count;j++){
for(i=0;i<16;i++){
tempData=pData[i+j*32];
pData[i+j*32]=pData[j*32+31-i];
pData[j*32+31-i]=tempData;
}
}
*/
return 1;
}
//
//
//
////////////////////////////////
void saveBinDataTofile(unsigned char *pData,int len,char * fname)
{
int i,fileSize,ret;
FILE *fp;
fp=fopen(fname,"wb+");
if(fp==NULL){
printf("This %s file is open failed.\n",fname);
}
ret=fwrite(pData,1,len,fp);
//printf("ret=0x%x\n",ret);
fclose(fp);
}
char tempData[512];
char saveDataDirDe[]="./saveData/de";
char saveDataDirEn[]="./saveData/en";
static int count1=0,count2=0;
void saveBinData(unsigned char *pData, int type)
{
int i;
DataHeadInfo *pDataHeadInfo;
DataHeadInfo TempDataHead;
unsigned char *pDataHead;
char fname[64];
/*
for(i=0;i<32;i++){
//printf("%02x_",*(pData+i));
sprintf(tempData+(i*3),"%02x_",*(pData+i));
}
*(tempData+32*3)='\0';
//sprintf(tempData+(6*3),"%02x_", 0x17);
zLog(PHY_LOG_INFO,"rec header:=%s---[DRV_LOG]",tempData);
*/
pDataHeadInfo=(DataHeadInfo *)pData;
//zLog(PHY_LOG_INFO,"rec header: len=%x---[DRV_LOG]",pDataHeadInfo->pktLen);
if(type==FEC_DECODE_DATA){
sprintf(fname,"%s/decode_%08d.bin",saveDataDirDe,count2++);
}else if(type==FEC_ENCODE_DATA){
sprintf(fname,"%s/encode_%08d.bin",saveDataDirEn,count1++);
}
saveBinDataTofile(pData, pDataHeadInfo->pktLen+32, fname);
}
//
//
//
//
////////////////////////////////////////////
void load_expect_data(unsigned char *pData, char *fname)
{
int len;
getBinDataFromFile(pData, &len, fname);
}
//
//
//
//
////////////////////////////////////////////
int compare_data(unsigned char *pDst1, unsigned char *pDst2, int len)
{
int ret=0;
//ret=memcmp(pDst1,pDst2,len);
return ret;
}
#ifndef __DEV2_DATA_FILE__
#define __DEV2_DATA_FILE__
//
int getBinDataFromFile(unsigned char *pData,int *len, char * fname);
//
void saveBinDataTofile(unsigned char *pData,int len, char *fname);
//
void saveBinData(unsigned char *pData, int type);
//
int compare_data(unsigned char *pDst1, unsigned char *pDst2, int len);
//
void load_expect_data(unsigned char *pData, char *fname);
#endif //__DEV2_DATA_FILE__
#ifndef __FF_DEMO_DEFINE__
#define __FF_DEMO_DEFINE__
#include "fec_c_if.h"
#define FPGA_FRONTHAUL 0
#define FPGA_FEC 1
#define FPGA_NUM 2
#define IS_FREE 0
#define IS_BUSY 1
#define IS_FULL 2
#define IS_INVAL 3
#define MILLION 1000000
#define THOUSAND 1000
#define FEC_DECODE_DATA 0x01
#define FEC_ENCODE_DATA 0x02
// log mask
#define ZLOG_DRIVER_DM_TX (1<<20)
#define ZLOG_DRIVER_DM_RX (1<<21)
#define ZLOG_DRIVER_DM_FEC (1<<22)
#define ZLOG_DRIVER_DM_STATUS (1<<23)
/*
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
typedef int int32_t;
typedef long int int64_t;
typedef short int int16_t;
*/
/*
typedef struct __DescriptorAddrRingStruct
{
uint32_t nRingBufferPoolIndex;
HugepageTblStruct RxFhRingBuffer;
HugepageTblStruct RxEnCodeRingBuffer;
HugepageTblStruct RxDeCodeRingBuffer;
HugepageTblStruct SyncFhRingBuffer;
HugepageTblStruct TxFhRingBuffer;
HugepageTblStruct TxEnCodeRingBuffer;
HugepageTblStruct TxDeCodeRingBuffer;
uint64_t BaseAddress;
}DescriptorAddrRingStruct;
typedef struct __DmaDescInfo
{
uint32_t nAddressHigh;
uint32_t nAddressLow;
uint32_t nAddressLen;
uint32_t rsvrd;
}DescInfo;
typedef struct __DmaDescChainInfo
{
volatile uint32_t nDescriptorStatus[127];
volatile uint32_t nTotalDescriptorStatus;
DescInfo sDescriptor[127];
}DescChainInfo;
typedef struct __HugepageInfo
{
void* pHugepages;
uint32_t nHugePage;
uint32_t nSegment;
uint32_t nHugePagePerSegment;
uint64_t nHugePageSize;
}HugepageInfo;
typedef struct __HugepageTbl
{
void *pPageVirtAddr;
uint64_t nPagePhyAddr;
uint8_t nIsAllocated:1;
HugepageInfo info;
}HugepageTblStruct;
typedef struct __DmaDescDataInfo
{
uint64_t nPhysicalAddr;
void * nVirtAddr;
void * pBarVirtAddr;
uint32_t dataLen;
}DescDataInfo;
typedef struct __DataHeadStruct
{
unsigned int pktType :8;
unsigned int rsv0 :8;
unsigned int chkCode :16;
unsigned int pktLen :21;
unsigned int rsv1:11;
unsigned int rsv2;
unsigned int rsv3;
unsigned int rsv4;
unsigned int rsv5;
unsigned int rsv6;
unsigned int rsv7;
}DataHeadInfo;
*/
typedef struct __MemorySegment
{
void *pSegment;
uint64_t nPhysicalAddr;
uint32_t nSize;
uint8_t nReferences;
}MemorySegmentStruct;
typedef union
{
uint32_t nAll;
struct
{
uint32_t nSlotIdx : 5;
uint32_t nSubFrameIdx : 6;
uint32_t nFrameIdx : 10;
uint32_t nSymbolIdx : 4;
uint32_t nReservd : 7;
} bit;
}TimeStempIndUnion;
#endif // __FF_DEMO_DEFINE__
#!/bin/bash
echo "Insmod NR_Drv"
NR_DRV=./
lsmod | grep nr_drv >& /dev/null
if [ $? -eq 0 ]; then
rmmod nr_drv
rm -rf /dev/nr_cdev0
rm -rf /dev/nr_cdev1
rm -rf /dev/nr_sys
fi
insmod ${NR_DRV}/nr_drv.ko
mknod /dev/nr_sys c 200 0
mknod /dev/nr_cdev0 c 201 0
mknod /dev/nr_cdev1 c 202 0
#include <cstdio>
#include <ctime>
#include <cmath>
#include <iostream>
#include <string>
#include <sstream>
#include <cstdint>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <hugetlbfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include "logger_wrapper.h"
#include "ff_define.h"
#include "mem.h"
#include "dataFile.h"
#include "nr_sys_info.h"
#include "nr_rf_chan.h"
#include "fec_c_if.h"
using namespace std;
int32_t zlogMask=0xF00000; //driver log all open
char FecDeDataFileName[]="decode_data_3.bin";
char FecEnDataFileName[]="encode_data_2.bin";
//char fecDataFileName[]="rx_decode_In_slot_Counter0312.bin";
char saveDataFileName[]="save_data.bin";
//
//
//
//
////////////////////////////////////////////////////////
void dm_time_rec_add(struct timespec *t)
{
clock_gettime(CLOCK_MONOTONIC, t);
}
uint64_t dm_time_rec_diff(struct timespec* now, struct timespec* old) {
uint64_t diff_time = 0;
diff_time = MILLION * (now->tv_sec - old->tv_sec) + (now->tv_nsec - old->tv_nsec) / THOUSAND;
return diff_time;
}
volatile TimeStempIndUnion gTxTimeIndex;
volatile uint64_t *pTxTimeIndex = NULL;
volatile int32_t newSlotIdx,oldSlotIdx;
volatile uint32_t tti_loop_count=0;
int32_t lstSlotIdx =0;
//
//
//
//
////////////////////////////////////////////////////////
int get_tti_valid()
{
int32_t slot_step,ret;
ret=0;
gTxTimeIndex.nAll = *pTxTimeIndex;
newSlotIdx=(gTxTimeIndex.bit.nFrameIdx*10 + gTxTimeIndex.bit.nSubFrameIdx) * 2 + gTxTimeIndex.bit.nSlotIdx;
if(lstSlotIdx==0){
oldSlotIdx=newSlotIdx;
lstSlotIdx=1;
return 3;
}
slot_step=newSlotIdx-oldSlotIdx;
tti_loop_count++;
if(slot_step>1)
{
zLog(PHY_LOG_ERROR,"[TTI] slot_step=%d, tti_loop_count=0x%x, nFrameIdx=%d,nSubFrameIdx=%d,nSlotIdx=%d,nSymbolIdx=%d -------[DRV_LOG]",slot_step, tti_loop_count, gTxTimeIndex.bit.nFrameIdx,gTxTimeIndex.bit.nSubFrameIdx,gTxTimeIndex.bit.nSlotIdx,gTxTimeIndex.bit.nSymbolIdx);
ret=2;
}else if(slot_step==1){
zLog(PHY_LOG_INFO,"[TTI] slot_step=%d, tti_loop_count=0x%x, nFrameIdx=%d,nSubFrameIdx=%d,nSlotIdx=%d,nSymbolIdx=%d -------[DRV_LOG]",slot_step, tti_loop_count, gTxTimeIndex.bit.nFrameIdx,gTxTimeIndex.bit.nSubFrameIdx,gTxTimeIndex.bit.nSlotIdx,gTxTimeIndex.bit.nSymbolIdx);
ret=1;
}else{
//zLog(PHY_LOG_INFO,"[TTI] slot_step=%d, tti_loop_count=%d, nFrameIdx=%d,nSubFrameIdx=%d,nSlotIdx=%d,nSymbolIdx=%d -------[DRV_LOG]",slot_step, tti_loop_count, gTxTimeIndex.bit.nFrameIdx,gTxTimeIndex.bit.nSubFrameIdx,gTxTimeIndex.bit.nSlotIdx,gTxTimeIndex.bit.nSymbolIdx);
ret=0;
}
oldSlotIdx=newSlotIdx;
return ret;
}
#define DE_RESULT_DATA_MAX 0x100000
#define EN_RESULT_DATA_MAX 0x10000
unsigned char DeDataResult[DE_RESULT_DATA_MAX];
unsigned char EnDataResult[EN_RESULT_DATA_MAX];
char DeResultFileName[]="decode_00.bin";
char EnResultFileName[]="encode_00.bin";
//
//
//
//
////////////////////////////////////////////////////////
int main(int argc,char *argv[])
{
int32_t retVal,i;
uint64_t DmaBaseVirAddr,DmaBasePhyAddr, TtiPhyAddr;
uint8_t *pTtiVirAddr;
MemorySegmentStruct *pFecSegentInfo,*pFthSegentInfo;
HugepageTblStruct *pFecHugepageTbl,*pFthHugepageTbl;
DescriptorAddrRingStruct DescRingAddr={0};
uint64_t time_dis = 0;
uint32_t fpgaData1,fpgaData2;
DescDataInfo EnDataTx, EnDataRx;
DescDataInfo DeDataTx, DeDataRx;
volatile uint32_t nStatFecTxEnDma = IS_FREE;
volatile uint32_t nStatFecRxEnDma = IS_FREE;
volatile uint32_t nStatFecTxDeDma = IS_FREE;
volatile uint32_t nStatFecRxDeDma = IS_FREE;
volatile uint32_t nStatFthTxDma = IS_FREE;
volatile uint32_t nStatFthRxDma = IS_FREE;
DescChainInfo *pFecTxEnRing = NULL;
DescChainInfo *pFecRxEnRing = NULL;
DescChainInfo *pFecTxDeRing = NULL;
DescChainInfo *pFecRxDeRing = NULL;
DescChainInfo *pFthTxRing = NULL;
DescChainInfo *pFthRxRing = NULL;
struct timespec deRxEndNew;
struct timespec deRxEndOld;
struct timespec deTxEndNew;
struct timespec deTxEndOld;
struct timespec enRxEndNew;
struct timespec enRxEndOld;
struct timespec enTxEndNew;
struct timespec enTxEndOld;
struct timespec deTxStartRec;
struct timespec deTxStartNew;
struct timespec deRxStartRec;
struct timespec deRxStartNew;
struct timespec enTxStartRec;
struct timespec enTxStartNew;
struct timespec enRxStartRec;
struct timespec enRxStartNew;
uint8_t tmpData;
volatile uint32_t k,m;
volatile int count_en=0;
volatile int count_de=0;
mm_huge_table_init(&pFecHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
mm_huge_table_init(&pFthHugepageTbl, SW_FPGA_FH_TOTAL_BUFFER_LEN);
printf("%s>>>---pFecHugepageTbl->nPagePhyAddr=0x%lx pFthHugepageTbl->nPagePhyAddr=0x%lx---\n",__FUNCTION__,(uint64_t)pFecHugepageTbl->nPagePhyAddr,(uint64_t)pFthHugepageTbl->nPagePhyAddr);
//printf(">>>huge init ok.\n");
mm_segment_init(&pFecSegentInfo, pFecHugepageTbl);
mm_segment_init(&pFthSegentInfo, pFthHugepageTbl);
printf("%s>>> pFecSegentInfo->pSegment=0x%lx, pFecSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFecSegentInfo->pSegment, pFecSegentInfo->nPhysicalAddr);
printf("%s>>> pFthSegentInfo->pSegment=0x%lx, pFthSegentInfo->nPhysicalAddr=0x%lx\n", __FUNCTION__, pFthSegentInfo->pSegment, pFthSegentInfo->nPhysicalAddr);
//printf(">>>segment init ok.\n");
mm_regist_addr_to_ring(&DescRingAddr,pFthSegentInfo,pFecSegentInfo);
printf(">>>DescRingAddr.TxEnCodeRingBuffer.pPageVirtAddr=0x%lx\n",DescRingAddr.TxEnCodeRingBuffer.pPageVirtAddr);
get_data_addr_len(&DescRingAddr, &EnDataTx, &EnDataRx, &DeDataTx, &DeDataRx);
//log init
GLOBAL_FRLOG_INIT("/tmp/usrp/l1/", "l1", 2, 3);
//
dev2_init_fec();
//
dev2_register_ring_addr(&DescRingAddr);
// test date load
dm_time_rec_add(&enTxStartNew);
dm_time_rec_add(&enRxStartNew);
dm_time_rec_add(&deTxEndNew);
dm_time_rec_add(&deRxEndNew);
getBinDataFromFile((unsigned char *)DeDataTx.nVirtAddr, &DeDataTx.dataLen, FecDeDataFileName);
getBinDataFromFile((unsigned char *)EnDataTx.nVirtAddr, &EnDataTx.dataLen, FecEnDataFileName);
load_expect_data(DeDataResult,DeResultFileName);
load_expect_data(EnDataResult,EnResultFileName);
// main loop !!!
while(1)
{
//tti process. return 0:tti step=0, 1:tti step=1, 2:tti step>1
retVal=get_tti_valid();
if(retVal!=1) continue;
//for(k=0;k<0x40000;k++); //0x4000==25us
// Fec Encode Ring
if( fec_en_tx_release() )
{
if(zlogMask & ZLOG_DRIVER_DM_FEC){
enTxEndOld.tv_sec =enTxEndNew.tv_sec;
enTxEndOld.tv_nsec=enTxEndNew.tv_nsec;
dm_time_rec_add(&enTxEndNew);
time_dis = dm_time_rec_diff(&enTxEndNew, &enTxEndOld);
zLog(PHY_LOG_INFO,"[FecEnTxRing] time=%d ---[DRV_LOG]",time_dis);
}
}
if( fec_en_rx_release() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
enRxEndOld.tv_sec =enRxEndNew.tv_sec;
enRxEndOld.tv_nsec=enRxEndNew.tv_nsec;
dm_time_rec_add(&enRxEndNew);
time_dis = dm_time_rec_diff(&enRxEndNew, &enRxEndOld);
zLog(PHY_LOG_INFO,"[FecEnRxRing] time=%d ---[DRV_LOG]", time_dis);
}
saveBinData((unsigned char *)EnDataRx.nVirtAddr, FEC_ENCODE_DATA);
}
// Fec Decode Ring
if( fec_de_tx_release() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
deTxEndOld.tv_sec =deTxEndNew.tv_sec;
deTxEndOld.tv_nsec=deTxEndNew.tv_nsec;
dm_time_rec_add(&deTxEndNew);
time_dis = dm_time_rec_diff(&deTxEndNew, &deTxEndOld);
zLog(PHY_LOG_INFO,"[FecDeTxRing] time=%d -----[DRV_LOG]",time_dis);
}
}
if( fec_de_rx_release() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
deRxEndOld.tv_sec =deRxEndNew.tv_sec;
deRxEndOld.tv_nsec=deRxEndNew.tv_nsec;
dm_time_rec_add(&deRxEndNew);
time_dis = dm_time_rec_diff(&deRxEndNew, &deRxEndOld);
zLog(PHY_LOG_INFO,"[FecDeRxRing] time=%d ----[DRV_LOG]", time_dis);
}
//compare_data();
saveBinData((unsigned char *)DeDataRx.nVirtAddr, FEC_DECODE_DATA);
}
//FEC Encode
if( fec_en_tx_require() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
enTxStartRec.tv_sec =enTxStartNew.tv_sec;
enTxStartRec.tv_nsec=enTxStartNew.tv_nsec;
dm_time_rec_add(&enTxStartNew);
time_dis = dm_time_rec_diff(&enTxStartNew, &enTxStartRec);
zLog(PHY_LOG_INFO,"[FecEnTX] time=%d -----------[DRV_LOG]",time_dis);
}
dev2_send_en_data(&EnDataTx);
}
if( fec_en_rx_require() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
enRxStartRec.tv_sec =enRxStartNew.tv_sec;
enRxStartRec.tv_nsec=enRxStartNew.tv_nsec;
dm_time_rec_add(&enRxStartNew);
time_dis = dm_time_rec_diff(&enRxStartNew, &enRxStartRec);
zLog(PHY_LOG_INFO,"[FecEnRX] time=%d -----------[DRV_LOG]",time_dis);
}
dev2_recv_en_data(&EnDataRx);
}
// FEC Decode
if( fec_de_tx_require() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
deTxStartRec.tv_sec =deTxStartNew.tv_sec;
deTxStartRec.tv_nsec=deTxStartNew.tv_nsec;
dm_time_rec_add(&deTxStartNew);
time_dis = dm_time_rec_diff(&deTxStartNew, &deTxStartRec);
zLog(PHY_LOG_INFO,"[FecDeTx] time=%d ----[DRV_LOG]",time_dis);
}
dev2_send_de_data(&DeDataRx);
}
if( fec_de_rx_require() )
{
if( zlogMask & ZLOG_DRIVER_DM_FEC ){
deRxStartRec.tv_sec =deRxStartNew.tv_sec;
deRxStartRec.tv_nsec=deRxStartNew.tv_nsec;
dm_time_rec_add(&deRxStartNew);
time_dis = dm_time_rec_diff(&deRxStartNew, &deRxStartRec);
zLog(PHY_LOG_INFO,"[FecDeRx] time=%d -----------[DRV_LOG]",time_dis);
}
dev2_recv_de_data(&DeDataRx);
}
}
return 0;
}
#include <cstdio>
#include <ctime>
#include <cmath>
#include <iostream>
#include <string>
#include <sstream>
#include <cstdint>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
extern "C"{
#include <hugetlbfs.h>
}
#include "logger_wrapper.h"
#include "ff_define.h"
#include "mem.h"
#include "nr_sys_info.h"
#include "nr_rf_chan.h"
#define ADDR (void *)(0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
#define PROTECTION (PROT_READ | PROT_WRITE)
using namespace std;
//
//
//
//
////////////////////////////////////////////////////////
int get_hugepage_size(uint64_t* hugepage_size)
{
if (!hugepage_size) {
return -1;
}
if (gethugepagesizes ((int64_t *)hugepage_size, 1) == -1) {
printf("get huge size failed\n");
return -1;
}
return 0;
}
//
//
//
//
////////////////////////////////////////////////////////
int cpa_bb_mm_virttophys (void * pVirtAddr, uint64_t * pPhysAddr)
{
int32_t nMapFd;
uint64_t nPage;
uint32_t nPageSize;
uint64_t nVirtualPageNumber;
nMapFd = open ("/proc/self/pagemap", O_RDONLY);
if (nMapFd < 0)
{
printf("ERROR: Could't open pagemap file\n");
return 0;
}
/*get standard page size */
nPageSize = (uint32_t) getpagesize ();
nVirtualPageNumber = (uint64_t) pVirtAddr / nPageSize;
lseek (nMapFd, nVirtualPageNumber * sizeof (uint64_t), SEEK_SET);
if (read (nMapFd, &nPage, sizeof (uint64_t)) < 0)
{
close (nMapFd);
printf("ERROR: Could't read pagemap file\n");
return 0;
}
*pPhysAddr = ((nPage & 0x007fffffffffffffULL) * nPageSize);
printf("nVirtualPageNumber=0x%lx, nPage=0x%lx, nPageSize=0x%x PhysAddr=0x%lx\n", nVirtualPageNumber, nPage, nPageSize, *pPhysAddr);
close (nMapFd);
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
uint64_t q_partition (HugepageTblStruct * pHugepageTbl, uint64_t nLow, uint64_t nHigh)
{
uint64_t nLowIndex = 0;
uint64_t nHiIndex = 0;
nLowIndex = nLow + 1;
nHiIndex = nHigh;
HugepageTblStruct sTemp;
while (nHiIndex >= nLowIndex)
{
while ((nLowIndex <= nHiIndex) &&
(pHugepageTbl[nLowIndex].nPagePhyAddr < pHugepageTbl[nLow].nPagePhyAddr))
{
nLowIndex++;
}
while ((nHiIndex >= nLowIndex) &&
(pHugepageTbl[nHiIndex].nPagePhyAddr > pHugepageTbl[nLow].nPagePhyAddr))
{
nHiIndex--;
}
if (nHiIndex > nLowIndex)
{
memcpy (&sTemp, &pHugepageTbl[nHiIndex], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nHiIndex], &pHugepageTbl[nLowIndex],
sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nLowIndex], &sTemp, sizeof (HugepageTblStruct));
}
}
memcpy (&sTemp, &pHugepageTbl[nLow], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nLow], &pHugepageTbl[nHiIndex], sizeof (HugepageTblStruct));
memcpy (&pHugepageTbl[nHiIndex], &sTemp, sizeof (HugepageTblStruct));
return nHiIndex;
}
//
//
//
//
////////////////////////////////////////////////////////
void sort_hugepage_table (HugepageTblStruct * pHugepageTbl, uint64_t nLow, uint64_t nHigh)
{
uint64_t nKey = 0;
if (nHigh > nLow)
{
nKey = q_partition (pHugepageTbl, nLow, nHigh);
if (nKey != 0)
{
sort_hugepage_table (pHugepageTbl, nLow, nKey - 1);
}
sort_hugepage_table (pHugepageTbl, nKey + 1, nHigh);
}
return;
}
//
//
//
//
////////////////////////////////////////////////////////
int is_flat (uint64_t nPhysAddr1, uint64_t nPhysAddr2, uint64_t nHugePageSize)
{
if (nPhysAddr1 > nPhysAddr2)
{
return 0;
}
else
{
return ((nPhysAddr1 + nHugePageSize) == nPhysAddr2) ? 1 : 0;
}
}
//
//
//
//
////////////////////////////////////////////////////////
int is_contiguous (HugepageTblStruct * pHugepageTbl,
uint32_t nTblOffset,
uint32_t nHugePagePerSegment,
uint64_t nHugePageSize)
{
uint32_t nCount;
for (nCount = 1; nCount < nHugePagePerSegment; nCount++)
{
/*Check current page and next page are contiguous */
if (is_flat (pHugepageTbl[nTblOffset + nCount - 1].nPagePhyAddr,
pHugepageTbl[nTblOffset + nCount].nPagePhyAddr,
nHugePageSize) == 0)
{
return 0;
}
}
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
int check_no_of_segments (HugepageTblStruct * pHugepageTbl,
uint32_t nHugePage, uint32_t nSegment,
uint32_t nHugePagePerSegment,
uint64_t nHugePageSize, uint32_t * segmentCount)
{
uint32_t nCount = 0;
*segmentCount = 0;
if (nHugePagePerSegment == 1)
{
for (nCount = 0; nCount < nHugePage; nCount++)
{
pHugepageTbl[nCount].nIsAllocated = 1;
}
*segmentCount = nSegment;
return 0;
}
do
{
if (is_contiguous (pHugepageTbl, nCount, nHugePagePerSegment, nHugePageSize))
{
if (*segmentCount <= nSegment)
{
pHugepageTbl[nCount].nIsAllocated = 1;
}
nCount += nHugePagePerSegment;
(*segmentCount)++;
}
else
{
nCount++;
}
}
while (nCount <= (nHugePage - nHugePagePerSegment));
printf("INFO: required segment %d segments formed %d\n",
nSegment,
*segmentCount);
printf("INFO: percentage of segment got %f\n",
(((float) *segmentCount / nSegment) * 100));
return (*segmentCount < nSegment) ? -1 : 0;
}
//
//
//
//
////////////////////////////////////////////////////////
void mm_register_ring_addr_to_bar (DescriptorAddrRingStruct * pDring, uint64_t nFuncBaseAddr)
{
uint32_t *pIfftReg = (uint32_t *)(nFuncBaseAddr + 0x1000);
uint32_t *pFecDeReg = (uint32_t *)(nFuncBaseAddr + 0x1100);
uint32_t *pFecEnReg = (uint32_t *)(nFuncBaseAddr + 0x1200);
uint32_t *pFftDmaReg = (uint32_t *)(nFuncBaseAddr + 0x2000);
uint32_t *pFecRstDeReg = (uint32_t *)(nFuncBaseAddr + 0x2100);
uint32_t *pFecRstEnReg = (uint32_t *)(nFuncBaseAddr + 0x2200);
uint32_t *pRdSyncDmaReg = (uint32_t *)(nFuncBaseAddr + 0x2300);
uint64_t nPhysicalAddr = 0;
pDring->BaseAddress=nFuncBaseAddr;
//fth
nPhysicalAddr = pDring->TxFhRingBuffer.nPagePhyAddr;
pIfftReg[CTRL_MODE_CFG_REG] = (BAR_MODE_READ_DESC |BAR_MODE_NOTIFY_EACH);
pIfftReg[DESC_RING_HADDR_REG] = (uint32_t) (((uint64_t) nPhysicalAddr) >> SHIFTBITS_32);
pIfftReg[DESC_RING_LADDR_REG] = (uint32_t) nPhysicalAddr;
zLog(PHY_LOG_INFO, "~~ pIfftReg Reg FH Down[0x%x]:0x%lx PADDR:0x%lx ",
0x1000, nFuncBaseAddr+0x1000, pDring->TxFhRingBuffer.nPagePhyAddr);
nPhysicalAddr = pDring->RxFhRingBuffer.nPagePhyAddr;
pFftDmaReg[CTRL_MODE_CFG_REG] = (BAR_MODE_READ_DESC | BAR_MODE_NOTIFY_EACH);
pFftDmaReg[DESC_RING_HADDR_REG] = (uint32_t) (((uint64_t) nPhysicalAddr) >> SHIFTBITS_32);
pFftDmaReg[DESC_RING_LADDR_REG] = (uint32_t) nPhysicalAddr;
zLog(PHY_LOG_INFO, "~~ pFftDmaReg Reg FH Up [0x%x]:0x%lx PADDR:0x%lx ",
0x2000, nFuncBaseAddr+0x2000, pDring->RxFhRingBuffer.nPagePhyAddr);
//fec tx
nPhysicalAddr = pDring->TxDeCodeRingBuffer.nPagePhyAddr;
pFecDeReg[CTRL_MODE_CFG_REG] = (BAR_MODE_READ_DESC | BAR_MODE_NOTIFY_EACH);
pFecDeReg[DESC_RING_HADDR_REG] = (uint32_t) (((uint64_t) nPhysicalAddr) >> SHIFTBITS_32);
pFecDeReg[DESC_RING_LADDR_REG] = (uint32_t) nPhysicalAddr;
zLog(PHY_LOG_INFO, "~~ pFecDeReg Reg FEC De Down[0x%x]:0x%lx PADDR:0x%lx ",
0x1100, nFuncBaseAddr+0x1100, pDring->TxDeCodeRingBuffer.nPagePhyAddr);
nPhysicalAddr = pDring->TxEnCodeRingBuffer.nPagePhyAddr;
pFecEnReg[CTRL_MODE_CFG_REG] = (BAR_MODE_READ_DESC | BAR_MODE_NOTIFY_EACH);
pFecEnReg[DESC_RING_HADDR_REG] = (uint32_t) (((uint64_t) nPhysicalAddr) >> SHIFTBITS_32);
pFecEnReg[DESC_RING_LADDR_REG] = (uint32_t) nPhysicalAddr;
zLog(PHY_LOG_INFO, "~~ pFecEnReg Reg FEC En Down[0x%x]:0x%lx PADDR:0x%lx ",
0x1200, nFuncBaseAddr+0x1200, pDring->TxEnCodeRingBuffer.nPagePhyAddr);
//fec rx
nPhysicalAddr = pDring->RxDeCodeRingBuffer.nPagePhyAddr;
pFecRstDeReg[CTRL_MODE_CFG_REG] = (BAR_MODE_READ_DESC | BAR_MODE_NOTIFY_EACH);
pFecRstDeReg[DESC_RING_HADDR_REG] = (uint32_t) (((uint64_t) nPhysicalAddr) >> SHIFTBITS_32);
pFecRstDeReg[DESC_RING_LADDR_REG] = (uint32_t) nPhysicalAddr;
zLog(PHY_LOG_INFO, "~~ pFecRstDeReg Reg FEC Rst De [0x%x]:0x%lx PADDR:0x%lx ",
0x2100, nFuncBaseAddr+0x2100, pDring->RxDeCodeRingBuffer.nPagePhyAddr);
nPhysicalAddr = pDring->RxEnCodeRingBuffer.nPagePhyAddr;
pFecRstEnReg[CTRL_MODE_CFG_REG] = (BAR_MODE_READ_DESC | BAR_MODE_NOTIFY_EACH);
pFecRstEnReg[DESC_RING_HADDR_REG] = (uint32_t) (((uint64_t) nPhysicalAddr) >> SHIFTBITS_32);
pFecRstEnReg[DESC_RING_LADDR_REG] = (uint32_t) nPhysicalAddr;
zLog(PHY_LOG_INFO, "~~ pFecRstEnReg Reg FEC Rst En [0x%x]:0x%lx PADDR:0x%lx ",
0x2200, nFuncBaseAddr+0x2200, pDring->RxEnCodeRingBuffer.nPagePhyAddr);
}
//
//
//
//
////////////////////////////////////////////////////////
int mm_huge_table_init(HugepageTblStruct **pHugepageTbl, uint64_t memSize)
{
uint64_t nHugePageSize;
uint64_t nMemorySize, nMemorySegmentSize;
uint32_t nHugePagePerSegment = 0;
uint32_t nSegmentCount = 0;
uint32_t nHugePage = 0;
uint32_t nSegment = 0;
void *VirtAddr = NULL;
uint64_t PhyAddr;
uint32_t nCount = 0;
uint32_t * pSegmentCount;
uint32_t SegmentCount;
HugepageTblStruct *pHT;
if (get_hugepage_size(&nHugePageSize) != 0) {
return -1;
}
nMemorySize=memSize;
nMemorySegmentSize=SW_FPGA_SEGMENT_BUFFER_LEN;
/*Calculate number of segment */
nSegment = DIV_ROUND_OFF (nMemorySize, nMemorySegmentSize);
/*Calculate number of hugepsges per segment */
nHugePagePerSegment = DIV_ROUND_OFF (nMemorySegmentSize, nHugePageSize);
/* calculate total number of hugepages */
nHugePage = nSegment * nHugePagePerSegment;
pHT = (HugepageTblStruct *) malloc (sizeof (HugepageTblStruct) * nHugePage);
if (pHT == NULL)
{
printf("ERROR: HugepageTblStruct memory allocation failed cause: %s\n", strerror(errno));
return 0;
}
//printf("nHugePageSize=0x%lx, nSegment=%d, nHugePagePerSegment=%d, nHugePage=%d\n", nHugePageSize, nSegment, nHugePagePerSegment, nHugePage);
/*Allocate required number of pages to sort */
VirtAddr = mmap (ADDR, (nHugePage * nHugePageSize), PROTECTION, FLAGS, 0, 0);
if (VirtAddr == MAP_FAILED)
{
printf("ERROR: mmap was failed cause: %s\n", strerror(errno));
free(pHT);
return 0;
}
for(nCount = 0; nCount < nHugePage; nCount++)
{
pHT[nCount].pPageVirtAddr = (uint8_t *) VirtAddr + (nCount * nHugePageSize);
/*Creating dummy page fault in process for each page inorder to get pagemap */
*(uint8_t *) pHT[nCount].pPageVirtAddr = 1;
cpa_bb_mm_virttophys(pHT[nCount].pPageVirtAddr, &pHT[nCount].nPagePhyAddr);
//printf("VirtAddr=0x%lx PhyAddr=0x%lx\n", (uint64_t)(uint64_t *)pHT[nCount].pPageVirtAddr, pHT[nCount].nPagePhyAddr);
pHT[nCount].nIsAllocated = 0;
}
sort_hugepage_table(pHT, 0, nHugePage - 1);
/*
for(nCount = 0; nCount < nHugePage; nCount++)
{
printf("VirtAddr=0x%lx PhyAddr=0x%lx\n", (uint64_t)(uint64_t *)pHT[nCount].pPageVirtAddr, pHT[nCount].nPagePhyAddr);
}
*/
pSegmentCount=&SegmentCount;
if (check_no_of_segments(pHT,
nHugePage,
nSegment,
nHugePagePerSegment,
nHugePageSize, pSegmentCount) == -1)
{
printf("ERROR: failed to get required number of pages\n");
munmap (VirtAddr, (nHugePage * nHugePageSize));
free (pHT);
return -1;
}
pHT[0].info.nHugePage=nHugePage;
pHT[0].info.nHugePagePerSegment=nHugePagePerSegment;
pHT[0].info.nHugePageSize=nHugePageSize;
pHT[0].info.nSegment=nSegment;
*pHugepageTbl=pHT;
printf(">>> mm_huge_table_init is ok.\n");
return 1;
}
//
//
//
//
////////////////////////////////////////////////////////
int mm_segment_init(MemorySegmentStruct **pSegInfo, HugepageTblStruct *pHugepageTbl)
{
uint32_t nCount = 0;
MemorySegmentStruct *pSegment = NULL;
char nDevname[32];
int32_t nDevFd = 0;
void *VirtAddr = NULL;
//segment calloc
pSegment = (MemorySegmentStruct *)malloc ((sizeof (MemorySegmentStruct) * pHugepageTbl->info.nSegment ));
if (pSegment == NULL)
{
printf("ERROR: No sufficient memory to store segment info\n");
return -3;
}
sprintf(nDevname, "%s%d", DEVICE_NAME, 0);
nDevFd = open (nDevname, O_RDWR);
if (nDevFd < 0)
{
printf ("form_segments: Error opening the dev node file %s\n", strerror(errno));
free (pSegment);
return -3;
}
*pSegInfo=pSegment;
pSegment->nPhysicalAddr=pHugepageTbl[0].nPagePhyAddr;
pSegment->pSegment=pHugepageTbl[0].pPageVirtAddr;
/*
//printf("*pSegInfo=%lx pSegment=%lx\n",*pSegInfo,pSegment);
//printf("pHugepageTbl->info.nHugePage=%d\n",pHugepageTbl->info.nHugePage);
for (nCount = 0; nCount < pHugepageTbl->info.nHugePage; nCount++)
{
if (pHugepageTbl[nCount].nIsAllocated == 1)
{
pSegment->nSize = (pHugepageTbl->info.nHugePagePerSegment * pHugepageTbl->info.nHugePageSize);
pSegment->pSegment = mmap (0,
pSegment->nSize,
PROT_READ | PROT_WRITE,
MAP_SHARED,
//nDevFd, pHugepageTbl[nCount].nPagePhyAddr);
nDevFd, 0);
if(pSegment->pSegment == MAP_FAILED)
{
printf("ERROR: mmap failed in segment formation cause: %s\n", strerror(errno));
for (; nCount > 0; nCount--)
{
pSegment--;
munmap (pSegment->pSegment, pSegment->nSize);
}
free (pSegment);
close (nDevFd);
return -3;
}
*(uint8_t *)pSegment->pSegment = 1;
usleep(100);
printf("pSegment->nSize=0x%lx, pSegment->pSegment=0x%lx\n", pSegment->nSize, pSegment->pSegment);
//pSegment->nPhysicalAddr=pHugepageTbl[nCount].nPagePhyAddr;
cpa_bb_mm_virttophys(pSegment->pSegment, &pSegment->nPhysicalAddr);
//pSegment->nPhysicalAddr=pHugepageTbl[nCount].nPagePhyAddr+((char *)pHugepageTbl[nCount].pPageVirtAddr-(char *)pSegment->pSegment);
//printf("pSegment->pSegment=0x%lx pSegment->nSize=%x pSegment->nPhysicalAddr=0x%lx\n",(uint64_t)(uint64_t *)pSegment->pSegment, pSegment->nSize, pSegment->nPhysicalAddr);
pSegment++;
}
}
*/
close (nDevFd);
//
return 0;
}
//
//
//
//
////////////////////////////////////////////////////////
void mm_regist_addr_to_ring(DescriptorAddrRingStruct *pDescRing, MemorySegmentStruct *pFthSegInfo, MemorySegmentStruct *pFecSegInfo)
{
pDescRing->RxFhRingBuffer.pPageVirtAddr=pFthSegInfo->pSegment + FTH_MEM_SIZE*0x20;
pDescRing->RxFhRingBuffer.nPagePhyAddr=pFthSegInfo->nPhysicalAddr + FTH_MEM_SIZE*0x20;
pDescRing->TxFhRingBuffer.pPageVirtAddr=pFthSegInfo->pSegment+FTH_MEM_SIZE*0x40;
pDescRing->TxFhRingBuffer.nPagePhyAddr=pFthSegInfo->nPhysicalAddr+FTH_MEM_SIZE*0x40;
pDescRing->TxEnCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment;
pDescRing->TxEnCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr;
pDescRing->RxEnCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x20;
pDescRing->RxEnCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x20;
pDescRing->TxDeCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x40;
pDescRing->TxDeCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x40;
pDescRing->RxDeCodeRingBuffer.pPageVirtAddr=pFecSegInfo->pSegment+FEC_MEM_SIZE*0x60;
pDescRing->RxDeCodeRingBuffer.nPagePhyAddr=pFecSegInfo->nPhysicalAddr+FEC_MEM_SIZE*0x60;
}
//
//
//
//
////////////////////////////////////////////////////////
void mm_get_tti_phy_addr(MemorySegmentStruct *pFthSegInfo, uint8_t **pDmaBaseVirAddr,uint64_t *pDmaBasePhyAddr)
{
*pDmaBaseVirAddr=(uint8_t *)pFthSegInfo->pSegment + FTH_MEM_SIZE*0x10;
*pDmaBasePhyAddr=pFthSegInfo->nPhysicalAddr + FTH_MEM_SIZE*0x10;
//*pDmaBaseVirAddr=(uint64_t *)pFthSegInfo->pSegment;
//*pDmaBasePhyAddr=pFthSegInfo->nPhysicalAddr;
}
void get_data_addr_len(DescriptorAddrRingStruct *pDescRingAddr, DescDataInfo *pEnDataTx, DescDataInfo *pEnDataRx, DescDataInfo *pDeDataTx, DescDataInfo *pDeDataRx)
{
uint64_t phyAddr;
uint64_t nFuncBaseAddr = pDescRingAddr->BaseAddress;
//encode tx
phyAddr=pDescRingAddr->TxEnCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pEnDataTx->nPhysicalAddr=phyAddr;
pEnDataTx->nVirtAddr=pDescRingAddr->TxEnCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataTx->pBarVirtAddr=(uint32_t *)(nFuncBaseAddr + 0x1200);
pEnDataTx->dataLen=0;
//rx
phyAddr=pDescRingAddr->RxEnCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pEnDataRx->nPhysicalAddr=phyAddr;
pEnDataRx->nVirtAddr=pDescRingAddr->RxEnCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pEnDataRx->pBarVirtAddr=(uint32_t *)(nFuncBaseAddr + 0x2200);
pEnDataRx->dataLen=0;
//decode tx
phyAddr=pDescRingAddr->TxDeCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pDeDataTx->nPhysicalAddr=phyAddr;
pDeDataTx->nVirtAddr=pDescRingAddr->TxDeCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pDeDataTx->pBarVirtAddr=(uint32_t *)(nFuncBaseAddr + 0x1100);
pDeDataTx->dataLen=0;
//rx
phyAddr=pDescRingAddr->RxDeCodeRingBuffer.nPagePhyAddr+RING_MEM_SIZE;
pDeDataRx->nPhysicalAddr=phyAddr;
pDeDataRx->nVirtAddr=pDescRingAddr->RxDeCodeRingBuffer.pPageVirtAddr+RING_MEM_SIZE;
pDeDataRx->pBarVirtAddr=(uint32_t *)(nFuncBaseAddr + 0x2100);
pEnDataRx->dataLen=0;
}
void de_tx_update_data_addr_len(DescChainInfo *pRingInfo,DescDataInfo *pData)
{
uint64_t phyAddr;
uint32_t *pReg,i;
//memset(pRingInfo, 0, sizeof(DescChainInfo));
for(i=0;i<128;i++){
pRingInfo->nDescriptorStatus[i] = 0;
}
pRingInfo->sDescriptor[0].nAddressHigh=(uint32_t) (((uint64_t) pData->nPhysicalAddr) >> SHIFTBITS_32);
pRingInfo->sDescriptor[0].nAddressLow=(uint32_t) pData->nPhysicalAddr;
pRingInfo->sDescriptor[0].nAddressLen=pData->dataLen;
pReg=(uint32_t *)pData->pBarVirtAddr;
pReg[VALID_DES_NUM_REG] = 1*16;
}
void de_rx_update_data_addr_len(DescChainInfo *pRingInfo,DescDataInfo *pData)
{
uint32_t *pReg,i;
//for(i=0;i<128;i++){
pRingInfo->nDescriptorStatus[0] = 0;
//}
pRingInfo->sDescriptor[0].nAddressHigh=(uint32_t) (((uint64_t) pData->nPhysicalAddr) >> SHIFTBITS_32);
pRingInfo->sDescriptor[0].nAddressLow=(uint32_t) pData->nPhysicalAddr;
pReg=(uint32_t *)pData->pBarVirtAddr;
pReg[VALID_DES_NUM_REG] = 1*16;
}
#ifndef __DEV2_FF_DEMO_MEM__
#define __DEV2_FF_DEMO_MEM__
/*DMA CONTROL REG*/
#define CTRL_MODE_CFG_REG 0
#define STATUS_HADDR_REG 1
#define STATUS_LADDR_REG 2
#define VALID_DES_NUM_REG 3
#define DESC_RING_HADDR_REG 4
#define DESC_RING_LADDR_REG 5
#define BAR_MODE_READ_DESC 0x0 /*2'b00'*/
#define BAR_MODE_READ_MEM 0x2 /*2'b10'*/
#define BAR_MODE_NOTIFY_EACH 0x0 /*2'b00'*/
#define BAR_MODE_NOTIFY_ALL 0x1 /*2'b01'*/
/* hugepage setting */
#define SW_FPGA_TOTAL_BUFFER_LEN 4LL*1024*1024*1024
#define SW_FPGA_SEGMENT_BUFFER_LEN 1LL*1024*1024*1024
#define SW_FPGA_FH_TOTAL_BUFFER_LEN 1LL*1024*1024*1024
#define DIV_ROUND_OFF(X,Y) ( X/Y + ((X%Y)?1:0) )
#define DEVICE_NAME "/dev/nr_cdev"
#define FTH_MEM_SIZE (0x100000)
#define FEC_MEM_SIZE (0x100000)
#define RING_MEM_SIZE (0x10000)
#define SHIFTBITS_32 (32)
#define IS_DESC_DONE(desc) (0xFF&desc)
//
int mm_huge_table_init(HugepageTblStruct **pHugepageTbl, uint64_t memSize);
//
int mm_segment_init(MemorySegmentStruct **pFecSegInfo, HugepageTblStruct *pHugepageTbl);
//
void mm_regist_addr_to_ring(DescriptorAddrRingStruct *pDescRing, MemorySegmentStruct *pFthSegInfo, MemorySegmentStruct *pFecSegInfo);
//
void mm_get_tti_phy_addr(MemorySegmentStruct *pFthSegInfo, uint8_t **pDmaBaseVirAddr,uint64_t *pDmaBasePhyAddr);
//
void mm_register_ring_addr_to_bar ( DescriptorAddrRingStruct * pDring, uint64_t nFuncBaseAddr);
//
void de_tx_update_data_addr_len(DescChainInfo *pRingInfo,DescDataInfo *pData);
//
void de_rx_update_data_addr_len(DescChainInfo *pRingInfo,DescDataInfo *pData);
//
void get_data_addr_len(DescriptorAddrRingStruct *pDescRingAddr, DescDataInfo *pEnDataTx, DescDataInfo *pEnDataRx, DescDataInfo *pDeDataTx, DescDataInfo *pDeDataRx);
#endif //__DEV2_FF_DEMO_MEM__
18.04 vm.nr_hugepages=4096
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment