> 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 */ \ >
