简体   繁体   中英

Instruction for changing the ARM mode is not working “msr cpsr_c XX”

need a help.

Trying to run a test code for Raspberry Pi2 (Cortex-A7) Baremetal Led blinking example.

Below code works perfectly.

.extern __bss_start
.extern __bss_end

.extern FreeRTOS_IRQ_Handler
.extern FreeRTOS_SVC_Handler
.extern main

.section .init
.global _start

.equ CPSR_MODE_USER,       0x10
.equ CPSR_MODE_FIQ,        0x11
.equ CPSR_MODE_IRQ,        0x12
.equ CPSR_MODE_SVR,        0x13
.equ CPSR_MODE_ABORT,      0x17
.equ CPSR_MODE_UNDEFINED,  0x1B
.equ CPSR_MDOE_SYSTEM,     0x1F

.equ CPSR_IRQ_INHIBIT,     0x80
.equ CPSR_FIQ_INHIBIT,     0x40
.equ CPSR_THUMB,           0x20

_start:
  ldr pc, _reset_vector
  ldr pc, _undefined_instruction_vector
  ldr pc, _software_interrupt_vector
  ldr pc, _prefetch_abort_vector
  ldr pc, _data_abort_vector
  ldr pc, _unused_vector
  ldr pc, _interrupt_vector
  ldr pc, _fast_interrupt_vector

_reset_vector:                   .word _reset
_undefined_instruction_vector:   .word _undefined_instruction
_software_interrupt_vector:      .word _software_interrupt
_prefetch_abort_vector:          .word _prefetch_abort
_data_abort_vector:              .word _data_abort
_unused_vector:                  .word _unused
_interrupt_vector:               .word _interrupt
_fast_interrupt_vector:          .word _fast_interrupt

_reset:
  mov    r0, #0x8000
  mov    r1, #0x0000
  ldmia  r0!,{r2, r3, r4, r5, r6, r7, r8, r9}
  stmia  r1!,{r2, r3, r4, r5, r6, r7, r8, r9}
  ldmia  r0!,{r2, r3, r4, r5, r6, r7, r8, r9}
  stmia  r1!,{r2, r3, r4, r5, r6, r7, r8, r9}

//      mov r0, #(CPSR_MODE_SVR | CPSR_IRQ_INHIBIT | CPSR_FIQ_INHIBIT)
//      msr cpsr_c, r0
  mov sp, #(64 * 1024 * 1024)

  ldr r0, =__bss_start
  ldr r1, =__bss_end

  mov r2, #0

 _bss_init:
    cmp     r0,r1
    it      lt
    strlt   r2,[r0], #4
    blt     _bss_init

bl main

_loop:
  b _loop


_undefined_instruction:
  b _undefined_instruction

_software_interrupt:
  b _software_interrupt

_prefetch_abort:
  b _prefetch_abort

_data_abort:
  b _data_abort

_unused:
  b _unused

_interrupt:
  b _interrupt

_fast_interrupt:
  b _fast_interrupt

However, when I remove the comment which is in the middle of the code.

  mov r0, #(CPSR_MODE_SVR | CPSR_IRQ_INHIBIT | CPSR_FIQ_INHIBIT)
  msr cpsr_c, r0

This no longer boots to the main function.

Need to change the mode so that I can setup the stack pointer for each mode. but the instructions for doing it seems not working.

Do you have idea? Any help to understand what is happening is welcome.

First of all, thanks, "old_timer" for giving me a comment.

From certain point of Raspberry Pi 2 image release, they've decided to boot with HYP mode (not SVC mode).

Inserting following check code resolves the issue.

_reset:
    cpsid if

    /* Check if HYP mode */
    mrs r0, cpsr_all
    and r0, r0, #0x1F
    mov r8, #0x1A
    cmp r0, r8
    beq overHyped
    b continueBoot

overHyped: /* Get out of HYP mode */
    ldr r1, =continueBoot
    msr ELR_hyp, r1
    mrs r1, cpsr_all
    and r1, r1, #0x1f   ;@ CPSR_MODE_MASK
    orr r1, r1, #0x13   ;@ CPSR_MODE_SUPERVISOR
    msr SPSR_hyp, r1
    eret

continueBoot:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM