From 343243c7c0de3d0696fa19c08d8d81e8d6cf0a1c Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Thu, 7 Apr 2016 15:51:48 +0900 Subject: [PATCH] ARMv7-R: fix CPSR corruption after exception handling A sporadic hang with consequent crash is observed when booting: arm_prefetchabort: Prefetch abort. PC: 04d34a00 IFAR: 04d34a00 IFSR: 00000008 up_assert: Assertion failed at file:armv7-r/arm_prefetchabort.c line: 87 task: init up_dumpstate: Current sp: 004c3df0 up_dumpstate: Interrupt stack: up_dumpstate: base: 004c05fc up_dumpstate: size: 00000800 up_dumpstate: User stack: up_dumpstate: base: 004c3f58 up_dumpstate: size: 00000fec up_dumpstate: User Stack up_stackdump: 004c3de0: 004a0d14 004c3df0 004c3f58 004a0d20 00000057 004c2c58 09000000 004a42a4 up_stackdump: 004c3e00: 00000003 004c3e10 004a0f1c 004bbcef 33c44b00 004a0f28 04d34a00 00000008 up_stackdump: 004c3e20: 00000008 004a01bc 004bfd38 00000001 00007fff 00000001 34134a00 d83e4c00 up_stackdump: 004c3e40: 09000000 00000000 33c44b00 d83e4c00 0c3f4c00 00000000 00000000 00000003 up_stackdump: 004c3e60: 004c3e70 004a1494 04d34a00 200b0253 004c3ed8 004a5298 004c3ed8 6d00006d up_stackdump: 004c3e80: 0000006d 004bc3f4 00000009 004a4f64 00000009 b9e0784f 333f3ed0 69d4227d up_stackdump: 004c3ea0: d81f09bd 0f867344 5a7e2c12 8acefd34 5d00dc1b 004bc432 004c3f08 004c0e08 up_stackdump: 004c3ec0: 00000000 00000000 00000000 00000000 00000000 004a4210 004a5258 004a5300 up_stackdump: 004c3ee0: 00000000 00000001 ffffffff 004c3f80 000002b0 004a4234 00000007 004c3f08 up_stackdump: 004c3f00: 004a58b4 004bc432 004bc3f4 004c3f80 000002b0 0000029c 00000000 0000029c up_stackdump: 004c3f20: 00000000 004a5900 0000ff01 00000000 00000000 004a61f4 00000000 004a5fa4 up_stackdump: 004c3f40: 00000000 004a5f6c 00000000 004a2668 00000000 00000000 b7509f04 004c3f64 up_registerdump: R0: 00000001 00007fff 00000001 34134a00 d83e4c00 09000000 00000000 33c44b00 up_registerdump: R8: d83e4c00 0c3f4c00 00000000 00000000 00000003 004c3e70 004a1494 04d34a00 up_registerdump: CPSR: 200b0253 It seems to be caused by the corrupted or wrong CPSR restored on return from exception. NuttX restores the context using code like this: msr spsr, r1 GCC translates this to: msr spsr_fc, r1 As a result, not all SPSR fields are updated on exception return. This should be: msr spsr_fsxc, r1 On some evaluation boards, spsr_svc may have totally invalid value at power-on-reset. As it is not initialized at boot, the code above may result in the corruption of cpsr and thus unexpected behavior. Reported-by: Eunbong Song Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/arm_vectors.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S index 216633e3a36..0f088b73586 100644 --- a/arch/arm/src/armv7-r/arm_vectors.S +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -202,7 +202,7 @@ arm_vectorirq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -331,7 +331,7 @@ arm_vectorsvc: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -913,7 +913,7 @@ arm_vectorfiq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the