📄 usb_boot.c
字号:
/*********************************************************************************************
* File: u241mon.c
* Author: Embest
* Desc: u241mon entry point,menu,download
* History:
* Y.J.Guo, April 28, 2005
* Modifying and reusing of S3C2410X u24xmon
*********************************************************************************************/
#include "usb_boot.h"
/*------------------------------------------------------------------------------------------*/
/* global variablese */
/*------------------------------------------------------------------------------------------*/
//#define DOWNLOAD_ADDRESS _RAM_STARTADDRESS
volatile UINT32T downloadAddress;
volatile unsigned char *downPt;
volatile UINT32T downloadFileSize;
volatile UINT16T checkSum;
volatile unsigned int err=0;
volatile UINT32T totalDmaCount;
volatile int isUsbdSetConfiguration;
int download_run=0;
UINT32T tempDownloadAddress=0x31000000;
UINT32T test_ram_start;
UINT32T test_ram_end;
int menuUsed=0;
UINT32T g_nKeyPress;
extern char Image$$RW_ZI$$ZI$$Limit[];
UINT32T *pMagicNum=(UINT32T *)Image$$RW_ZI$$ZI$$Limit;
int consoleNum;
void (*run)(void);
/*******************add by lht***********/
#define U8 unsigned char
#define U16 unsigned short
#define U32 UINT32T
#define COMMAND_LINE_SIZE 1024
#define LINUX_PAGE_SHIFT 12
#define LINUX_PAGE_SIZE (1<<LINUX_PAGE_SHIFT)
void call_linux(U32 a0, U32 a1, U32 a2);
void set_param();
void Nand_Erase();
static void ProgNorFlash(void);
static void NorRunSystem(void);
void comdownload(void);
/*********************************************************************************************
* name: MemoryTest
* func: Test Ram
* para: none
* ret: none
* modify:
* comment: comparing the data writen to RAM and the data read from RAM
*********************************************************************************************/
void MemoryTest(void)
{
int i;
UINT32T data;
int memError=0;
UINT32T *pt;
// memory test
uart_printf("\nEnter a start address of ram to test(0x3...):");
test_ram_start = uart_getintnum();
uart_printf("\nEnter a end address of ram to test(0x3...):");
test_ram_end = uart_getintnum();
uart_printf("Memory Test(%xh-%xh):WR",test_ram_start,test_ram_end);
pt=(UINT32T *)(test_ram_start);
while((UINT32T)pt<(test_ram_end))
{
*pt=(UINT32T)pt;
pt++;
}
uart_printf("\b\bRD");
pt=(UINT32T *)(test_ram_start);
while((UINT32T)pt<(test_ram_end))
{
data=*pt;
if(data!=(UINT32T)pt)
{
memError=1;
uart_printf("\b\bFAIL:0x%x=0x%x\n",i,data);
break;
}
pt++;
}
if(memError==0)uart_printf("\b\bO.K.\n");
}
/*********************************************************************************************
* name: usb_test
* func: usb monitor entry
* para: none
* ret: none
* modify:
* comment:
*********************************************************************************************/
void usb_boot(void)
{
char *mode;
// int i;
// UINT8T key;
rGPHCON = rGPHCON&~(0xf<<18)|(0x5<<18);
//To enhance the USB signal quality.
//CLKOUT 0,1=OUTPUT to reduce the power consumption.
rGPGCON &= 0xfff3ffff; //GPG9 input add by lht
Isr_Init();
// uart_printf("Isr_Init end\n");
if(*pMagicNum!=0x12345678)
consoleNum=0;
else
consoleNum=1;
uart_init(0,115200,UART0);
uart_select(consoleNum);
rMISCCR=rMISCCR&~(1<<3); // USBD is selected instead of USBH1
rMISCCR=rMISCCR&~(1<<13); // USB port 1 is enabled.
//
// USBD should be initialized first of all.
//
isUsbdSetConfiguration=0;
/*
*/
pISR_SWI=(_ISR_STARTADDRESS+0xf0); //for pSOS
#if USBDMA
mode="DMA";
#else
mode="Int";
#endif
/* uart_printf("\n");
uart_printf("+---------------------------------------------+\n");
uart_printf("| S3C2410X USB Downloader ver R1.11 APR/29/05 |\n");
uart_printf("+---------------------------------------------+\n");
uart_printf("FCLK=%dMHz,%s mode\n",FCLK/1000000,mode);
uart_printf("USB: IN_ENDPOINT:1 OUT_ENDPOINT:3\n");
uart_printf("FORMAT: <ADDR(DATA):4>+<SIZE(n+10):4>+<DATA:n>+<CS:2>\n");
uart_printf("NOTE: 1. Power off/on or press the reset button for 1 sec\n");
uart_printf(" in order to get a valid USB device address.\n");
uart_printf(" 2. For additional menu, Press any key. \n");
uart_printf("\n"); */
download_run=0; //The default menu is the Download mode.
while(1)
{
// if(menuUsed==1) Menu();
Menu();
WaitDownload();
#ifdef BOARDTEST
break;
#endif
}
// uart_printf(" end.\n");
}
/*********************************************************************************************
* name: Menu
* func: usb monitor Menu
* para: none
* ret: none
* modify:
* comment:
*********************************************************************************************/
void Menu(void)
{
// int i;
UINT8T key;
menuUsed=1;
g_nKeyPress = 1;
while(g_nKeyPress==1) // only for board test to exit
{
uart_printf("\n###### Select Menu ######\n");
uart_printf(" [0] download image file from uart to ram addr 31000000\n");
uart_printf(" [1] download image file from usb to ram addr 31000000\n");
uart_printf(" [2] erase nand flash regions\n");
uart_printf(" [3] write nand flash with download file\n");
uart_printf(" [4] load image from nand flash and boot\n");
uart_printf(" [5] Write NOR flash with download file \n");
uart_printf(" [6] load image from nor flash and boot \n");
while(g_nKeyPress==1)
{
if(key = uart_getkey()) break;
}
switch(key)
{
case '0': //by lht
comdownload();
// download_run=1;
break;
case '1':
UsbdMain();
delay(0); //calibrate delay()
delay(1000);//add by lht
rGPGCON |= 0x00040000;
rGPGDAT |= 0x0200; //GPG9 ouput 1
tempDownloadAddress=0x31000000;
// uart_printf("addr=%x\n",tempDownloadAddress);
download_run=0;
uart_printf("\nThe temporary download address is 0x%x.\n\n",tempDownloadAddress);
return;
case '2':
Nand_Erase();
break;
case '3':
NandWrite();
break;
case '4':
NandRunSystem();
set_param();
call_linux(0, 193, tempDownloadAddress);
break;
case '5' :
ProgNorFlash();
break;
case '6':
NorRunSystem();
set_param();
// uart_printf("end of set_param tempDownloadAddress=%x\n",tempDownloadAddress);
call_linux(0, 193, tempDownloadAddress);
break;
default:
break;
}
}
}
/********************************************* /
* void call_linux(U32 a0, U32 a1, U32 a2)
*add by lht
**************************************************/
struct param_struct {
union {
struct {
unsigned long page_size; /* 0 */
unsigned long nr_pages; /* 4 */
unsigned long ramdisk_size; /* 8 */
unsigned long flags; /* 12 */
#define FLAG_READONLY 1
#define FLAG_RDLOAD 4
#define FLAG_RDPROMPT 8
unsigned long rootdev; /* 16 */
unsigned long video_num_cols; /* 20 */
unsigned long video_num_rows; /* 24 */
unsigned long video_x; /* 28 */
unsigned long video_y; /* 32 */
unsigned long memc_control_reg; /* 36 */
unsigned char sounddefault; /* 40 */
unsigned char adfsdrives; /* 41 */
unsigned char bytes_per_char_h; /* 42 */
unsigned char bytes_per_char_v; /* 43 */
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];
};
void set_param()
{
struct param_struct *params = (struct param_struct *)0x30000100;
char *linux_params = "root=nfs nfsroot=192.168.1.110:/source/rootfs ip=192.168.1.120 init=/linuxrc console=ttySAC0,115200 devfs=mount display=shp240";
params->u1.s.page_size = LINUX_PAGE_SIZE;
params->u1.s.nr_pages = (0x04000000 >> LINUX_PAGE_SHIFT);
memcpy(params->commandline,linux_params,strlen(linux_params)+1);
//for net cs3
rBWSCON |= 0x0000d000;
rBWSCON &= ~0x00040000;
}
void call_linux(U32 a0, U32 a1, U32 a2)
{
// uart_printf("in call_linux\n");
int i, j,r0;
void (*goto_start)(U32, U32);
//lht cache_clean_invalidate();
//lht tlb_invalidate();
// DisableInt();
// disable_irq();
__asm{
mrs r0, cpsr // ;enter svc mode and disable irq,fiq
orr r0, r0, #0xc0
msr cpsr_c, r0
// mov pc, lr
}
//If write-back is used,the DCache should be cleared.
/*
for(i=0; i<64; i++)
for(j=0; j<8; j++) ;
MMU_CleanInvalidateDCacheIndex((i<<26)|(j<<5));
__asm {
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 // drain WB
}
MMU_DisableDCache();
MMU_DisableICache();
MMU_InvalidateICache();
MMU_DisableMMU();
MMU_InvalidateTLB();*/
/* __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)
}
*/
// __asm{
// ;mov r1, #193
// mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
// mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
// 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 */
// ;mov pc, %0\n"
// nop
// ;:
// ;:"r"(addr)
// }
// SetClockDivider(1, 1);
// SetSysFclk(FCLK_200M); //start kernel, use 200M
// Delay(1000);
// disable_irq();
// uart_printf("a2=%\n",a2);
goto_start = (void (*)(U32, U32))a2;
(*goto_start)(a0, a1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -