📄 bootloader.c
字号:
/// @ingroup AMD_BOOTLOADER/// @file bootloader.c/// @brief Main file of bootloader.////// It copies Kernel from AMD Flash to SDRAM and jump to Kernel./// It includes some tool to program AMD Flash and debug./// /// @remarks Bootloader Size must be below 1M-16K\n/// linkscript is Init/link.lds\n/// init asm code is Init/startup.S/// @bug //<<<<<Include#include "Include/type.h"#include "Include/mx2.h"#include "Include/devnode.h"#include "Include/Tahiti_def.h"//>>>>>Include//<<<<<< Private Macro#define CMD_LINE_LEN 80#define DELAY_LOOP_COUNT 0x20000//>>>>>> Private Macro//<<<<<< Private Structuredevnode_t *pNode1, *pNode2;//>>>>>> Private Structure//<<<<<< Global Variablechar *pMemName, *pCmdNodeName, *pCmdLine, *pChar;const char memName[] = "DRAMM";const char cmdNodeName[] = "command line";unsigned char CharOut[50] = "This is Tahiti Uart Test\n";char cmdLine[CMD_LINE_LEN] = "rw root=/dev/mtdblock/2 load_ramdisk=0 prompt_ramdisk=0 noinitrd mem=48M";//#define _reg_PLL_PCDR (*((volatile unsigned long *)(IO_ADDRESS(0x21b020))))//>>>>>> Global Variable//<<<<<Private Function Declearationextern void EUARTinit(void);extern U8 EUARTdataReady(void);extern U8 EUARTgetData(void);extern void EUARTputData(U8);extern void EUARTputString(U8 *line);extern void MX21_InitInternalUART();void mx21_module_init();void mx21_gpio_init(); //Added Aug-17-04//>>>>>Private Function Declearation//<<<<<Body///The Main Functionint main(){ U32 *pSource, *pDestin, count; U8 countDown, bootOption; U32 delayCount; U32 fileSize, i,*p=(U32*)0xc0000000; char c; char *pCmdLine; char *pMem;#ifdef __PLL_CHOICE__ int mpll[3]; int MFI,MFN,MFD; unsigned long mpll_value,fout; unsigned long presc,bclkdiv,ipdiv,fref; int fout_trial; S32 deviation; U32 temp; int redundant = 0; //stat data char freq = '7';//default setting, mpll 266,fclk 266, bclk 88. #endif /*init is for CS1, burst flash*/ init(); MX21_UartSetting(); //config the GPIO and PLL setting for UART MX21_InitInternalUART(); // InitInternalUART mx21_gpio_init(); //Added Aug-17-04 EUARTputString("\n\ni.MX21 Linux Bootloader ver mx21_to3_rel_3.2\n"); EUARTputString("Copyright (C) 2005 Freescale Semiconductor Suzhou Ltd.\n\n"); EUARTputString((U8 *)cmdLine); EUARTputString("\n\n"); // EUARTputString("MPLL = 266, FCLK = 266, BCLK = 133\n"); // alternate boot-up options ? while (EUARTdataReady()) EUARTgetData(); // clear input buffer EUARTputString("Press any key for alternate boot-up options ... "); countDown = 2; bootOption = 0; while ((countDown) && (!bootOption)) { EUARTputString("\b\b"); // two back spaces EUARTputHex(countDown); delayCount = 0; do { delayCount++; if (EUARTdataReady()) bootOption = 1; } while ((delayCount < DELAY_LOOP_COUNT) && (!bootOption)); --countDown; } EUARTputString("\b\b"); // two back spaces EUARTputHex(countDown); EUARTputString("\n\n"); if (bootOption) { while (EUARTdataReady()) EUARTgetData(); // clear input buffer // print options EUARTputString("0. Program bootloader image\n"); EUARTputString("1. Program kernel image\n"); EUARTputString("2. Program root-disk image\n"); EUARTputString("3. Download kernel and boot from RAM\n"); EUARTputString("4. Download kernel and boot with ver 0.1.x bootloader format\n"); EUARTputString("5. Boot a ver0.1.x kernel\n"); EUARTputString("6. Boot with a different command line\n"); EUARTputString("7. Command Shell\n");#ifdef __PLL_CHOICE__ EUARTputString("8. Booting with different fclk/bclk \n");#endif EUARTputString("\n Please enter selection -> "); do { while (!EUARTdataReady()); // wait for key press bootOption = EUARTgetData(); if (bootOption >= 0x20) { EUARTputData('\b'); EUARTputData(bootOption); } } while ((bootOption < '0') || (bootOption > '8')); EUARTputString("\n\n"); // process boot option if ((bootOption >= '0') && (bootOption <= '4')) { fileSize = usbrx(); EUARTputData('\n'); } if ((bootOption >= '0') && (bootOption <= '2')) // i.e. flash programming { switch (bootOption) {#if 0 case '0': // i.e. program bootloader progFlash(0x0B006E00, 0x0C000000, fileSize); break; case '1': // i.e. program kernel image progFlash(0x0B006E00, 0x0C100000, fileSize); break; case '2': // i.e. program root-disk progFlash(0x0B006E00, 0x0C300000, fileSize);#else //MX2#define USB_DISK_START (0xc2000000)#define BIN_START_IN_SDRAM (USB_DISK_START +0x9A00) case '0': // i.e. program bootloader progFlash(BIN_START_IN_SDRAM, 0xc8000000, fileSize); break; case '1': // i.e. program kernel image progFlash(BIN_START_IN_SDRAM, 0xc8100000, fileSize); break; case '2': // i.e. program root-disk progFlash(BIN_START_IN_SDRAM, 0xc8300000, fileSize);#endif } EUARTputString("\nPress RESET button on ADS board ..."); while (1); // infinite loop } } if (bootOption == '6') // i.e. boot with a different command line { EUARTputString("New command line: "); i = 0; do { while (!EUARTdataReady()); // wait for key press c = EUARTgetData(); if (c != '\r') { if (c == '\b') { if (i > 0) { // erase the character EUARTputData('\b'); EUARTputData(' '); EUARTputData('\b'); --i; } } else { EUARTputData(c); cmdLine[i++] = c; } } } while ((c != '\r') && (i < CMD_LINE_LEN-1)); if (i > 0) cmdLine[i] = 0; // mark end of string EUARTputData('\n'); } if (bootOption == '7') // i.e.read/write command { while(1) { EUARTputString(">: "); i = 0; do { while (!EUARTdataReady()); // wait for key press c = EUARTgetData(); if (c != '\r') { if (c == '\b') { if (i > 0) { // erase the character EUARTputData('\b'); EUARTputData(' '); EUARTputData('\b'); --i; } } else { EUARTputData(c); cmdLine[i++] = c; } } } while ((c != '\r') && (i < CMD_LINE_LEN-1)); if (i > 0) cmdLine[i] = 0; // mark end of string //command_parase(); EUARTputData('\n'); } }#ifdef __PLL_CHOICE__ if(bootOption == '8') { //now it is mpll266,presc 0, bclkdiv 2,ipdiv 1. //get input mpll EUARTputString("Please enter your settings mpll(MHz)... \n "); i = 0; do { while (!EUARTdataReady()); // wait for key press c = EUARTgetData(); if (c != '\r') { EUARTputData(c); c = c - '0'; mpll[i++] = c; } } while ((c != '\r') && (i<3)); mpll_value = mpll[0]*100 + (mpll[1])*10 + mpll[2]; EUARTputString("\n"); //get input presc value #if 0 EUARTputString("Please enter your settings PRESC(0~3)... \n ");#else//Changed for TO2 EUARTputString("Please enter your settings PRESC(0~7)... \n ");#endif while (!EUARTdataReady()); // wait for key press c = EUARTgetData(); if (c != '\r') { EUARTputData(c); c = c - '0'; presc = c; } EUARTputString("\n"); //get input bclkdiv value EUARTputString("Please enter your settings BCLKDIV(00~15)... \n "); i = 0; do { while (!EUARTdataReady()); // wait for key press c = EUARTgetData(); if (c != '\r') { EUARTputData(c); c = c - '0'; mpll[i++] = c; } } while ((c != '\r') && (i <2)); bclkdiv = mpll[0]*10+mpll[1]; EUARTputString("\n"); //get input ipdiv value EUARTputString("Please enter your settings ipdiv(0~1)... \n "); while (!EUARTdataReady()); // wait for key press c = EUARTgetData(); if (c != '\r') { EUARTputData(c); c = c - '0'; ipdiv = c; } *(VP_U32)CRM_MPCTL0 = mpll_value | (presc<<10) | (bclkdiv<<16) | (ipdiv<<26); EUARTputString("\n"); }#endif if ((bootOption == '3') || (bootOption == '4')) { // i.e. download kernel and run // copy kernel from 0xc8100000 to 0xc0008000 EUARTputString("Copying Kernel from USB disk to RAM...\n"); count = fileSize; pSource = (U32 *)0xc2006e00; pDestin = (U32 *)0xc0008000; do { *(pDestin++) = *(pSource++); count -= 4; } while (count > 0); } else // i.e. kernel image is in FLASH { // copy kernel from FLASH to RAM EUARTputString("Copying kernel from Flash to RAM ...\n"); count = 0x200000; // 2 Mbytes pSource = (U32 *)0xc8100000; pDestin = (U32 *)0xc0008000; do { *(pDestin++) = *(pSource++); count -= 4; } while(count!=0); } EUARTputString("Booting kernel ...\n\n"); if ((bootOption == '4') || (bootOption == '5')) // boot a ver0.1.x kernel { // prepare devnodes // Parameters passed to kernel must reside in the memory range // of 0x08000000 to 0x083FFFFF (kernel will map to this 4M of // memory during startup with proper MMU setting). // We should be very careful of not to put parameters in those // locations occupied by the kernel itself. So we'll use the // last 4K only. pNode1 = (devnode_t *) 0x083FF000; pNode2 = (devnode_t *) 0x083FF100; pMemName = (char *) 0x083FF200; pChar = (char *)&memName; do { } while ((*(pMemName++) = *(pChar++)) != 0); pMemName = (char *) 0x083FF200; pCmdNodeName = (char *) 0x083FF300; pChar = (char *)&cmdNodeName; do { } while ((*(pCmdNodeName++) = *(pChar++)) != 0); pCmdNodeName = (char *) 0x083FF300; pCmdLine = (char *) 0x083FF400; pChar = (char *)&cmdLine; do { } while ((*(pCmdLine++) = *(pChar++)) != 0); pCmdLine = (char *) 0x083FF400; pNode1->next = (devnode_t *)0; pNode1->type = (DEVNODE_DEVICE << 16) | DEVNODE_DEVICE_MEMORY; pNode1->params[0] = 0; pNode1->params[1] = MEM_SIZE; pNode1->name = pMemName; pNode1->data = (void *)0; pNode1->size = 0; pNode2->next = pNode1; pNode2->type = (DEVNODE_OS << 16) | DEVNODE_OS_COMMAND_LINE; pNode2->params[0] = 0; pNode2->params[1] = 0; pNode2->name = pCmdNodeName; pNode2->data = pCmdLine; pNode2->size = 23; mx21_module_init(); JumpToKernel0x((void *)0xc0008000, 0, 17, pNode2) ; } // the command line is passed through the last 4K of the 3M memory allocated to the kernel // this 3M memory block will be mapped to the kernel space during kernel startup pMem = (char *)0xc03FF000; pCmdLine = (char *)&cmdLine; while ((*(pMem++)=*(pCmdLine++)) != 0); mx21_module_init(); JumpToKernel((void *)0xc0008000, 0xc03FF000) ; return (0);}/* * Added Aug-17-04 * Config GPIO to save power in Sleep mode. */void mx21_gpio_init(){ //Enable *( (volatile U32 *)CRM_PCCR0 ) |= 0x800; //Set GPIO C, E as GPIO function, output *((volatile U32 *)GPIOC_GIUS) = 0xffffffe0; //This is the default value *((volatile U32 *)GPIOC_DDIR) = 0xffffffe0; //Output port *((volatile U32 *)GPIOC_OCR1) = 0xfffffc00; *((volatile U32 *)GPIOC_OCR2) = 0x00fc0f20; *((volatile U32 *)GPIOE_GIUS) = 0x00fc0f20; //This is the default value *((volatile U32 *)GPIOE_DDIR) = 0x00000020; //Set PE5(PWMO) as output *((volatile U32 *)GPIOE_OCR1) |= 0xc00; //Select data register as output for PWMO}void mx21_module_init(){ // enable it to let all the registers be accessed in user mode. *( (volatile U32 *)AIPI1_PAR ) = 0; *( (volatile U32 *)AIPI2_PAR ) = 0;//comment #################//comment # AHB-Lite IP Interface//setmem 0x10000000 0x00040304 32 *( (volatile U32 *)AIPI1_PSR0 ) = 0x00040304;//setmem 0x10020000 0x00000000 32 *( (volatile U32 *)AIPI2_PSR0 ) = 0;//setmem 0x10000004 0xFFFBFCFB 32 *( (volatile U32 *)AIPI1_PSR1 ) = 0xFFFBFCFB;//setmem 0x10020004 0xFFFFFFFF 32 *( (volatile U32 *)AIPI2_PSR1 ) = 0xFFFFFFFF;//comment # Config MUX for pin PF18->CS1//comment # Clear PTF_GIUSE //setmem 0x10015520 0x00000000 32 *( (volatile U32 *)GPIOF_GIUS ) = 0;//comment # Clear PTF_GPR//setmem 0x10015538 0x00000000 32 *( (volatile U32 *)GPIOF_GPR ) = 0; //comment # FMCR Register//comment # Select CS3/CSD0 Pin as CS3 only.//setmem 0x10027814 0xFFFFFFC9 32 *( (volatile U32 *)SYS_FMCR ) = 0xFFFFFFC9;//comment ### PCCR0 (Disable LCDC)//setmem 0x1002701C 0x35084003 32 *( (volatile U32 *)CRM_PCCR0 ) = 0x35084003; //comment ### Master Priority Register for Slave Port 3//setmem 0x1003F300 0x00123456 32// *( (volatile U32 *)0x1003F300 ) = 0x00123456; // Keep LCDC as the highest priority *( (volatile U32 *)SYS_PSCR ) = 0; *( (volatile U32 *)MAX_SLV3_MPR3 ) = 0x00123056; *( (volatile U32 *)MAX_SLV3_SGPCR3 ) = 0; //add for SLCDC// *( (volatile U32 *)0x1003F310 ) |= 0x00040000; //end/* 2comment ########################################################comment # CSD0 Initialization comment # 16Mx16x2 IAM=0 CSD0 CL3 comment ########################################################comment *** Set Precharge Commandsetmem 0xDF000000 0x92120300 32comment *** Issue Precharge all Commandmemory 0xC0200000 +1 32 comment *** Set AutoRefresh Commandsetmem 0xDF000000 0xA2120300 32 comment *** Issue AutoRefresh Commandmemory 0xC0000000 +1 32 memory 0xC0000000 +1 32memory 0xC0000000 +1 32memory 0xC0000000 +1 32memory 0xC0000000 +1 32 memory 0xC0000000 +1 32memory 0xC0000000 +1 32memory 0xC0000000 +1 32comment *** Set Mode Registersetmem 0xDF000000 0xB2120300 32comment *** Issue Mode Register Commandcomment Burst Length = 8memory 0xC0119800 +1 32 comment *** Set to Normal Modecomment # From the spec of the SDRAM K4S56163LC-RG75000, comment # 1. tRCD = 19ns minimum -> RCD = 3 clk (SDCLK=133MHz) -> SRCD = 11b comment # 2. tRP = 19ns minimum -> RP = 3 clk (SDCLK=133MHz) -> SRP = 0b comment # 3. tRC = 65ns minimum -> RC = 9 clk (SDCLK=133MHz) -> SRC = 1001b comment # 4. refresh rate = 8192rows/64ms -> SREFR = 11bsetmem 0xDF000000 0x8212F339 32 comment ### End of Memory Configuration ########################################## 2*///comment # ena emma//setmem 0x1002701C 0x3d0Cc003 32 *( (volatile U32 *)CRM_PCCR0 ) = 0x3d0Cc003; //comment # enable user mode CSI access//setmem 0x10027818 0x6000e 32 *( (volatile U32 *)SYS_GPCR ) = 0x6000e; //Just for test//*( ( volatile unsigned int *)0xe4021030 ) = 0x800f000f;//*( (volatile unsigned int *)0xe403f200 ) = 0x543012;//*( (volatile unsigned int *)0xe403fd00 ) = 1;//*( (volatile unsigned int *)0xe403f800 ) = 1;//*( (volatile unsigned int *)0xe403f900 ) = 1;}//>>>>>Body
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -