⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 2440 开发板的测试程序。包括uart,iic,lcd
💻 C
📖 第 1 页 / 共 2 页
字号:
			unsigned long pages_in_bank[4];		/* 44 */
			unsigned long pages_in_vram;		/* 60 */
			unsigned long initrd_start;			/* 64 */
			unsigned long initrd_size;			/* 68 */
			unsigned long rd_start;				/* 72 */
			unsigned long system_rev;			/* 76 */
			unsigned long system_serial_low;	/* 80 */
			unsigned long system_serial_high;	/* 84 */
			unsigned long mem_fclk_21285;   	/* 88 */
		} s;
		char unused[256];
	} u1;
	union
	{
		char paths[8][128];
		struct
		{
			unsigned long magic;
			char n[1024 - sizeof( unsigned long )];
		} s;
	} u2;
	char commandline[COMMAND_LINE_SIZE];
};

extern void call_linux( U32 a0 , U32 a1 , U32 a2 );

/*************************************************************/
static __inline void cpu_arm920_cache_clean_invalidate_all( void )
{
	__asm
	{
		mov	r1, #0		
		mov	r1, #7 << 5			  	/* 8 segments */
		cache_clean_loop1:		
		orr	r3, r1, #63UL << 26	  	/* 64 entries */
		cache_clean_loop2:	
		mcr	p15, 0, r3, c7, c14, 2	/* clean & invalidate D index */
		subs	r3, r3, #1 << 26
		bcs	cache_clean_loop2		/* entries 64 to 0 */
		subs	r1, r1, #1 << 5
		bcs	cache_clean_loop1		/* segments 7 to 0 */
		mcr	p15, 0, r1, c7, c5, 0	/* invalidate I cache */
		mcr	p15, 0, r1, c7, c10, 4	/* drain WB */
	}
}
void cache_clean_invalidate( void )
{
	cpu_arm920_cache_clean_invalidate_all();
}

static __inline void cpu_arm920_tlb_invalidate_all( void )
{
	__asm
	{
		mov	r0, #0
		mcr	p15, 0, r0, c7, c10, 4	/* drain WB */
		mcr	p15, 0, r0, c8, c7, 0	/* invalidate I & D TLBs */
	}
}

void tlb_invalidate( void )
{
	cpu_arm920_tlb_invalidate_all();
}

void disable_irq( void );

void call_linux( U32 a0 , U32 a1 , U32 a2 )
{
	void ( *goto_start ) ( U32 , U32 );
	cache_clean_invalidate();
	tlb_invalidate();	

	__asm
	{
		//		mov	r0, a0//%0
		//		mov	r1, a1//%1
		//		mov	r2, a2//%2
		mov	ip, #0
		mcr	p15, 0, ip, c13, c0, 0	/* zero PID */
		mcr	p15, 0, ip, c7, c7, 0	/* invalidate I,D caches */
		mcr	p15, 0, ip, c7, c10, 4	/* drain write buffer */
		mcr	p15, 0, ip, c8, c7, 0	/* invalidate I,D TLBs */
		mrc	p15, 0, ip, c1, c0, 0	/* get control register */
		bic	ip, ip, #0x0001			/* disable MMU */
		mcr	p15, 0, ip, c1, c0, 0	/* write control register */
		//mov	pc, r2
		//nop
		//nop
		/* no outpus */
		//: "r" (a0), "r" (a1), "r" (a2)

	}
	//	SetClockDivider(1, 1);
	//	SetSysFclk(FCLK_200M);		//start kernel, use 200M
	SET_IF();
	goto_start = ( void ( * ) ( U32 , U32 ) ) a2;
	( *goto_start ) ( a0 , a1 );
}

static void LoadRun( void )
{
	U32 i, ram_addr, buf = boot_params.run_addr.val;
	struct param_struct* params = ( struct param_struct* ) 0x30000100;
	int size;

	memset( params , 0 , sizeof( struct param_struct ) );
	/*{
		U32 *pD = (U32 *)0x30000100;
		
		for(i=0; i<0x1000; i++)
			pD[i] = 0;
	}*/
	if ( boot_params.start.val )
	{
		char parameters[512];
		char* rootfs;
		char initrd[32];
		char* tty_sel;
		char* devfs_sel;

		switch ( boot_params.root_sel.val )
		{
			case 0:
				rootfs = "/dev/ram";
				break;
			case 1:
				rootfs = "nfs";
				break;
			case 2:
				rootfs = "/dev/mtdblock2";
				break;
			case 3:
				rootfs = "/dev/mtdblock3";
				break;
			case 4:
				rootfs = "/dev/hda1";
			default:
				rootfs = "";	//user define
				break;
		}

		if ( boot_params.root_sel.val )
			Uart_Printf( initrd , "load_ramdisk=0" );
		else
			Uart_Printf( initrd , "initrd=0x%08x,0x%08x" , boot_params.initrd_addr.val , boot_params.initrd_len.val );

		switch ( boot_params.tty_sel.val )
		{
			case 0:
				tty_sel = "ttyS0";
				break;
			case 1:
				tty_sel = "ttyS1";
				break;
			case 2:
				tty_sel = "tty1";
				break;
			default:
				tty_sel = "";	//user define
				break;
		}

		if ( boot_params.devfs_sel.val )
			devfs_sel = "devfs=mount";
		else
			devfs_sel = "";

		memset( parameters , 0 , sizeof( parameters ) );
		Uart_Printf( parameters , "root=%s init=/linuxrc %s console=%s,%d mem=%dK %s %s" , rootfs , initrd , tty_sel ,
			boot_params.serial_baud.val , boot_params.mem_cfg.val >> 10 , devfs_sel , boot_params.string );

		params->u1.s.page_size = LINUX_PAGE_SIZE;
		params->u1.s.nr_pages = ( boot_params.mem_cfg.val >> LINUX_PAGE_SHIFT );
		memcpy( params->commandline , parameters , strlen( parameters ) );

		Uart_Printf( "Set boot params = %s\n" , params->commandline );
	}

	StartPage = NandPart[1].offset >> 9;
	size = NandPart[1].size;
	ram_addr = buf;	

	Uart_Printf( "Load Kernel...\n" );
	for ( i = 0; size > 0; )
	{
		if ( !( i & 0x1f ) )
		{
			if ( CheckBadBlk( i + StartPage ) )
			{
				Uart_Printf( "Skipped bad block at 0x%x\n" , i + StartPage );
				i += 32;
				size -= 32 << 9;
				continue;
			}
		}
		ReadPage( ( i + StartPage ) , ( U8 * ) ram_addr );
		i++;
		size -= 512;
		ram_addr += 512;
	}

	if ( !boot_params.root_sel.val )
	{
		int ramdisk_sz;

		Uart_Printf( "Load Ramdisk...\n" );

		StartPage = NandPart[2].offset >> 9;
		size = NandPart[1].size;

		ram_addr = boot_params.initrd_addr.val;
		ramdisk_sz = boot_params.initrd_len.val;

		for ( i = 0; size > 0 && ramdisk_sz > 0; )
		{
			if ( !( i & 0x1f ) )
			{
				if ( CheckBadBlk( i + StartPage ) )
				{
					Uart_Printf( "Skipped bad block at 0x%x\n" , i + StartPage );
					i += 32;
					size -= 32 << 9;
					continue;
				}
			}
			ReadPage( ( i + StartPage ) , ( U8 * ) ram_addr );
			i++;
			size -= 512;
			ram_addr += 512;
			ramdisk_sz -= 512;
		}
	}

	DsNandFlash();

	//ChangeClockDivider(13,12);
	//ChangeMPllValue(67,1,1);	//300MHz,2440A!
	//rCLKCON = 0x7fff0;
	call_linux( 0 , boot_params.machine.val , buf );
}

/************************************************************/
static void InitNandFlash( int info )
{
	U32 i;

	InitNandCfg();
	i = ReadChipId();
	if ( info )
		Uart_Printf( "Read chip id = %x\n" , i );	
	if ( ( i == 0x9873 ) || ( i == 0xec75 ) )
		NandAddr = 0;
	else if ( i == 0xec76 )
		NandAddr = 1;
	else
	{
		Uart_Printf( "Chip id error!!!\n" );
		return;
	}
	if ( info )
		Uart_Printf( "Nand flash status = %x\n" , ReadStatus() );
}

void NandErase( void )
{
	int i, err = 0;

	InitNandFlash( 1 );

	i = NandSelPart( "erase" );
	if ( i < 0 )
		return;	

	Uart_Printf( "Are you sure to erase nand flash from page 0x%x, block count 0x%x ? [y/n]\n" , StartPage , BlockCnt );
	while ( 1 )
	{
		char c;

		c = Uart_Getch();
		if ( ( c == 'y' ) || ( c == 'Y' ) )
			break;
		if ( ( c == 'n' ) || ( c == 'N' ) )
			return;
	}	

	for ( i = 0; BlockCnt; BlockCnt--, i += 32 )
	{
		if ( EraseBlock( i + StartPage ) )
		{
			err ++;
			Uart_Printf( "Press any key to continue...\n" );
			Uart_Getch();
		}
	}	

	DsNandFlash();		//disable nand flash interface
	Uart_Printf( "Erase Nand partition completed " );
	if ( err )
		Uart_Printf( "with %d bad block(s)\n" , err );
	else
		Uart_Printf( "success\n" );
}

void NandWrite( void )
{
	InitNandFlash( 1 );
	WrFileToNF();
	DsNandFlash();		//disable nand flash interface
}

void NandLoadRun( void )
{
	InitNandFlash( 1 );
	LoadRun();
}

/*
void TestNandFlash(void)
{		
	InitNandFlash();	
	
	while(1)
	{
		U8 key = '2';
		
		Uart_Printf("\nNand flash operations, press ESC to exit\n");
		Uart_Printf("1.Write nand flash with download file\n");
		Uart_Printf("2.Load progam from nand flash and run\n");
		Uart_Printf("3.Erase nand flash partition\n");
		Uart_Printf("4.Test nand flash erase, write, read\n");
	
		key = Uart_Getch();		
		
		if(key==0x1b)
			goto TestNandExit;
		else if(key=='1')
			WrFileToNF();
		else if(key=='2')
			LoadRun();
		else if(key=='3')
			NandErase();
		else if(key=='4')	
			TestFunc();
	}			
TestNandExit:	
	DsNandFlash();		//disable nand flash interface
}*/

int search_params( void )
{
	U32 page, page_cnt;
	U8 dat[528];
	BootParams* pBP = ( BootParams* ) dat;
	int ret = -1;

	InitNandFlash( 0 );	//don't show info in InitNandFlash!

	page = NandPart[0].offset >> 9;
	page_cnt = NandPart[0].size >> 9;

	//search from the last page	
	while ( page_cnt-- )
	{
		ReadPage( page + page_cnt , dat );
		if ( !strncmp( boot_params.start.flags , pBP->start.flags , 10 ) )
		{
			ret = 0;
			break;
		}
	}

	if ( !ret )
	{
		ParamItem* pPIS = &pBP-> start, * pPID = &boot_params.start;

		for ( ; pPID <= &boot_params.user_params; pPIS++, pPID++ )
			if ( !strncmp( pPID->flags , pPIS->flags , sizeof( pPID->flags ) ) )
				pPID->val = pPIS->val;
		strncpy( boot_params.string , pPIS->flags , boot_params.user_params.val + 1 );
		if ( boot_params.user_params.val != strlen( pPID->flags ) )
		{
			memset( boot_params.string , 0 , sizeof( boot_params.string ) );
			boot_params.user_params.val = 0;
		}
	}
	else
	{
		//Uart_Printf("Fail to find boot params! Use Default parameters.\n");
		//don't Uart_Printf anything before serial initialized!
	}

	DsNandFlash();

	return ret;
}

//保存在最后两个block,应确保程序(包括出现坏块时)不会覆盖到最后两块
int save_params( void )
{
	U32 page, page_cnt;
	U8 dat[528];

	InitNandFlash( 1 );

	memset( dat , 0 , sizeof( dat ) );
	memcpy( dat , &boot_params , sizeof( boot_params ) );

	page = ( NandPart[1].offset >> 9 ) - 64;

	for ( page_cnt = 0; page_cnt < 64; page_cnt++ )
	{
		if ( !( page_cnt % 32 ) )
			EraseBlock( page );
		if ( !WritePage( page + page_cnt , dat ) )
			break;
	}

	DsNandFlash();

	Uart_Printf( "Save boot params %s.\n" , ( page_cnt >= 64 ) ? "fail" : "success" );

	return page_cnt >= 64;
}

int set_params( void )
{
	int i, key, chg = 0;
	ParamItem* pPID;

	Uart_Printf( "\nConfig parameters\n" );

	do
	{
		pPID = &boot_params.start;
		for ( i = 0; pPID <= &boot_params.user_params; pPID++, i++ )
			Uart_Printf( "[%d] : %s%-8s is 0x%08x (%d)\n" , i , ( i > 9 ) ? "" : " ", pPID->flags, pPID->val, pPID->val );
		Uart_Printf( "[%d] : Exit\n" , i );
		if ( boot_params.user_params.val )
			Uart_Printf( "User parameters is : \"%s\"\n" , boot_params.string );

		Uart_Printf( "\nplease select item:" );
		key = Uart_GetIntNum();
		if ( key >= 0 && key < i )
		{
			chg = 1;
			Uart_Printf( "please enter value:" );
			i = key;
			if ( ( &boot_params.start + i ) == &boot_params.user_params )
			{
				//确保输入的字节数不超过127!
				char cmd[128];
				memset( cmd , 0 , sizeof( cmd ) );
				Uart_GetString( cmd );
				strncpy( boot_params.string , cmd , strlen( cmd ) + 1 );
				boot_params.user_params.val = strlen( cmd );
			}
			else
			{
				key = Uart_GetIntNum();
				( &boot_params.start + i )->val = key;
			}
		}
		else
			break;
	}
	while ( 1 );

	if ( chg )
	{
		Uart_Printf( "Do you want to save parameters? press y or Y for save.\n" );
		key = Uart_Getch();
		if ( key == 'y' || key == 'Y' )
			save_params();
	}

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -