The '_all' PSR mask ends up being treated as 'fc' so switch 'msr'
instructions with '_all' to '_fsxc' so  bits 23-8 are restored.
In older arm cores these bits were reserved now they are used.

While here fix 'mrs' instructions to not use psr masks, they
should take psr names.  In other words 'spsr' not 'spsr_all'.

In FreeBSD this problem caused returning from an exception to fail if
certain cortex a9 chips powered up with garbage in the psr extension/'x'
field that flipped the big endian bit.

In Bitrig these changes fixed cold boot crashes on Utilite and Nitrogen 6x.

https://mail-index.netbsd.org/source-changes/2013/12/20/msg050081.html
https://lists.freebsd.org/pipermail/svn-src-head/2014-February/055650.html
https://github.com/bitrig/bitrig/commit/f2fb0a86fc740253d02c7eb3f6d26ea48346be55

Index: arm/arm/cpufunc_asm_sa1.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/cpufunc_asm_sa1.S,v
retrieving revision 1.3
diff -u -p -r1.3 cpufunc_asm_sa1.S
--- arm/arm/cpufunc_asm_sa1.S   20 Sep 2011 22:11:40 -0000      1.3
+++ arm/arm/cpufunc_asm_sa1.S   14 Jan 2015 13:06:40 -0000
@@ -46,9 +46,9 @@
  * addresses that are about to change.
  */
 ENTRY(sa1_setttb)
-       mrs     r3, cpsr_all
+       mrs     r3, cpsr
        orr     r1, r3, #(I32_bit | F32_bit)
-       msr     cpsr_all, r1
+       msr     cpsr_fsxc, r1
 
        stmfd   sp!, {r0-r3, lr}
        bl      _C_LABEL(sa1_cache_cleanID)
@@ -69,7 +69,7 @@ ENTRY(sa1_setttb)
        mov     r0, r0
        mov     r0, r0
 
-       msr     cpsr_all, r3
+       msr     cpsr_fsxc, r3
        mov     pc, lr
 
 /*
@@ -131,12 +131,12 @@ _C_LABEL(sa1_cache_clean_size):
        .word   _C_LABEL(sa1_cache_clean_size)
 
 #define        SA1_CACHE_CLEAN_BLOCK                                           
\
-       mrs     r3, cpsr_all                                    ;       \
+       mrs     r3, cpsr                                        ;       \
        orr     r0, r3, #(I32_bit | F32_bit)                    ;       \
-       msr     cpsr_all, r0
+       msr     cpsr_fsxc, r0
 
 #define        SA1_CACHE_CLEAN_UNBLOCK                                         
\
-       msr     cpsr_all, r3
+       msr     cpsr_fsxc, r3
 
 #ifdef DOUBLE_CACHE_CLEAN_BANK
 #define        SA1_DOUBLE_CACHE_CLEAN_BANK                                     
\
Index: arm/arm/cpufunc_asm_xscale.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/cpufunc_asm_xscale.S,v
retrieving revision 1.4
diff -u -p -r1.4 cpufunc_asm_xscale.S
--- arm/arm/cpufunc_asm_xscale.S        20 Sep 2011 22:11:40 -0000      1.4
+++ arm/arm/cpufunc_asm_xscale.S        14 Jan 2015 13:06:40 -0000
@@ -128,9 +128,9 @@ ENTRY(xscale_control)
  * addresses that are about to change.
  */
 ENTRY(xscale_setttb)
-       mrs     r3, cpsr_all
+       mrs     r3, cpsr
        orr     r1, r3, #(I32_bit | F32_bit)
-       msr     cpsr_all, r1
+       msr     cpsr_fsxc, r1
 
        stmfd   sp!, {r0-r3, lr}
        bl      _C_LABEL(xscale_cache_cleanID)
@@ -152,7 +152,7 @@ ENTRY(xscale_setttb)
 
        CPWAIT(r0)
 
-       msr     cpsr_all, r3
+       msr     cpsr_fsxc, r3
        mov     pc, lr
 
 /*
@@ -244,12 +244,12 @@ _C_LABEL(xscale_cache_clean_size):
        .word   _C_LABEL(xscale_minidata_clean_size)
 
 #define        XSCALE_CACHE_CLEAN_BLOCK                                        
\
-       mrs     r3, cpsr_all                                    ;       \
+       mrs     r3, cpsr                                        ;       \
        orr     r0, r3, #(I32_bit | F32_bit)                    ;       \
-       msr     cpsr_all, r0
+       msr     cpsr_fsxc, r0
 
 #define        XSCALE_CACHE_CLEAN_UNBLOCK                                      
\
-       msr     cpsr_all, r3
+       msr     cpsr_fsxc, r3
 
 #define        XSCALE_CACHE_CLEAN_PROLOGUE                                     
\
        XSCALE_CACHE_CLEAN_BLOCK                                ;       \
Index: arm/arm/exception.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/exception.S,v
retrieving revision 1.3
diff -u -p -r1.3 exception.S
--- arm/arm/exception.S 20 Sep 2011 22:02:10 -0000      1.3
+++ arm/arm/exception.S 14 Jan 2015 13:06:41 -0000
@@ -169,8 +169,8 @@ abortdatamsg:
  *     it like a Data Abort.
  */
 ASENTRY_NP(address_exception_entry)
-       mrs     r1, cpsr_all
-       mrs     r2, spsr_all
+       mrs     r1, cpsr
+       mrs     r2, spsr
        mov     r3, lr
        adr     r0, Laddress_exception_msg
        bl      _C_LABEL(printf)        /* XXX CLOBBERS LR!! */
@@ -221,8 +221,8 @@ ASENTRY_NP(undefined_entry)
 /*
  * Get previous psr.
  */
-       mrs     r7, cpsr_all
-       mrs     r0, spsr_all
+       mrs     r7, cpsr
+       mrs     r0, spsr
        str     r0, [sp, #(16*4)]
 /*
  * Test for user mode.
@@ -237,23 +237,23 @@ ASENTRY_NP(undefined_entry)
  */
 .Lprenotuser_push:
        orr     r0, r0, #(I32_bit) /* disable interrupts */
-       msr     cpsr_all, r0
+       msr     cpsr_fsxc, r0
        mov     r1, r8
        mov     r2, r9
        mov     r3, r10
        mov     r4, r11
        mov     r5, r12
        mov     r6, r13
-       msr     cpsr_all, r7            /* back to undefined mode */
+       msr     cpsr_fsxc, r7           /* back to undefined mode */
        add     r8, sp, #(8*4)
        stmia   r8, {r1-r6}             /* r8-r13 */
 /*
  * Now back to previous mode to get r14 and spsr.
  */
-       msr     cpsr_all, r0
+       msr     cpsr_fsxc, r0
        mov     r1, r14
        mrs     r2, spsr
-       msr     cpsr_all, r7            /* back to undefined mode */
+       msr     cpsr_fsxc, r7           /* back to undefined mode */
        str     r1, [sp, #(14*4)]       /* r14 */
        str     r2, [sp, #(17*4)]       /* spsr */
 /*
@@ -272,7 +272,7 @@ ASENTRY_NP(undefined_entry)
  */
        ldr     r0, [sp, #(16*4)]       /* spsr */
        ldr     r1, [sp, #(15*4)]       /* r15 */
-       msr     spsr_all, r0
+       msr     spsr_fsxc, r0
        mov     r14, r1
 /*
  * Test for user mode.
@@ -289,23 +289,23 @@ ASENTRY_NP(undefined_entry)
        ldr     r1, [sp, #(17*4)]               /* spsr */
        ldr     r2, [sp, #(14*4)]               /* r14 */
        orr     r0, r0, #(I32_bit)
-       msr     cpsr_all, r0                    /* switch to previous mode */
-       msr     spsr_all, r1
+       msr     cpsr_fsxc, r0                   /* switch to previous mode */
+       msr     spsr_fsxc, r1
        mov     r14, r2
-       msr     cpsr_all, r7                    /* back to undefined mode */
+       msr     cpsr_fsxc, r7                   /* back to undefined mode */
 /*
  * Now r8-r13.
  */
        add     r8, sp, #(8*4)
        ldmia   r8, {r1-r6}             /* r8-r13 */
-       msr     cpsr_all, r0
+       msr     cpsr_fsxc, r0
        mov     r8, r1
        mov     r9, r2
        mov     r10, r3
        mov     r11, r4
        mov     r12, r5
        mov     r13, r6
-       msr     cpsr_all, r7
+       msr     cpsr_fsxc, r7
 .Lpull_r0r7:
 /*
  * Now the rest of the registers.
Index: arm/arm/fiq_subr.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/fiq_subr.S,v
retrieving revision 1.2
diff -u -p -r1.2 fiq_subr.S
--- arm/arm/fiq_subr.S  20 Sep 2011 22:02:11 -0000      1.2
+++ arm/arm/fiq_subr.S  14 Jan 2015 13:06:41 -0000
@@ -43,14 +43,14 @@
 #include <arm/cpuconf.h>
 
 #define        SWITCH_TO_FIQ_MODE                                              
\
-       mrs     r2, cpsr_all                                    ;       \
+       mrs     r2, cpsr                                        ;       \
        mov     r3, r2                                          ;       \
        bic     r2, r2, #(PSR_MODE)                             ;       \
        orr     r2, r2, #(PSR_FIQ32_MODE)                       ;       \
-       msr     cpsr_all, r2
+       msr     cpsr_fsxc, r2
 
 #define        BACK_TO_SVC_MODE                                                
\
-       msr     cpsr_all, r3
+       msr     cpsr_fsxc, r3
 
 /*
  * fiq_getregs:
Index: arm/arm/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/locore.S,v
retrieving revision 1.4
diff -u -p -r1.4 locore.S
--- arm/arm/locore.S    19 Oct 2011 20:18:31 -0000      1.4
+++ arm/arm/locore.S    14 Jan 2015 13:06:41 -0000
@@ -111,7 +111,7 @@ ENTRY_NP(cpu_reset)
        bic     r2, r2, #(PSR_MODE)
        orr     r2, r2, #(PSR_SVC32_MODE)
        orr     r2, r2, #(I32_bit | F32_bit)
-       msr     cpsr_all, r2
+       msr     cpsr_fsxc, r2
 
        ldr     r4, .Lcpu_reset_address
        ldr     r4, [r4]
@@ -180,12 +180,12 @@ ENTRY_NP(Execute)
        ldmia   r2, {r0-r3}
        mov     r6, sp
        mov     sp, ip
-       msr     cpsr_all, r5
+       msr     cpsr_fsxc, r5
        mov     pc, r6
 .LExec:
        mrs     r5, cpsr
 /* XXX Cannot switch thus easily back from user mode */
-       msr     cpsr_all, r4
+       msr     cpsr_fsxc, r4
        add     sp, r6, #8
        ldmfd   sp!, {r6}
        stmia   r6, {r0-r3}
Index: arm/arm/setstack.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/setstack.S,v
retrieving revision 1.2
diff -u -p -r1.2 setstack.S
--- arm/arm/setstack.S  1 Feb 2004 06:10:33 -0000       1.2
+++ arm/arm/setstack.S  14 Jan 2015 13:06:44 -0000
@@ -63,11 +63,11 @@ ENTRY(set_stackptr)
         mrs    r3, cpsr                /* Switch to the appropriate mode */
        bic     r2, r3, #(PSR_MODE)
        orr     r2, r2, r0
-        msr    cpsr_all, r2
+        msr    cpsr_fsxc, r2
 
        mov     sp, r1                  /* Set the stack pointer */
 
-        msr    cpsr_all, r3            /* Restore the old mode */
+        msr    cpsr_fsxc, r3           /* Restore the old mode */
 
        mov     pc, lr                  /* Exit */
 
@@ -82,11 +82,11 @@ ENTRY(get_stackptr)
         mrs    r3, cpsr                /* Switch to the appropriate mode */
        bic     r2, r3, #(PSR_MODE)
        orr     r2, r2, r0
-        msr    cpsr_all, r2
+        msr    cpsr_fsxc, r2
 
        mov     r0, sp                  /* Set the stack pointer */
 
-        msr    cpsr_all, r3            /* Restore the old mode */
+        msr    cpsr_fsxc, r3           /* Restore the old mode */
 
        mov     pc, lr                  /* Exit */
 
Index: arm/include/frame.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/frame.h,v
retrieving revision 1.4
diff -u -p -r1.4 frame.h
--- arm/include/frame.h 20 Sep 2011 22:02:13 -0000      1.4
+++ arm/include/frame.h 14 Jan 2015 13:06:44 -0000
@@ -207,7 +207,7 @@ struct frame {
        sub     sp, sp, #(4*17);        /* Adjust the stack pointer */     \
        stmia   sp, {r0-r14}^;          /* Push the user mode registers */ \
         mov     r0, r0;                 /* NOP for previous instruction */ \
-       mrs     r0, spsr_all;           /* Put the SPSR on the stack */    \
+       mrs     r0, spsr;               /* Put the SPSR on the stack */    \
        str     r0, [sp, #-4]!
 
 /*
@@ -217,7 +217,7 @@ struct frame {
 
 #define PULLFRAME                                                         \
         ldr     r0, [sp], #0x0004;      /* Get the SPSR from stack */     \
-        msr     spsr_all, r0;                                             \
+        msr     spsr_fsxc, r0;                                            \
         ldmia   sp, {r0-r14}^;         /* Restore registers (usr mode) */ \
         mov     r0, r0;                 /* NOP for previous instruction */ \
        add     sp, sp, #(4*17);        /* Adjust the stack pointer */     \
@@ -244,12 +244,12 @@ struct frame {
        str     r0, [sp, #-4]!;         /* Push return address */          \
        str     lr, [sp, #-4]!;         /* Push SVC lr */                  \
        str     r2, [sp, #-4]!;         /* Push SVC sp */                  \
-       msr     spsr_all, r3;           /* Restore correct spsr */         \
+       msr     spsr_fsxc, r3;          /* Restore correct spsr */         \
        ldmdb   r1, {r0-r3};            /* Restore 4 regs from xxx mode */ \
        sub     sp, sp, #(4*15);        /* Adjust the stack pointer */     \
        stmia   sp, {r0-r14}^;          /* Push the user mode registers */ \
         mov     r0, r0;                 /* NOP for previous instruction */ \
-       mrs     r0, spsr_all;           /* Put the SPSR on the stack */    \
+       mrs     r0, spsr;               /* Put the SPSR on the stack */    \
        str     r0, [sp, #-4]!
 
 /*
@@ -261,7 +261,7 @@ struct frame {
 
 #define PULLFRAMEFROMSVCANDEXIT                                                
   \
         ldr     r0, [sp], #0x0004;     /* Get the SPSR from stack */      \
-        msr     spsr_all, r0;          /* restore SPSR */                 \
+        msr     spsr_fsxc, r0;         /* restore SPSR */                 \
         ldmia   sp, {r0-r14}^;         /* Restore registers (usr mode) */ \
         mov     r0, r0;                        /* NOP for previous instruction 
*/ \
        add     sp, sp, #(4*15);        /* Adjust the stack pointer */     \

Reply via email to