⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 44b0init.s

📁 44B0启动原代码
💻 S
📖 第 1 页 / 共 2 页
字号:
    ;*  change BDMACON reset value for BDMA *   
    ;****************************************
    ldr     r0,=BDIDES0       
    ldr     r1,=0x40000000   ;BDIDESn reset value should be 0x40000000  
    str     r1,[r0]
    ldr     r0,=BDIDES1      
    ldr     r1,=0x40000000   ;BDIDESn reset value should be 0x40000000  
    str     r1,[r0]
    ;****************************************************
    ;* Set memory control registers     *  
    ;****************************************************
    ldr     r0,=SMRDATA
    ldmia   r0,{r1-r13}
    ldr     r0,=0x01c80000  ;BWSCON Address
    stmia   r0,{r1-r13}
    ;****************************************************
    ;* Initialize stacks        * 
    ;****************************************************
    ldr     sp, =SVCStack ;
    bl     InitStacks
    
    ;****************************************************
    ;* Setup IRQ handler        *
    ;****************************************************
 ;Setup IRQ handler 主体就是将0x0处的异常表搬运到_IRQ_BASEADDRESS,并设置irq服务(none vector mode)
 ;为什么要这么做?中断发生时不是自动转到0x0处的中断异常表吗?
 ;莫非日后,再修改此表使他指向_IRQ_BASEADDRESS处?这样都在ram中,加快速度???
 ;————不是的!!!看一下分析即可知道。
 
 
 ;下面这段代码看似将_IRQ_BASEADDRESS + 0x100之后的0x100全部初始化为_IRQ_BASEADDRESS
 ;事实上,结合44b.h中的isr部分就清楚了,那里是安装isr的地方,而起始地址正是_IRQ_BASEADDRESS + 0x100!
 ;当irq到来时,无论是非vector mode还是vector mode,都要跳转到HandleXXX处,
 ;而HandleXXX的首地址正是(_IRQ_BASEADDRESS+0x100)!
 
 ;再回顾一下中断或异常到来后的行为:
 ; 1,异常发生
 ; 2,转到0x0为首地址的异常表
 ; 3,根据异常类型,转入某个项,比如SWI
 ;  ldr    pc, =(_IRQ_BASEADDRESS + 0x08)    ;    HandlerSWI
 ; 4,那么(_IRQ_BASEADDRESS + 0x08)处放的是什么呢?
 ;  见下表
 ;    ^ (_IRQ_BASEADDRESS)
 ;    HandleReset     # 4
 ;    HandleUndef     # 4
 ;    HandleSWI       # 4
 ;    ...
 ; 由此可知HandleSWI是位于_IRQ_BASEADDRESS + 0x08处的,而44b.h中定义:
 ;  #define pISR_SWI (*(unsigned *)(_IRQ_BASEADDRESS+0x8))
 ; 我们可以安装这个异常处理函数!
 
 ; irq到来时,情况差不多。
 ; A) 如果是vector mode
 ;  那么直接载入0x20开始的指令,比如ldr pc,=HandlerEINT4567 ;
 ;  HandlerEINT4567的定义可知:
 ;        ^ (_IRQ_BASEADDRESS+0x100)
 ;     HandleADC     # 4
 ;     HandleRTC     # 4
 ;     ...
 ;     HandleEINT4567  # 4
 ;  他位于_IRQ_BASEADDRESS+0x154处,而44b.h中定义:
 ;   #define pISR_EINT4567 (*(unsigned *)(_IRQ_BASEADDRESS+0x154))//0x74))
 ;  于是我们可以安装处理函数。
 ;
 ; B) 如果是none vector mode
 ;  那么仅在装入HandlerEINT4567时方法不同,它是通过判断程序来完成的,剩下的步骤还是相同的。
 
 
    ldr     r0,=(_IRQ_BASEADDRESS + 0x100)
    ldr     r2,=_IRQ_BASEADDRESS
    add     r3,r0, #0x100            ;r3指向_IRQ_BASEADDRESS+0x200处
0    
    CMP     r0, r3      ;do what?  <- 哈哈,我知道了,居然你们立宇泰的人不知道!!!
    STRCC   r2, [r0], #4;cc:Carry clear;save R2 to R0 address, R0 + 4=R0。
    BCC     %B0
    
 ;----------------------------------------------------------------------------------------
 ;将0x0处的vector table 拷贝到 _IRQ_BASEADDRESS(0xc000000)
    ldr     r1,=_IRQ_BASEADDRESS            
    ldr     r0,=ExceptionHanlderBegin ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
    ldr     r3,=ExceptionHanlderEnd
0    
    CMP     r0, r3              ;put the vector table at _IRQ_BASEADDRESS(0xc000000)
    LDRCC   r2, [r0], #4  
    STRCC   r2, [r1], #4
    BCC     %B0
            
 ;----------------------------------------------------------------------------------------
 ;下面代码将非向量模式下的中断判断处理函数拷贝到_IRQ_BASEADDRESS+0x80(0xc000080)
    ldr     r1,=DIsrIRQ     ;put the IRQ judge program at _IRQ_BASEADDRESS+0x80(0xc000080)       
    ldr     r0,=IsrIRQ      ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
    ldr     r3,=IsrIRQEnd
0    
    CMP     r0, r3
    LDRCC   r2, [r0], #4
    STRCC   r2, [r1], #4
    BCC     %B0
 ;----------------------------------------------------------------------------------------
 ;将非向量模式的中断处理函数装入_IRQ_BASEADDRESS处的HandleIRQ
    ldr     r1, =MyHandleIRQ   ;MyHandleIRQ point to DIsrIRQ
    ldr     r0, =ExceptionHanlderBegin
    ldr     r4, =_IRQ_BASEADDRESS;////
    sub     r0, r1, r0   ;计算MyHandleIRQ在ExceptionHanlderBegin这个中断表中的偏移
    ;add     r0, r0, #_IRQ_BASEADDRESS
    add     r0, r0,r4   ;r0指向_IRQ_BASEADDRESS+(MyHandleIRQ的偏移),即0xc000000处的HandleIRQ
    ldr     r1, =DIsrIRQ     ;将非向量模式的中断处理函数装入0xc000000处的HandleIRQ
    str     r1, [r0]    
;    ldr     r0,=HandleIRQ  ;This routine is needed
;    ldr     r1,=IsrIRQ   ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
;    str     r1,[r0]
 ;-----------------------------------------------------------------------------------------
; --- Initialise memory required by C code
    ;********************************************************
    ;* Copy and paste RW data/zero initialized data     *
    ;********************************************************
    LDR     r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
    LDR     r1, =|Image$$RW$$Base| ; and RAM copy
    LDR     r3, =|Image$$ZI$$Base| 
 ;Zero init base => top of initialised data
   
    CMP     r0, r1     ; Check that they are different 确保数据段就是代码段的后面,如果已经是了,就跳过下面搬运
    BEQ     %F1
0  
    CMP     r1, r3     ; Copy init data 将数据段搬运到代码段的后面
    LDRCC   r2, [r0], #4    ;--> LDRCC r2, [r0] + ADD r0, r0, #4   
    STRCC   r2, [r1], #4    ;--> STRCC r2, [r1] + ADD r1, r1, #4
    BCC     %B0
1  
    LDR     r1, =|Image$$ZI$$Limit| ; Top of zero init segment
    MOV     r2, #0
2  
    CMP     r3, r1     ; Zero init 初始化bss段
    STRCC   r2, [r3], #4
    BCC     %B2
    
;--------Now we enter the C code
    [ :LNOT:THUMBCODE   ;if(!thumbcode) arm state;
 BL Main         ;Don't use main() because ...... 为什么呢?
 B .      
    ];
    [ THUMBCODE      ;for start-up code for Thumb mode;
 orr     lr,pc,#1
 bx      lr
 CODE16
 bl      Main     ;Don't use main() because ......
 b       .
 CODE32
   ]
;****************************************************
;* The function for initializing stack    *
;****************************************************
;4.初始化各模式下的栈指针 
InitStacks
 ;Don't use DRAM,such as stmfd,ldmfd......
 ;SVCstack is initialized before
 ;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
    mrs     r0,cpsr
    bic     r0,r0,#MODEMASK
    orr     r1,r0,#UNDEFMODE|NOINT
    msr     cpsr_cxsf,r1  ;UndefMode
    ldr     sp,=UndefStack
 
    orr     r1,r0,#ABORTMODE|NOINT
    msr     cpsr_cxsf,r1       ;AbortMode
    ldr     sp,=AbortStack
    orr     r1,r0,#IRQMODE|NOINT
    msr     cpsr_cxsf,r1       ;IRQMode
    ldr     sp,=IRQStack
 
    orr     r1,r0,#FIQMODE|NOINT
    msr     cpsr_cxsf,r1       ;FIQMode
    ldr     sp,=FIQStack
    bic     r0,r0,#MODEMASK|NOINT
    orr     r1,r0,#SVCMODE
    msr     cpsr_cxsf,r1       ;SVCMode
    ldr     sp,=SVCStack
 ;USER mode is not initialized.
    mov     pc,lr ;The LR register may be not valid for the mode changes.
;****************************************************
;* The function for entering power down mode  *
;****************************************************
;void EnterPWDN(int CLKCON);
EnterPWDN
    mov     r2,r0               ;r0=CLKCON
    ldr     r0,=REFRESH  
    ldr     r3,[r0]
    mov     r1, r3
    orr     r1, r1, #0x400000   ;self-refresh enable
    str     r1, [r0]
    nop     ;Wait until self-refresh is issued. May not be needed.
    nop     ;If the other bus master holds the bus, ...
    nop     ; mov r0, r0
    nop
    nop
    nop
    nop
;enter POWERDN mode
    ldr     r0,=CLKCON
    str     r2,[r0]
;wait until enter SL_IDLE,STOP mode and until wake-up
    ldr     r0,=0x10
0   subs    r0,r0,#1
    bne     %B0
;exit from DRAM/SDRAM self refresh mode.
    ldr     r0,=REFRESH
    str     r3,[r0]
    mov     pc,lr
    ;LTORG
SMRDATA DATA
;*****************************************************************
;* Memory configuration has to be optimized for best performance *
;* The following parameter is not optimized.                     *
;*****************************************************************
;*** memory access cycle parameter strategy ***
; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock
; 2) The memory settings,here, are made the safe parameters even at 66Mhz.
; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.
; 4) DRAM refresh rate is for 40Mhz. 
;bank0 16bit BOOT ROM
;bank1 8bit NandFlash
;bank2 16bit IDE
;bank3 8bit UDB
;bank4 rtl8019
;bank5 8bit usb host
;bank6 16bit SDRAM
;bank7 16bit SDRAM
    [ BUSWIDTH=16
    DCD 0x11010101 ;Bank0=16bit BootRom(AT29C010A*2) :0x0 8bit usb host![20:23]=0
    | ;BUSWIDTH=32
 DCD 0x22222220 ;Bank0=OM[1:0], Bank1~Bank7=32bit
    ]
 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
 [ BDRAMTYPE="DRAM" 
     DCD ((B6_MT<<15)+(B6_Trcd<<4)+(B6_Tcas<<3)+(B6_Tcp<<2)+(B6_CAN)) ;GCS6 check the MT value in parameter.a
     DCD ((B7_MT<<15)+(B7_Trcd<<4)+(B7_Tcas<<3)+(B7_Tcp<<2)+(B7_CAN)) ;GCS7
 | ;"SDRAM"
  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)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019
 DCD 0x10   ;SCLK power down mode, BANKSIZE 32M/32M
 DCD 0x20   ;MRSR6 CL=2clk
 DCD 0x20   ;MRSR7
 ALIGN               ;?
;==========================================================================================================================================
;以下的数据段充分的说明了中断处理程序的存储结构
;分为3个区域
;   1,异常向量表(_IRQ_BASEADDRESS ~ _IRQ_BASEADDRESS+0x4*8)
;   2,none vector mode的判断程序(_IRQ_BASEADDRESS+0x80~...)
;   3,isr表(中断处理服务表)(_IRQ_BASEADDRESS+0x100~...)
;最后还有堆栈区域
 AREA RamData, DATA, READWRITE

    ^ (_IRQ_BASEADDRESS)
HandleReset     # 4
HandleUndef     # 4
HandleSWI       # 4
HandlePabort    # 4
HandleDabort    # 4
HandleReserved  # 4
HandleIRQ       # 4
HandleFIQ       # 4
  
  ^ (_IRQ_BASEADDRESS+0x80)
DIsrIRQ       # 4

;Don't use the label 'IntVectorTable',
;because armasm.exe cann't recognize this label correctly.
;the value is different with an address you think it may be.
;IntVectorTable
    ^ (_IRQ_BASEADDRESS+0x100)
HandleADC     # 4
HandleRTC     # 4
HandleUTXD1   # 4
HandleUTXD0   # 4
HandleSIO     # 4
HandleIIC     # 4
HandleURXD1   # 4
HandleURXD0   # 4
HandleTIMER5  # 4
HandleTIMER4  # 4
HandleTIMER3  # 4
HandleTIMER2  # 4
HandleTIMER1  # 4
HandleTIMER0  # 4
HandleUERR01  # 4
HandleWDT     # 4
HandleBDMA1   # 4
HandleBDMA0   # 4
HandleZDMA1   # 4
HandleZDMA0   # 4
HandleTICK    # 4
HandleEINT4567  # 4
HandleEINT3   # 4
HandleEINT2   # 4
HandleEINT1   # 4
HandleEINT0   # 4   
 ^ (_ISR_STARTADDRESS-0x1400)
    
UserStack # 1024 ;c1(c7)fe600
SVCStack # 1024 ;c1(c7)feb00
UndefStack # 1024 ;c1(c7)ff000
AbortStack # 1024 ;c1(c7)ff500
IRQStack # 1024 ;c1(c7)ffa00
FIQStack # 0 ;c1(c7)fff00
  END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -