2410init.s

来自「2410处理器bootloader,的初试化配置和 系统调用的寄存器配置函数」· S 代码 · 共 429 行

S
429
字号
;=======================================================================================================================
; File Name : 2410init.s
; Author	: Hanl
; Descript	: S3C2410x system start up codes
;			  Configure memory, ISR ,stacks
;			  Initialize C-variables
; History	:
;			(1) Hanl, Programming start, Dec 27, 2005
;=======================================================================================================================

;*------------------------------------------------------------------------------------------*/
;*	 								constant define						 				    */
;*------------------------------------------------------------------------------------------*/
USERMODE				EQU			0x10
FIQMODE					EQU			0x11
IRQMODE					EQU			0x12
SVCMODE					EQU			0x13
ABORTMODE				EQU			0x17
UNDEFMODE				EQU			0x1b
MODEMASK				EQU			0x1f
NOINT					EQU			0xc0
CPSR_IRQ_EN				EQU			0x80		;/*  */
CPSR_IRQ_MASK			EQU			0x40		;/* disable Interrupt Mode (IRQ) */
CPSR_FIQ_MASK			EQU			0x80		;/* disable Fast Interrupt Mode (FIQ) */

;	include ../inc/option.inc
	include ../inc/memcfg.inc
	include ../inc/2410addr.inc
  
	IMPORT			|Image$$RO$$Base|
	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 */


	MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
    sub	    sp,sp,#4			;	/* decrement sp(to store jump address) */							
    stmfd   sp!,{r0}			;	/* PUSH 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}			;	/* POP the work register and pc(jump to ISR) */
	MEND

;*******************************************************************************
;* Macro Name     : MOV_PC_LR
;* Description    : lr -> pc without mode change
;* Input          : none
;* Output         : none
;*******************************************************************************

;=============================================================================================
; reset entry point  
;=============================================================================================
	AREA        rst, CODE, READONLY

	EXPORT	__ENTRY
__ENTRY
	b	ResetHandler 
	
	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

	
;=============================================================================================
; EnterPWDN  
; 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			
	mov r2,r0			; r2=rCLKCON
	tst r0,#0x8			; POWER_OFF mode?
	bne ENTER_POWER_OFF

ENTER_STOP	
	ldr r0,=REFRESH		
	ldr r3,[r0]			; r3=rREFRESH	
	mov r1, r3
	orr r1, r1, #BIT_SELFREFRESH
	str r1, [r0]		; Enable SDRAM self-refresh
	mov r1,#16			; wait until self-refresh is issued. may not be needed.
B0
	subs r1,r1,#1
	bne B0
	ldr r0,=CLKCON		; enter STOP mode.
	str r2,[r0] 
	mov r1,#32
	
	subs r1,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 POWER_OFF mode, only the reset by wake-up is available.
	ldr r0,=REFRESH		; exit from SDRAM self refresh mode.
	str r3,[r0]	
	MOV_PC_LR

;=============================================================================================
; ENTER_POWER_OFF  
;=============================================================================================
ENTER_POWER_OFF	
; NOTE.
; 1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.	
	ldr r0,=REFRESH		
	ldr r1,[r0]			; r1=rREFRESH	
	orr r1, r1, #BIT_SELFREFRESH
	str r1, [r0]		; Enable SDRAM self-refresh
	
	mov r1,#16	   		; Wait until self-refresh is issued,which may not be needed.
B1	subs r1,r1,#1
	bne B1
	ldr r1,=MISCCR
	ldr	r0,[r1]
	orr	r0,r0,#(7<<17)  ; Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 
	str	r0,[r1]
	ldr r0,=CLKCON
	str r2,[r0]
	b .					; CPU will die here.
	
;=============================================================================================
; WAKEUP_POWER_OFF  
;=============================================================================================
WAKEUP_POWER_OFF
; Release SCLKn after wake-up from the POWER_OFF mode.
	ldr r1,=MISCCR
	ldr	r0,[r1]
	bic	r0,r0,#(7<<17)  ; SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
	str	r0,[r1]
	
; Set memory control registers
    ldr	r0,=SMRDATA
	ldr	r1,=BWSCON		; BWSCON Address
	add	r2, r0, #52		; End address of SMRDATA
B2       
	ldr	r3, [r0], #4    
	str	r3, [r1], #4    
	cmp	r2, r0		
	bne	B2
	mov r1,#256
B3	
	subs r1,r1,#1		; 1) wait until the SelfRefresh is released.
	bne B3	

	ldr r1,=GSTATUS3 	; GSTATUS3 has the start address just after POWER_OFF wake-up
	ldr r0,[r1]
	mov pc,r0

;=============================================================================================
; ARM core's exception entry  
;=============================================================================================
	ALIGN   
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ
	HANDLER HandleIRQ
HandlerUndef
	HANDLER HandleUndef
HandlerSWI     
	HANDLER HandleSWI
HandlerDabort   
	HANDLER HandleDabort
HandlerPabort   
	HANDLER HandlePabort

IsrIRQ  
	sub	sp,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,[sp,#8]
	ldmfd	sp!,{r8-r9,pc}

;=============================================================================================
; ResetHandler  
;=============================================================================================
ResetHandler
	ldr	r0,=WTCON       ; watch dog disable 
	ldr	r1,=0x0         
	str	r1,[r0]
	
	ldr	r0,=INTMSK
	ldr	r1,=0xffffffff  ; all interrupt disable
	str	r1,[r0]

	ldr	r0,=INTSUBMSK
	ldr	r1,=0x7ff		; all sub interrupt disable, 2002/04/10
	str	r1,[r0]

; To reduce PLL lock time, adjust the LOCKTIME register. 
	ldr	r0,=LOCKTIME
	ldr	r1,=0xffffff
	str	r1,[r0]

	ldr	r0,=GPBCON
	ldr	r1,=0x150055
	str	r1,[r0]
	
	ldr	r0,=GPBDAT
	ldr	r1,=0x100
	str	r1,[r0]

    
	IF PLL_ON_START = 1
; Configure MPLL
	ldr	r0,=MPLLCON          
	ldr	r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ; Fin=12MHz,Fout=50MHz
	str	r1,[r0]
	ENDIF

; Check if the boot is caused by the wake-up from POWER_OFF mode.
	ldr	r1,=GSTATUS2
	ldr	r0,[r1]
	tst	r0,#0x2
; In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler. 
	bne	WAKEUP_POWER_OFF

;=============================================================================================
; StartPointAfterPowerOffWakeUp  
;=============================================================================================
	EXPORT StartPointAfterPowerOffWakeUp
StartPointAfterPowerOffWakeUp
; Set memory control registers
;.equ	ROM_BASE,	0x0		/* image store address (in Flash)*/
	ldr	    r0,=SMRDATA

	IF	EXEC_FROM_RAM = 1
	ldr		lr,=|Image$$RO$$Base|

	sub		r0,r0,lr
	ldr		lr,=ROM_BASE
	add		r0,r0,lr
	ENDIF
	
	ldmia   r0,{r1-r13}
	ldr	    r0,=BWSCON  	;/* BWSCON Address */
	stmia   r0,{r1-r13}

	IF EXEC_FROM_RAM = 1
	ldr r0,=ROM_BASE
	ldr r1,=Image_RO_Base
	ldr r3,=Image_ZI_Limit
LoopRw
	cmp  	r1, r3
	ldrcc   r2, [r0], #4
	strcc  	r2, [r1], #4
	bcc   	LoopRw
		
	ldr 	pc,	=Jump
Jump:
	nop
	nop
	nop
	ENDIF

; Initialize stacks
;	bl	InitStacks			; if SVCstack is initialized before

;=============================================================================================
; InitStacks, initializing stacks of different mode
; Don't use DRAM operation, such as stmfd,ldmfd......
; 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
;=============================================================================================
InitStacks 
	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 has not be initialized.
;	mov	pc,lr 				; The LR register won't be valid if the current mode is not SVC mode.

;  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]

; 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	F2_1
F1_1       
	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	F1_1
F2_1       
	ldr	r1, = |Image$$ZI$$Limit|; Top of zero init segment
	mov	r2, #0
B5      
	cmp	r3, r1				; Zero init
	strcc	r2, [r3], #4
	bcc	B5

	MRS	r0, CPSR
	BIC	r0, r0, #0x80		; IRQ enable
	MSR	CPSR_cxsf, r0
	
;/* jump to Main() */	
	IF THUMBCODE=1		; for start-up code for Thumb mode
	orr	lr,pc,#1
	bx	lr
	CODE16
	bl	Main			; Don't use main() because...
	ELSE
	CODE32
	bl	Main			; Don't use main() because...
	ENDIF
	b	.                       

;=============================================================================================
;SMRDATA
; 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. 
;=============================================================================================
	LTORG
SMRDATA
	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)+(Trc<<18)+(Tchr<<16)+REFCNT)    

	DCD 0x32            ; SCLK power saving mode, BANKSIZE 128M/128M
  DCD 0x30            ; MRSR6 CL=3clk
  DCD 0x30            ; MRSR7
;	.long 0x20            ; MRSR6 CL=2clk
;	.long 0x20            ; MRSR7

;=======================================================================================================================
; ARM core's exception and user interrupt handler store address 
; The address may be different between the different assemble after link.
;=============================================================================================
	ALIGN
HandleReset			EQU		_ISR_STARTADDRESS
HandleUndef			EQU		_ISR_STARTADDRESS+4
HandleSWI				EQU		_ISR_STARTADDRESS+4*2
HandlePabort		EQU		_ISR_STARTADDRESS+4*3
HandleDabort		EQU		_ISR_STARTADDRESS+4*4
HandleReserved	EQU		_ISR_STARTADDRESS+4*5
HandleIRQ				EQU		_ISR_STARTADDRESS+4*6
HandleFIQ				EQU		_ISR_STARTADDRESS+4*7

;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
HandleEINT0		  EQU	  _ISR_STARTADDRESS+4*8
HandleEINT1			EQU		_ISR_STARTADDRESS+4*9
HandleEINT2			EQU	 	_ISR_STARTADDRESS+4*10
HandleEINT3			EQU		_ISR_STARTADDRESS+4*11
HandleEINT4_7		EQU		_ISR_STARTADDRESS+4*12
HandleEINT8_23	EQU		_ISR_STARTADDRESS+4*13
HandleRSV6			EQU		_ISR_STARTADDRESS+4*14
HandleBATFLT		EQU		_ISR_STARTADDRESS+4*15
HandleTICK			EQU		_ISR_STARTADDRESS+4*16
HandleWDT				EQU		_ISR_STARTADDRESS+4*17
HandleTIMER0		EQU		_ISR_STARTADDRESS+4*18
HandleTIMER1		EQU		_ISR_STARTADDRESS+4*19
HandleTIMER2		EQU	 	_ISR_STARTADDRESS+4*20
HandleTIMER3		EQU	 	_ISR_STARTADDRESS+4*21
HandleTIMER4		EQU	 	_ISR_STARTADDRESS+4*22
HandleUART2			EQU	 	_ISR_STARTADDRESS+4*23
HandleLCD				EQU		_ISR_STARTADDRESS+4*24
HandleDMA0			EQU		_ISR_STARTADDRESS+4*25
HandleDMA1			EQU		_ISR_STARTADDRESS+4*26
HandleDMA2    	EQU    		_ISR_STARTADDRESS+4*27
HandleDMA3    	EQU    		_ISR_STARTADDRESS+4*28
HandleMMC    		EQU    		_ISR_STARTADDRESS+4*29
HandleSPI0   		 EQU    		_ISR_STARTADDRESS+4*30
HandleUART1   	 EQU    	_ISR_STARTADDRESS+4*31
HandleRSV24   	 EQU    	_ISR_STARTADDRESS+4*32
HandleUSBD   		 EQU    		_ISR_STARTADDRESS+4*33	
HandleUSBH 		   EQU         _ISR_STARTADDRESS+4*34	
HandleIIC  			  EQU    		_ISR_STARTADDRESS+4*35  	
HandleUART 		   EQU         _ISR_STARTADDRESS+4*36 	
HandleSPI1	    EQU         _ISR_STARTADDRESS+4*37 	
HandleRTC 	   EQU    		_ISR_STARTADDRESS+4*38
HandleADC 	   EQU    		_ISR_STARTADDRESS+4*39


END

⌨️ 快捷键说明

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