www.pudn.com > s3c2442_firmware.rar > 2442loader-1208.c


/************************************************ 
 * NAME    : 2442loader.c 
 * DESC    :  
 * History : 2002.02.25 ver 0.0 
 * rev0.1  : 2003. 05.xx modified for 2442 
 * rev0.2  : 2004. 02.xx modified for 2442A(xtal 16.9344MHz) 
************************************************/ 
 
#include  
#include  
#include "def.h" 
#include "option.h" 
#include "2442addr.h" 
#include "2442slib.h" 
#include "Nand.h" 
//#include "mmu.h" 
 
// Downfile Size, OS Start Address Offset, Core voltage, download address setting 
#if 1 
#ifdef DOWNFILE_SIZE 
#define OS_IMAGE_BLOCK_SIZE ( ((DOWNFILE_SIZE/512)/32) +1 ) 
#else  
//#define OS_IMAGE_BLOCK_SIZE (0x7b0)	// blocks 
//#define OS_IMAGE_BLOCK_SIZE (0x800)	// blocks 
#define OS_IMAGE_BLOCK_SIZE (0x100)	// blocks 
#endif 
 
#ifndef OS_START_ADDR_OFFSET 
#define	OS_START_ADDR_OFFSET (0x00000000)		// 0x3020_0000 
#endif 
//PPC2003 offset	(0x02040000) 
//WINCE	offset		(0x00040000) 
//Firmware offset	(0x00000000) 
 
 
#ifndef	COREVOLT_M100 
#define	COREVOLT_M100	(130)	// value = voltage(0.8V ~ 1.3V)x100. -> 100->1.0V 
#endif 
 
#define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET) 
 
#else 
#define OS_IMAGE_BLOCK_SIZE (0x7b0)	// blocks 
#define	OS_START_ADDR_OFFSET (0x02040000)		// 0x3204_0000 
#define	COREVOLT_M100	(135)	// value = voltage(0.8V ~ 1.3V)x100. -> 100->1.0V 
#define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET) 
#endif 
 
void (*run)(void)=(void (*)(void))(DOWNLOAD_ADDRESS); 
 
void Port_Init(void); 
void Led_Display(int); 
void Delay(int); 
 
volatile unsigned char *downPt; 
 
void Timer4_Start(void); 
void Timer4_Stop(void); 
char *hex2char(int val); 
 
void Set_Pre(void);	// for current test 
 
 
void Main(void) 
{ 
    register page, block, blockcopy_count; 
    int i, j; 
 
    MMU_EnableICache(); 
	 
//   	ChangeClockDivider(12,12);	// 1:2:4 
//  	ChangeClockDivider(13,12);	// 1:3:6 
// 	ChangeClockDivider(14,12);	// 1:4:8 
//	ChangeMPllValue(88, 1, 1);	// FCLK=192MHz 
//	ChangeMPllValue(246, 13, 0); 	// FCLK=203.2MHz 
//	ChangeMPllValue(92, 1, 0); 	// FCLK=400MHz 
//	ChangeMPllValue(214, 3, 0);	// FCLK=532MHz 
 
 
    	Port_Init(); 
 
    	Uart_Init(PCLK, 115200); 
    	Uart_Select(1); 
	 
    	downPt=(unsigned char *)DOWNLOAD_ADDRESS; 
 
 	// GPA    22         21         20     19      18    17 
	//         nFCE   nRSTOUT  nFRE  nFWE  ALE  CLE 
    	rGPACON = (rGPACON &~(0x3f<<17)) | (0x3f<<17); 
	 
    	NF8_Init(); 
   
 
 
  	Max1718_Set(COREVOLT_M100);	// ex)120:1.2V 
 
  	Led_Display(1); 
 
	// To calculation copy time. 
     	Timer4_Start(); 
	 
    	block=0; 
    	blockcopy_count=0; 
    	while(blockcopy_count<(OS_IMAGE_BLOCK_SIZE)) {		 // Read OS image 
		block++; 
		if(!NF8_IsBadBlock(block))  continue;      // Skip bad block 
		blockcopy_count++; 
		for(page=0;page<32;page++) {  // Read 32 page 
			if(!NF8_ReadPage(block, page, (U8 *)downPt)) {  //(U32 block,U32 page,U32 *buffer) 
			 Led_Display(0x8);   // real ECC Error 
			 while(1); 
			} 
	  	downPt += 512;	 
             } 
	} 
   	 Led_Display(0xf); 
  
    	Timer4_Stop(); 
 
    	Set_Pre(); 
 
	//rCLKCON = (0x0<<16)|(0x6<<12)|(0x9<<8)|(0x2<<4);	// for test 
	//Uart_SendString(" Setting CLKCON]\n"); 
 
    	run(); 
	 
} 
 
 
#define TIMER_IINIT_VAL	(0xffff) 
 
void Timer4_Start(void) 
{ 
    Uart_SendString("\n\nNAND Boot Start\n"); 
     
    rTCFG0=0xff00;		// Prescaler 0xff+1(256) 
    rTCFG1=(0x3<<16);	//T4=PCLK period*256*16 =  
    rTCNTB4=TIMER_IINIT_VAL; 
    rTCON=(1<<22)|(1<<21);  //Manual update, to validate TCNTB4 value. 
    rTCON=(1<<22)|(1<<20);  //Start T4 
} 
 
void Timer4_Stop(void) 
{ 
    int cnt; 
	 
	rTCON=(1<<22)|(0<<20);  //Stop T4 
    cnt=TIMER_IINIT_VAL-rTCNTO4;	// actual count number 
 
    Uart_SendString("NAND Boot End\n"); 
    Uart_SendString("Boot time=nTCNT*82uS. nTCNT=0x"); 
    Uart_SendString(hex2char((cnt&0xf000)>>12)); 
    Uart_SendString(hex2char((cnt&0x0f00)>>8)); 
    Uart_SendString(hex2char((cnt&0x00f0)>>4)); 
    Uart_SendString(hex2char((cnt&0x000f)>>0)); 
	Uart_SendString(". \n"); 
	 
} 
 
 
char *hex2char(int val) 
{ 
    static char str[2]; 
	 
    str[1]='\0'; 
    if(val<=9)str[0]='0'+val; 
    else str[0]=('a'+val-10); 
	 
    return str; 
} 
 
void Set_Pre(void) 
{ 
 
	int i; 
 
	i = rGPDCON;  
 
	rGPDCON = (rGPFCON & ~(3<<4)) | (0<<4); 
	if((rGPFDAT&(1<<2))==0) {    // If EINT2 key is pressed. 
		Uart_SendString("I/O Strength Min\n"); 
		// Set I/O strength control. 
		rDSC0 = (0<<31)|(3<<8)|(3<<0); 
		// nEN_DSC  [31]    : 0:I/O drive strength enable, 1:Disable 
		// DSC_ADR  [9:8]   : Addr drive strength, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_DATA [7:0]   : DATA drive strength, 0:12mA, 1:10mA, 2:8mA, 3:6mA 
		 
		rDSC1 = (3<<28)|(3<<26)|(0xffffff<<0); 
		// DSC_SCK1 [29:28] : SCLK1, 0:16mA, 1:12mA, 2:8mA, 3:6mA  
		// DSC_SCK0 [27:26] : SCLK0, 0:16mA, 1:12mA, 2:8mA, 3:6mA  
		// DSC_SCKE [25:24] : SCLKE, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_SDR  [23:22] : nRAS/nCAS, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_NFC  [21:20] : Nand flash(nFCE,nFRE,nFWE,CLE,ALE), 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_BE   [19:18] : nBE[3:0], 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_WOE  [17:16] : nBE[3:0], 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS7  [15:14] : nGCS7, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS6  [13:12] : nGCS6, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS5  [11:10] : nGCS5, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS4  [9:8]   : nGCS4, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS3  [7:6]   : nGCS3, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS2  [5:4]   : nGCS2, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS1  [3:2]   : nGCS1, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
		// DSC_CS0  [1:0]   : nGCS0, 0:10mA, 1:8mA, 2:6mA, 3:4mA  
	} else { 
 
		Uart_SendString("I/O Strength Max\n"); 
		// Set I/O strength control. 
		rDSC0 = (0<<31)|(0<<8)|(0<<0); 
		rDSC1 = (0<<28)|(0<<26)|(0x000000<<0); 
	} 
	rGPDCON = i; 
}