bootmain.c

来自「s3c2440 bootloader适用于S3C2440开发板」· C语言 代码 · 共 1,058 行 · 第 1/2 页

C
1,058
字号
	/*******************************/
	/*	Test program download	*/
	/*******************************/
	j=0;

	if(isUsbdSetConfiguration==0)
	{
		Uart_Printf("USB host is not connected yet.\n");
	}

	while(downloadFileSize==0)
	{
		if(first==1 && isUsbdSetConfiguration!=0)
		{
			Uart_Printf("USB host is connected. Waiting a download.\n");
			first=0;
		}

		if(j%0x50000==0)Led_Display(0x6);
		if(j%0x50000==0x28000)Led_Display(0x9);
		j++;

		key = Uart_GetKey();
		
		if(autorun_trig)
			NandLoadRun();	                 //run it in svc mode
		if(key!=0)
		{
			autorun_ds = 1;
			Menu();
			first = 1;                       //To display the message,"USB host ...."
	       									 //在串口下载返回后downloadFileSize不为0,因此不能再执行USB下载! 
		}
	}
	
	autorun_ds = 1;
	
	Timer_InitEx();	  
	Timer_StartEx();  

#if USBDMA	

	rINTMSK&=~(BIT_DMA2);  

	ClearEp3OutPktReady(); 
	// indicate the first packit is processed.
	// has been delayed for DMA2 cofiguration.

	if(downloadFileSize>EP3_PKT_SIZE)
	{
		if(downloadFileSize<=(0x80000))
		{
	  		ConfigEp3DmaMode(downloadAddress+EP3_PKT_SIZE-8,downloadFileSize-EP3_PKT_SIZE);
		}
	  	else
	  	{
	  		ConfigEp3DmaMode(downloadAddress+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);
	  		//2440比2410的DIDSTCx寄存器多了中断产生条件的控制位,USB的DMA传输为字节计数
	  		//防止高频开cache运行时下载大于0x80000字节文件时IsrDma2出错!!! hzh
	  		//while((rDSTAT2&0xfffff)==(0x80000-EP3_PKT_SIZE));
	  		while(!(rDSTAT2&(1<<20)));	//防止DMA传输尚未开始就写入下一次重装值!!! hzh
			if(downloadFileSize>(0x80000*2))//for 1st autoreload
			{
				rDIDST2=(downloadAddress+0x80000-8);  //for 1st autoreload.
			    rDIDSTC2=(1<<2)|(0<<1)|(0<<0);  
				rDCON2=rDCON2&~(0xfffff)|(0x80000);			  

		  		while(rEP3_DMA_TTC<0xfffff)
		  		{
		  			rEP3_DMA_TTC_L=0xff; 
		  			rEP3_DMA_TTC_M=0xff;
		  			rEP3_DMA_TTC_H=0xf;
		  		}
			}	
	 		else
	 		{
	 			rDIDST2=(downloadAddress+0x80000-8);  //for 1st autoreload.
		  			rDIDSTC2=(1<<2)|(0<<1)|(0<<0);  
	 			rDCON2=rDCON2&~(0xfffff)|(downloadFileSize-0x80000); 		

		  		while(rEP3_DMA_TTC<0xfffff)
		  		{
		  			rEP3_DMA_TTC_L=0xff; 
		  			rEP3_DMA_TTC_M=0xff;
		  			rEP3_DMA_TTC_H=0xf;
		  		}
			}
		}
 		totalDmaCount = 0;
	}
	else
	{
		totalDmaCount = downloadFileSize;
	}
#endif

	Uart_Printf("\nNow, Downloading [ADDRESS:%xh,TOTAL:%d]\n",
			downloadAddress,downloadFileSize);
	Uart_Printf("RECEIVED FILE SIZE:%8d",0);
   
#if USBDMA	
	j=0x10000;

	while(1)
	{
		if( (rDCDST2-(U32)downloadAddress+8)>=j)
		{
			Uart_Printf("\b\b\b\b\b\b\b\b%8d",j);
	   		j+=0x10000;
		}
		if(totalDmaCount>=downloadFileSize)break;
	}

#else
	j=0x10000;

	while(((U32)downPt-downloadAddress)<(downloadFileSize-8))
	{
	if( ((U32)downPt-downloadAddress)>=j)
	{
		Uart_Printf("\b\b\b\b\b\b\b\b%8d",j);
   		j+=0x10000;
	}
	}
#endif

	time=Timer_StopEx();
	
	Uart_Printf("\b\b\b\b\b\b\b\b%8d",downloadFileSize);	
	Uart_Printf("\n(%5.1fKB/S,%3.1fS)\n",(float)(downloadFileSize/time/1000.),time);
	
#if USBDMA	
	/*******************************/
	/*	 Verify check sum		*/
	/*******************************/

	Uart_Printf("Now, Checksum calculation\n");

	cs=0;	
	i=(downloadAddress);
	j=(downloadAddress+downloadFileSize-10)&0xfffffffc;
	while(i<j)
	{
		temp=*((U32 *)i);
		i+=4;
		cs+=(U16)(temp&0xff);
		cs+=(U16)((temp&0xff00)>>8);
		cs+=(U16)((temp&0xff0000)>>16);
		cs+=(U16)((temp&0xff000000)>>24);
	}

	i=(downloadAddress+downloadFileSize-10)&0xfffffffc;
	j=(downloadAddress+downloadFileSize-10);
	while(i<j)
	{
  		cs+=*((U8 *)i++);
	}
	
	checkSum=cs;
#else
	//checkSum was calculated including dnCS. So, dnCS should be subtracted.
	checkSum=checkSum - *((unsigned char *)(downloadAddress+downloadFileSize-8-2))
		 - *( (unsigned char *)(downloadAddress+downloadFileSize-8-1) );	
#endif	  

	dnCS=*((unsigned char *)(downloadAddress+downloadFileSize-8-2))+
	(*( (unsigned char *)(downloadAddress+downloadFileSize-8-1) )<<8);

	if(checkSum!=dnCS)
	{
		Uart_Printf("Checksum Error!!! MEM:%x DN:%x\n",checkSum,dnCS);
		return;
	}

	Uart_Printf("Download O.K.\n\n");

	{
		U32 launch;
		
		if(!RelocateNKBIN(downloadAddress, (U32 *)&downloadAddress, (U32 *)&downloadFileSize, &launch)) {
			boot_params.run_addr.val    = launch;
			boot_params.initrd_addr.val = downloadAddress;
			boot_params.initrd_len.val  = downloadFileSize;
			

			if(download_run == 0){   // 如果是 auto_nk 保存参数
			    Uart_Printf("\nSave_params Now, boot_params.run_addr.val:%xh,boot_params.initrd_addr.val:%xh,boot_params.initrd_len.val:%xh,\n",
				launch,downloadAddress,downloadFileSize);
				
				save_params();       // 保存参数
			}/* else {                 // 如果是下载了 NK.bin返回主界面
			   Uart_Printf("Please Choose NK.nb0 to Donw&&Run!..........\n");
			   download_run     = 0;
			   downloadFileSize = 0;
			   return;
			}*/		                 
		}
		
		if(boot_params.start.val < 2){
			if(*(U32*)(downloadAddress+0x24) == 0x16f2818){	//kernel
				boot_params.run_addr.val = 0x30008000;
				//printf("magic=0x%x\n", (*(U32*)(downloadAddress+0x24)));
				boot_params.initrd_len.val  = downloadFileSize;
				save_params();
//				Uart_Printf("boot_params.run_addr.val=%x!\n", boot_params.run_addr.val);
				}
			else	//jffs2_root-fs
				jffs2 = 1;
		}
			
		if(auto_nk==1 && downloadFileSize)
			NandWrite();
	}
	
	if(download_run==1)              // 如果是下载运行。
	{
		rINTMSK=BIT_ALLMSK;
    	call_os(0, 0, DOWN_RUN_ADDR);	        //或不用上面3个函数而直接使用call_os
	}
}




void Isr_Init(void)
{
	pISR_UNDEF  = (unsigned)HaltUndef;
	pISR_SWI    = (unsigned)HaltSwi;
	pISR_PABORT = (unsigned)HaltPabort;
	pISR_DABORT = (unsigned)HaltDabort;
	rINTMOD     = 0x0;	                     // All=IRQ mode
	rINTMSK     = BIT_ALLMSK;	             // All interrupt is masked.

#if 1
	pISR_USBD = (unsigned)IsrUsbd;
	pISR_DMA2 = (unsigned)IsrDma2;
#else
	pISR_IRQ  = (unsigned)IsrUsbd;	
	//Why doesn't it receive the big file if use this. (???)
	//It always stops when 327680 bytes are received.
#endif	
	ClearPending(BIT_DMA2);
	ClearPending(BIT_USBD);
	//pISR_FIQ,pISR_IRQ must be initialized
}


void HaltUndef(void)
{
	Uart_Printf("Undefined instruction exception!!!\n");
	while(1);
}

void HaltSwi(void)
{
	Uart_Printf("SWI exception!!!\n");
	while(1);
}

void HaltPabort(void)
{
	Uart_Printf("Pabort exception!!!\n");
	while(1);
}

void HaltDabort(void)
{
	Uart_Printf("Dabort exception!!!\n");
	while(1);
}


void ClearMemory(void)
{
	int memError=0;
	U32 *pt;
	
	//
	// memory clear
	//
	Uart_Printf("Clear Memory (%xh-%xh):WR",_RAM_STARTADDRESS,HEAPEND);

	pt=(U32 *)_RAM_STARTADDRESS;
	while((U32)pt < HEAPEND)
	{
		*pt=(U32)0x0;
		pt++;
	}
	
	if(memError==0)Uart_Printf("\b\bO.K.\n");
}

void Clk0_Enable(int clock_sel)	
{	// 0:MPLLin, 1:UPLL, 2:FCLK, 3:HCLK, 4:PCLK, 5:DCLK0
	rMISCCR = rMISCCR&~(7<<4) | (clock_sel<<4);
	rGPHCON = rGPHCON&~(3<<18) | (2<<18);
}
void Clk1_Enable(int clock_sel)
{	// 0:MPLLout, 1:UPLL, 2:RTC, 3:HCLK, 4:PCLK, 5:DCLK1	
	rMISCCR = rMISCCR&~(7<<8) | (clock_sel<<8);
	rGPHCON = rGPHCON&~(3<<20) | (2<<20);
}
void Clk0_Disable(void)
{
	rGPHCON = rGPHCON&~(3<<18);	// GPH9 Input
}
void Clk1_Disable(void)
{
	rGPHCON = rGPHCON&~(3<<20);	// GPH10 Input
}

/*
static U8 dm9000_ior(int reg)
{
	*(volatile U8 *)DM9000_BASE = reg;
	return *(volatile U8 *)(DM9000_BASE+DM9000_DATA_OFFSET);
}

static void rd_dm9000_id(void)
{
	U16 id;
	
	id = dm9000_ior(0x28) | (dm9000_ior(0x29)<<8);
	printf("read dm9000 vid = 0x%x\n", id);
	
	id = dm9000_ior(0x2a) | (dm9000_ior(0x2b)<<8);
	printf("read dm9000 pid = 0x%x\n", id);
	
	id = dm9000_ior(0x8) | (dm9000_ior(0x9)<<8);
	printf("read dm9000 reg(0x09,0x08) = 0x%x\n", id);
	
	printf("dm9000 isr = 0x%x\n", dm9000_ior(0xfe));
}

static void buzzer(int freq, int ms)
{
	rGPBCON &= ~3;			//set GPB0 as tout0, pwm output
	rGPBCON |= 2;
		
	rTCFG0 &= ~0xff;
	rTCFG0 |= 15;			//prescaler = 15+1
	rTCFG1 &= ~0xf;
	rTCFG1 |= 2;			//mux = 1/8
	rTCNTB0 = (PCLK>>7)/freq;
	rTCMPB0 = rTCNTB0>>1;	// 50%
	rTCON &= ~0x1f;
	rTCON |= 0xb;			//disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
	rTCON &= ~2;			//clear manual update bit
	
	mdelay(ms);
	
	
	rGPBCON &= ~3;			//set GPB0 as output
	rGPBCON |= 1;
	rGPBDAT &= ~1;
}
*/


/*
//关闭所有IO口控制的电源,将不用的IO口设置为输入并禁止上拉
static void ConfigPowerOffGPIO(void)
{
	 //CAUTION:Follow the configuration order for setting the ports. 
    // 1) setting value(GPnDAT) 
    // 2) setting control register  (GPnCON)
    // 3) configure pull-up resistor(GPnUP)  

    //32bit data bus configuration  
    // PORT A GROUP
    //Ports  : GPA22 GPA21  GPA20 GPA19 GPA18 GPA17 GPA16 GPA15 GPA14 GPA13 GPA12  
    //Signal : nFCE nRSTOUT nFRE   nFWE  ALE   CLE  nGCS5 nGCS4 nGCS3 nGCS2 nGCS1 
    //Binary :  1     0      1  , 1   1   1    1   ,  1     1     1     1
    //Ports  : GPA11   GPA10  GPA9   GPA8   GPA7   GPA6   GPA5   GPA4   GPA3   GPA2   GPA1  GPA0
    //Signal : ADDR26 ADDR25 ADDR24 ADDR23 ADDR22 ADDR21 ADDR20 ADDR19 ADDR18 ADDR17 ADDR16 ADDR0 
    //Binary :  1       1      1      1   , 1       1      1      1   ,  1       1     1      0
    rGPACON = 0x7fffff;

    // PORT B GROUP
    //Ports  : GPB10    GPB9    GPB8    GPB7    GPB6     GPB5    GPB4   GPB3   GPB2     GPB1      GPB0
    //Signal : nXDREQ0 nXDACK0 nXDREQ1 nXDACK1 nSS_KBD nDIS_OFF L3CLOCK L3DATA L3MODE nIrDATXDEN Keyboard
    //Setting: INPUT  OUTPUT   INPUT  OUTPUT   INPUT   OUTPUT   OUTPUT OUTPUT OUTPUT   OUTPUT    OUTPUT 
    //Binary :   00  ,  01       00  ,   01      00   ,  01       01  ,   01     01   ,  01        01  
    rGPBCON = 0x0;
    rGPBUP  = 0x7ff;     // The pull up function is disabled GPB[10:0]

    // PORT C GROUP
    //Ports  : GPC15 GPC14 GPC13 GPC12 GPC11 GPC10 GPC9 GPC8  GPC7   GPC6   GPC5 GPC4 GPC3  GPC2  GPC1 GPC0
    //Signal : VD7   VD6   VD5   VD4   VD3   VD2   VD1  VD0 LCDVF2 LCDVF1 LCDVF0 VM VFRAME VLINE VCLK LEND  
    //Binary :  10   10  , 10    10  , 10    10  , 10   10  , 10     10  ,  10   10 , 10     10 , 10   10
    rGPCCON = 0x0;
    rGPCUP  = 0xffff;     // The pull up function is disabled GPC[15:0] 

    // PORT D GROUP
    //Ports  : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0
    //Signal : VD23  VD22  VD21  VD20  VD19  VD18  VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9  VD8
    //Binary : 10    10  , 10    10  , 10    10  , 10   10 , 10   10 , 10   10 , 10   10 ,10   10
    rGPDCON = 0x0;
    rGPDUP  = 0xffff;     // The pull up function is disabled GPD[15:0]

    // PORT E GROUP
    //Ports  : GPE15  GPE14 GPE13   GPE12   GPE11   GPE10   GPE9    GPE8     GPE7  GPE6  GPE5   GPE4  
    //Signal : IICSDA IICSCL SPICLK SPIMOSI SPIMISO SDDATA3 SDDATA2 SDDATA1 SDDATA0 SDCMD SDCLK I2SSDO 
    //Binary :  10     10  ,  10      10  ,  10      10   ,  10      10   ,   10    10  , 10     10  ,     
    //-------------------------------------------------------------------------------------------------------
    //Ports  :  GPE3   GPE2  GPE1    GPE0    
    //Signal : I2SSDI CDCLK I2SSCLK I2SLRCK     
    //Binary :  10     10  ,  10      10 
    rGPECON = 0x0;
    rGPEUP  = 0xffff;     // The pull up function is disabled GPE[15:0]

    // PORT F GROUP
    //Ports  : GPF7   GPF6   GPF5   GPF4      GPF3     GPF2  GPF1   GPF0
    //Signal : nLED_8 nLED_4 nLED_2 nLED_1 nIRQ_PCMCIA EINT2 KBDINT EINT0
    //Setting: Output Output Output Output    EINT3    EINT2 EINT1  EINT0
    //Binary :  01      01 ,  01     01  ,     10       10  , 10     10
    rGPFCON = 0x0;
    rGPFUP  = 0xff;     // The pull up function is disabled GPF[7:0]

    // PORT G GROUP
    //Ports  : GPG15 GPG14 GPG13 GPG12 GPG11    GPG10    GPG9     GPG8     GPG7      GPG6    
    //Signal : nYPON  YMON nXPON XMON  EINT19 DMAMODE1 DMAMODE0 DMASTART KBDSPICLK KBDSPIMOSI
    //Setting: nYPON  YMON nXPON XMON  EINT19  Output   Output   Output   SPICLK1    SPIMOSI1
    //Binary :   11    11 , 11    11  , 10      01    ,   01       01   ,    11         11
    //-----------------------------------------------------------------------------------------
    //Ports  :    GPG5       GPG4    GPG3    GPG2    GPG1    GPG0    
    //Signal : KBDSPIMISO LCD_PWREN EINT11 nSS_SPI IRQ_LAN IRQ_PCMCIA
    //Setting:  SPIMISO1  LCD_PWRDN EINT11   nSS0   EINT9    EINT8
    //Binary :     11         11   ,  10      11  ,  10        10
    rGPGCON = 0x0;
    rGPGUP  = 0xffff;    // The pull up function is disabled GPG[15:0]

    // PORT H GROUP
    //Ports  :  GPH10    GPH9  GPH8 GPH7  GPH6  GPH5 GPH4 GPH3 GPH2 GPH1  GPH0 
    //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
    //Binary :   10   ,  10     10 , 11    11  , 10   10 , 10   10 , 10    10
    rGPHCON = 0x0;
    rGPHUP  = 0x7ff;    // The pull up function is disabled GPH[10:0]	
	//PORT J GROUP
	//Ports	:  GPJ12    GPJ11     GPJ10	  GPJ9  GPJ8      GPJ7	GPJ6  GPJ5	GPJ4  GPJ3  GPJ2  GPJ1  GPJ0
	//Signal : CAMRESET CAMCLKOUT CAMHREF CAMVS CAMPCLKIN CAMD7 CAMD6 CAMD5 CAMD4 CAMD3 CAMD2 CAMD1 CAMD0
	//Setting: Out      Out       Out     Out   Out       Out   Out   Out   Out   Out   Out   Out   Out
	//Binary : 01	    01        01      01    01        01    01    01    01    01    01    01    01
	rGPJCON = 0x0;
    rGPJUP  = 0x1fff;    // The pull up function is disabled GPJ[12:0]	
//	LcdBackLightOff();
}

static void EnterPowerOff(void)
{
	U32 r;
	
	Uart_TxEmpty(0);	//Wait until UART0 Tx buffer empty.

	ConfigPowerOffGPIO();
	
    rEINTPEND = 1<<11;					//clear EINT11
	rEXTINT1  = 0;						//EINT11 low-level interrupt
    rEINTMASK = rEINTMASK&~(1<<11); 	//SRCPND:EINT8_23 will be set by EINT19 after wake-up.
	ClearPending(BIT_EINT8_23|BIT_RTC);
	rINTMSK = BIT_ALLMSK;

	rRTCCON = 0x0;		//R/W disable, 1/32768, Normal(merge), No reset
	rADCCON |= (1<<2);	//ADC additional power down

	rGSTATUS3 = (U32)StartPointAfterSleepWakeUp;
	rGSTATUS4 = 0xbe50dead;
	
	//MISCCR[13:12] set usb port0,1 suspend
	//MISCCR[2] Previous state at STOP(?) mode (???)
	//MISCCR[1:0] D0~D31 pull-up disable	
	rMISCCR |= 0x3007;

	rLCDCON1 &= ~1;		//Before entering STOP mode, LCD must be off
	
	//=================================================================
	//  VERY IMPORTANT NOTE 
	//  To enter STOP/SLIDLE mode, MMU TLB-fill operation should be prohibited
	//  because MTT table is in SDRAM and SDRAM is in the self-refresh mode.
	//  So, we will fill TLB before entering SDRAM self-refresh 
	//  instead of disabling MMU.
	r = rREFRESH;	//To fill TLB for the special register used in EnterPWDN
	r = rCLKCON;
    //=================================================================
    	
	//EnterPWDN(0x7fff8);	//POWER_OFF mode
	rCLKCON = 0x7fff8;		//needn't set sdram sel-refresh, directly power-down
	//Never return here.
}
*/


/*
static __irq void autorun_proc(void)
{
	ClearPending(BIT_TIMER4);

	if(autorun_ds)
		DisableIrq(BIT_TIMER4);
	
	autorun_10ms--;
	if(!autorun_10ms) {
		DisableIrq(BIT_TIMER4);
		//CLR_IF();	//in irq service routine, irq is disabled
		autorun_trig = 1;
		//NandLoadRun();
	}
}

static void init_autorun_timer(int sec)
{
	U32 val = (PCLK>>4)/100-1;
	
	autorun_10ms = sec*100;
	
	pISR_TIMER4 = (U32)autorun_proc;
	
	rTCFG0 &= ~(0xff<<8);
	rTCFG0 |= 3<<8;			//prescaler = 3+1
	rTCFG1 &= ~(0xf<<16);
	rTCFG1 |= 1<<16;		//mux = 1/4

	rTCNTB4 = val;
	rTCON &= ~(0xf<<20);
	rTCON |= 7<<20;			//interval, inv-off, update TCNTB4&TCMPB4, start timer 4
	rTCON &= ~(2<<20);		//clear manual update bit
	EnableIrq(BIT_TIMER4);
}
*/

⌨️ 快捷键说明

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