memtest 函数

 

/*
**  Reorganize the test_memtest code.
**					Leon   2013.04.14
*/
/* DMA related definition */
/* Following structure used for special hardware implement */
/* DMA transmission width, bit 31:6 */
#define HAL_PACERS_DMA_TRANS_WIDTH_BIT	6
/* DMA destination address increase enable, bit 5 */
#define HAL_PACERS_DMA_DST_INC_BIT		5
/* DMA source address increase enable, bit 3 */
#define HAL_PACERS_DMA_SRC_INC_BIT		3
/* DMA destination transport disable, bit 4 */
#define HAL_PACERS_DMA_TRANS_DIS_BIT		4
/* DMA enable, bit 2 */
#define HAL_PACERS_DMA_ENABLE_BIT		2
	
#define LOG_PRINTF printf
#define debug_printf printf /*on or off debug print*/
#define ATOI atoi
#define STRCMP strcmp
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned int
#define INT32  int
#define GDMA_DST_ADDR 0x85000000
#define GDMA_SRC_ADDR 0x8a000000
#define NULL 0
	
struct dma_link_node {
	UINT32 control; 				/* Channel control register value */
	UINT32 src_addr;				/* Source address */
	UINT32 dst_addr;				/* Destin address */
	UINT32 next_node;				/* Next node address */
};
inline void *hal_vaddr_to_paddr(void *vaddr)
{
	UINT8 tmp = (UINT32)vaddr >> 29;

	if (tmp >= 0x4 && tmp < 0x6) {
		return (void *)((UINT32)vaddr & ~0xE0000000);
	} else {
		return vaddr;
	}
}

void reset_gdma()/*reset  gdma.*/
{
	CPUregWrite_32(0xbf20009c, 0x00000080); 
	CPUregWrite_32(0xbf200080, 0xfffff7ff); 
	delay(50000);
	CPUregWrite_32(0xbf200080, 0xffffffff);
}
UINT32 fill_data(void *addr,UINT32 length)/*fill data at some physical addr.*/
{
	UINT32 i,data;
	UINT32 gdma_src_addr = (UINT32)addr;
	
	for (i = 0; i < length/4; i++) 
	{
		if((i%4)==0)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0xa5a5a5a5;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data !=0xa5a5a5a5) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
				return 0;
			}
		}
		if((i%4)==1)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data != 0) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
				return 0;
			}
		}
		if((i%4)==2)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0x5a5a5a5a;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data !=0x5a5a5a5a) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
				return 0;
			}
		}	
		if((i%4)==3)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data != 0) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
				return 0;
			}
		}
	}
	return 0;
}
UINT32 check_data(void *addr,UINT32 length)/*fill data at some physical addr.*/
{
	UINT32 i,data;
	UINT32 gdma_src_addr = (UINT32)addr;
	
	for (i = 0; i < length/4; i++) 
	{
		if((i%4)==0)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0xa5a5a5a5;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data !=0xa5a5a5a5) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
//				return 0;
			}
		}
		if((i%4)==1)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data != 0) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
//				return 0;
			}
		}
		if((i%4)==2)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0x5a5a5a5a;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data !=0x5a5a5a5a) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
//				return 0;
			}
		}	
		if((i%4)==3)
		{
			((volatile UINT32 *)gdma_src_addr)[i] = 0;
			data = ((volatile UINT32 *)gdma_src_addr)[i];
			if ((UINT32)data != 0) {
				LOG_PRINTF("0x%08x: Error! 0x%08x\n", ((int *)gdma_src_addr) + i, data);
//				return 0;
			}
		}
	}
	return 0;
}

struct item_node
{
	UINT32 control;
	UINT32 src_addr;
	UINT32 dst_addr;
	UINT32 next_node;
};

void gdma_mv_data(void *psrc,void *pdst,UINT32 length)
{
	reset_gdma();
	CPUregWrite_32(0xbf3c0804, 0x001fffff);/*need or not?*/
	
	UINT32 item_addr = (UINT32)malloc(0x100*sizeof(int));/*don't forget to free*/
	item_addr = (item_addr + 63)&0xfffffff0;/*16bytes align*/
	debug_printf("item_addr = 0x%x\n",item_addr);
	
	struct item_node *node =(struct item_node *)item_addr;
	node->control = ((length<<HAL_PACERS_DMA_TRANS_WIDTH_BIT)|(1<<HAL_PACERS_DMA_SRC_INC_BIT));
	node->src_addr = (UINT32)psrc;
	node->dst_addr = (UINT32)pdst;
	node->next_node = NULL;
	
	CPUregWrite_32(0xbf3c0010, (UINT32)hal_vaddr_to_paddr(&node));
	CPUregWrite_32(0xbf3c0000, 0x00021c01);
	CPUregWrite_32(0xbf3c00c4, 0x00000000);/*enable channel*/
	CPUregWrite_32(0xbf3c0004, 0x00000001);/*start to move data*/	

	free(node);	
}
UINT32 gdma_check_idle(UINT32 channel)
{
	int m = 0,timeout_flag = 0;
	while((~(((CPUregRead_32(0xbf3c0008))>>4)&0x1))&0x01)/*FIXME*/
	{
		delay(500000);
		m++;
		if(m == 100)/*LEON*/
		{
			timeout_flag = 1;
			break;		
		}
	};
	return timeout_flag;
}
static int test_memtest(int argc, char *argv[])
{
	UINT32 *start_addr, loop_num;
	INT32 data,i,j,k = 0,length,testmode = 0;
	UINT32 random,m;

	if (argc < 4) 
	{
		printf("Usage: %s [start_addr] [length] [loop_num] [testmode 0|1|2].\n", argv[0]);
		return -1;
	}
	if (!get_rsa ((UINT32 *)&start_addr, argv[1]))
	{
		printf("Please input the start address \n");
		return -1;
	}	
	if (!get_rsa ((UINT32 *)&length, argv[2]))
	{
		printf("Please input the length \n");
		return -1;
	}
	if (!get_rsa ((UINT32 *)&loop_num, argv[3]))
	{
		printf("Please input the loop number \n");
		return -1;
	}
	m = loop_num;

	if(argc > 4){
		get_rsa ((UINT32 *)&testmode, argv[4]);
	}
	
	if(testmode == 1)
	{
		printf("StartAddr:0x%x Length:0x%x Loop:0x%x\n",(UINT32)start_addr,length,loop_num);
		printf("TestMode = 1,In GDMA VDDR MODE.\n");		
		while(1)
		{
			printf("Loop Number = 0x%x\n",k++);
			
			int overtime_flag = 0;
			
			fill_data((void *)GDMA_SRC_ADDR,length);
			
			flushcache();
			
			gdma_mv_data(hal_vaddr_to_paddr((void *)GDMA_SRC_ADDR),((void *)start_addr),length);/*need to be fix!!!*/

			gdma_check_idle(0);
			
			gdma_mv_data(((void *)start_addr),hal_vaddr_to_paddr((void *)GDMA_DST_ADDR),length);/*need to be fix!!!*/			

			if (gdma_check_idle(0) == 1)/*check channel idle or not*/
			{
				overtime_flag = 1;
			}
			
			flushcache();
			
			check_data((void *)GDMA_DST_ADDR,length);
			
			if (overtime_flag == 1)
			{
				printf("WAIT TOO LONG FOR GDMA!\n");
				overtime_flag = 0;/*make sure*/
				return 0;
			}

			if ((loop_num != 0)&&((m--) == 0))/*deal with loop_num*/
			{
				break;/*break out of while(1)*/
			}
			printf("GDMA VDDR MEM TEST DONE.SUCCESS.\n");			
		}				
		return 0;		
	}
	else if(testmode==2)/*Test mddr.*/
	{
		printf("StartAddr:0x%x Length:0x%x Loop:0x%x\n",(UINT32)start_addr,length,loop_num);
		printf("TestMode = 2,In GDMA MDDR MODE.\n");
		while(1)
		{
			printf("Loop Number = 0x%x\n",k++);
			
			int overtime_flag = 0;
			
			fill_data((void *)GDMA_SRC_ADDR,length);
			
			flushcache();
			
			gdma_mv_data(hal_vaddr_to_paddr((void *)GDMA_SRC_ADDR),hal_vaddr_to_paddr((void *)GDMA_DST_ADDR),length);

			gdma_check_idle(0);
			
	//		gdma_mv_data(((void *)start_addr),hal_vaddr_to_paddr((void *)GDMA_DST_ADDR),length);/*need to be fix!!!*/			

			if (gdma_check_idle(0) == 1)/*check channel idle or not*/
			{
				overtime_flag = 1;
			}
			
			flushcache();
			
			check_data((void *)GDMA_DST_ADDR,length);
			
			if (overtime_flag == 1)
			{
				printf("WAIT TOO LONG FOR GDMA!\n");
				overtime_flag = 0;/*make sure*/
				return 0;
			}

			if ((loop_num != 0)&&((m--) == 0))/*deal with loop_num*/
			{
				break;
			}
			printf("GDMA VDDR MEM TEST DONE.SUCCESS.\n");			
		}
		return 0;
	}
	else
	{
		printf("StartAddr:0x%x Length:0x%x Loop:0x%x",(UINT32)start_addr,length,loop_num);
		printf("  TestMode = 0,In Normal MODE.\n");
		while(1)
		{
			LOG_PRINTF("Loop Number = 0x%x\n",k++);	
			int overtime_flag = 0;
			random = (UINT32)rand();
			
			for (i = 0; i < length; i++) {
				((volatile UINT8 *)start_addr)[i] = (UINT8)(i+random);
				data = ((volatile UINT8 *)start_addr)[i];
				if ((UINT8)data != (UINT8)(i+random)){
					LOG_PRINTF("0x%08x: Error! 0x%02x : 0x%02x\n", ((char *)start_addr) + i, (UINT8)(i+random), data);
					break;
				}
			}
			LOG_PRINTF("...");
			for (i = 0; i < length/2; i++) {
				((volatile UINT16 *)start_addr)[i] = (UINT16)(i+random);
				data = ((volatile UINT16 *)start_addr)[i];
				if ((UINT16)data != (UINT16)(i+random)){
					LOG_PRINTF("0x%08x: Error! 0x%04x : 0x%04x\n", ((short *)start_addr) + i, (UINT16)(i+random), data);
					break;
				}
			}
			LOG_PRINTF("...");
			for (i = 0; i < length/4; i++) {
				((volatile UINT32 *)start_addr)[i] = (UINT32)(i+random);
				data = ((volatile UINT32 *)start_addr)[i];
				if ((UINT32)data != (UINT32)(i+random)) {
					LOG_PRINTF("0x%08x: Error! 0x%08x : 0x%08x\n", ((int *)start_addr) + i, (UINT32)(i+random), data);
					break;
				}
			}
			for (i = length - 1; i >= 0; i--) {
				((volatile UINT8 *)start_addr)[i] = (UINT8)(i+random);
				data = ((volatile UINT8 *)start_addr)[i];
				if ((UINT8)data != (UINT8)(i+random)) {
					LOG_PRINTF("0x%08x: Error! 0x%02x : 0x%02x\n", ((char *)start_addr) + i, (UINT8)(i+random), data);
					break;
				}
			}
			LOG_PRINTF("...");
			for (i = length/2 - 1; i >= 0; i--) {
				((volatile UINT16 *)start_addr)[i] = (UINT16)(i+random);
				data = ((volatile UINT16 *)start_addr)[i];
				if ((UINT16)data != (UINT16)(i+random)) {
					LOG_PRINTF("0x%08x: Error! 0x%04x : 0x%04x\n", ((short *)start_addr) + i, (UINT16)(i+random), data);
					break;
				}
			}
			LOG_PRINTF("...");
			for (i = length/4 -1; i >= 0; i--) {
				((volatile UINT32 *)start_addr)[i] = (UINT32)(i+random);
				data = (UINT32)(((volatile UINT32 *)start_addr)[i]);
				if ((UINT32)data != (UINT32)(i+random)) {
					LOG_PRINTF("0x%08x: Error! 0x%08x : 0x%08x\n", ((int *)start_addr) + i, (UINT32)(i+random), data);
					break;
				}
			}

			if (overtime_flag == 1)
			{
				printf("WAIT TOO LONG FOR GDMA!\n");
				overtime_flag = 0;/*make sure*/
				return 0;
			}

			if ((loop_num != 0)&&((m--) == 0))/*deal with loop_num*/
			{
				break;
			}	
			
			printf("\nNormal MEM TEST DONE,SUCCESS.\n");
		}
		return 0;	
	}	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值