S3C44b0引導註釋

admin @ 2014-03-25 , reply:0

 *******************************************************
; * NAME : 44BINIT.S *
; * Version : 10.JAn.2003 *
; * Description: *
; * C start up codes *
; * Configure memory, Initialize ISR ,stacks *
; * Initialize C-variables *
; * Fill zeros into zero-initialized C-variables *
; *******************************************************

GET option.s ;相當於c語言中的#include "option.s"
GET memcfg.s

;Interrupt Control
;聲明一些符號常量,這些符號常量和地址相應寄存器的地址對應
INTPND EQU 0x01e00004 ;指示中斷請求狀態寄存器 每一位代變一種中斷請求具體表示哪一種中斷請參考44b0 spec
INTMOD EQU 0x01e00008 ;中斷模式寄存器 有兩種中斷模式對應位為1代表fip mode 0代表riq mode
INTMSK EQU 0x01e0000c ;確定哪個中斷源被屏蔽 屏蔽的中斷源將不被服務
I_ISPR EQU 0x01e00020 ;中斷服務掛起寄存器
I_CMST EQU 0x01e0001c ;當前主寄存器irq優先順序

;Watchdog timer
WTCON EQU 0x01d30000 ;看門狗定時器控制寄存器

;Clock Controller
PLLCON EQU 0x01d80000 ;pll控制寄存器
CLKCON EQU 0x01d80004 ;時鐘控制寄存器
LOCKTIME EQU 0x01d8000c ;鎖定時間計數值寄存器

;Memory Controller
REFRESH EQU 0x01c80024 ;Dram/sdram刷新控制寄存器
;下面是對arm處理器模式寄存器對應值的常數定義,arm處理器中有一個CPSR程序狀態寄存器 它的后五位決定目前的處理器模式
;Pre-defined constants
USERMODE EQU 0x10 ;0b10000用戶模式
FIQMODE EQU 0x11 ;0b10001FIQ模式
IRQMODE EQU 0x12 ;0b10010IRQ模式
SVCMODE EQU 0x13 ;0b10011管理模式
ABORTMODE EQU 0x17 ;0b10111中止模式
UNDEFMODE EQU 0x1b ;0b11011未定義
MODEMASK EQU 0x1f ;0b11111系統模式
NOINT EQU 0xc0 ;

;check if tasm.exe is used.
;arm處理器有兩種工作狀態 1.arm:32位 這種工作狀態下執行字對準的arm指令 2.Thumb:16位 這種工作狀態執行半字對準的Thumb指令
;因為處理器分為16位 32位兩種工作狀態 程序的編譯器也是分16位和32兩種編譯方式 所以下面的程序用於根據處理器工作狀態確定編譯器編譯方式
;code16偽指令指示彙編編譯器後面的指令為16位的thumb指令
;code32偽指令指示彙編編譯器後面的指令為32位的arm指令
;這段是為了統一目前的處理器工作狀態和軟體編譯方式(16位編譯環境使用tasm.exe編譯)
GBLL THUMBCODE ;設置一個全局邏輯變數
[ {CONFIG} = 16 ;if config==16 這裡表示你的目前處於領先地16位編譯方式
THUMBCODE SETL {TRUE} ;設置THUMBCODE 為 true
CODE32 ;轉入32位編譯模式
| 次 ;else
THUMBCODE SETL {FALSE} ;設置THUMBCODE 為 false
]

[ THUMBCODE ;if THUMBCODE==TRUE
CODE32 ;for start-up code for Thumb mode;轉入32位編譯方式
]
;注意下面這段程序是個宏定義 很多人對這段程序不理解 我再次強調這是一個宏定義 所以大家要注意了下面包含的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} ;PUSH the work register to stack
;將要使用的r0寄存器入棧
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} ;POP the work register and pc(jump to ISR)
;將中斷函數首地址出棧 放入程序指針中 系統將跳轉到對應中斷處理函數
MEND
;一個arm由RO,RW,ZI三個斷組成 其中RO為代碼段,RW是已經初始化的全局變數,ZI是未初始化的全局變數(對於GNU工具 對應的概念是TEXT ,DATA,BSS)bootloader
;bootloader要將RW段複製到ram中並將ZI段清零 編譯器使用下列段來記錄各段的起始和結束地址
; |Image$$RO$$Base| ; RO段起始地址
; |Image$$RO$$Limit| ; RO段結束地址加1
; |Image$$RW$$Base| ; RW段起始地址
; |Image$$RW$$Limit| ; RW段結束地址加1
; |Image$$ZI$$Base| ; ZI段起始地址
; |Image$$ZI$$Limit| ; ZI段結束地址加1
;這些標號的值是通過編譯器的設定來確定的 如編譯軟體中對ro-base和rw-base的設定,例如 ro-base=0xc000000 rw-base=0xc5f0000


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

IMPORT Main ; The main entry of mon program
;下面為代碼段
AREA Init,CODE,READONLY

;異常中斷矢量表(每個表項佔4個位元組) 下面是中斷向量表 一旦系統運行時有中斷髮生 即使移植了操作系統 如linux 處理器已經把控制權交給了操作系統 一旦發生中斷 處理器還是會跳轉到從0x0開始
;中斷向量表中某個中斷表項(依據中斷類型)開始執行
;具體中斷向量布局請參考s3c44b0 spec 例如 adc中斷向量為 0x000000c0下面對應表中第49項位置 向量地址0x0+4*(49-1)=0x000000c0
ENTRY
;扳子上電和複位后 程序開始從位於0x0處開始執行硬體剛剛上電複位后 程序從這裡開始執行跳轉到標號為ResetHandler處執行
b ResetHandler ;for debug
b HandlerUndef ;handlerUndef
b HandlerSWI ;SWI interrupt handler
b HandlerPabort ;handlerPAbort
b HandlerDabort ;handlerDAbort
b . ;handlerReserved
b HandlerIRQ
b HandlerFIQ
;***IMPORTANT NOTE***
;If the H/W vectored interrutp mode is enabled, The above two instructions should
;be changed like below, to work-around with H/W bug of S3C44B0X interrupt controller.
; b HandlerIRQ -> subs pc,lr,#4
; b HandlerIRQ -> subs pc,lr,#4

VECTOR_BRANCH
ldr pc,=HandlerEINT0 ;mGA H/W interrupt vector table
ldr pc,=HandlerEINT1 ;
ldr pc,=HandlerEINT2 ;
ldr pc,=HandlerEINT3 ;
ldr pc,=HandlerEINT4567 ;
ldr pc,=HandlerTICK ;mGA
b .
b .
ldr pc,=HandlerZDMA0 ;mGB
ldr pc,=HandlerZDMA1 ;
ldr pc,=HandlerBDMA0 ;
ldr pc,=HandlerBDMA1 ;
ldr pc,=HandlerWDT ;
ldr pc,=HandlerUERR01 ;mGB
b .
b .
ldr pc,=HandlerTIMER0 ;mGC
ldr pc,=HandlerTIMER1 ;
ldr pc,=HandlerTIMER2 ;
ldr pc,=HandlerTIMER3 ;
ldr pc,=HandlerTIMER4 ;
ldr pc,=HandlerTIMER5 ;mGC
b .
b .
ldr pc,=HandlerURXD0 ;mGD
ldr pc,=HandlerURXD1 ;
ldr pc,=HandlerIIC ;
ldr pc,=HandlerSIO ;
ldr pc,=HandlerUTXD0 ;
ldr pc,=HandlerUTXD1 ;mGD
b .
b .
ldr pc,=HandlerRTC ;mGKA
b . ;
b . ;
b . ;
b . ;
b . ;mGKA
b .
b .
ldr pc,=HandlerADC ;mGKB
b . ;
b . ;
b . ;
b . ;
b . ;mGKB
b .
b .
;0xe0=EnterPWDN
ldr pc,=EnterPWDN

LTORG
;下面是具體的中斷處理函數跳轉的宏,通過上面的$HandlerLabel的宏定義展開后跳轉到對應的中斷處理函數(對於向量中斷)
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort

HandlerADC HANDLER HandleADC
HandlerRTC HANDLER HandleRTC
HandlerUTXD1 HANDLER HandleUTXD1
HandlerUTXD0 HANDLER HandleUTXD0
HandlerSIO HANDLER HandleSIO
HandlerIIC HANDLER HandleIIC
HandlerURXD1 HANDLER HandleURXD1
HandlerURXD0 HANDLER HandleURXD0
HandlerTIMER5 HANDLER HandleTIMER5
HandlerTIMER4 HANDLER HandleTIMER4
HandlerTIMER3 HANDLER HandleTIMER3
HandlerTIMER2 HANDLER HandleTIMER2
HandlerTIMER1 HANDLER HandleTIMER1
HandlerTIMER0 HANDLER HandleTIMER0
HandlerUERR01 HANDLER HandleUERR01
HandlerWDT HANDLER HandleWDT
HandlerBDMA1 HANDLER HandleBDMA1
HandlerBDMA0 HANDLER HandleBDMA0
HandlerZDMA1 HANDLER HandleZDMA1
HandlerZDMA0 HANDLER HandleZDMA0
HandlerTICK HANDLER HandleTICK
HandlerEINT4567 HANDLER HandleEINT4567
HandlerEINT3 HANDLER HandleEINT3
HandlerEINT2 HANDLER HandleEINT2
HandlerEINT1 HANDLER HandleEINT1
HandlerEINT0 HANDLER HandleEINT0


;One of the following two routines can be used for non-vectored interrupt.
;下面這段程序是用來處理非向量中斷,具體判斷I_ISPR中各位是否置1 置1表示目前此中斷等待響應(每次只能有一位置1),從最高優先順序中斷位開始判斷,檢測到等待服務
;中斷就將pc置為中斷服務函數首地址
IsrIRQ ;using I_ISPR register.
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}

;IMPORTANT CAUTION
;if I_ISPC isn't used properly, I_ISPR can be 0 in this routine.

ldr r9,=I_ISPR
ldr r9,[r9]
mov r8,#0x0
0
movs r9,r9,lsr #1
bcs %F1
add r8,r8,#4
b %B0

1
ldr r9,=HandleADC
add r9,r9,r8
ldr r9,[r9]
str r9,[sp,#8]
ldmfd sp!,{r8-r9,pc}


;****************************************************
;* START *
;****************************************************
;扳子上電和複位后 程序開始從位於0x0執行b ResetHandler 程序從跳轉到這裡執行
;板子上電複位后 執行幾個步驟這裡通過標號在註釋中加1,2,3....標示 標號表示執行順序
;1.禁止看門狗 屏蔽所有中斷
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]

ldr r0,=INTMSK
ldr r1,=0x07ffffff ;all interrupt disable
str r1,[r0]
;2.根據工作頻率設置pll
;這裡介紹一下計算公式
;Fpllo=(m*Fin)/(p*2^s)
;m=MDIV+8,p=PDIV+2,s=SDIV
;Fpllo必須大於20Mhz小於66Mhz
;Fpllo*2^s必須小於170Mhz
;如下面的PLLCON設定中的M_DIV P_DIV S_DIV是取自option.h中
;#elif (MCLK==40000000)
;#define PLL_M (0x48)
;#define PLL_P (0x3)
;#define PLL_S (0x2)
;所以m=MDIV+8=80,p=PDIV+2=5,s=SDIV=2
;硬體使用晶振為10Mhz,即Fin=10Mhz
;Fpllo=80*10/5*2^2=40Mhz

;****************************************************
;* Set clock control registers *
;****************************************************
ldr r0,=LOCKTIME
ldr r1,=800 ; count = t_lock * Fin (t_lock=200us, Fin=4MHz) = 800
str r1,[r0]

[ PLLONSTART
ldr r0,=PLLCON ;temporary setting of PLL
ldr r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV) ;Fin=10MHz,Fout=40MHz
str r1,[r0]
]

ldr r0,=CLKCON
ldr r1,=0x7ff8 ;All unit block CLK enable
str r1,[r0]
;3.置存儲相關寄存器的程序
;這是設置SDRAM,flash ROM 存儲器連接和工作時序的程序,片選定義的程序
;SMRDATA map在下面的程序中定義
;SMRDATA中涉及的值請參考memcfg.s程序
;具體寄存器各位含義請參考s3c44b0 spec

;****************************************************
;* 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 ;Why?
bl InitStacks
;5.設置預設中斷處理函數
;****************************************************
;* 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]
;6.將數據段拷貝到ram中 將零初始化數據段清零 跳入C語言的main函數執行 到這步結束bootloader初步引導結束
;********************************************************
;* 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
STRCC r2, [r3], #4
BCC %B2

[ :LNOT:THUMBCODE
BL Main ;Don't use main() because ......;跳入main函數
B .
]

[ THUMBCODE ;for start-up code for Thumb mode
orr lr,pc,#1
bx lr
CODE16
bl Main ;Don't use main() because ......;跳入main函數
b .
CODE32
]
;4.初始化各模式下的棧指針
;****************************************************
;* The function for initializing stack *
;****************************************************
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.
;下面是pwdn模式下的相關寄存器的定義
;****************************************************
;* 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
mov r0,#0xff
0 subs r0,r0,#1
bne %B0

;exit from DRAM/SDRAM self refresh mode.
ldr r0,=REFRESH
str r3,[r0]

mov pc,lr

LTORG
;這是上面提到的對存儲寄存器初始化的數據map
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.


DCD 0x11110090 ;Bank0=OM[1:0], Bank1~Bank7=16bit, bank2=8bit;
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)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019
DCD 0x16 ;SCLK power mode, BANKSIZE 32M/32M
DCD 0x20 ;MRSR6 CL=2clk
DCD 0x20 ;MRSR7

ALIGN

;下面是對ram區域map的定義
AREA RamData, DATA, READWRITE
;這裡定義了處理器工作於各模式的堆棧區在ram中map
^ (_ISR_STARTADDRESS-0x500)

UserStack # 256 ;c1(c7)ffa00
SVCStack # 256 ;c1(c7)ffb00
UndefStack # 256 ;c1(c7)ffc00
AbortStack # 256 ;c1(c7)ffd00
IRQStack # 256 ;c1(c7)ffe00
FIQStack # 0 ;c1(c7)fff00

;這裡將中斷異常向量建立在sdram中
^ _ISR_STARTADDRESS
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 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
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 ;0xc1(c7)fff84

END 




[admin via 研發互助社區 ] S3C44b0引導註釋已經有1785次圍觀

http://cocdig.com/docs/show-post-42934.html