IMX53 initialize stacks

2019-09-16 16:30发布

问题:

I am booting Android on an IMX53 Sabre tablet. I am trying to initialize stacks for the different processor modes. The following is my monitor initialization code:

@ Install Secure Monitor
@ -----------------------
ldr r1, =ns_image                   @ R1 is used
str r0, [r1]
ldr r0, =tz_monitor                    @ Get address of Monitors vector table
mcr p15, 0, r0, c12, c0, 1          @ Write Monitor Vector Base Address Register

@ Save Secure state
@ ------------------
ldr    r0, =S_STACK_LIMIT           @ Get address of Secure state stack
stmfd  r0!, {r4-r12}                @ Save general purpose registers
@ ADD support for SPs
mrs    r1, cpsr                     @ Also get a copy of the CPSR
stmfd  r0!, {r1, lr}                @ Save CPSR and LR


ldr r1, =STACK_ADDR

msr cpsr_c, #Mode_FIQ | I_Bit | F_Bit 
sub sp, r1, #Offset_FIQ_Stack

msr cpsr_c, #Mode_IRQ | I_Bit | F_Bit 
sub sp, r1, #Offset_IRQ_Stack

msr cpsr_c, #Mode_ABT | I_Bit | F_Bit 
sub sp, r1, #Offset_ABT_Stack

msr cpsr_c, #Mode_UND | I_Bit | F_Bit  
sub sp, r1, #Offset_UND_Stack   

msr cpsr_c, #Mode_SYS | I_Bit | F_Bit 
sub sp, r1, #Offset_SYS_Stack

msr cpsr_c, #Mode_SVC | I_Bit | F_Bit 
sub sp, r1, #Offset_SVC_Stack

msr cpsr_c, #Mode_MON | I_Bit | F_Bit 
sub sp, r1, #Offset_MON_Stack


cps    #Mode_MON                    @ Move to Monitor mode after saving Secure state


@ Save Secure state stack pointer
@ --------------------------------
ldr r1, =S_STACK_SP                 @ Get address of global
str r0, [r1]                        @ Save pointer


@ Set up initial NS state stack pointer
@ --------------------------------------
ldr r0, =NS_STACK_SP                @ Get address of global
ldr r1, =NS_STACK_LIMIT             @ Get top of Normal state stack (assuming FD model)
str r1, [r0]                        @ Save pointer


@ Set up exception return information
@ ------------------------------------
@IMPORT  ns_image

ldr lr, ns_image                    @ ns_image
msr spsr_cxsf, #Mode_SVC            @ Set SPSR to be SVC mode

@ Switch to Normal world
@ -----------------------
mrc p15, 0, r4, c1, c1, 0           @ Read Secure Configuration Register data
bic r4, #0x66
orr r4, #0x19
//orr r4, #NS_BIT                     @ Set NS bit
mcr p15, 0, r4, c1, c1, 0           @ Write Secure Configuration Register data

@ Clear general purpose registers
@ --------------------------------
mov r0,  #0
mov r1,  #0
mov r2,  #0
mov r3,  #0
mov r4,  #0
mov r5,  #0
mov r6,  #0
mov r7,  #0
mov r8,  #0
mov r9,  #0
mov r10, #0
mov r11, #0
mov r12, #0

movs pc, lr

Android booting happens fine with this, but I am not sure if the stack pointers are set up correctly, as I am not able to use them as described at IMX53 external abort. Are the stack initializations correct?

Other relevant code snippets:

.equ Mode_USR, 0x10 @ User Mode
.equ Mode_FIQ, 0x11 @ Fast Interrupt Mode
.equ Mode_IRQ, 0x12 @ Interrupt Mode
.equ Mode_SVC, 0x13 @ Supervisor Mode
.equ Mode_ABT, 0x17 @ Abort Mode
.equ Mode_UND, 0x1B @ Undefined Mode
.equ Mode_SYS, 0x1F @ System Mode
.equ Mode_MON, 0x16 @ Monitor Mode
.equ STACK_ADDR,    0xa0000000

.equ I_Bit,    0x80 @ IRQ interrupts disabled
.equ F_Bit,    0x40 @ FIQ interrupts disabled
.equ NS_BIT,   0x1



/* memory reserved (in bytes) for stacks of different mode */
.equ Len_FIQ_Stack,  64
.equ Len_IRQ_Stack,  64
.equ Len_ABT_Stack,  64
.equ Len_UND_Stack,  64
.equ Len_SVC_Stack,  64
.equ Len_USR_Stack,  64
.equ Len_MON_Stack,  64
.equ Len_SYS_Stack,  64

.equ Offset_FIQ_Stack, 0
.equ Offset_IRQ_Stack, Offset_FIQ_Stack + Len_FIQ_Stack
.equ Offset_ABT_Stack, Offset_IRQ_Stack + Len_IRQ_Stack
.equ Offset_UND_Stack, Offset_ABT_Stack + Len_ABT_Stack
.equ Offset_SVC_Stack, Offset_UND_Stack + Len_UND_Stack
.equ Offset_USR_Stack, Offset_SVC_Stack + Len_SVC_Stack
.equ Offset_MON_Stack, Offset_USR_Stack + Len_USR_Stack
.equ Offset_SYS_Stack, Offset_MON_Stack + Len_MON_Stack