I know that ARM926ej-s is using full descending stack. Now I have this startup code in which i have comented using /**/
on lines that are relevant for this question.
.global __start
.global arm926ejs_reset
.global dcache_flush
.global __gnu_bssstart
.global __gnu_bssend
.global __image_size
.EQU MODE_USR, 0x010
.EQU MODE_FIQ, 0x011
.EQU MODE_IRQ, 0x012
.EQU MODE_SVC, 0x013
.EQU MODE_SVC_NI, 0x0D3
.EQU MODE_ABORT, 0x017
.EQU MODE_UNDEF, 0x01b
.EQU MODE_SYSTEM, 0x01f
.EQU MODE_BITS, 0x01f
.EQU I_MASK, 0x080
.EQU F_MASK, 0x040
.EQU IF_MASK, 0x0C0
.EQU BROM_MMU_BASE_ADDR, 0x1201C000
.EQU MMU_DISABLE_MASK, 0xFFFFEFFA
.EQU MMU_ENABLE_MASK, 0x00001005
.EQU FIQ_STACK_SIZE, 128
.EQU IRQ_STACK_SIZE, 256
.EQU ABORT_STACK_SIZE, 32
.EQU UNDEF_STACK_SIZE, 32
.EQU SYSTEM_STACK_SIZE, 64
.text
.code 32
.align 2
__start:
arm926ejs_reset:
B arm926ejs_reset_handler /*reset vector*/
.word 0x41676d69
.word 0,0,0,0,0
image_type:
.word 0x0000000A
sizeOfPermanentCode:
.word (__image_size)
.word 0,0
bootparameter:
.word 0
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
arm926ejs_reset_handler:
MOV r0, #MODE_SVC_NI
MSR cpsr_cxsf, r0
MRC p15, 0, r1, c1, c0, 0
LDR r2,=MMU_DISABLE_MASK
AND r1, r1, r2
MCR p15, 0, r1, c1, c0, 0
MOV r1,#0
MCR p15, 0, r1, c8, c7, 0
MCR p15, 0, r1, c7, c7, 0
MRC p15, 0, r1, c1, c0, 0
LDR r2,=0x1000
ORR r1, r1, r2
MCR p15, 0, r1, c1, c0, 0
MVN r1, #0
MCR p15, 0, r1, c3, c0, 0
LDR r3, =BROM_MMU_BASE_ADDR
MCR p15, 0, r3, c2, c0, 0
LDR r5, =inVirtMem
MRC p15, 0, r1, c1, c0, 0
LDR r2,=MMU_ENABLE_MASK
ORR r1, r1, r2
MCR p15, 0, r1, c1, c0, 0
MOV pc, r5
NOP
NOP
NOP
inVirtMem:
ADR r3, arm926ejs_reset /*we store the reset vector address*/
SUB r3, r3, #4 /*why do we then substract 4 bytes?*/
MOV r1, #IF_MASK
ORR r0, r1, #MODE_FIQ /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #FIQ_STACK_SIZE
ORR r0, r1, #MODE_IRQ /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #IRQ_STACK_SIZE
ORR r0, r1, #MODE_ABORT /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #ABORT_STACK_SIZE
ORR r0, r1, #MODE_UNDEF /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #UNDEF_STACK_SIZE
ORR r0, r1, #MODE_SYSTEM /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #SYSTEM_STACK_SIZE
ORR r0, r1, #MODE_SVC /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
LDR r0, =__gnu_bssstart
LDR r1, =__gnu_bssend
MOV r2, #0
clearzi:
CMP r0, r1
BEQ clearzi_exit
STR r2, [r0]
ADD r0, r0, #4
B clearzi
clearzi_exit:
load_entry:
LDR pc, =c_entry
NOP
dcache_flush:
CMP r0, #0
BNE inval
flushonly:
MRC p15, 0, r15, c7, c10, 3
BNE flushonly
MOV pc, lr
inval:
MRC p15, 0, r15, c7, c14, 3
BNE inval
MOV pc, lr
.END
In the code above the first comment shows a reset vector (a branching instruction B arm926ejs_reset_handler
) immediately followed by a header and some commands to prepare the mcu...
Now take a look at the next comment where we store the reset vector's address into register r3
and in the next line we substract the 4
bytes from this address.
Q1: Why do we do this? Does this address now show at the location of the .word 0x41676d69
?
In next lines there are multiple simmilar blocks and each sets the stack for different mcpu modes. Lets take a look at the first one where stack pointer sp
is loaded with register r3
and then the size of the stack is substracted from this address to get the stack size for this mcpu mode.
Q2: Does this stack overwrite the header from .word 0x41676d69
on and all the instructions used to prepare the mcu? Does reset vector B arm926ejs_reset_handler
stay intact? Why do we owerwrite header? Don't we need it anymore?
Now take a look at the next comment where we store the reset vector's address into register r3 and in the next line we substract the 4 bytes from this address.
Q1: Why do we do this? Does this address now show at the location of the .word 0x41676d69 ?
Generally code increments. So the value .word 0x41676d69
is after or *arm926ejs_reset+4*. When you subtract, you put the start of the descending stack just before the code memory.
Q2: Does this stack overwrite the header from .word 0x41676d69 on and all the instructions used to prepare the mcu? Does reset vector B arm926ejs_reset_handler stay intact? Why do we owerwrite header? Don't we need it anymore?
No, it is not over-written. The memory before the image is used for the stacks.
User contributions licensed under CC BY-SA 3.0