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

📄 boot.s

📁 HAL硬件抽象层源码
💻 S
📖 第 1 页 / 共 2 页
字号:
	MSR	spsr_c, r2
	MOV	sp, r7			; Initial SVC stack pointer...
	SUB	r7, r7, #SVCStackSize
	BIC	r7, r7, #3		; Must be word-aligned
	MOV	r10, r7			; Bottom of SVC stack

	; Need to protect stack pointer from the SWI. When switching
	; modes Semihosted also switches stack so we end up with the user
	; stack. Semihosted SWIs promise to protect r1, r2 and r3, so copy
	; TopOfMemory to r2 and sp to r3.
	MOV	r2, r0			; Protect TopOfMemory
	MOV	r3, sp			; Protect SVC stack

	; Setup User/System mode stacks.
	ORR	r5, r4, #User32Mode
	MSR	cpsr_c, r5
	MOV	sp, r7			; Initial User stack pointer...
	SUB	r7, r7, #UserStackSize
	BIC	r7, r7, #3		; Must be word-aligned
	MOV	r10, r7			; Bottom of stacks

	; Save the top of free RAM = TopOfMemory - all stacks
	MOV	r1, r7			; Return top of free RAM in r1

	; Switch back to supervisor & recover stack & TopOfMemory.
	MOV	r0, #angel_SWIreason_EnterSVC
	SWI	SWI_Angel		; Returns EnterUSR routine in r0
	MOV	sp, r3			; Restore SVC stack
	MOV	r0, r2			; Restore TopOfMemory

	MOV	r11, #0			; No previous frame, so fp=0
	MOV	pc, r6			; Branch back to boot-up code


	INCLUDE linkdata.s		; Any compiler dependencies are in here

;	uHALir_InitBSSMemory
;
; Routine called from boot-up to initialise all memory used by 'C' and any
; predefined assembler data areas. Use of indirect links to real linker
; variables allows any memory map to be used & hides linker specifics.
; This is a real subroutine, called after stack initialisation.

uHALir_InitBSSMemory
	STMFD	sp!, {r4-r8, r14}
	LDR	r4, uHAL_TopOfROM	; Copy predefined variables from here..
	LDR	r5, uHAL_StartOfBSS	; ..to here
	LDR	r6, uHAL_ZeroBSS	; 'C' BSS starts here
	CMP	r4, r5			; Make sure there are some..
	BEQ	%8
7
	CMP	r5, r6			; Check if done..
	LDRCC	r7, [r4], #4		; if not, get word and store to RAM
	STRCC	r7, [r5], #4
	BCC	%7
8
	LDR	r4, uHAL_EndOfBSS		; Top of zero init memory

; FIXME! vvvv! How do I reserve sequential data areas which are not zero-init?
	LDR	r7, uHAL_NonZeroBSS	; Start of MMU tables
	LDR	r8, uHAL_EndOfNonZ	; End of MMU tables
; FIXME! ^^^^!

	MOV	r5, #0
9
; FIXME! vvvv! See above comment.
	; Don't zero NonZero area!
	CMP	r6, r7			; > uHAL_NonZeroBSS
	CMPCS	r6, r8			; & < uHAL_EndOfNonZ ?
	MOVCC	r6, r8			; Yes, just skip completely
; FIXME! ^^^^!

	CMP	r6, r4			; Check if done..
	STRCC	r5, [r6], #4		; if not, clear another word
	BCC	%9

	; Save the Base of Free RAM.
	; NOTE: When running semihosted, this overwrites the value
	;	returned by the host because the uHAL application is
	;	running _in_ that memory space.
	LDR	r5, =uHALiv_BaseOfMemory
	BIC	r4, r4, #3		; Make it word-aligned
	ADD	r4, r4, #8		; Next accessable word + 1
	STR	r4, [r5]

	LDMFD	sp!, {r4-r8, pc}	; restore registers and return


; Routines to return addresses of start & end of free & end of installed RAM.
uHALr_StartOfRam
	LDR	r0, uHAL_EndOfBSS	; 1st available uninitialised RAM
	MOV	pc, r14			; Return

uHALr_EndOfRam
	STMFD	sp!, {r4, r14}
	LDR	r4, =uHALiv_TopOfMemory
	LDR	r0, [r4]
	LDMFD	sp!, {r4, pc}		; restore registers and return

uHALr_EndOfFreeRam
	STMFD	sp!, {r4, r14}
	LDR	r4, =uHALiv_TopOfHeap
	LDR	r0, [r4]
	LDMFD	sp!, {r4, pc}		; restore registers and return


; STacK OVerFlow handling routine - minimum required by ARM Linker without
; defining no stack checking.
; void __rt_stkovf_split_big(void);
|__rt_stkovf_split_big|
	MOV	pc, r14			; just return



; STacK OVerFlow handling routine - minimum required by ARM Linker without
; defining no stack checking.
; void __rt_stkovf_split_small(void);
|__rt_stkovf_split_small|
	MOV	pc, r14			; just return

|_main_arg|
	MOV	pc, r14			; just return
	
; SWI handler - currently only handles switch to SVC mode.
uHALr_TrapSWI
	; SWI switches to SVC mode, with no IRQs (ARM Architecture Reference)
	STMFD	sp!, {r0-r1}
	LDR	r0, [r14, #-4]		; Read SWI instruction
	BIC	r0, r0, #0xff000000	; extract the SWI number

	LDR	r1, =SWI_Angel
	CMP	r0, r1
	LDMFD	sp!, {r0-r1}		; restore register
	BNE	uHALil_ExitSWI		; Unknown SWI

	CMP	r0, #angel_SWIreason_EnterSVC
	BEQ	uHALir_SWIEnterOS	; return in SVC mode

	CMP	r0, #angel_SWI_SYS_HEAPINFO
	BNE	uHALil_ExitSWI		; Unknown SWI

	; Load area pointed to by r1 with heap and stack info
	STMFD	sp!, {r0-r4}
	LDR	r0, [r1]		; Pointer to variables
	LDR	r4, =uHALiv_TopOfHeap
	LDR	r3, [r4], #4		; top of free RAM
	LDR	r2, [r4], #8		; base of free RAM
	STR	r2, [r0], #4
	STR	r3, [r0], #4
	LDR	r2, [r4], #4		; base of stack
	LDR	r3, [r4]
	STR	r2, [r0], #4
	STR	r3, [r0]
	LDMFD	sp!, {r0-r4}		; restore register
uHALil_ExitSWI
	MOV	r0, #0			; Pretend it was all okay
	MOVS	pc, r14			; just ignore SWI

uHALir_SWIEnterOS
	MOV	pc, r14			; return without restoring mode!


; Dummy IRQ handler - gets overwritten
uHALir_IRQProcess
	STMFD	sp!, {r4}
	MRS	r4, cpsr		; Re-enable interrupt
	BIC	r4, r4, #NoIRQ
	MSR	cpsr_c, r4
	LDMFD	sp!, {r4}
	SUBS	pc, r14, #4		; return from IRQ


; Try and capture some sensible data after undefined instruction.
uHALir_UndefProcess
	MOV	r0, sp
	; Hacked from vector copy. Should be done properly to a system
	; defined address.
	MOV	r0, #0
	LDR	r1, =uHALip_FirstVector	; Copy from here..
	LDR	r2, =uHALip_LastVector	; ..to here
	MOV	r6, #0x00010000		; Debug - make a copy of originals
	MOV	r5, r14			; Old return address (if any)
	STR	r5, [r6], #4
	MRS	r5, cpsr		; CPSR
	STR	r5, [r6], #4
	MRC	p15, 0, r5, c5, c0, 0	; Coproc 5 - 1 byte of status
	STR	r5, [r6], #4
	MRC	p15, 0, r5, c6, c0, 0	; Coproc 6 - Fault address
	STR	r5, [r6],#4
	MOV	r5, sp
	STR	r4, [r6],#4		; Old Stack
	STR	r5, [r6],#4		; New Stack
_undefLoop
	LDR	r4, [r5], #-4		; Look at stack
	STR	r4, [r6], #4
	CMP	r1,r2			; Repeat until all done
	BLO	_undefLoop

	; Okay, we've done enough, add further specific initialisation here
	BL	uHALir_DebugUndefinedInst
_Undef4ever
	B	_Undef4ever		; Try and restart..

;
; The 2.50 C compiler makes references to _memcpy,
; we don't have this routine, therefore will map this
; to uHALr_memcpy.
;
_memcpy
	B	uHALr_memcpy



 IF :DEF: DEBUG

	IMPORT	sputchar
	EXPORT	PostMortem
	EXPORT	spitword

;===========================================================================
; Ths routine will put a word value via sputchar
;===========================================================================
PutWord
	mov	r4, r14
	mov	r5, r0
	mov	r0, #0x20		; ' '
	bl	sputchar
PutWord2
	mov	r3, #28
01	mov	r0, r5, LSR r3
	ands	r0, r0, #0xf
	bne	%f02			; the first non-zero
;	subs	r3, r3, #4
;	bne	%b01			; all but the last digit
;	mov	r0, r5			; Get the only digit
02	cmp	r0, #10
	addlo	r0, r0, #0x30		; 0 - 9
	addhs	r0, r0, #0x61 - 10	; a - f
	bl	sputchar
	subs	r3, r3, #4
	mov	r0, r5, LSR r3
	and	r0, r0, #0xf
	bpl	%b02
	mov	pc, r4

; 'C' callable version of PutWord
spitword
	STMFD	sp!, {r3-r5, r14}
	BL	PutWord
	LDMFD	sp!, {r3-r5, pc}

spitstr
	MOV	r4, r14
	MOV	r5, r0
3
	LDRB	r0, [r5], #1
	CMP	r0, #0
	MOVEQ	pc, r4

	BL	sputchar
	B	%B03


;===========================================================================
; It's dead Jim, dead. Who, what where, when, how?
;
; 'Routine' to print out r0-r12, r14, spsr, fsr & far, ttb, tlb & contents
; Called only when debug system crashes (doesn't return). Uses stack so
; memory must be working and sputchar() - serial-only version of putchar().
; Make sure 'DEBUG' is defined for 'C' too.
;===========================================================================
PostMortem
	STMFD	sp!, {r9-r12, r14}	; X marks the spot
	MOV	r9, r0
	MOV	r10, r3
	MOV	r11, r4
	MOV	r12, r5

	LDR	r0, =Mort0		; Tell user what kind of error
	BL	spitstr
	MRS	r0, cpsr
	BL	PutWord

	LDR	r0, =Mort1
	BL	spitstr
	MOV	r0, r9
	BL	PutWord			; r0
	MOV	r0, r1
	BL	PutWord			; r1
	MOV	r0, r2
	BL	PutWord			; r2
	MOV	r0, r10
	BL	PutWord			; r3
	MOV	r0, r11
	BL	PutWord			; r4
	MOV	r0, r12
	BL	PutWord			; r5
	MOV	r0, r6
	BL	PutWord			; r6
	LDR	r0, =Mort2
	BL	spitstr
	MOV	r0, r7
	BL	PutWord			; r7
	MOV	r0, r8
	BL	PutWord			; r8
	LDMFD	sp!, {r9-r12, r14}	; X marks the spot
	MOV	r8, r14
	MOV	r0, r9
	BL	PutWord			; r9
	MOV	r0, r10
	BL	PutWord			; r10
	MOV	r0, r11
	BL	PutWord			; r11
	MOV	r0, r12
	BL	PutWord			; r12
	MOV	r0, r13
	STMFD	r0!, {r13, r14}^	; Assembler warns about this!
	LDMFD	r0!, {r6, r7}
	MOV	r0, r6
	BL	PutWord			; r13
	LDR	r0, =Mort3
	BL	spitstr
	MOV	r0, r7
	BL	PutWord			; r14
	MOV	r0, r8
	BL	PutWord			; pc

	; Mode before exception
	LDR	r0, =Mort4
	BL	spitstr
	MRS	r0, spsr
	BL	PutWord

	; Read Fault Status register and Fault Address register
	LDR	r0, =Mort5
	BL	spitstr
	RDMMU_FaultStatus	r0
	BL	PutWord
	LDR	r0, =Mort6
	BL	spitstr
	RDMMU_FaultAddress	r0
	MOV	r8, r0, LSR #20		; Strip irrelevent bits
	BL	PutWord
	; Read Translation Table Base reg.
	LDR	r0, =Mort7
	BL	spitstr
	RDMMU_TTBase 	 r0
	MOV	r9, r0, LSR #14		; Strip irrelevent bits
	BL	PutWord

	; Now rebuild address of page table entry
	MOV	r9, r9, LSL #14
	ORR	r9, r9, r8, LSL #2
	LDR	r0, =Mort8
	BL	spitstr
	MOV	r0, r9
	BL	PutWord
	LDR	r0, =':'
	BL	sputchar
	LDR	r0, [r9]
	BL	PutWord
	LDR	r0, ='\n'
	BL	sputchar		; Newline
	LDR	r0, ='\n'
	BL	sputchar		; Newline

	; Try again?
	B	uHALir_ResetGo

Mort0	DCB	"\ncpsr\t", 0
Mort1	DCB	"\nr0-r6\t", 0
Mort2	DCB	"\nr7-r13\t", 0
Mort3	DCB	"\nr14, pc\t", 0
Mort4	DCB	"\nspsr\t", 0
Mort5	DCB	"\nfsr", 0
Mort6	DCB	"\tfar", 0
Mort7	DCB	"\nttb\t", 0
Mort8	DCB	"\ttlb", 0

 ENDIF
 IF :DEF: USE_C_LIBRARY
   IF :DEF: uHAL_HEAP
	LTORG
	AREA CONSTANTS, DATA, READONLY
	
	EXPORT __heap_base
	EXPORT __heap_limit
	EXPORT __stack_base
	EXPORT __stack_limit

__heap_base	DCD	(uHAL_HEAP_BASE)
__heap_limit	DCD	(__heap_base + uHAL_HEAP_SIZE)
__stack_base	DCD	(uHAL_STACK_SIZE)
__stack_limit	DCD	(__stack_base - uHAL_STACK_SIZE)
		
   ENDIF	
 ENDIF	
	LTORG

	AREA uHAL_BootRam, DATA


uHALiv_TopOfHeap	% 4		; Top of free RAM (below stacks)
uHALiv_BaseOfMemory	% 4		; Semihosted Base of Heap
uHALiv_TopOfMemory	% 4		; Top of installed RAM + 1
uHALiv_BaseOfStack	% 4		; Semihosted Base of Stack

uHALiv_TopOfStack	% 4		; Semihosted Top of Stack
uHALiv_MemorySize	% 4		; Memory size in bytes
uHALv_BootSwitcherStatus % 4		; Boot Switcher Status

exit

	END

⌨️ 快捷键说明

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