On Tue, 07 Dec 2004 09:05:04 GMT, "Richard" <Nowhere@Nowhere.com>
wrote:
>
>You need to setup the stacks in your startup code as follows:
>
>First define the size of the stack for each mode:
>.set UND_STACK_SIZE, 0x00000004
>.set ABT_STACK_SIZE, 0x00000004
>.set FIQ_STACK_SIZE, 0x00000004
>.set IRQ_STACK_SIZE, 0X00000400
>.set SVC_STACK_SIZE, 0x00000400
>
>A few other constants just for ease of reading.
>.set MODE_USR, 0x10 /* User Mode */
>.set MODE_FIQ, 0x11 /* FIQ Mode */
>.set MODE_IRQ, 0x12 /* IRQ Mode */
>.set MODE_SVC, 0x13 /* Supervisor Mode */
>.set MODE_ABT, 0x17 /* Abort Mode */
>.set MODE_UND, 0x1B /* Undefined Mode */
>.set MODE_SYS, 0x1F /* System Mode */
>
>
>
>////// CODE ///////
>
>/* Load R0 with the address for the first stack */
>ldr r0, .START_ADDRESS
>/* Switch to the mode for which you are going to setup the stack. */
>msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction mode */
>/* Move the stack address into the stack pointer. */
>mov sp, r0
>/* Move the address past the stack just setup. */
>sub r0, r0, #UND_STACK_SIZE
>/* Repeat for every mode. */
>msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
>mov sp, r0
>sub r0, r0, #ABT_STACK_SIZE
>msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
>mov sp, r0
>sub r0, r0, #FIQ_STACK_SIZE
>msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
>mov sp, r0
>sub r0, r0, #IRQ_STACK_SIZE
>msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
>mov sp, r0
>sub r0, r0, #SVC_STACK_SIZE
>msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
>mov sp, r0
>
>///// CODE END //////
>
>This holds the RAM address to use for the stack in R0. For each mode you
>switch to the MODE, then copy the value from R0 into the stack pointer.
>Then modifiy R0 by however many bytes you want to be available for that
>stack, before moving onto the next mode and repeating.
>
>Hope this helps.
>
>Richard.
>
>http://www.FreeRTOS.org
>
I think that I'm finally starting to see how this works. I added most
of your code and this still builds. I only modified boot.s. But I
still need clarification of ".START_ADDRESS" and the relation between
boot.s and ram.ld. I've left in my old stack initialization stuff from
a non-interrupt example. I'll remove that eventually. What do I need
to do in ram.ld to make this work? Do all the stacks go in the .bss
section? Also should I zero each stack after setting the sp? Can I
just set the stacks up in boot.s and not have to mess with ram.ld?
Paul
BOOT.S:
=============
.section .text
.code 32
.global vectors
@ define the size of the stack for each mode:
.set UND_STACK_SIZE, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000004
.set IRQ_STACK_SIZE, 0X00000400
.set SVC_STACK_SIZE, 0x00000400
@ A few other constants just for ease of reading
.set MODE_USR, 0x10 @ User Mode
.set MODE_FIQ, 0x11 @ FIQ Mode
.set MODE_IRQ, 0x12 @ IRQ Mode
.set MODE_SVC, 0x13 @ Supervisor Mode
.set MODE_ABT, 0x17 @ Abort Mode
.set MODE_UND, 0x1B @ Undefined Mode
.set MODE_SYS, 0x1F @ System Mode
.equ F_BIT, 0x40
.equ I_BIT, 0x80
vectors:
b reset @ 0x00 Reset
b exception @ 0x04 Undefined instruction
b exception @ 0x08 SWI
b exception @ 0xc0 Prefetch abort
b exception @ 0x10 Data abort
b exception @ 0x14 reserved vector
ldr pc, [pc, # -0xF20] @ 0x18 irqs fffff100 (AIC_IVR)
@ldr pc, [pc, #0xfffff100] @ 0x18 irqs fffff100 (AIC_IVR)
b exception @ 0x1c fast irqs
exception: @ 0x20
b exception
reset:
@ old code (((((((((((((((((((((
@ Begin by clearing out the .bss section defined in ram.ld
ldr r1, bss_start @ defined in ram.ld 0x4c
ldr r2, bss_end @ defined in ram.ld 0x50
ldr r3, =0
clear_bss:
cmp r1,r2
strne r3,[r1],#+4
bne clear_bss
@))))))))))))))))))))))))))))) old code
/***
@ old code:
@ldr r13,stack_pointer @ Initialize the stack pointer
@ldr r0, .START_ADDRESS @ Load R0 with the
address for the first stack
***/
ldr r0, start_address @ Load R0 with the address for
the first stack
@ Switch to the mode for which you are going to setup the
stack
msr CPSR_c, #MODE_UND|I_BIT|F_BIT @ Undefined
Instruction mode
mov sp, r0 @ Move the stack
address into the stack pointer
sub r0, r0, #UND_STACK_SIZE @ Move the address
past the stack just setup
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT @ Abort Mode
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT @ FIQ Mode
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT @ IRQ Mode
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT @ Supervisor Mode
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT @ System Mode
mov sp, r0
bl main
b vectors
stack_pointer: .word _stack_top @ defined in ram.ld
bss_start: .word __bss_start__ @ defined in ram.ld 0x4c
bss_end: .word __bss_end__ @ defined in ram.ld 0x50
start_address:
.end
RAM.LD:
==========
ENTRY(vectors)
SEARCH_DIR(.)
MEMORY {
sram : org = 0x00000000, len = 256K
}
SECTIONS {
.text : {
*(.text);
. = ALIGN(4);
} > sram
.data ADDR(.text) + SIZEOF(.text) : {
datastart = .;
__data_start__ = . ;
*(.data)
. = ALIGN(4);
__data_end__ = . ;
edata = .;
_edata = .;
} > sram
.bss ADDR(.data) + SIZEOF(.data) : {
__bss_start__ = . ;
*(.bss); *(COMMON)
__bss_end__ = . ;
_stack_bottom = . ;
. += 0x800 ;
_stack_top = . ;
} > sram
end = .;
_end = .;
__end__ = .;
/* Symbols */
.stab 0 (NOLOAD) : {
[ .stab ]
}
.stabstr 0 (NOLOAD) : {
[ .stabstr ]
}
}