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

📄 start.s

📁 学习启动代码过程中
💻 S
📖 第 1 页 / 共 2 页
字号:
    ;Initialize stacks
	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]

	ldr	r0, =BWSCON
	ldr	r0, [r0]
	ands	r0, r0, #6		;OM[1:0] != 0, NOR FLash boot
	bne	copy_proc_beg		;don't read nand flash
	adr	r0, ResetEntry		;OM[1:0] == 0, NAND FLash boot
	cmp	r0, #0				;if use Multi-ice, 
	bne	copy_proc_beg		;don't read nand flash for boot
;===========================================================
nand_boot_beg
	mov	r5, #NFCONF
	;使能NAND FLASH控制器
	;初始化ECC
	;禁止NAND FLASH片选,也就是指明当前不使用NAND(不进行读写操作)
	;TACLS=7,即OLE&ALE持续时间=HCLK * (7+1)
	;TWRPH0=7,即TWRPH0持续时间=HCLK * (7+1)
	;TWRPH1=7,即TWRPH1持续时间=HCLK * (7+1)
	ldr	r0,	=(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7)
	str	r0,	[r5]
	
	bl	ReadNandID	;返回后,r5存放id

	;校验NAND FLASH id是否正确
	mov	r6, #0
	ldr	r0, =0xec73
	cmp	r5,	r0
	beq	%F1
	ldr	r0, =0xec75
	cmp	r5, r0
	beq	%F1
	mov	r6, #1
1	
	bl	ReadNandStatus	;返回后,r1存放Status
	
	mov	r8, #0
	ldr	r9, =ResetEntry
2	
	ands	r0, r8, #0x1f
	bne		%F3
	mov		r0, r8
	bl		CheckBadBlk
	cmp		r0, #0
	addne	r8, r8, #32
	bne		%F4
3	
	mov	r0, r8
	mov	r1, r9
	bl	ReadNandPage	;r0存放要读取的地址,作为参数传递给ReadNandPage。
				;读取的数据,存方在[r4]之后的连续512字节中。
	add	r9, r9, #512
	add	r8, r8, #1
4	
	cmp	r8, #256
	bcc	%B2
	
	mov	r5, #NFCONF			;DsNandFlash
	ldr	r0, [r5]
	and	r0, r0, #~0x8000
	str	r0, [r5]
	ldr	pc, =copy_proc_beg
;===========================================================

;6.搬运RO、RW段到预设的地址
;注意:这里是从SRAM搬运到SDARM,所以可以直接通过地址访问。
;如果要访问FLASH,需要专门的代码,而不能通过全局地址直接访问FLASH中的内容。
copy_proc_beg
	adr	r0, ResetEntry
	ldr	r2, BaseOfROM
	
	;判断是否需要把启动代码搬运到SDRAM中。
	;如果不需要,直接跳转到InitRam,搬运RW段。
	;关于不需要搬运的情况,可以是R0=0x0,也就是只读程序在ROM中运行,只需要把RW段搬运到RAM中即可。
	cmp	r0, r1
	ldreq	r0, TopOfROM
	beq	InitRam	

	ldr r3, TopOfROM
0	
	;r0=0x0		;r2=R0_Base	;r3=R0_Limit
	;把0x0处的启动代码,搬运到R0_Base所在地址,也就是从 NAND FLASH 搬运到 SDRAM 中。
	ldmia	r0!, {r4-r7}
	stmia	r2!, {r4-r7}
	cmp	r2, r3
	bcc	%B0
	
	;计算r0,让 r0=下载时R0段的结束地址
	sub	r2, r2, r3
	sub	r0, r0, r2				
	
	;下载时,R0和RW是连在一起的。
	;同样,上电之前,RO和RW也是连在一起存储在ROM中,而运行时,RW必须在RAM中,所以要进行搬运。
	;这里需要把RW搬到运行时的RW地址
	;这牵扯到 下载域 和 运行域 的概念,请参阅相关的资料。
InitRam
	ldr	r2, BaseOfBSS
	ldr	r3, BaseOfZero	
0
	;r0=下载时R0段的结束地址	;r2=RW_Base	;r3=ZI_Base
	;把RO段后面的数据(也就是下载时的RW段),搬运到RW_Base所在地址。
	cmp	r2, r3
	ldrcc	r1, [r0], #4
	strcc	r1, [r2], #4
	bcc	%B0	

	mov	r0,	#0
	ldr	r3,	EndOfBSS
1	
	;r2=刚才搬运的RW段实际长度
	;r3=RW_Limit,是设置的RW段最大长度
	;r0=0
	;这里是把RW中没有用到的地方清零
	cmp	r2,	r3
	strcc	r0, [r2], #4
	bcc	%B1	

	;send reset status to main function
	ldr	r1, =GSTATUS2
	ldr	r0, [r1]
	str	r0, [r1]	;clear reset status

;7.把控制权交给main函数

    [ :LNOT:THUMBCODE
    	ldr pc, GotoMain	;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
    ]

;===========================================================
	EXPORT	disable_irq
disable_irq
	mrs	r0, cpsr				;enter svc mode and disable irq,fiq
	orr	r0, r0, #0xc0
	msr	cpsr_c, r0
	mov	pc, lr
	
ReadNandID
	mov	 r7,#NFCONF	

	;[r7,#0]是NFCONF寄存器的地址,这里使能NAND FLASH Chip
	ldr      r0,[r7,#0]		;NFChipEn();
	bic      r0,r0,#0x800
	str      r0,[r7,#0]

	;[r7,#4]是NFCMD寄存器的地址,这里把0x90写入,它是读ID操作的命令。
	mov      r0,#0x90		;WrNFCmd(RdIDCMD);
	strb     r0,[r7,#4]
	;[r7,#8]是NFADDR寄存器的地址,这里把地址0x0写入。
	mov      r4,#0			;WrNFAddr(0);
	strb     r4,[r7,#8]	
1
	;[r7,#0x10]是NFSTAT寄存器的地址,等待读操作完成
	ldr      r0,[r7,#0x10]	
	tst      r0,#1
	beq      %B1

	;[r7,#0xc]是NFDATA寄存器的地址,它存放了刚才读取的数据。
	ldrb     r0,[r7,#0xc]	
	mov      r0,r0,lsl #8	;id  = 读取的数据<<8;

	ldrb     r1,[r7,#0xc]	
	orr      r5,r1,r0	;id |= RdNFDat();

	;[r7,#0]是NFCONF寄存器的地址,这里禁止NAND FLASH Chip
	ldr      r0,[r7,#0]		;NFChipDs();
	orr      r0,r0,#0x800
	str      r0,[r7,#0]	
	mov		 pc,lr		;r5存放id
	
ReadNandStatus
	mov	 r7,#NFCONF
	ldr      r0,[r7,#0]		;NFChipEn();
	bic      r0,r0,#0x800
	str      r0,[r7,#0]
	mov      r0,#0x70		;WrNFCmd(QUERYCMD);
	strb     r0,[r7,#4]	
	ldrb     r1,[r7,#0xc]		;r1 = RdNFDat();
	ldr      r0,[r7,#0]		;NFChipDs();
	orr      r0,r0,#0x800
	str      r0,[r7,#0]
	mov		 pc,lr		;r1存放Status

WaitNandBusy
	mov      r0,#0x70		;WrNFCmd(QUERYCMD);
	mov      r1,#NFCONF
	strb     r0,[r1,#4]
1							;while(!(RdNFDat()&0x40));	
	ldrb     r0,[r1,#0xc]
	tst      r0,#0x40
	beq		 %B1
	mov      r0,#0			;WrNFCmd(READCMD0);
	strb     r0,[r1,#4]
	mov      pc,lr

CheckBadBlk
	mov		r7, lr
	mov		r5, #NFCONF
	
	bic		r0, r0, #0x1f	;addr &= ~0x1f;
	ldr      r1,[r5,#0]		;NFChipEn()
	bic      r1,r1,#0x800
	str      r1,[r5,#0]	

	mov      r1,#0x50		;WrNFCmd(READCMD2)
	strb     r1,[r5,#4]	
	mov      r1, #5
	strb     r1,[r5,#8]		;WrNFAddr(5)
	strb     r0,[r5,#8]		;WrNFAddr(addr)
	mov      r1,r0,lsr #8	;WrNFAddr(addr>>8)
	strb     r1,[r5,#8]	
	cmp      r6,#0			;if(NandAddr)		
	movne    r0,r0,lsr #16	;WrNFAddr(addr>>16)
	strneb   r0,[r5,#8]
	
	bl		WaitNandBusy	;WaitNFBusy()

	ldrb	r0, [r5,#0xc]	;RdNFDat()
	sub		r0, r0, #0xff
	
	mov      r1,#0			;WrNFCmd(READCMD0)
	strb     r1,[r5,#4]	
	
	ldr      r1,[r5,#0]		;NFChipDs()
	orr      r1,r1,#0x800
	str      r1,[r5,#0]
	
	mov		pc, r7
	
ReadNandPage
	mov	 r7,lr
	mov      r4,r1
	mov      r5,#NFCONF

	ldr      r1,[r5,#0]		;NFChipEn()
	bic      r1,r1,#0x800
	str      r1,[r5,#0]	

	mov      r1,#0			
	strb     r1,[r5,#4]		;WrNFCmd(READCMD0)
	strb     r1,[r5,#8]		;WrNFAddr(0),column地址,0表示从页首开始读取。
	strb     r0,[r5,#8]		;WrNFAddr(addr)
	mov      r1,r0,lsr #8		
	strb     r1,[r5,#8]		;WrNFAddr(addr>>8),接着连续写入两次地址,共16位,是page地址
	cmp      r6,#0			;if(NandAddr)		
	movne    r0,r0,lsr #16	
	strneb   r0,[r5,#8]		;WrNFAddr(addr>>16),接着连续写入三次地址,共17位,是page地址
	
	ldr      r0,[r5,#0]		;InitEcc()
	orr      r0,r0,#0x1000
	str      r0,[r5,#0]	
	
	bl       WaitNandBusy	;WaitNFBusy()
	
	mov      r0,#0			;for(i=0; i<512; i++)
1
	ldrb     r1,[r5,#0xc]		;buf[i] = RdNFDat()
	strb     r1,[r4,r0]
	add      r0,r0,#1
	bic      r0,r0,#0x10000
	cmp      r0,#0x200
	bcc      %B1
	
	ldr      r0,[r5,#0]		;NFChipDs()
	orr      r0,r0,#0x800
	str      r0,[r5,#0]
		
	mov		 pc,r7		;读取的数据,存方在[r4]之后的连续512字节中。

;===========================================================
;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'

	;每一种模式都拥有自己的物理sp。程序初始化R13,使其指向该模式专用的栈地址。
	;需要分别初始化各个模式的SP。
	mrs	r0,cpsr			;mrs,专门用来操作(读取和写入)CPSR或SPSR的指令。
	bic	r0,r0,#MODEMASK		;位清零指令,清r0,再附给ro
	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.
	

;这是上面提到的对存储寄存器初始化的数据map
	LTORG

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 0x1f7c;((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
;    	DCD 0x20            ;MRSR6 CL=2clk
;    	DCD 0x20            ;MRSR7

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|

	GBLS	main_entry
main_entry	SETS	"Main"	
	IMPORT	$main_entry
GotoMain	DCD	$main_entry		

    	ALIGN


    	AREA RamData, DATA, READWRITE
;这里将中断异常向量建立在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',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
HandleEINT0   	#   4
HandleEINT1   	#   4
HandleEINT2   	#   4
HandleEINT3   	#   4
HandleEINT4_7	#   4
HandleEINT8_23	#   4
HandleRSV6	#   4
HandleBATFLT   	#   4
HandleTICK   	#   4
HandleWDT	#   4
HandleTIMER0 	#   4
HandleTIMER1 	#   4
HandleTIMER2 	#   4
HandleTIMER3 	#   4
HandleTIMER4 	#   4
HandleUART2  	#   4
HandleLCD 	#   4
HandleDMA0	#   4
HandleDMA1	#   4
HandleDMA2	#   4
HandleDMA3	#   4
HandleMMC	#   4
HandleSPI0	#   4
HandleUART1	#   4
HandleRSV24	#   4
HandleUSBD	#   4
HandleUSBH	#   4
HandleIIC   	#   4
HandleUART0 	#   4
HandleSPI1 	#   4
HandleRTC 	#   4
HandleADC 	#   4

        END

⌨️ 快捷键说明

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