/*  ============================================================================
 *   Copyright (c) Texas Instruments Inc 2014
 *
 *   Use of this software is controlled by the terms and conditions found in the
 *   license agreement under which this software has been supplied.
* ============================================================================
Example to show the performance of CPU access memory
* =============================================================================
 *  Revision History
 *  ===============
 *  July 31, 2014 Brighton Feng   File Created
 * ============================================================================
 */
#include <stdio.h>
#include "K2_common.h"
#include "common_test.h"
#include "Mem_Access_performance.h"
#include "CPU_access_test.h"

//limit copy size to save test time
#define MAX_COPY_SIZE 	(128*1024)

#if 1
#define MemCopyTest 	AsmMemCopy8Test
#else
#define MemCopyTest 	MemCopy8Test
#endif

//memory copy test inside each block and between all blocks
void MemoryCopyTest()
{
	int src_index, dst_index;
	Uint32 uiByteCnt;

	for(src_index=0; src_index<num_mem_test_blocks; src_index++)
		for(dst_index=0; dst_index<num_mem_test_blocks; dst_index++)
		{
			if(src_index==dst_index) //copy inside block
			{
				uiByteCnt= mem_test_blocks[src_index].uiByteCnt/2;
				if(uiByteCnt>MAX_COPY_SIZE) //limit the size to save test time
					uiByteCnt= MAX_COPY_SIZE;

				//copy from the first half of the block to the second half of the block
				MemCopyTest((unsigned long long *)mem_test_blocks[src_index].uiAddress, 
					(unsigned long long *)(mem_test_blocks[src_index].uiAddress+uiByteCnt), 
					uiByteCnt, 
					mem_test_blocks[src_index].type, 
					mem_test_blocks[src_index].type);

				//for DDR, test copy between different banks
				if(mem_test_blocks[src_index].uiAddress>=0x60000000) 	
				{
					//copy from the first half of the block to the second half of the block
					MemCopyTest((unsigned long long *)mem_test_blocks[src_index].uiAddress, 
						(unsigned long long *)(mem_test_blocks[src_index].uiAddress+uiByteCnt+DDR_PAGE_SIZE), 
						uiByteCnt, 
						mem_test_blocks[src_index].type, 
						mem_test_blocks[src_index].type);
				}
			}
			else //copy between blocks
			{
				//use the size of the smaller block
				uiByteCnt= (mem_test_blocks[src_index].uiByteCnt<mem_test_blocks[dst_index].uiByteCnt)?
					mem_test_blocks[src_index].uiByteCnt:mem_test_blocks[dst_index].uiByteCnt;
				if(uiByteCnt>MAX_COPY_SIZE) //limit the size to save test time
					uiByteCnt= MAX_COPY_SIZE;

				MemCopyTest((unsigned long long *)mem_test_blocks[src_index].uiAddress, 
					(unsigned long long *)mem_test_blocks[dst_index].uiAddress, 
					uiByteCnt,
					mem_test_blocks[src_index].type, 
					mem_test_blocks[dst_index].type);
			}
		}
}

//test the load/store cycle in all memory blocks
void LoadStoreCycleTest()
{
	Int32 i;
	for(i=0; i< num_mem_test_blocks; i++)
	{
		LDRDTest(mem_test_blocks[i].uiAddress, mem_test_blocks[i].uiByteCnt, mem_test_blocks[i].type);
		STRDTest(mem_test_blocks[i].uiAddress, mem_test_blocks[i].uiByteCnt, mem_test_blocks[i].type);
	}
}

