> Am 15.01.2015 um 02:51 schrieb Jonathan Gray <[email protected]>:
> 
> 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.

Yeah, those cold boot crashes are the same as FreeBSD’s issues.
On returning from the first interrupt, the garbaged spsr flips the endianness
bit and makes it panic.

spsr_all not actually being all bits is really really weird.

> 
> 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