/*
** 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;
}
}