/****************************************************************************\
 *           Copyright (C) 2011 Texas Instruments Incorporated.             *
 *                           All Rights Reserved                            *
 *                                                                          *
 * GENERAL DISCLAIMER                                                       *
 * ------------------                                                       *
 * All software and related documentation is provided "AS IS" and without   *
 * warranty or support of any kind and Texas Instruments expressly disclaims*
 * all other warranties, express or implied, including, but not limited to, *
 * the implied warranties of merchantability and fitness for a particular   *
 * purpose.  Under no circumstances shall Texas Instruments be liable for   *
 * any incidental, special or consequential damages that result from the    *
 * use or inability to use the software or related documentation, even if   *
 * Texas Instruments has been advised of the liability.                     *
  ****************************************************************************
This example shows the performance of memory shared by multiple masters 
on KeyStone DSP. Steps to run it:
1, load this project to all cores
2, run all cores synchronously
3, check the stdout of DSP for result
****************************************************************************
 * Created by :                                                             *
 *            Brighton Feng                                    *
 *            Texas Instruments                                             * 
 *            12 Jan, 2011                                                  *
 *  Updated on March 30 2011 for C6678 EVM
 *  Updated on April 26 2011, support run multiple test cases
***************************************************************************/
#include <c6x.h>
#include <stdio.h>
#include <string.h>
#include <csl_cacheAux.h>
#include <csl_edma3.h>
#include "MEM_Sharing.h"
#include "KeyStone_DDR_Init.h"
#include "MEM_share_EDMA_Timer_Intc_setup.h"
#include "KeyStone_common.h"

#define DSP_CORE_NUM 	4
#define TEST_CASE_NUM 	8

#define L2_TEST_ADDR 	(0x00820000)
#define SL2_TEST_ADDR 	(0x0C080000)
#define DDR_TEST_ADDR 	(0x82000000)

#define DDR_BANK_NUM 	8
#define DDR_PAGE_SIZE 	(1024*8)
#define SL2_BANK_NUM 	4
#define SL2_BANK_WIDTH 	64

Uint32 testCaseCnt=0;
TestConfig testCases[]=
{
	{
		1, 	 	/*0:DSP core test; 1:EDMA test*/
		0, 	 	/*0:SL2 test; 1:DDR test*/
		1, 		/*0:Access same bank; 1:Access different bank*/
		4 		/*DDR priority raise count*/
	},
	{
		1, 	 	/*0:DSP core test; 1:EDMA test*/
		1, 	 	/*0:SL2 test; 1:DDR test*/
		1, 		/*0:Access same bank; 1:Access different bank*/
		4 		/*DDR priority raise count*/
	},
	{
		1, 	 	/*0:DSP core test; 1:EDMA test*/
		1, 	 	/*0:SL2 test; 1:DDR test*/
		0, 		/*0:Access same bank; 1:Access different bank*/
		4 		/*DDR priority raise count*/
	},
	{
		0, 	 	/*0:DSP core test; 1:EDMA test*/
		0, 	 	/*0:SL2 test; 1:DDR test*/
		1, 		/*0:Access same bank; 1:Access different bank*/
		4 		/*DDR priority raise count*/
	},
	{
		0, 	 	/*0:DSP core test; 1:EDMA test*/
		1, 	 	/*0:SL2 test; 1:DDR test*/
		1, 		/*0:Access same bank; 1:Access different bank*/
		4 		/*DDR priority raise count*/
	},
	{
		0, 	 	/*0:DSP core test; 1:EDMA test*/
		1, 	 	/*0:SL2 test; 1:DDR test*/
		0, 		/*0:Access same bank; 1:Access different bank*/
		4 		/*DDR priority raise count*/
	},
	{
		0, 	 	/*0:DSP core test; 1:EDMA test*/
		1, 	 	/*0:SL2 test; 1:DDR test*/
		1, 		/*0:Access same bank; 1:Access different bank*/
		0 		/*DDR priority raise count*/
	},
	{
		0, 	 	/*0:DSP core test; 1:EDMA test*/
		1, 	 	/*0:SL2 test; 1:DDR test*/
		1, 		/*0:Access same bank; 1:Access different bank*/
		255 		/*DDR priority raise count*/
	}
};

#pragma DATA_SECTION(edmaTestInfo, "GlobalData")
EdmaTestInfo edmaTestInfo[]= 
{
	/*EDMA0 TC0 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		DDR_TEST_ADDR, 	
		/*dstAddr*/
		SL2_TEST_ADDR+0*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		0, 	/*EDMA number*/
		0, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA0 TC1 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		(DDR_TEST_ADDR+DDR_PAGE_SIZE), 	
		/*dstAddr*/
		SL2_TEST_ADDR+1*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		0, 	/*EDMA number*/
		1, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA1 TC0 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+2*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+2*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		1, 	/*EDMA number*/
		0, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA1 TC1 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+3*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+3*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		1, 	/*EDMA number*/
		1, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA1 TC2 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+4*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+4*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		1, 	/*EDMA number*/
		2, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA1 TC3 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+5*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+5*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		1, 	/*EDMA number*/
		3, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA2 TC0 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+6*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+6*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		2, 	/*EDMA number*/
		0, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA2 TC1 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+7*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+7*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		2, 	/*EDMA number*/
		1, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA2 TC2 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+8*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+8*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		2, 	/*EDMA number*/
		2, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	},
	/*EDMA2 TC3 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		/*srcAddr*/
		L2_TEST_ADDR+9*DDR_PAGE_SIZE, 	
		/*dstAddr*/
		SL2_TEST_ADDR+9*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		DDR_PAGE_SIZE, 	/*aCnt*/
		32, 	/*bCnt*/
		2, 	/*EDMA number*/
		3, 	/*TC/Channel number*/
		0, 	/*bandwith achieved*/
		0, 	/*TestTimes*/
		0 	/*running*/
	}
};
#pragma DATA_SECTION(coreTestInfo, "GlobalData")
CoreTestInfo coreTestInfo[]=
{
	/*Core0 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+0*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core1 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+1*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core2 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+2*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core3 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+3*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core4 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+4*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core5 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+5*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core6 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+6*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	},
	/*Core7 transfer configuration*/
	{
		1, 	/*enabled	*/
		0, 	/*priority*/
		SL2_TEST_ADDR+7*DDR_PAGE_SIZE*DDR_BANK_NUM, 	
		L2_TEST_ADDR,/*dstAddr*/
		DDR_PAGE_SIZE, 	/*size*/
		32, 	/*repeatCount*/
		CACHE_L1_32KCACHE, 	/*L1d Size*/
		CACHE_256KCACHE, 	/*L2 cache Size*/
		0, 	/*bandwith achieved*/
		0 	/*TestTimes*/
	}

};

Int32 priorityLoop=0;
Uint32 priorityPattern[]={
	0x00000000,

	0x01234567,
	0x76543210
/*
	0x70123456,
	0x67012345,
	0x56701234,
	0x45670123,
	0x34567012,
	0x23456701,
	0x12345670,
	0x44444444
	
	0x77777777*/
};
Int32 enableMaskLoop=0;
Uint32 dmaEnableMaskPattern[]={
	0x1   ,
	0x3   ,
	0x7   ,
	0xF   ,
	0x1F  ,
	0x3F  ,
	0x7F  ,
	0xFF  ,
	0x1FF ,
	0x3FF ,
	~0x1  ,
	~0x3  ,
	~0x7  ,
	~0xF  ,
	~0x1F ,
	~0x3F ,
	~0x7F ,
	~0xFF ,
	~0x1FF
};
Uint32 coreEnableMaskPattern[]={
	0x1   ,
	0x3   ,
	0x7   ,
	0xF   ,
#if (DSP_CORE_NUM>4) 	/*for Nyquist*/
	0x1F  ,
	0x3F  ,
	0x7F  ,
	0xFF  ,
#endif
	~0x1  ,
	~0x3  ,
	~0x7  ,
#if (DSP_CORE_NUM>4) 	/*for Nyquist*/
	~0xF  ,
	~0x1F ,
	~0x3F ,
	~0x7F
#endif
};

#pragma DATA_SECTION(readyFlag, "GlobalData")
volatile Uint32  readyFlag=0;
Uint32 testCount=0;
Uint32 srcDstSwap=0;

void ConfigureTest()
{
	int i;
	TestConfig * testCfg;
	unsigned int uiTestAddr;
	unsigned int uiEDMA0_TC0_SrcAddr;
	unsigned int uiEDMA0_TC1_SrcAddr;
	unsigned int uiBankWidth;

	if(testCaseCnt>=TEST_CASE_NUM)
		return;

	testCfg= &testCases[testCaseCnt];
	if(testCfg->bEDMA_Test>1||testCfg->bDDR_Test>1||
		testCfg->bAccessDifBank>1||testCfg->uiDDR_PRI_RAISE_CNT>255)
		return;	/*invalid configuration*/
	
	/*DDR LAT_CONFIG*/
	DDR_Regs->VBUSM_CONFIG= 
		(testCfg->uiDDR_PRI_RAISE_CNT<<CSL_EMIF4F_VBUSM_CONFIG_REG_COS_COUNT_1_SHIFT)|
		(testCfg->uiDDR_PRI_RAISE_CNT<<CSL_EMIF4F_VBUSM_CONFIG_REG_COS_COUNT_2_SHIFT)|
		(testCfg->uiDDR_PRI_RAISE_CNT<<CSL_EMIF4F_VBUSM_CONFIG_REG_PR_OLD_COUNT_SHIFT);
	printf("DDR priority raise count= %d\n", testCfg->uiDDR_PRI_RAISE_CNT);

	if(testCfg->bDDR_Test) 	/*test DDR*/
	{
		uiTestAddr 	   =	DDR_TEST_ADDR                         ;
		uiEDMA0_TC0_SrcAddr= 		SL2_TEST_ADDR                 ;
		uiEDMA0_TC1_SrcAddr= 		(SL2_TEST_ADDR+SL2_BANK_WIDTH);
		uiBankWidth 	   =	DDR_PAGE_SIZE                     ;
	}
	else 	/*test SL2*/
	{
		uiTestAddr 	   =	SL2_TEST_ADDR                         ;
		uiEDMA0_TC0_SrcAddr= 		DDR_TEST_ADDR                 ;
		uiEDMA0_TC1_SrcAddr= 		(DDR_TEST_ADDR+DDR_PAGE_SIZE) ;
		uiBankWidth 	   =	SL2_BANK_WIDTH                    ;
	}

	if(testCfg->bEDMA_Test) 	/*test with EDMA*/
	{
		edmaTestInfo[0].srcAddr= uiEDMA0_TC0_SrcAddr;
		edmaTestInfo[1].srcAddr= uiEDMA0_TC1_SrcAddr;

		for(i=0; i<EDMA_TC_NUM; i++)
		{
			edmaTestInfo[i].dstAddr=
				uiTestAddr+i*DDR_PAGE_SIZE*DDR_BANK_NUM+
				i*testCfg->bAccessDifBank*uiBankWidth; 	
		}
		for(i=0; i<DSP_CORE_NUM; i++)
		{
			/*disalbe DSP core when test with EDMA*/
			coreTestInfo[i].enabled= 0; 
		}
		printf("EDMA Test, ACNT= %6d BCNT= %3d\n", 
			edmaTestInfo[0].ACnt,edmaTestInfo[0].BCnt);
	}
	else 	/*test with DSP core*/
	{
		for(i=0; i<DSP_CORE_NUM; i++)
		{
			coreTestInfo[i].srcAddr=
				uiTestAddr+i*DDR_PAGE_SIZE*DDR_BANK_NUM+
				i*testCfg->bAccessDifBank*uiBankWidth;
		}
		for(i=0; i<EDMA_TC_NUM; i++)
		{
			/*disable EDMA when test with DSP core*/
			edmaTestInfo[i].enabled= 0;	
		}
		printf("DSP core Test, size= %8d bytes, L1d= %2d L2= %3d \n", 
			coreTestInfo[0].size*coreTestInfo[0].repeatCount, 
				coreTestInfo[0].L1dCacheSize, coreTestInfo[0].L2CacheSize);
	}

	priorityLoop=0;
	enableMaskLoop=0;
	testCount=0;
	srcDstSwap=0;
}

void EDMA_pri_set()
{
	int i;
	Uint32 TC_pri[3];

	TC_pri[0]= 0;
	TC_pri[1]= 0;
	TC_pri[2]= 0;
	
	for(i=0; i<EDMA_TC_NUM; i++)
	{
		TC_pri[edmaTestInfo[i].EDMA_number] |= 
			(edmaTestInfo[i].priority<<edmaTestInfo[i].TC_channel*4);	
	}
	gEDMACCRegs[0]->TPCC_QUEPRI= TC_pri[0];
	gEDMACCRegs[1]->TPCC_QUEPRI= TC_pri[1];
	gEDMACCRegs[2]->TPCC_QUEPRI= TC_pri[2];
}

void EDMA_init_for_mem_share()
{
	int i;

	edma_Init();

	/*Initialize PaRAM for each channel/TC*/
	/*this test use channel 0 with TC0, channel 1 with TC1...*/
	for(i=0; i< CSL_EDMA3_TPCC0_NUM_TC; i++) 	
	{
		gEDMACC0Regs->PARAMSET[i].OPT= 
		CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, 
			CSL_EDMA3_TCCH_DIS, 
			CSL_EDMA3_ITCINT_DIS, 
			CSL_EDMA3_TCINT_EN,
			i,
			CSL_EDMA3_TCC_NORMAL,
			CSL_EDMA3_FIFOWIDTH_NONE, 
			CSL_EDMA3_STATIC_EN, 
			CSL_EDMA3_SYNC_AB, 
			CSL_EDMA3_ADDRMODE_INCR, 
			CSL_EDMA3_ADDRMODE_INCR);
		gEDMACC0Regs->PARAMSET[i].SRC_DST_BIDX= 0;
		gEDMACC0Regs->PARAMSET[i].LINK_BCNTRLD= 0xFFFF;
		gEDMACC0Regs->PARAMSET[i].SRC_DST_CIDX= 0;
		gEDMACC0Regs->PARAMSET[i].CCNT= 1;
	}
	for(i=0; i< CSL_EDMA3_TPCC1_NUM_TC; i++) 	
	{
		gEDMACC1Regs->PARAMSET[i].OPT= 
		CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, 
			CSL_EDMA3_TCCH_DIS, 
			CSL_EDMA3_ITCINT_DIS, 
			CSL_EDMA3_TCINT_EN,
			i,
			CSL_EDMA3_TCC_NORMAL,
			CSL_EDMA3_FIFOWIDTH_NONE, 
			CSL_EDMA3_STATIC_EN, 
			CSL_EDMA3_SYNC_AB, 
			CSL_EDMA3_ADDRMODE_INCR, 
			CSL_EDMA3_ADDRMODE_INCR);
		gEDMACC1Regs->PARAMSET[i].SRC_DST_BIDX= 0;
		gEDMACC1Regs->PARAMSET[i].LINK_BCNTRLD= 0xFFFF;
		gEDMACC1Regs->PARAMSET[i].SRC_DST_CIDX= 0;
		gEDMACC1Regs->PARAMSET[i].CCNT= 1;
	}
	for(i=0; i< CSL_EDMA3_TPCC2_NUM_TC; i++) 	
	{
		gEDMACC2Regs->PARAMSET[i].OPT= 
		CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, 
			CSL_EDMA3_TCCH_DIS, 
			CSL_EDMA3_ITCINT_DIS, 
			CSL_EDMA3_TCINT_EN,
			i,
			CSL_EDMA3_TCC_NORMAL,
			CSL_EDMA3_FIFOWIDTH_NONE, 
			CSL_EDMA3_STATIC_EN, 
			CSL_EDMA3_SYNC_AB, 
			CSL_EDMA3_ADDRMODE_INCR, 
			CSL_EDMA3_ADDRMODE_INCR);
		gEDMACC2Regs->PARAMSET[i].SRC_DST_BIDX= 0;
		gEDMACC2Regs->PARAMSET[i].LINK_BCNTRLD= 0xFFFF;
		gEDMACC2Regs->PARAMSET[i].SRC_DST_CIDX= 0;
		gEDMACC2Regs->PARAMSET[i].CCNT= 1;
	}

	gEDMACC0Regs->TPCC_IESR= 0x3;
	gEDMACC1Regs->TPCC_IESR= 0xF;
	gEDMACC2Regs->TPCC_IESR= 0xF;
}


void main()
{
	int i;
	TDSP_Board_Type DSP_Board_Type;

	IER= 0; 	//disable interrupt;
	
	TSCL = 0; 	/* Enable the TSC */

	CACHE_setL1PSize(CACHE_L1_32KCACHE);
	CACHE_setL1DSize(CACHE_L1_32KCACHE);

	/*make DDR cacheable and prefetchable*/
	CGEM_regs->MAR[(DDR_TEST_ADDR/16/1024/1024)]=1|
		(1<<CSL_CGEM_MAR0_PFX_SHIFT);	

	/*make SL2 cacheable and prefetchable*/
	CGEM_regs->MAR[(SL2_TEST_ADDR/16/1024/1024)]=1|
		(1<<CSL_CGEM_MAR0_PFX_SHIFT);	

	/*make core's global address noncacheable nonprefetchable for global data access*/
	for(i=0; i<DSP_CORE_NUM; i++)
		CGEM_regs->MAR[(0x10800000+i*0x1000000)/16/1024/1024]=0;

	if(0==DNUM)	//core 0 is the main control core
	{
		Timer64_Config tmrCfg;

		DSP_Board_Type= KeyStone_Get_dsp_board_type();
		if(C6678_EVM==DSP_Board_Type)
		{
			//DSP core speed: 100*10/1=1000MHz
			KeyStone_main_PLL_init(100, 10, 1); 
		}
		else if(TCI6614_EVM==DSP_Board_Type
			||DUAL_NYQUIST_EVM==DSP_Board_Type
			||C6670_EVM==DSP_Board_Type)
		{
			//DSP core speed: 122.88*236/29= 999.9889655MHz
			KeyStone_main_PLL_init(122.88, 236, 29);
		}
		else
		{
			puts("Unknown DSP board type!");
			return;
		}

		//DDR init 66.667*20/1= 1333
		KeyStone_DDR_init (66.667, 20, 1, NULL);

		/* protect L1 as cache */
	   	L1_cache_protection();

		/*enable L1P ED and scrub whole L1P*/
		L1P_EDC_setup();

	   	/*enable LL2 EDC and scrub whole LL2*/
		LL2_EDC_setup();

		/*Enable MSMC EDC and setup scrubbing cycle counter= 255*1024*/
		KeyStone_SL2_EDC_enable(255);

		tmrCfg.timer_num= 0;
		tmrCfg.timerMode= TIMER_PERIODIC_PULSE;
		tmrCfg.period= 700000000; 	/*period is in DSP core clock/6*/
		tmrCfg.pulseWidth= 3;
		Timer64_Init(&tmrCfg);

		EDMA_init_for_mem_share();

		ConfigureTest();

		EDMA_pri_set();

		CP_INTC_Init_EDMA();

	   	/*exception configuration, also configure event 23 as the CIC exception input*/
	   	KeyStone_Exception_cfg();

		readyFlag=1;
	}

	if(0==readyFlag)
		puts("wait for first core initialization...");
	//wait untile the main control Core finished the initialization of configuration structrue
	while(!(readyFlag)); 	

	EDMA_Timer_Interrupts_Init();

	Edma_Test_Start();
	
	DSP_Core_Test_Start();

	while(1)
		asm(" IDLE");
}

void swapDSPCoreAddress()
{
	Int32 i;
	Uint32 	tempAddress;
	CoreTestInfo 	* core;

	//swap src/dst address and test again
	for(i=0; i<DSP_CORE_NUM; i++)
	{
		core= &(coreTestInfo[i]);
		tempAddress= core->dstAddr;
		core->dstAddr= core->srcAddr;
		core->srcAddr= tempAddress;
	}
}

void swapEDMAAddress()
{
	Int32 i;
	Uint32 	tempAddress;
	EdmaTestInfo 	* edma;

	//swap src/dst address and test again
	for(i=0; i<EDMA_TC_NUM; i++)
	{
		edma= &(edmaTestInfo[i]);
		tempAddress= (edma->dstAddr);
		edma->dstAddr= (edma->srcAddr);
		edma->srcAddr= tempAddress;
	}
}

void restartEDMA()
{
	Int32 i;
	Uint32 	priPattern, enableMask;

	//reconfigure priority
	priPattern= priorityPattern[priorityLoop];
	gEDMACC0Regs->TPCC_QUEPRI= priPattern&0xff;		
	gEDMACC1Regs->TPCC_QUEPRI= (priPattern>>8)&0xffff;		
	gEDMACC2Regs->TPCC_QUEPRI= _rotl(priPattern,8)&0xffff;		
	for(i=0; i<8; i++)
	{
		edmaTestInfo[i].priority= priPattern&0xf;
		priPattern >>= 4;
	}
	priPattern= priorityPattern[priorityLoop];
	for(i=8; i<EDMA_TC_NUM; i++)
	{
		edmaTestInfo[i].priority= priPattern&0xf;
		priPattern >>= 4;
	}

	if(priorityLoop== 0&&0==enableMaskLoop&&1==srcDstSwap)
	{
		swapEDMAAddress();
	}

	//waiting for all EDMA stopped
	for(i=0; i<EDMA_TC_NUM; i++)
	{
		while(edmaTestInfo[i].running);
	}

	//reconfigure enable mask
	enableMask= dmaEnableMaskPattern[enableMaskLoop];
	for(i=0; i<EDMA_TC_NUM; i++)
	{
		edmaTestInfo[i].enabled= enableMask&1;
		enableMask>>=1;
	}

	//adjust index for next test;
	priorityLoop++;
	if(priorityLoop*4== sizeof(priorityPattern))
	{
		priorityLoop= 0;
		enableMaskLoop++;
		if(enableMaskLoop*4==sizeof(dmaEnableMaskPattern))
		{
			enableMaskLoop= 0;
			srcDstSwap++; 	//swap src/dst address and test again
		}
	}

	//restart EDMA test;
	Edma_Test_Start();
}

void restartDSPCore()
{
	Int32 i;
	Uint32 	priPattern, enableMask;

	//reconfigure priority
	priPattern= priorityPattern[priorityLoop];
	for(i=0; i<DSP_CORE_NUM; i++)
	{
		coreTestInfo[i].priority= priPattern&0xf;
		priPattern>>= 4;
	}

	if(priorityLoop== 0&&0==enableMaskLoop&&1==srcDstSwap)
	{
		swapDSPCoreAddress();
	}

	//reconfigure enable mask
	enableMask= coreEnableMaskPattern[enableMaskLoop];
	for(i=0; i<DSP_CORE_NUM; i++)
	{
		coreTestInfo[i].enabled= enableMask&1;
		enableMask>>=1;
	}

	for(i=0; i<DSP_CORE_NUM; i++)
	{
		coreTestInfo[i].start_TSC = 0;
		coreTestInfo[i].last_TSC = 0;
		coreTestInfo[i].testTimes=0;
		coreTestInfo[i].averageBandwidth=0;
		coreTestInfo[i].reStat= 1; 	//requires the mast to re-statistic bandwidth after re-configuration
	}

	//adjust index for next test;
	priorityLoop++;
	if(priorityLoop*4== sizeof(priorityPattern))
	{
		priorityLoop= 0;
		enableMaskLoop++;
		if(enableMaskLoop*4==sizeof(coreEnableMaskPattern))
		{
			enableMaskLoop= 0;
			srcDstSwap++; 	//swap src/dst address and test again
		}
	}
}

/*Bandwith information is polled and printed on the TIMER ISR of core0*/
void interrupt Timer_ISR(void)
{
	Int32 i;
	EdmaTestInfo 	* edma;
	CoreTestInfo 	* core;
	Uint32  coreEnable[DSP_CORE_NUM];
	Uint32  edmaEnable[EDMA_TC_NUM];
	Uint32 	bandwidthSum=0;

	/*only core0 is used for control and output information*/
	if(0!=DNUM)	
		return;

	if(testCases[testCaseCnt].bEDMA_Test)	//test with EDMA
	{
		//disable the EDMA, stop all EDMA for next test
		for(i=0; i<EDMA_TC_NUM; i++)
		{
			edmaEnable[i]= edmaTestInfo[i].enabled;
			edmaTestInfo[i].enabled= 0;
		}

		//printf test result
		for(i=0; i<EDMA_TC_NUM; i++)
		{
			edma= &(edmaTestInfo[i]);
			if(edmaEnable[i])
			{
				//measure the bandwidth
				edma->averageBandwidth= (unsigned long long)edma->ACnt*edma->BCnt*edma->testTimes*DSP_Core_Clock_KHz/
					((unsigned int)(edma->last_TSC - edma->start_TSC))/1000;

				bandwidthSum+= edma->averageBandwidth;
				printf("EDMA%d TC%d 0x%8x -> 0x%8x, BW= %5d MB/s, pri= %d, Times= %3d\n", 
					edma->EDMA_number, edma->TC_channel, edma->srcAddr,edma->dstAddr,
					edma->averageBandwidth, edma->priority, edma->testTimes);

			}
			else
				printf("EDMA%d TC%d is disabled\n",edma->EDMA_number, edma->TC_channel); 
		}
		printf("%4d                          Total BW= %5d MB/s\n\n", ++testCount, bandwidthSum);

		if(2==srcDstSwap)		//src/dst address was already swapped, test case finished
		{
			printf("EDMA test case %d complete.\n", testCaseCnt);
			swapEDMAAddress();
		}

	}	
	else 	//test with DSP core
	{
		//stop all DSP core for reconfiguration
		for(i=0; i<DSP_CORE_NUM; i++)
		{
			coreEnable[i]= coreTestInfo[i].enabled;
			coreTestInfo[i].enabled= 0;
		}

		//printf test result
		for(i=0; i<DSP_CORE_NUM; i++)
		{
			if(coreEnable[i])
			{
				core = &(coreTestInfo[i]);
				bandwidthSum+= core->averageBandwidth;
				printf("DSP Core%d 0x%8x -> 0x%8x, BW= %5d MB/s pri= %d  Times= %d\n", 
					i, core->srcAddr, core->dstAddr, core->averageBandwidth, 
					core->priority, core->testTimes);
			}
			else
				printf("DSP Core%d is disabled\n",i); 
		}
		printf("%4d                          Total BW= %5d MB/s\n\n", ++testCount, bandwidthSum);

		if(2==srcDstSwap)		//src/dst address was already swapped, test case finished
		{
			printf("DSP core test case %d complete.\n", testCaseCnt);
			swapDSPCoreAddress();
		}

	}
	if(2==srcDstSwap)		//src/dst address was already swapped, test case finished
	{
		testCaseCnt++;
		if(testCaseCnt<TEST_CASE_NUM)
		{
			ConfigureTest(); 	//configure the next test case
		}
		else
		{
			//disable interrupts
			IER= 0;
			return;
		}
	}

	if(testCases[testCaseCnt].bEDMA_Test)	//test with EDMA
	{
		restartEDMA();
	}
	else
	{
		restartDSPCore();
	}
}

