加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

开贴分析FL2440的bootloader

发布时间:2020-12-15 18:44:37 所属栏目:百科 来源:网络整理
导读:首先申明本人学习ARM不过数月,根基尚浅。以下分析如有谬误,还请大家之争。本着探讨和共同进步的目的,我把我花了几个星期看完的bootloader并做得分析贴出。首先,bootloader中最重要的就是2440init.s引导代码,现将其贴出,整个文档太大,附件中没法上传,

首先申明本人学习ARM不过数月,根基尚浅。以下分析如有谬误,还请大家之争。本着探讨和共同进步的目的,我把我花了几个星期看完的bootloader并做得分析贴出。首先,bootloader中最重要的就是2440init.s引导代码,现将其贴出,整个文档太大,附件中没法上传,需要的朋友可以去FL群空间里下载
;=========================================
; NAME: 2440INIT.S
; DESC: C start up codes
;?????? Configure memory,ISR,stacks
;??????? Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
; 2003.03.14onGo: Modified for 2440.
;2010.09.02:jinzhenjun analysed
;=========================================

??????? GET option.inc
??????? GET memcfg.inc
??????? GET 2440addr.inc

BIT_SELFREFRESH EQU??????? (1<<22)

re-defined constants??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;系统的工作模式设定,宏定义
;对应的是各工作模式在CPSR中的位
;??????????????????????????????????????????????????????? 7??????????????? 6??????????????? 5??????????????? 4??????????????? 3??????????????? 2??????????????? 1??????????????? 0
;??????????????????????????????????????????????????????? I???????? F???????? T???????? M4??????? M3??????? M2??????? M1??????? M0
;USERMODE??????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 0??????????????? 0??????????????? 0??????????????? 0????????????????
;FIQMODE???????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 0??????????????? 0??????????????? 0??????????????? 1
;IRQMODE???????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 0??????????????? 0??????????????? 1??????????????? 0
;SVCMODE???????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 0??????????????? 0??????????????? 1??????????????? 1
;ABORTMODE?????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 0??????????????? 1??????????????? 1??????????????? 1????????????????
;UNDEFMODE?????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 1??????????????? 0??????????????? 1??????????????? 1
;MODEMASK??????????? 0??????????????? 0??????????????? 0??????????????? 1??????????????? 1??????????????? 1??????????????? 1??????????????? 1????????
;NOINT??????????????????????????????? 1??????????????? 1??????????????? 0??????????????? 0??????????????? 0??????????????? 0??????????????? 0??????????????? 0

USERMODE??? EQU???????? 0x10????????????????
FIQMODE???? EQU???????? 0x11
IRQMODE???? EQU???????? 0x12
SVCMODE???? EQU???????? 0x13
ABORTMODE?? EQU???????? 0x17
UNDEFMODE?? EQU???????? 0x1b
MODEMASK??? EQU???????? 0x1f
NOINT?????? EQU???????? 0xc0

;The location of stacks???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;各种工作模式的堆栈首地址定义
;_STACK_BASEADDRESS??????? EQU??????? 0x33ff8000????????????????????????????????????????????????????????????????????????????????????????????????????????? ;在内存中的堆栈表首地址

UserStack??????? EQU??????? (_STACK_BASEADDRESS-0x3800)??????? ;0x33ff4800 ~
SVCStack??????? EQU??????? (_STACK_BASEADDRESS-0x2800)??????? ;0x33ff5800 ~
UndefStack??????? EQU??????? (_STACK_BASEADDRESS-0x2400)??????? ;0x33ff5c00 ~
AbortStack??????? EQU??????? (_STACK_BASEADDRESS-0x2000)??????? ;0x33ff6000 ~
IRQStack??????? EQU??????? (_STACK_BASEADDRESS-0x1000)??????? ;0x33ff7000 ~
FIQStack??????? EQU??????? (_STACK_BASEADDRESS-0x0)??????? ;0x33ff8000 ~

;=============================================================================================;

;??????? arm处理器有两种工作状态 1.arm:32位 这种工作状态下执行字对准的arm指令 2.Thumb:16位这种工作状??????? ;
;??????? 态执行半字对准的Thumb指令因为处理器分为16位 32位两种工作状态 程序的编译器也是分16位和32两种??????? ;
;??????? 编译方式 所以下面的程序用于根据处理器工作状态确定编译器编译方式code16伪指令指示汇编编译器后??????? ;
;??????? 面的指令为16位的thumb指令code32伪指令指示汇编编译器后面的指令为32位的arm指令这段是为了统一??????? ;
;??????? 目前的处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译)??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;

;Check if tasm.exe(armasm -16?...@ADS?1.0) is used.
??????? GBLL??? THUMBCODE????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;定义一个全局变量
??????? [ {CONFIG} = 16???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;if config==16 这里表示你的目前处于领先地16位编译方式
THUMBCODE SETL? {TRUE}???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;设置THUMBCODE 为 true表示告诉系统当前想用thumb,但实际启动时不行,只能启动后再跳
??????????? CODE32???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;启动时强制使用32位编译模式
??????????????? |???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ; [ | ]表示if else endif
THUMBCODE SETL? {FALSE}???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;如果系统要求是ARM指令,则直接设置THUMBCODE 为 false 说明当前的是32位编译模式
??? ]

??????????????? MACRO???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;宏定义
??????? MOV_PC_LR???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;程序跳转,当CODE16时编译器切换成Tumb模式
??????????????? [ THUMBCODE
??????????? bx lr
??????????????? |
??????????? mov??????? pc,lr
??????????????? ]
??????? MEND

??????????????? MACRO?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??????? MOVEQ_PC_LR???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;条件相等则程序跳转,当CODE16时编译器切换成Tumb模式
??????????????? [ THUMBCODE
??????? bxeq lr???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;相等Z=1,则跳转
??????????????? |
??????????? moveq pc,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ;===============================================================================================;

;??????? 注意下面这段程序是个宏定义 很多人对这段程序不理解 我再次强调这是一个宏定义 所以大家要注意了下??????? ;
;??????? 面包含的HandlerXXX HANDLER HandleXXX将都被下面这段程序展开这段程序用于把中断服务程序的首地址???????? ;
;??????? 装载到pc中,有人称之为“加载程序”。本初始化程序定义了一个数据区(在文件最后),34个字空间,存???????? ;
;??????? 放相应中断服务程序的首地址。每个字空间都有一个标号,以Handle***命名。在向量中断模式下使用“加???????? ;
;??????? 载程序”来执行中断服务程序。这里就必须讲一下向量中断模式和非向量中断模式的概念向量中断模式是当??????? ;
;??????? cpu读取位于0x18处的IRQ中断指令的时候,系统自动读取对应于该中断源确定地址上的;指令取代0x18处的??????? ;
;??????? 指令,通过跳转指令系统就直接跳转到对应地址函数中 节省了中断处理时间提高了中断处理速度标 例如???????? ;
;??????? ADC中断的向量地址为0xC0,则在0xC0处放如下代码:ldr PC,=HandlerADC 当ADC中断产生的时候系统会自???????? ;
;??????? 动跳转到HandlerADC函数中非向量中断模式处理方式是一种传统的中断处理方法,当系统产生中断的时候???????? ;
;??????? 系统将interrupt pending寄存器中对应标志位置位 然后跳转到位于0x18处的统一中断函数中 该函数通过??????? ;
;??????? 读取interrupt pending寄存器中对应标志位 来判断中断源 并根据优先级关系再跳到对应中断源的处理代??????? ;
;??????? 码中??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
;===============================================================================================;

??????????????? MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
??????? sub??????? sp,sp,#4??????? ;decrement sp(to store jump address)
??????? stmfd??????? sp!,{r0}??????? USH the work register to stack(lr does t push because it return to original address)
??????? ldr???? r0,=$HandleLabel;load the address of HandleXXX to r0
??????? ldr???? r0,[r0]???????? ;load the contents(service routine start address) of HandleXXX
??????? str???? r0,[sp,#4]????? ;store the contents(ISR) of HandleXXX to stack
??????? ldmfd?? sp!,{r0,pc}???? OP the work register and pc(jump to ISR)
??????? MEND
????????
;从ADS的段设置中导入字符常量

??????? IMPORT? |Image$$RO$$Base|??????? ; Base of ROM code
??????? IMPORT? |Image$$RO$$Limit|? ; End of ROM code (=start of ROM data)
??????? IMPORT? |Image$$RW$$Base|?? ; Base of RAM to initialise
??????? IMPORT? |Image$$ZI$$Base|?? ; Base and limit of area
??????? IMPORT? |Image$$ZI$$Limit|? ; to zero initialise

;从后续的C语言中导入函数地址
??????? IMPORT??????? MMU_SetAsyncBusMode
??????? IMPORT??????? MMU_SetFastBusMode???????

??????? IMPORT? Main??? ; The main entry of mon program


??????? AREA??? Init,CODE,READONLY

??????? ENTRY
????????
??????? EXPORT??????? __ENTRY
__ENTRY
;========
;复位
;========
ResetEntry
??????? ;1)The code,which converts to Big-endian,should be in little endian code.
??????? ;2)The following little endian code will be compiled in Big-Endian mode.
??????? ;? The code byte order should be changed as the memory bus width.
??????? ;3)The pseudo instruction,DCD can t be used here because the linker generates error.
??????? ASSERT??????? EF:ENDIAN_CHANGE??????????????????????????????????????????????????????????????????????????????????????????????? ;条件编译,在编译成机器码前就设定好,判断ENDIAN_CHANGE是否已定义,在Option.inc中GBLL ENDIAN_CHANGE
??????? [ ENDIAN_CHANGE??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;如果已经定义了ENDIAN_CHANGE,则判断,Option.inc中赋值ENDIAN_CHANGE??????? SETL??????? {FALSE}
??????????? ASSERT? EF:ENTRY_BUS_WIDTH??????????????????????????????????????????????????????????????????????? ;判断ENTRY_BUS_WIDTH是否已定义
??????????? [ ENTRY_BUS_WIDTH=32??????????????????????????????????????????????????????????????????????????????????????????????????????? ;Option.inc中赋值ENTRY_BUS_WIDTH??????? SETA??????? 16
??????????????? b??????? ChangeBigEndian??????????? ;DCD 0xea000007
??????????? ]

??????????? [ ENTRY_BUS_WIDTH=16
??????????????? andeq??????? r14,r7,r0,lsl #20?? ;DCD 0x0007ea00
??????????? ]

??????????? [ ENTRY_BUS_WIDTH=8
??????????????? streq??????? r0,[r0,-r10,ror #1] ;DCD 0x070000ea
??????????? ]
??????? |
??????????? b??????? ResetHandler
??? ]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;此段代码没有可读性,待有时间查阅相关资料,芯片手册貌似没有记录
????
;===============================================================================================;

; 异常中断矢量表(每个表项占4个字节)首地址在Option.inc中定义 _ISR_STARTADDRESS??????? EQU 0x33ffff00? ;
; 下面是中断向量表 一旦系统运行时中断发生 即使移植了操作系统 如linux 处理器已经把控制权交给了操 ;
; 作系统一旦发生中断 处理器还是会跳转到从0x0开始从中断向量表中某个中断表项(依据中断类型)开始? ;
; 执行具体中断向量布局请参考s3c44b0 spec 例如 adc中断向量为0x000000c0下面对应表中第49项位置向量 ;
; 地址0x0+4*(49-1)=0x000000c0??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;

;===============================================================================================;
????
??????? b??????? HandlerUndef??????? ;handler for Undefined mode
??????? b??????? HandlerSWI??????? ;handler for SWI interrupt
??????? b??????? HandlerPabort??????? ;handler for PAbort
??????? b??????? HandlerDabort??????? ;handler for DAbort
??????? b??????? .??????????????? ;reserved
??????? b??????? HandlerIRQ??????? ;handler for IRQ interrupt
??????? b??????? HandlerFIQ??????? ;handler for FIQ interrupt

;@0x20
??????? b??????? EnterPWDN??????? ; Must be @0x20.??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;这个可不是中断哦,个人认为这一代码在机器正常运转的时候不会执行,放在这儿应该是
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;当程序异常走到这儿的时候,可以执行类似睡眠这类处理,属异常操作。另一个重要原因
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;是可以避免下面过程的执行????????
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
ChangeBigEndian??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;该段代码生涩难懂,属机器码。不加深入研究,同时该段代码根本就没有被执行过????????????????????????????????????????????????????????????????????????????????
;@0x24??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;主要用途:改变大小端存储的方式,而这种改变又与总线宽度有关
??????? [ ENTRY_BUS_WIDTH=32
??????????? DCD??????? 0xee110f10??????? ;0xee110f10 =>? p15,c1,c0,0
??????????? DCD??????? 0xe3800080??????? ;0xe3800080 => orr r0,#0x80;? //Big-endian
??????????? DCD??????? 0xee010f10??????? ;0xee010f10 => mcr p15,0
??????? ]
??????? [ ENTRY_BUS_WIDTH=16
??????????? DCD 0x0f10ee11
??????????? DCD 0x0080e380
??????????? DCD 0x0f10ee01
??????? ]
??????? [ ENTRY_BUS_WIDTH=8
??????????? DCD 0x100f11ee
??????????? DCD 0x800080e3
??????????? DCD 0x100f01ee
??? ]
??????? DCD 0xffffffff? ;swinv 0xffffff is similar with NOP and run well in both endian mode.
??????? DCD 0xffffffff
??????? DCD 0xffffffff
??????? DCD 0xffffffff
??????? DCD 0xffffffff
??????? b ResetHandler
????????
HandlerFIQ????? HANDLER HandleFIQ
HandlerIRQ????? HANDLER HandleIRQ
HandlerUndef??? HANDLER HandleUndef
HandlerSWI????? HANDLER HandleSWI
HandlerDabort?? HANDLER HandleDabort
HandlerPabort?? HANDLER HandlePabort

IsrIRQ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;下面有中断向量表跳转的具体分析
??????? sub??????? sp,#4?????? ;reserved for PC
??????? stmfd??????? sp!,{r8-r9}

??????? ldr??????? r9,=INTOFFSET
??????? ldr??????? r9,[r9]
??????? ldr??????? r8,=HandleEINT0
??????? add??????? r8,r8,r9,lsl #2
??????? ldr??????? r8,[r8]
??????? str??????? r8,#8]
??????? ldmfd??????? sp!,{r8-r9,pc}


??????? LTORG

;=======
; ENTRY
;=======
ResetHandler??????????

ldr??????? r0,=WTCON?????? ;watch dog disable??????????????????????????????????????????????????????????????????????????????????????? ;关看门狗
??????? ldr??????? r1,=0x0
??????? str??????? r1,[r0]

??????? ldr??????? r0,=INTMSK??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;禁全部中断
??????? ldr??????? r1,=0xffffffff? ;all interrupt disable
??????? str??????? r1,=INTSUBMSK??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;禁全部子中断
??????? ldr??????? r1,=0x7fff??????????????? ;all sub interrupt disable
??????? str??????? r1,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ??????? ;led显示
??????? [ {FALSE}??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;因为FALSE值,所以这段代码无效
??????? ; rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
??????? ; Led_Display
??????? ldr??????? r0,=GPFCON
??????? ldr??????? r1,=0x5500
??????? str??????? r1,[r0]
??????? ldr??????? r0,=GPFDAT
??????? ldr??????? r1,=0x10
??????? str??????? r1,[r0]
??????? ]

??????? ;To reduce PLL lock time,adjust the LOCKTIME register.
??????? ldr??????? r0,=LOCKTIME??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;设置时钟稳定等待的时间
??????? ldr??????? r1,=0xffffff
??????? str??????? r1,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ??? [ PLL_ON_START??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;配置时钟分频寄存器,确定系统各总线时钟的分频系数
??????? ; Added for confirm clock divide. for 2440.
??????? ; Setting value Fclk:Hclkclk
??????? ldr??????? r0,=CLKDIVN
??????? ldr??????? r1,=CLKDIV_VAL??????????????? ; 0=1:1:1,1=1:1:2,2=1:2:2,3=1:2:4,4=1:4:4,5=1:4:8,6=1:3:3,7=1:3:6.
??????? str??????? r1,[r0]
????????
;===============================================================================================;

; MCR 指令用于将ARM 处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成操作,则产 ;
; 生未定义指令异常。其中协处理器操作码1 和协处理器操作码2 为协处理器将要执行的操作,源寄存器为? ;
; ARM 处理器的寄存器,目的寄存器1 和目的寄存器2 均为协处理器的寄存器。??????????????????????????????????????????????????????????????????????????????????????????????????????? ;

;===============================================================================================;???????
??????? [ CLKDIV_VAL>1???????????????? ; means Fclk:Hclk is not 1:1.
??????? mrc p15,0??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;读MMU控制命令
??????? orr r0,#0xc0000000;R1_nF:OR:R1_iA??????????????????????????????????????????????????????????????????????????????????????????????? ;功能如下:31位(iA bit)Function:Asynchronous clock select (选择异步时钟)30位(nF bit)Function: notFastBus select
??????? mcr p15,0
??????? |
??????? mrc p15,0
??????? bic r0,#0xc0000000;R1_iA:OR:R1_nF
??????? mcr p15,0
??????? ]

??????? ;Configure UPLL??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;配置USB时钟锁相环
??????? ldr??????? r0,=UPLLCON
??????? ldr??????? r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)??
??????? str??????? r1,[r0]
??????? nop??????? ; Caution: After UPLL setting,at least 7-clocks delay must be inserted for setting hardware be completed.
??????? nop
??????? nop
??????? nop
??????? nop
??????? nop
??????? nop
??????? ;Configure MPLL
??????? ldr??????? r0,=MPLLCON??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;配置系统时钟锁相环
??????? ldr??????? r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)? ;Fin=16.9344MHz
??????? str??????? r1,[r0]
??? ]
????
??????? ;Check if the boot is caused by the wake-up from SLEEP mode.
??????? ldr??????? r1,=GSTATUS2??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;判断系统是否是被唤醒的,是的话转入唤醒中断函数
??????? ldr??????? r0,[r1]
??????? tst??????? r0,#0x2
??????? ;In case of the wake-up from SLEEP mode,go to SLEEP_WAKEUP handler.
??????? bne??????? WAKEUP_SLEEP

;??????? EXPORT StartPointAfterSleepWakeUp
;StartPointAfterSleepWakeUp

??????? ;Set memory control registers
??????? ;ldr??????? r0,=SMRDATA
??????? adrl??????? r0,SMRDATA??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;配置SDRAM各组控制寄存器,配置信息在SMRDATA数据区中
??????? ldr??????? r1,=BWSCON??????? ;BWSCON Address
??????? add??????? r2,#52??????? ;End address of SMRDATA

0
??????? ldr??????? r3,[r0],#4
??????? str??????? r3,[r1],#4
??????? cmp??????? r2,r0
??????? bne??????? %B0
????????
??????? ;delay
??????? mov??????? r0,#&1000??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;等待SDRAM稳定运行
1
??????? subs??????? r0,#1
??????? bne??????? %B1
??????? ;===

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;?????? When EINT0 is pressed,? Clear SDRAM?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed

;??????? ldr??????? r0,=GPFCON
;??????? ldr??????? r1,=0x0
;??????? str??????? r1,[r0]
;??????? ldr??????? r0,=GPFUP
;??????? ldr??????? r1,=0xff
;??????? str??????? r1,[r0]
;
;??????? ldr??????? r1,=GPFDAT
;??????? ldr??????? r0,[r1]
;??????? bic??????? r0,#(0x1e<<1)? ; bit clear
;??????? tst??????? r0,#0x1
;??????? bne %F1

; Clear SDRAM Start
??
;??????? ldr??????? r0,=0x55aa
;??????? str??????? r1,=GPFDAT
;??????? ldr??????? r1,[r0]??????? ;LED=****


;Clear SDRAM End

1

??????? ;Initialize stacks
??????? bl??????? InitStacks??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;初始化堆栈

;==========================================================
????????? ; Setup IRQ handler??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;建立中断表
??????? ldr??????? r0,=HandleIRQ?????? ;This routine is needed
??????? ldr??????? r1,=IsrIRQ????????? ;if there isn t 'subs pc,lr,#4' at 0x18,0x1c
??????? str??????? r1,[r0]
;===========================================================
;// 判断是从nor启动还是从nand启动
;===========================================================
??????? ;bl??????? Led_Test
????????
??????? ldr??????? r0,=BWSCON
??????? ldr??????? r0,[r0]
??????? ands??????? r0,#6??????????????? ;OM[1:0] != 0,NOR FLash boot
??????? bne??????? NORRoCopy??????????????? ;don t read nand flash
??????? adr??????? r0,ResetEntry??????????????? ;OM[1:0] == 0,NAND FLash boot // ADR ;装载参照的地址=sub r0,pc,#0x268;
??????? cmp??????? r0,#0??????????????????????????????? ;if use Multi-ice,//??????????????????????????????????????????????????????????????????????????????????????? ;JTAG调试时是直接下载到内存中运行,不需要再从nand拷贝?
??????? bne??????? InitRamZero??????????????? ;don t read nand flash for boot
??????? ;nop
???????

????????
;===========================================================
;//将程序从nandflash拷贝到sdram
;===========================================================
nand_boot_beg
??????? bl??????? ClearSdram
??????? mov??????? r5,#NFCONF??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;配置NandFlash的配置寄存器
??????? ;set timing value
??????? ldr??????? r0,??????? =(7<<12)|(7<<8)|(7<<4)
??????? str??????? r0,??????? [r5]
??????? ;enable control
??????? ldr??????? r0,=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
??????? str??????? r0,[r5,#4]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;配置控制寄存器
????????
??????? bl??????? ReadNandID??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;跳转到读取芯片ID函数,芯片ID存在R5中
??????? mov??????? r6,#0
??????? ldr??????? r0,=0xecF1
??????? cmp??????? r5,??????? r0
??????? beq??????? %F1
;??????? ldr??????? r0,=0xecda
;??????? cmp??????? r5,r0
??????? mov??????? r6,#1??????????????????????? ;Nandaddr(寻址周期 0:4? 1:5)
1????????
??????? bl??????? ReadNandStatus

; ldr取得是ResetEntry的绝对地址??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 这里ResetEntry的绝对地址是0x30100000,由ADS连接器中指定??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 这里不用adr,adr只适合短地址读取??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;

;===============================================================================================;????????
??????? mov??????? r8,#0
??????? ldr??????? r9,=ResetEntry
??????? mov r10,#32??????????????????????? ;+081010 feiling
????????
;===============================================================================================;

; 这个的意思是看 r8 是不是一个block的第一个扇区的地址就看作为页计数的r8是不是64的整数倍,如果是 ;
; 整数倍那么就是block的第一个扇区了,那么在3段代码执行后下一步执行什么,3段是读一页的操作吧。如 ;
; 果是的话,后多少位会是0 如果是一个block的第一个扇区就执行CheckBadBlk 如果不是的话就直接读数据? ;

2????????
??????? ands??????? r0,#0x3f??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;如果是第一页,则检测坏块。这里0x3f代表一块是64页
??????? bne??????????????? %F3
??????? mov??????????????? r0,r8
??????? bl??????????????? CheckBadBlk
??????? cmp??????????????? r0,#0??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;该处的r0是坏快标志,是0的时候不是坏快,否则就是坏快
??????? addne??????? r8,#64??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;每块的页数? 此处有BUG r8同时也做计数用。。
??????? addne??????? r10,r10,#64 ;+081010 feiling??????????????????????????????????????????????????????????????????????????????????????????????????????? ;当是坏快的时候跳过该坏快
??????? bne??????????????? %F4
3????????
??????? mov??????? r0,r8
??????? mov??????? r1,r9
??????? bl??????? ReadNandPage??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;跳转到的函数的功能是把nandflash中的程序数据搬运到SDRAM中
??????? add??????? r9,#2048??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;每页的字节数
??????? add??????? r8,#1??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;页数+1
????????
; 步骤4将前32页全部搬运一遍,这前32页应该已经包含了bootload在nandflash中固化了的RO段和RW段

4????????
??????? cmp??????? r8,r10?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;要拷贝的页数 081010 pht:#32->r10?
??????? bcc??????? %B2??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;CC 无符号小于
????????
??????? mov??????? r5,#NFCONF??????????????????????? ;DsNandFlash
??????? ldr??????? r0,#4]
??????? bic r0,#1
??????? str??????? r0,#4]
??????? ldr??????? pc,=InitRamZero??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;此处跳转到内存空间 LDR 装载数据,寻址灵活。 但不改变PSR
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;要装载一个被存储的‘状态’并正确的恢复它 可以这样写:ldr r0,[base] 换行? moves pc,r0
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;注意,程序不能在Nandflash中运行,NORFlash可以理解为类似SRAM的存储器,NandFlash可被理解为IO设备
;=============================================================================================
;若是从NAND启动,则拷贝工作已经在nand_boot_beg中完成,所以直接跳转到main
;若是从NOR启动,则将RO和RW部分都拷贝到内存,然后跳转到内存运行(也可在NOR中运行,只是速度稍慢)
;
;注:若在NOR中直接运行,需把RO/BASE改为0并定义RW/BASE 会跳过RO拷贝
;=============================================================================================
NORRoCopy??????????????????????? ;copy_proc_beg? by pht
??????? bl??????? ClearSdram

??????? adr??????? r0,ResetEntry??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;判断是否在ROM中运行,ROM即RO指定的地址 从NOR启动时ResetEntry为0
??????? ldr??????? r2,BaSEOfROM??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;如果相等,进行RW段的拷贝;不相等的话还需进行RO段,也就是程序段的拷贝?
??????? cmp??????? r0,r2
??????? beq??????? NORRwCopy????????????????????????????????
??????? ldr r3,TopOfROM??????????????? ;
0??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;程序段拷贝工作
??????? ldmia??????? r0!,{r4-r7}
??????? stmia??????? r2!,{r4-r7}
??????? cmp??????? r2,r3
??????? bcc??????? %B0
????????
????????????????
NORRwCopy??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;数据段的拷贝工作
??????? ldr??????? r0,TopOfROM
??????? ldr r1,BaSEOfROM
??????? sub r0,r1??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;TopOfROM-BaSEOfROM得到从0开始RW的偏移地址
??????? ldr??????? r2,BaSEOfBSS??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;将RW部分的数据从ROM拷贝到RAM
??????? ldr??????? r3,BaSEOfZero????????
0??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;BSS段的拷贝工作
??????? cmp??????? r2,r3
??????? ldrcc??????? r1,#4
??????? strcc??????? r1,[r2],#4
??????? bcc??????? %B0????????
????????
InitRamZero??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;此段代码不管在NOR还是Nand中都将搬运
??????? mov??????? r0,??????? #0
??????? ldr r2,BaSEOfZero
??????? ldr??????? r3,??????? EndOfBSS
1??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;ZERO段的初始化工作
??????? cmp??????? r2,??????? r3??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;初始化Zero部分 不管从哪里启动,这部分都需要执行
??????? strcc??????? r0,#4
??????? bcc??????? %B1
????????
??????? ldr??????? pc,=CEntry??????????????? ;goto compiler address

????????
;??????? [ CLKDIV_VAL>1???????????????? ; means Fclk:Hclk is not 1:1.
;??????? bl??????? MMU_SetAsyncBusMode
;??????? |
;??????? bl MMU_SetFastBusMode??????? ; default value.
;??????? ]
???????


CEntry
??????? bl??????? Main??????? ;Don t use main() because ......
??????? b??????? .

ClearSdram
??????? mov r1,#0
??????? mov r2,#0
??????? mov r3,#0
??????? mov r4,#0
??????? mov r5,#0
??????? mov r6,#0
??????? mov r7,#0
??????? mov r8,#0
????????
??????? ldr??????? r9,=0x00700000?? ;for wince
??????? ldr??????? r0,=0x30000000
0????????
??????? stmia??????? r0!,{r1-r8}
??????? subs??????? r9,#32?
??????? bne??????? %B0
??????? mov??????? pc,lr
????????
;===========================================================????????
;function initializing stacks
InitStacks??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;进入各种模式,分别配置各种模式的堆栈地址
??????? ;Don t use DRAM,such as stmfd,ldmfd......
??????? ;SVCstack is initialized before
??????? ;Under toolkit ver 2.5,'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
??????? mrs??????? r0,cpsr
??????? bic??????? r0,#MODEMASK
??????? orr??????? r1,#UNDEFMODE|NOINT
??????? msr??????? cpsr_cxsf,r1??????????????? ;UndefMode
??????? ldr??????? sp,=UndefStack??????????????? ; UndefStack=0x33FF_5C00

??????? orr??????? r1,#ABORTMODE|NOINT
??????? msr??????? cpsr_cxsf,r1??????????????? ;AbortMode
??????? ldr??????? sp,=AbortStack??????????????? ; AbortStack=0x33FF_6000

??????? msr??????? cpsr_cxsf,r1??????????????? ;FIQMode
??????? ldr??????? sp,=FIQStack??????????????? ; FIQStack=0x33FF_8000

??????? bic??????? r0,#MODEMASK|NOINT
??????? orr??????? r1,#SVCMODE
??????? msr??????? cpsr_cxsf,r1??????????????? ;SVCMode
??????? ldr??????? sp,=SVCStack??????????????? ; SVCStack=0x33FF_5800

??????? ;USER mode has not be initialized.

??????? mov??????? pc,lr
??????? ;The LR register won t be valid if the current mode is not SVC mode.
????????
;===========================================================
ReadNandID
??????? mov????? r7,#NFCONF
??????? ldr????? r0,[r7,#4]??????????????? ;NFChipEn();??????????????????????????????????????????????????????????????????????????????????????????????????????? ;使能NandFlash芯片
??????? bic????? r0,#2
??????? str????? r0,#4]????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??????? mov????? r0,#0x90??????????????? ;WrNFCmd(RdIDCMD);
??????? strb???? r0,#8]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;命令寄存器,写90h,读ID
??????? mov????? r4,#0??????????????????????? ;WrNFAddr(0);
??????? strb???? r4,#0xc]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;读命令第二步,地址写0
1??????????????????????????????????????????????????????? ;while(NFIsBusy());
??????? ldr????? r0,#0x20]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;判断是否忙,状态寄存器
??????? tst????? r0,#1
??????? beq????? %B1
??????? ldrb???? r0,#0x10]??????? ;id? = RdNFDat()<<8;??????????????????????????????????????????????????????????????? ;从读数据ID,读取ID,前两个周期即可分辨芯片
??????? mov????? r0,lsl #8
??????? ldrb???? r1,#0x10]??????? ;id |= RdNFDat();????????????????????????????????????????????????????????????????????????????????
??????? orr????? r5,r1,r0
??????? ldr????? r0,#4]??????????????? ;NFChipDs();??????????????????????????????????????????????????????????????????????????????????????????????????????? ;禁止NandFlash芯片
??????? orr????? r0,#4]
??????? mov???????????????? pc,lr????????
????????
ReadNandStatus
??????? mov???????????????? r7,#4]??????????????? ;NFChipEn();
??????? bic????? r0,#4]
??????? mov????? r0,#0x70??????????????? ;WrNFCmd(QUERYCMD);??????????????????????????????????????????????????????????????????????????????????????? ;命令为读状态寄存器
??????? strb???? r0,#8]????????
??????? ldrb???? r1,#0x10]??????? ;r1 = RdNFDat();??????????????????????????????????????????????????????????????????????????????? ;状态数据存在R1中
??????? ldr????? r0,#4]??????????????? ;NFChipDs();
??????? orr????? r0,lr

WaitNandBusy
??????? mov????? r0,#0x70??????????????? ;WrNFCmd(QUERYCMD);
??????? mov????? r1,#NFCONF
??????? strb???? r0,[r1,#8]
1??????????????????????????????????????????????????????? ;while(!(RdNFDat()&0x40));????????
??????? ldrb???? r0,#0x10]
??????? tst????? r0,#0x40
??????? beq???????????????? %B1
??????? mov????? r0,#0??????????????????????? ;WrNFCmd(READCMD0);??????????????????????????????????????????????????????????????????????????????????????? ;00h 老操作的结束,新操作的开始
??????? strb???? r0,#8]
??????? mov????? pc,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ; Samsung makes sure that either the 1st or 2nd page of every??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 坏快标志的检测步骤??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 1.Set Block Address = 0??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 2.Check "FFh" at the column address 2048,of the 1st and 2nd page in the block??????????????????????????????????????????????????????????????????????? ;
; 3.Check "FFh"??????????????? ???????????????????????????????? Y->继续??????? N->记录坏快进入坏块表??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
; 4.判断Last Block ???????????????????????????????????????? Y->检测完成??????? N->块数加1,跳转到地2歩??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;

;===============================================================================================;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

;initial invalid block has non-FFh data at the column address of 2048
CheckBadBlk
??????? mov??????????????? r7,lr
??????? mov??????????????? r5,#NFCONF
????????
??????? bic????? r0,#0x3f??????? ;addr &= ~0x3f;??????????????????????????????????????????????????????????????????????????????????????????????? ;r0中存放的是页数
??????? ldr????? r1,#4]??????????????? ;NFChipEn()
??????? bic????? r1,#2
??????? str????? r1,#4]

??????? mov????? r1,#0x00??????????????? ;WrNFCmd(READCMD)
??????? strb???? r1,#8]
??????? mov????? r1,#0??????????????????????? ;2048&0xff
??????? strb???? r1,#0xc]??????? ;WrNFAddr(2048&0xff);
??????? mov????? r1,#8??????????????????????? ;(2048>>8)&0xf??????????????????????????????????????????????????????????????????????????????????????????????????????? ;这里的坏快检测操作就是获取每页1K地址处的值,看看是不是为0xff
??????? strb???? r1,#0xc]
????????
??????? strb???? r0,#0xc]??????? ;WrNFAddr(addr)
??????? mov????? r1,lsr #8??????? ;WrNFAddr(addr>>8)
??????? strb???? r1,#0xc]
??????? cmp????? r6,#0??????????????????????? ;if(NandAddr)
??????? movne??? r1,lsr #16??????? ;WrNFAddr(addr>>16)
??????? strb???? r1,#0xc]
????????
??????? mov????? r1,#0x30??????????????????????? ;WrNFCmd(0x30)
??????? strb???? r1,#8]
????????????????
;??????? cmp????? r6,#0??????????????????????? ;if(NandAddr)????????????????
;??????? movne??? r0,lsr #16??????? ;WrNFAddr(addr>>16)
;??????? strneb?? r0,#0xc]
????????
;??????? bl??????????????? WaitNandBusy??????? ;WaitNFBusy()
??????? ;don t use WaitNandBusy,after WaitNandBusy will read part A!
??????? mov??????? r0,#100
1
??????? subs??????? r0,#1
??????? bne??????? %B1
2
??????? ldr??????? r0,#0x20]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;1歩与2歩都在等待
??????? tst??????? r0,#1
??????? beq??????? %B2???????

??????? ldrb??????? r0,#0x10]??????? ;RdNFDat()
??????? sub??????????????? r0,#0xff??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;r0中的数据为nandflash中该地址数据减去0xff,因为非坏块时该处值为0xff
????????
;??????? mov????? r1,#0??????????????????????? ;WrNFCmd(READCMD0)
;??????? strb???? r1,#8]
????????
??????? ldr????? r1,#4]??????????????? ;NFChipDs()
??????? orr????? r1,#4]
????????
??????? mov??????????????? pc,r7
????????
ReadNandPage
??????? mov???????????????? r7,lr
??????? mov????? r4,r1
??????? mov????? r5,#NFCONF

??????? ldr????? r1,#4]???????

; K9F2G08UXA的地址传送方式如下????????????????????????????????????????????????????????????????? ;
;???????????????????????? I/O0??????????????? I/O1??????????????? I/O2??????????????? I/O3??????????????? I/O4??????????????? I/O5??????????????? I/O6??????????????? I/O7??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
;??????? 1st??????????????????????? 0??????????????????????????????? 1??????????????????????????????? 2??????????????????????????????? 3??????????????????????????????? 4??????????????????????????????? 5??????????????????????????????? 6??????????????????????????????? 7??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
;??????? 2st??????????????????????? 8??????????????????????????????? 9??????????????????????????????? 10??????????????????????? 11??????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????????????????????????????? L(Low)??????????????????????????????????????? ;
; 3st??????????????????????? 12??????????????????????? 13??????????????????????? 14??????????????????????? 15??????????????????????? 16??????????????????????? 17??????????????????????? 18??????????????????????? 19??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
;??????? 4st??????????????????????? 20??????????????????????? 21??????????????????????? 22??????????????????????? 23??????????????????????? 24??????????????????????? 25??????????????????????? 26??????????????????????? 27??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
;??????? 5st??????????????????????? 28??????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????? L??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;

; K9F2G08UXA的读地址中数据的流程为:(一下程序段即此过程展示)??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 1. Write 00h??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 2. Write Address??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 3. Write 30h??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 4. Read Data??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 5. ECC Generation??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 6. Verify ECC并判断是否正确(硬件自动实现)??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;
; 7. 完成??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;

????????????????
????????
??????? ldr????? r0,#4]??????????????? ;InitEcc()
??????? orr????? r0,#0x10
??????? str????? r0,#4]
????????
??????? bl?????? WaitNandBusy??????? ;WaitNFBusy()
????????
??????? mov????? r0,#0??????????????????????? ;for(i=0; i<2048; i++)
1
??????? ldrb???? r1,#0x10]??????? ;buf[i] = RdNFDat()
??????? strb???? r1,[r4,r0]??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;r4中存放的是RO中程序段对应复制页的地址
??????? add????? r0,#1
??????? bic????? r0,#0x10000??????? ;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;最大1G
??????? cmp????? r0,#0x800??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;一页有2048个字节,全部放入执行段中去
??????? bcc????? %B1
????????
??????? ldr????? r0,#4]??????????????? ;NFChipDs()
??????? orr????? r0,#4]
????????????????
??????? mov???????????????? pc,r7

;--------------------LED test------------------------------
??????? EXPORT??????? Led_Test??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;LED测试代码,没有太多分析价值
Led_Test
??????? mov??????? r0,#0x56000000
??????? mov??????? r1,#0x5500
??????? str??????? r1,#0x50]
????????
0????????
??????? mov??????? r1,#0x50
??????? str??????? r1,#0x54]
??????? mov??????? r2,#0x100000
1
??????? subs??????? r2,r2,#1
??????? bne??????? %B1
????????
??????? mov??????? r1,#0xa0
??????? str??????? r1,#0x100000
2
??????? subs??????? r2,#1
??????? bne??????? %B2
??????? b??????? %B0
??????? mov??????? pc,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ;===========================================================

??????? LTORG

;GCS0->SST39VF1601
;GCS1->16c550
;GCS2->IDE
;GCS3->CS8900
;GCS4->DM9000
;GCS5->CF Card
;GCS6->SDRAM
;GCS7->unused

SMRDATA DATA
; Memory configuration should be optimized for best performance
; The following parameter is not optimized.
; Memory access cycle parameter strategy
; 1) The memory settings is? safe parameters even at HCLK=75Mhz.
; 2) SDRAM refresh period is for HCLK<=75Mhz.

??????? DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
??????? DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))?? ;GCS0
??????? DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))?? ;GCS1
??????? DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))?? ;GCS2
??????? DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))?? ;GCS3
??????? DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))?? ;GCS4
??????? DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))?? ;GCS5
??????? DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))??? ;GCS6
??????? DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))??? ;GCS7
??????? DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Tsrc<<18)+(Tchr<<16)+REFCNT)

??????? DCD 0x32??????????? ;SCLK power saving mode,BANKSIZE 128M/128M
??????? ;DCD 0x02??????????? ;SCLK power saving disable,BANKSIZE 128M/128M

??????? DCD 0x20??????????? ;MRSR6 CL=2clk
??????? DCD 0x20??????????? ;MRSR7 CL=2clk
????????
BaSEOfROM??????? DCD??????? |Image$$RO$$Base|
TopOfROM??????? DCD??????? |Image$$RO$$Limit|
BaSEOfBSS??????? DCD??????? |Image$$RW$$Base|
BaSEOfZero??????? DCD??????? |Image$$ZI$$Base|
EndOfBSS??????? DCD??????? |Image$$ZI$$Limit|

??????? ALIGN
????????
;Function for entering power down mode
; 1. SDRAM should be in self-refresh mode.
; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.
; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.
; 4. The I-cache may have to be turned on.
; 5. The location of the following code may have not to be changed.

;void EnterPWDN(int CLKCON);
EnterPWDN??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;其实bootload根本不会执行到下面的代码,下面关于EnterPWDN的代码纯属废码
??????? mov r2,r0??????????????? ;r2=rCLKCON
??????? tst r0,#0x8??????????????? ;SLEEP mode?
??????? bne ENTER_SLEEP

ENTER_STOP
??????? ldr r0,=REFRESH??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ;2440addr.inc中定义REFRESH???????? EQU? 0x48000024???? ;DRAM/SDRAM refresh
??????? ldr r3,[r0]??????????????? ;r3=rREFRESH
??????? mov r1,r3
??????? orr r1,#BIT_SELFREFRESH
??????? str r1,[r0]??????????????? ;Enable SDRAM self-refresh

??????? mov r1,#16??????????????????????? ;wait until self-refresh is issued. may not be needed.
0??????? subs r1,#1
??????? bne %B0

??????? ldr r0,=CLKCON??????????????? ;enter STOP mode.
??????? str r2,#32
0??????? subs r1,#1??????? ;1) wait until the STOP mode is in effect.
??????? bne %B0??????????????? ;2) Or wait here until the CPU&Peripherals will be turned-off
??????????????????????? ;?? Entering SLEEP mode,only the reset by wake-up is available.

??????? MOV_PC_LR

ENTER_SLEEP
??????? ;NOTE.
??????? ;1) rGSTATUS3 should have the return address after wake-up from SLEEP mode.

??????? ldr??????? r1,=MISCCR
??????? ldr??????? r0,[r1]
??????? orr??????? r0,#(7<<17)? ;Set SCLK0=0,SCLK1=0,SCKE=0.
??????? str??????? r0,[r1]

??????? b .??????????????????????? ;CPU will die here.

WAKEUP_SLEEP
??????? ;Release SCLKn after wake-up from the SLEEP mode.
??????? ldr??????? r1,[r1]
??????? bic??????? r0,#(7<<17)? ;SCLK0:0->SCLK,SCLK1:0->SCLK,SCKE:0->=SCKE.
??????? str??????? r0,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ??????? ;Set memory control registers
??????? ldr??????? r0,=SMRDATA????????
??????? ldr??????? r1,#52??????? ;End address of SMRDATA
0
??????? ldr??????? r3,r0
??????? bne??????? %B0

??????? ldr r1,=GSTATUS3???????? ;GSTATUS3 has the start address just after SLEEP wake-up
??????? ldr r0,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> ??????? mov pc,r0
????????
;=====================================================================
; Clock division test
; Assemble code,because VSYNC time is very short
;=====================================================================
??????? EXPORT CLKDIV124
??????? EXPORT CLKDIV144
????????
CLKDIV124
????????
??????? ldr???? r0,= CLKDIVN
??????? ldr???? r1,= 0x3??????????????? ; 0x3 = 1:2:4
??????? str???? r1,[r0]
;??????? wait until clock is stable
??????? nop
??????? nop
??????? nop
??????? nop
??????? nop

??????? ldr???? r0,= REFRESH
??????? ldr???? r1,[r0]
??????? bic??????????????? r1,#0xff
??????? bic??????????????? r1,#(0x7<<8)
??????? orr??????????????? r1,#0x470??????? ; REFCNT135
??????? str???? r1,[r0]
??????? nop
??????? nop
??????? nop
??????? nop
??????? nop
??????? mov???? pc,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left"> CLKDIV144
??????? ldr???? r0,= 0x4??????????????? ; 0x4 = 1:4:4
??????? str???? r1,#0x630??????? ; REFCNT675 - 1520
??????? str???? r1,51); font-family:Arial; font-size:14px; line-height:26px; text-align:left">
??????? ALIGN

??????? AREA RamData,DATA,READWRITE
;================================================================================================;

; 按照我的分析,IRQ或者FIQ中断操作的时候一共跳了三次。一次当中断产生时进入绝对跳转地址,也就是硬 ;
; 件中断地址0x018或0x1c。然后跳转到HandleXXX函数,HandleXXX函数就是下面的中断向量表的HandleIRQ或 ;
; HandleFIQ。其中HandleIRQ存放IsrIRQ的地址,而ISRIRQ这个函数就是跳转到中断源对应的中断向量入口, ;
; 其中断向量在下面这张中断向量表的后大半部分。向量偏移由寄存器INTOFFSET指定,而INTOFFSET也是中断 ;
; 源硬件设置的。然后,在从次中断向量入口跳转到用户定义的中断处理函数,通过这一方法实现了中断跳转 ;

;=============================================================================================== ;
????????
??????? ^?? _ISR_STARTADDRESS??????????????? ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset???????? #?? 4
HandleUndef???????? #?? 4
HandleSWI??????????????? #?? 4
HandlePabort??? #?? 4
HandleDabort??? #?? 4
HandleReserved? #?? 4
HandleIRQ??????????????? #?? 4
HandleFIQ??????????????? #?? 4

;Don t use the label 'IntVectorTable',;The value of IntVectorTable is different with the address you think it may be. ;IntVectorTable ;@0x33FF_FF20 HandleEINT0??????????????? #?? 4 HandleEINT1??????????????? #?? 4 HandleEINT2??????????????? #?? 4 HandleEINT3??????????????? #?? 4 HandleEINT4_7??????? #?? 4 HandleEINT8_23??????? #?? 4 HandleCAM??????????????? #?? 4??????????????? ; Added for 2440. HandleBATFLT??????? #?? 4 HandleTICK??????????????? #?? 4 HandleWDT??????????????? #?? 4 HandleTIMER0???????? #?? 4 HandleTIMER1???????? #?? 4 HandleTIMER2???????? #?? 4 HandleTIMER3???????? #?? 4 HandleTIMER4???????? #?? 4 HandleUART2????????? #?? 4 ;@0x33FF_FF60 HandleLCD???????????????? #?? 4 HandleDMA0??????????????? #?? 4 HandleDMA1??????????????? #?? 4 HandleDMA2??????????????? #?? 4 HandleDMA3??????????????? #?? 4 HandleMMC??????????????? #?? 4 HandleSPI0??????????????? #?? 4 HandleUART1??????????????? #?? 4 HandleNFCON??????????????? #?? 4??????????????? ; Added for 2440. HandleUSBD??????????????? #?? 4 HandleUSBH??????????????? #?? 4 HandleIIC??????????????? #?? 4 HandleUART0???????? #?? 4 HandleSPI1???????????????? #?? 4 HandleRTC???????????????? #?? 4 HandleADC???????????????? #?? 4 ;@0x33FF_FFA0 ??????? END

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读