ºìÁªLinuxÃÅ»§
Linux°ïÖú

Çó½Ì: ±àÒëu-boot 1.1.4ÒÔÉÏ°æ±¾Æô¶¯»ùÓÚS3C2410µÄ¿ª·¢°å

·¢²¼Ê±¼ä:2006-11-21 12:31:05À´Ô´:ºìÁª×÷Õß:bbdjlinuxdiyf
ÓÐÈËÊÔ¹ý±àÒëU-BOOT 1.1.4ÒÔÉϵİ汾Æô¶¯S3C2410/SMDK2410¼æÈݵĿª·¢°åÂð? ÎÒ×î½üÊÔ×űàÒëÁËU-BOOT-1.1.4, U-BOOT-1.1.5, U-BOOT-1.1.6ºÍU-BOOT-2006-06-30-2020, ʹÓõĿª·¢°åÊdzɶ¼²©î£µÄMC2410A. MC2410A¾Ý˵ÊÇ»ùÓÚS3C2410µÄ, Ö»Êdzɶ¼²©î£ÔÚS3C2410µÄ»ù´¡ÉÏ×öÁËÒ»µã¸Ä¶¯, »ù±¾ÅäÖÃÊÇARM920T, 64MB SDRAM¼Ó64MB NAND FLASH, ûÓÐNOR FLASH. MC2410A¿ÉÒÔÓÃVIVI BOOTLOADERÆô¶¯. µ«ÊÇÎҰѱàÒëºÃµÄu-boot.binͨ¹ýJTAG½Ó¿ÚÉÕµ½NAND FLASHÉÏÒÔºó, ¹ØµçÔ´ÔÙ¼ÓµçȴûÓÐÈκÎÆÁÄ»ÏÔʾ (ÎÒÊÇͨ¹ý´®¿ÚÁ¬½ÓCONSOLEµÄ). ÎÒÊÔ¹ýÐÞ¸Ä u-boot/board/smdk2410/ Ŀ¼ÏµÄu-boot.lds, °ÑSECTIONS{¡­}ÀïµÄµÚÒ»ÐÐ ¡°. = 0x¡­¡± ¸Ä³É0x33f80000, 0x33f00000»ò0x00000000, ¶¼Ã»ÓÐÓÃ. ÎÒÒ²ÊÔ¹ýÓà vivi/arch/s3c2410/ Ŀ¼ÏµÄhead.S ÍêÈ«Ìæ»» u-boot/cpu/arm920t/ ϵÄstart.S, ¿´¿´ÆðʼÓÚ¡±_start:¡±µÄÕâ¶Î»ã±à´úÂëÔÚu-boot.binÄÜ·ñ±»Ó²¼þʶ±ð, µ«»¹ÊÇʲô·´Ó¦¶¼Ã»ÓÐ (ÎÒÔÚÕâ¶Î»ã±à´úÂëÀï²åÈëÁË»ã±à´òÓ¡Óï¾äÏò´®¿ÚÊä³öµ÷ÊÔÐÅÏ¢, ÔÚVIVIÖбàÒëºóÊÇÄܹ»Õý³£´òÓ¡µÄ). ÎÒûÓÐÐÞ¸ÄÈκÎMakefile»òconfig.mk, ²»ÖªµÀÊÇ·ñºÍMakefileµÄÉèÖÃÓйØ. ÄÄλ´óÏÀÄÜ°ïÎÒ¿´¿´Ë³±ãÖ¸µãÒ»ÏÂ, ÎÒÏÈллÁË.

ÒÔÏÂÊÇÎÒÓÃÀ´Ìæ»»u-boot/cpu/arm920t/start.S µÄvivi/arch/s3c2410/head.S. ÔÚVIVIϱàÒëÊÇ¿ÉÒÔÕý³£Æô¶¯µÄ, ·ÅÔÚU-BOOTÀï¾Íû·´Ó¦ÁË.

/*
* vivi/arch/s3c2410/head.S:
* Initialise hardware
*
* Copyright (C) 2001 MIZI Research, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* Author: Janghoon Lyu <nandy@mizi.com>
* Date : $Date: 2003/02/26 10:38:11 $
*
* $Revision: 1.18 $
*
*
* History:
*
* 2002-05-14: Janghoon Lyu <nandy@mizi.com>
* - Initial code
*
*/

#include "linkage-vivi.h"

@ Start of executable code

ENTRY(_start)
ENTRY(ResetEntryPoint)

@
@ Exception vector table (physical address = 0x00000000)
@

@ 0x00: Reset
b Reset

@ 0x04: Undefined instruction exception
UndefEntryPoint:
b HandleUndef

@ 0x08: Software interrupt exception
SWIEntryPoint:
b HandleSWI

@ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort)
PrefetchAbortEnteryPoint:
b HandlePrefetchAbort

@ 0x10: Data Access Memory Abort
DataAbortEntryPoint:
b HandleDataAbort

@ 0x14: Not used
NotUsedEntryPoint:
b HandleNotUsed

@ 0x18: IRQ(Interrupt Request) exception
IRQEntryPoint:
b HandleIRQ

@ 0x1c: FIQ(Fast Interrupt Request) exception
FIQEntryPoint:
b HandleFIQ

@
@ VIVI magics
@

@ 0x20: magic number so we can verify that we only put
.long 0
@ 0x24:
.long 0
@ 0x28: where this vivi was linked, so we can put it in memory in the right place
.long _start
@ 0x2C: this contains the platform, cpu and machine id
.long 0x010600C1
@ 0x30: vivi capabilities
.long 0
@ 0x34:
b SleepRamProc

.balignl 16,0xdeadbeef

_TEXT_BASE:
.word 0x33f00000

.globl _armboot_start
_armboot_start:
.word _start

/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word 0

.globl _bss_end
_bss_end:
.word 0


@
@ Start VIVI head
@
Reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0

@ disable watch dog timer
mov r0, #0x53000000
mov r1, #0x0
str r1, [r0]

@ disable all interrupts
mov r0, #0x4A000000
mov r1, #0xffffffff
str r1, [r0, #0x00000008]
ldr r1, =0x3ff
str r1, [r0, #0x0000001C]

@ initialise system clocks
mov r1, #CLK_CTL_BASE
mvn r2, #0xff000000
str r2, [r1, #oLOCKTIME]

@ 1:2:4
mov r0, #0x4C000000
mov r1, #0x3
str r1, [r0, #0x00000014]

mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
orr r1, r1, #0xc0000000 @ Asynchronous
mcr p15, 0, r1, c1, c0, 0 @ write ctrl register

@ now, CPU clock is 200 Mhz
mov r1, #CLK_CTL_BASE
ldr r2, mpll_200mhz
str r2, [r1, #oMPLLCON]

bl memsetup

@ All LED on
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F
ldr r2,=0x55aa
str r2, [r1, #oGPIO_CON]
mov r2, #0xff
str r2, [r1, #oGPIO_UP]
mov r2, #0x00
str r2, [r1, #oGPIO_DAT]

@ set GPIO for UART
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_H
ldr r2, gpio_con_uart
str r2, [r1, #oGPIO_CON]
ldr r2, gpio_up_uart
str r2, [r1, #oGPIO_UP]
bl InitUART

#ifdef CONFIG_DEBUG_LL
@ Print current Program Counter
ldr r1, SerBase
mov r0, #'\r'
bl PrintChar
mov r0, #'\n'
bl PrintChar
mov r0, #'@'
bl PrintChar
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
mov r0, pc
bl PrintHexWord
#endif

bl copy_myself

@ jump to ram
ldr r1, =on_the_ram
add pc, r1, #0
nop
nop
1: b 1b @ infinite loop

on_the_ram:

#ifdef CONFIG_DEBUG_LL
ldr r1, SerBase
ldr r0, STR_STACK
bl PrintWord
ldr r0, DW_STACK_START
bl PrintHexWord
#endif

@ get read to call C functions
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
mov a2, #0 @ set argv to NULL

bl main @ call main

mov pc, #0x00000000 @ otherwise, reboot

@
@ End VIVI head
@

/*
* subroutines
*/

@
@ Wake-up codes
@
WakeupStart:
@ Clear sleep reset bit
ldr r0, PMST_ADDR
mov r1, #0x10
str r1, [r0]

@ Release the SDRAM signal protections
ldr r0, PMCTL1_ADDR
ldr r1, [r0]
bic r1, r1, #((1 << 19) | (1 << 18) | (1 << 17))
str r1, [r0]

@ Go...
ldr r0, PMSR0_ADDR @ read a return address
ldr r1, [r0]
mov pc, r1
nop
nop
1: b 1b @ infinite loop

SleepRamProc:
@ SDRAM is in the self-refresh mode */
ldr r0, REFR_ADDR
ldr r1, [r0]
orr r1, r1, #(1 << 22)
str r1, [r0]

@ wait until SDRAM into self-refresh
mov r1, #16
1: subs r1, r1, #1
bne 1b

@ Set the SDRAM singal protections
ldr r0, PMCTL1_ADDR
ldr r1, [r0]
orr r1, r1, #((1 << 19) | (1 << 18) | (1 << 17))
str r1, [r0]

/* Sleep... Now */
ldr r0, PMCTL0_ADDR
ldr r1, [r0]
orr r1, r1, #(1 << 3)
str r1, [r0]
1: b 1b

ENTRY(memsetup)
@ initialise the static memory

@ set memory control registers
mov r1, #0x48000000
adrl r0, mem_cfg_val
add r2, r0, #52
1: ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 1b

mov pc, lr


@
@ copy_myself: copy vivi to ram
@
copy_myself:
mov r10, lr

@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq 2b
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]

@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0

@ copy vivi to RAM
ldr r0, =0x33f00000
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll

tst r0, #0x0
beq ok_nand_read
#ifdef CONFIG_DEBUG_LL
bad_nand_read:
ldr r0, STR_FAIL
ldr r1, SerBase
bl PrintWord
1: b 1b @ infinite loop
#endif

ok_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
#endif

@ verify
mov r0, #0
ldr r1, =0x33f00000
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq done_nand_read
bne go_next
notmatch:
#ifdef CONFIG_DEBUG_LL
sub r0, r0, #4
ldr r1, SerBase
bl PrintHexWord
ldr r0, STR_FAIL
ldr r1, SerBase
bl PrintWord
#endif
1: b 1b
done_nand_read:

#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
#endif

mov pc, r10

@ clear memory
@ r0: start address
@ r1: length
mem_clear:
mov r2, #0
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2

clear_loop:
stmia r0!, {r2-r9}
subs r1, r1, #(8 * 4)
bne clear_loop

mov pc, lr



@ Initialize UART
@
@ r0 = number of UART port
InitUART:
ldr r1, SerBase
mov r2, #0x0
str r2, [r1, #oUFCON]
str r2, [r1, #oUMCON]
mov r2, #0x3
str r2, [r1, #oULCON]
ldr r2, =0x245
str r2, [r1, #oUCON]
#define UART_BRD ((50000000 / (115200 * 16)) - 1)
mov r2, #UART_BRD
str r2, [r1, #oUBRDIV]

mov r3, #100
mov r2, #0x0
1: sub r3, r3, #0x1
tst r2, r3
bne 1b

mov pc, lr


@
@ Exception handling functions
@
HandleUndef:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_UNDEF
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop

HandleSWI:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_SWI
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop

HandlePrefetchAbort:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_PREFETCH_ABORT
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop

HandleDataAbort:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_DATA_ABORT
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop

HandleIRQ:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_IRQ
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop

HandleFIQ:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_FIQ
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop

HandleNotUsed:
#ifdef CONFIG_DEBUG_LL
mov r12, r14
ldr r0, STR_NOT_USED
ldr r1, SerBase
bl PrintWord
bl PrintFaultAddr
#endif
1: b 1b @ infinite loop


@
@ Low Level Debug
@
#ifdef CONFIG_DEBUG_LL

@
@ PrintFaultAddr: Print falut address
@
@ r12: contains address of instruction + 4
@
PrintFaultAddr:
mov r0, r12 @ Print address of instruction + 4
ldr r1, SerBase
bl PrintHexWord
mrc p15, 0, r0, c6, c0, 0 @ Read fault virtual address
ldr r1, SerBase
bl PrintHexWord
mov pc, lr

@ PrintHexNibble : prints the least-significant nibble in R0 as a
@ hex digit
@ r0 contains nibble to write as Hex
@ r1 contains base of serial port
@ writes ro with XXX, modifies r0,r1,r2
@ TODO : write ro with XXX reg to error handling
@ Falls through to PrintChar
PrintHexNibble:
adr r2, HEX_TO_ASCII_TABLE
and r0, r0, #0xF
ldr r0, [r2, r0] @ convert to ascii
b PrintChar

@ PrintChar : prints the character in R0
@ r0 contains the character
@ r1 contains base of serial port
@ writes ro with XXX, modifies r0,r1,r2
@ TODO : write ro with XXX reg to error handling
PrintChar:
TXBusy:
ldr r2, [r1, #oUTRSTAT]
and r2, r2, #UTRSTAT_TX_EMPTY
tst r2, #UTRSTAT_TX_EMPTY
beq TXBusy
str r0, [r1, #oUTXHL]
mov pc, lr

@ PrintWord : prints the 4 characters in R0
@ r0 contains the binary word
@ r1 contains the base of the serial port
@ writes ro with XXX, modifies r0,r1,r2
@ TODO : write ro with XXX reg to error handling
PrintWord:
mov r3, r0
mov r4, lr
bl PrintChar

mov r0, r3, LSR #8 /* shift word right 8 bits */
bl PrintChar

mov r0, r3, LSR #16 /* shift word right 16 bits */
bl PrintChar

mov r0, r3, LSR #24 /* shift word right 24 bits */
bl PrintChar

mov r0, #'\r'
bl PrintChar

mov r0, #'\n'
bl PrintChar

mov pc, r4

@ PrintHexWord : prints the 4 bytes in R0 as 8 hex ascii characters
@ followed by a newline
@ r0 contains the binary word
@ r1 contains the base of the serial port
@ writes ro with XXX, modifies r0,r1,r2
@ TODO : write ro with XXX reg to error handling
PrintHexWord:
mov r4, lr
mov r3, r0
mov r0, r3, LSR #28
bl PrintHexNibble
mov r0, r3, LSR #24
bl PrintHexNibble
mov r0, r3, LSR #20
bl PrintHexNibble
mov r0, r3, LSR #16
bl PrintHexNibble
mov r0, r3, LSR #12
bl PrintHexNibble
mov r0, r3, LSR #8
bl PrintHexNibble
mov r0, r3, LSR #4
bl PrintHexNibble
mov r0, r3
bl PrintHexNibble

mov r0, #'\r'
bl PrintChar

mov r0, #'\n'
bl PrintChar

mov pc, r4
#endif

@
@ Data Area
@
@ Memory configuration values
.align 4
mem_cfg_val:
.long 0x22111110 @vBWSCON
.long 0x00000700 @vBANKCON0
.long 0x00000700 @vBANKCON1
.long 0x00000700 @vBANKCON2
.long 0x00000700 @vBANKCON3
.long 0x00000700 @vBANKCON4
.long 0x00000700 @vBANKCON5
.long 0x00018005 @vBANKCON6
.long 0x00018005 @vBANKCON7
.long 0x008E0459 @vREFRESH
.long 0xb1 @vBANKSIZE
.long 0x30 @vMRSRB6
.long 0x30 @vMRSRB7

@ Processor clock values
.align 4
mpll_200mhz:
.long 0x33f00338
@ inital values for GPIO
gpio_con_uart:
.long 0x0016faaa
gpio_up_uart:
.long 0x000007ff

.align 2
DW_STACK_START:
.word 0x33E64000+0x00008000-4

#ifdef CONFIG_DEBUG_LL
.align 2
HEX_TO_ASCII_TABLE:
.ascii "0123456789ABCDEF"
STR_STACK:
.ascii "STKP"
STR_UNDEF:
.ascii "UNDF"
STR_SWI:
.ascii "SWI "
STR_PREFETCH_ABORT:
.ascii "PABT"
STR_DATA_ABORT:
.ascii "DABT"
STR_IRQ:
.ascii "IRQ "
STR_FIQ:
.ascii "FIQ"
STR_NOT_USED:
.ascii "NUSD"
.align 2
STR_OK:
.ascii "OK "
STR_FAIL:
.ascii "FAIL"
STR_CR:
.ascii "\r\n"
#endif

.align 4
SerBase:
.long UART0_CTL_BASE

.align 4
PMCTL0_ADDR:
.long 0x4c00000c
PMCTL1_ADDR:
.long 0x56000080
PMST_ADDR:
.long 0x560000B4
PMSR0_ADDR:
.long 0x560000B8
REFR_ADDR:
.long 0x48000024
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 1446 ÌõÆÀÂÛ