# 1 "arch/s3c2440/head.S"
# 1 ""
# 1 "<鍛戒护琛?"
# 1 "arch/s3c2440/head.S"
# 35 "arch/s3c2440/head.S"
# 1 "./include/config.h" 1
# 14 "./include/config.h"
# 1 "./include/autoconf.h" 1
# 15 "./include/config.h" 2
# 36 "arch/s3c2440/head.S" 2
# 1 "./include/linkage.h" 1
# 37 "arch/s3c2440/head.S" 2
# 1 "./include/machine.h" 1
# 1 "./include/config.h" 1
# 5 "./include/machine.h" 2
# 22 "./include/machine.h"
# 1 "./include/platform/smdk2440.h" 1
# 1 "./include/s3c2440.h" 1
# 22 "./include/s3c2440.h"
# 1 "./include/hardware.h" 1
# 23 "./include/s3c2440.h" 2
# 1 "./include/bitfield.h" 1
# 24 "./include/s3c2440.h" 2
# 3 "./include/platform/smdk2440.h" 2
# 1 "./include/sizes.h" 1
# 8 "./include/platform/smdk2440.h" 2
# 74 "./include/platform/smdk2440.h"
# 1 "./include/architecture.h" 1
# 75 "./include/platform/smdk2440.h" 2
# 23 "./include/machine.h" 2
# 38 "arch/s3c2440/head.S" 2
@ Start of executable code
.globl _start; .align 0; _start:
.globl ResetEntryPoint; .align 0; 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 ((1 << 24) | (7 << 16) | 782)
@ 0x30: vivi capabilities
.long 0
# 103 "arch/s3c2440/head.S"
@
@ Start VIVI head
@
Reset:
@ disable watch dog timer
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
@ disable all interrupts
mov r1, #0x4A000000
mov r2, #0xffffffff
str r2, [r1, #0x08]
ldr r2, =0x7ff
str r2, [r1, #0x1C]
@ initialise system clocks
mov r1, #0x4C000000
mvn r2, #0xff000000
str r2, [r1, #0x00]
mov r1, #0x4C000000
ldr r2, clkdivn_value
str r2, [r1, #0x14]
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
mov r1, #0x4C000000
@ldr r2, mpll_value @ clock default
ldr r2, =0x7f021 @mpll_value_USER @ clock user set
str r2, [r1, #0x04]
bl memsetup
# 147 "arch/s3c2440/head.S"
@ All LED on
mov r1, #0x56000000
add r1, r1, #0x50
ldr r2,=0x55aa
str r2, [r1, #0x0]
mov r2, #0xff
str r2, [r1, #0x8]
mov r2, #0x00
str r2, [r1, #0x4]
# 165 "arch/s3c2440/head.S"
@ set GPIO for UART
mov r1, #0x56000000
add r1, r1, #0x70
ldr r2, gpio_con_uart @0x16faaa
str r2, [r1, #0x0]
ldr r2, gpio_up_uart @0x7ff,enable the up resistence
str r2, [r1, #0x8]
bl InitUART
# 190 "arch/s3c2440/head.S"
bl copy_myself
mov r1, #0x56000000
add r1, r1, #0x50
mov r2, #0x00
str r2, [r1, #0x4]
@ jump to ram
ldr r1, =on_the_ram
add pc, r1, #0
nop
nop
1: b 1b @ infinite loop
on_the_ram:
# 217 "arch/s3c2440/head.S"
@ get read to call C functions
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@0x33defffc, there are 32k bytes stack in the vivi,the base address of the stack @is 0x33de8000
@and there are many parameter in the vivi from the base address of 0x33df0000
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
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
@
@
@ Wake-up codes
@
# 303 "arch/s3c2440/head.S"
.globl memsetup; .align 0; memsetup:
@ initialise the static memory
@ set memory control registers
mov r1, #0x48000000
adrl r2, mem_cfg_val
add r3, r1, #52
1: ldr r4, [r2], #4
str r4, [r1], #4
cmp r1, r3
bne 1b
mov pc, lr
1、ADR伪指令--- 小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
ADR伪指令格式 :ADR{cond} register, expr
地址表达式expr的取值范围:
当地址值是字节对齐时,其取指范围为: +255 ~ 255B;
当地址值是字对齐时,其取指范围为: -1020 ~ 1020B;
2、ADRL伪指令----中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。
ADRL伪指令格式:ADRL{cond} register, expr
地址表达式expr的取值范围:
当地址值是字节对齐时,其取指范围为: -64K~64K;
当地址值是字对齐时,其取指范围为: -256K~256K;
3、LDR伪指令-----大范围的地址读取
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。
@
@ copy_myself: copy vivi to ram
@
copy_myself:
mov r10, lr
@ reset NAND
mov r1, #0x4E000000
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #0x00]
ldr r2, [r1, #0x00]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
str r2, [r1, #0x04]
ldr r2, [r1, #0x04]
ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #0x20]
ldr r2, [r1, #0x20]
mov r2, #0xff @ RESET command
strb r2, [r1, #0x08]
mov r3, #0 @ wait
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #0x20] @ wait ready
tst r2, #0x4
beq 2b
ldr r2, [r1, #0x04]
orr r2, r2, #0x2 @ Flash Memory Chip Disable
str r2, [r1, #0x04]
@ 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
mov r1, #0x56000000
add r1, r1, #0x50
mov r2, #0xe0
str r2, [r1, #0x4]
@ copy vivi to RAM
ldr r0, =(0x30000000 + 0x04000000 - 0x00100000)
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll
mov r1, #0x56000000
add r1, r1, #0x50
mov r2, #0xb0
str r2, [r1, #0x4]
tst r0, #0x0
beq ok_nand_read
# 386 "arch/s3c2440/head.S"
ok_nand_read:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@if there is any mistake while reading the nand flash,jump to the bad_nand_read
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bad_nand_read:
ldr r0, STR_FAIL
ldr r1, SerBase
bl PrintWord
1:
b 1b @infinite loop
ok_nand_read:
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
@verrify
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:
sub r0, r0, #4
ldr r1, SerBase
bl PrintHexWord
ldr r0, STR_FAIL
ldr r1, SerBase
pl PrintWord
1:
b 1b
done_nand_read:
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F
mov r2, #0x70
str r2, [r1, #oGPIO_DAT]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
PrintChar:
TXBusy:
ldr r2, [r1, #oUTRSTAT]
and r2, r2, #UTRSTAT_TX_EMPTY
tst r2,#UTRSTAT_EX_EMPTY
beq TXBusy
str r0,[r1, #oTUXHL]
mov pc lr
PrintWord:
mov r3, r0
mov r4, lr
bl PrintChar
mov r0, r3, LSR #8
bl PrintChar
mov r0, r3, LSR #16
bl PrintChar
mov r0, r3, LSR #24
bl PrintChar
mov r0, #'\r'
bl PrintChar
mov r0, #'\n'
bl PrintChar
mov pc, r4
PrintHexNibble:
adr r2, HEX_TO_ASCII_TABLE
and r0, r0, #0xf
ldr r0, [r2, r0]
b PrintChar
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
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
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
多寄存器寻址: LDMIA R0!,{R1-R4} ;R1<----[R0] ;R2<----[R0+4]
;R3<----[R0+8] ;R4<----[R0+12]
堆栈寻址: STMFD入栈指令,相当于STMDB STMFD SP!,{R2-R4} ;[SP-4]<---R4 ;[SP-8]<---R3 ;[SP-12]<---R2
LDMFD出栈指令,相当于LDMIA LDMFD SP!,{R6-R8} ;R6<----[SP] ;R7<----[SP+4]
;R8<----[SP+8] LDMIA / STMIA Increment After(先操作,后增加) LDMIB / STMIB Increment Before(先增加,后操作) LDMDA / STMDA Decrement After (先操作,后递减) LDMDB / STMDB Decrement Before(先递减,后操作)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@end of nand_flash_read;in this function there are something you have to do
@first: initialize the nand_flash
@1: set the NFCONF register(NFCONF = 0X7770)
@2: set the NFCONT register(NFCONT = 0x11)
@3: clear the RnB bit in the NFSTAT register
@ (NFSTAT = 0X60?but i think it should be set to 0x40)
@4: reset the nand flash {MOV R1,#0XFF
@ STRB R1, [NFCMD]}
@5: wait ready{2:
@ LDR R2, =NFSTAT
@ TST R2, #0X04
@ beq 2b}
@6: disable_chip(NFCONT &= (~(1 << 1)))
@7: jump to the function of nand_read_ll
@second: copy the code from the nand flash to sdram(nand_read_ll)
@third: check the data you have copyed(check if the data in the nand flash is
@ equal to the data you have copy to the sdram)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Initialize UART
@
@ r0 = number of UART port
InitUART:
ldr r1, SerBase
mov r2, #0x0
str r2, [r1, #0x08] @Disable the FIFO control register
str r2, [r1, #0x0C] @Disable the MODULE control register
mov r2, #0x3
str r2, [r1, #0x00] @normal,no parity,1 bit stop per frame,8 bits transfer
ldr r2, =0x245
str r2, [r1, #0x04]
mov r2, #((50000000 / (115200 * 16)) - 1) @0x26
str r2, [r1, #0x28]
@
@ Wait a little while
@
mov r3, #100
mov r2, #0x0
1: sub r3, r3, #0x1
tst r2, r3
bne 1b
# 496 "arch/s3c2440/head.S"
mov pc, lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@UART register:
@ULCON0 0X50000000
@ULCON1 0X50004000
@ULCON2 0X50008000
@UCONn +0X04
@UFCONn +0X08
@UMCONn +0X0C
@UTRSTAT +0X10
@UBRDIV +0X28
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Exception handling functions
@
HandleUndef:
1: b 1b @ infinite loop
HandleSWI:
1: b 1b @ infinite loop
HandlePrefetchAbort:
1: b 1b @ infinite loop
HandleDataAbort:
1: b 1b @ infinite loop
HandleIRQ:
1: b 1b @ infinite loop
HandleFIQ:
1: b 1b @ infinite loop
HandleNotUsed:
1: b 1b @ infinite loop
@
@ Low Level Debug
@
# 681 "arch/s3c2440/head.S"
@
@ Data Area
@
@ Memory configuration values
.align 4
mem_cfg_val:
.long 0x22111110
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00018009
.long 0x00018009
.long 0x008e04eb
.long 0xB2
.long 0x30
.long 0x30
@ Processor clock values
.align 4
clock_locktime:
.long 0x00ffffff
@mpll_value:
@ .long vMPLLCON_NOW
mpll_value_USER:
.long ((0x5c << 12) | (0x1 << 4) | (0x0))
clkdivn_value:
.long 0x5
@ initial values for serial
uart_ulcon:
.long 0x3
uart_ucon:
.long 0x245
uart_ufcon:
.long 0x0
uart_umcon:
.long 0x0
@ inital values for GPIO
gpio_con_uart:
.long 0x0016faaa
gpio_up_uart:
.long 0x000007ff
.align 2
DW_STACK_START:
.word (((((0x30000000 + 0x04000000 - 0x00100000) - 0x00100000) - 0x00004000) - (0x00004000 + 0x00004000 + 0x00004000)) - 0x00008000)+0x00008000 -4 @ =0x33DEFFFC
# 761 "arch/s3c2440/head.S"
.align 4
SerBase:
.long 0x50000000
|