From 37211e7bcd59bc4d44c86b889c75527d6aff7577 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 2 Feb 2014 00:48:15 +0000 Subject: [PATCH] Update all arm code that manipulates the PSR registers to use modern syntax. It turns out the version of gas we're using interprets the old '_all' mask as 'fc' instead of 'fsxc'. That is, "all" doesn't really mean "all". This was the cause of the "wrong-endian register restore" bug that's been causing problems with some cortex-a9 chips. The 'endian' bit in the spsr register would never get changed (it falls into the 'x' mask group) and the first return-from-exception would fail if the chip had powered on with garbage in the spsr register that included the big-endian bit. It's unknown why this affected only certain cortex-a9 chips. --- sys/arm/arm/cpufunc_asm_arm8.S | 18 +++++++++--------- sys/arm/arm/cpufunc_asm_sa1.S | 12 ++++++------ sys/arm/arm/cpufunc_asm_sa11x0.S | 6 +++--- sys/arm/arm/cpufunc_asm_xscale.S | 12 ++++++------ sys/arm/arm/cpufunc_asm_xscale_c3.S | 12 ++++++------ sys/arm/arm/exception.S | 4 ++-- sys/arm/arm/fiq_subr.S | 6 +++--- sys/arm/arm/locore.S | 6 +++--- sys/arm/arm/setcpsr.S | 2 +- sys/arm/arm/setstack.s | 12 ++++++------ sys/arm/include/asmacros.h | 20 ++++++++++---------- sys/arm/include/atomic.h | 4 ++-- 12 files changed, 57 insertions(+), 57 deletions(-) diff --git a/sys/arm/arm/cpufunc_asm_arm8.S b/sys/arm/arm/cpufunc_asm_arm8.S index 2cb8b1171f25..787e5b287d48 100644 --- a/sys/arm/arm/cpufunc_asm_arm8.S +++ b/sys/arm/arm/cpufunc_asm_arm8.S @@ -67,9 +67,9 @@ END(arm8_clock_config) * addresses that are about to change. */ ENTRY(arm8_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(arm8_cache_cleanID) @@ -88,7 +88,7 @@ ENTRY(arm8_setttb) /* Make sure that pipeline is emptied */ mov r0, r0 mov r0, r0 - msr cpsr_all, r3 + msr cpsr_fsxc, r3 RET END(arm8_setttb) @@ -182,9 +182,9 @@ ENTRY(arm8_cache_purgeID) mov r0, #0x00000000 - mrs r3, cpsr_all + mrs r3, cpsr orr r2, r3, #(I32_bit | F32_bit) - msr cpsr_all, r2 + msr cpsr_fsxc, r2 1: mov r2, r0 mcr p15, 0, r2, c7, c11, 1 @@ -238,7 +238,7 @@ ENTRY(arm8_cache_purgeID) adds r0, r0, #0x04000000 bne 1b - msr cpsr_all, r3 + msr cpsr_fsxc, r3 RET END(arm8_cache_purgeID) @@ -255,12 +255,12 @@ ENTRY(arm8_cache_purgeID_E) * mcr p15, 0, rd, c7, c11, 1 * mcr p15, 0, rd, c7, c7, 1 */ - mrs r3, cpsr_all + mrs r3, cpsr orr r2, r3, #(I32_bit | F32_bit) - msr cpsr_all, r2 + msr cpsr_fsxc, r2 mcr p15, 0, r0, c7, c11, 1 /* clean I+D single entry */ mcr p15, 0, r0, c7, c7, 1 /* flush I+D single entry */ - msr cpsr_all, r3 + msr cpsr_fsxc, r3 RET END(arm8_cache_purgeID_E) diff --git a/sys/arm/arm/cpufunc_asm_sa1.S b/sys/arm/arm/cpufunc_asm_sa1.S index 99cd4f1f37d5..77602b1c6cc5 100644 --- a/sys/arm/arm/cpufunc_asm_sa1.S +++ b/sys/arm/arm/cpufunc_asm_sa1.S @@ -52,9 +52,9 @@ ENTRY(getttb) mrc p15, 0, r0, c2, c0, 0 ENTRY(sa1_setttb) #ifdef CACHE_CLEAN_BLOCK_INTR - mrs r3, cpsr_all + mrs r3, cpsr orr r1, r3, #(I32_bit | F32_bit) - msr cpsr_all, r1 + msr cpsr_fsxc, r1 #else ldr r3, .Lblock_userspace_access ldr r2, [r3] @@ -80,7 +80,7 @@ ENTRY(sa1_setttb) mov r0, r0 mov r0, r0 #ifdef CACHE_CLEAN_BLOCK_INTR - msr cpsr_all, r3 + msr cpsr_fsxc, r3 #else str r2, [r3] #endif @@ -154,12 +154,12 @@ _C_LABEL(sa1_cache_clean_size): #ifdef CACHE_CLEAN_BLOCK_INTR #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 #else #define SA1_CACHE_CLEAN_BLOCK \ ldr r3, .Lblock_userspace_access ; \ diff --git a/sys/arm/arm/cpufunc_asm_sa11x0.S b/sys/arm/arm/cpufunc_asm_sa11x0.S index 17efc8fcb640..ffd214ecd2ef 100644 --- a/sys/arm/arm/cpufunc_asm_sa11x0.S +++ b/sys/arm/arm/cpufunc_asm_sa11x0.S @@ -80,9 +80,9 @@ ENTRY(sa11x0_cpu_sleep) * re-enable clock switching before servicing interrupts. */ - mrs r3, cpsr_all /* 6 */ + mrs r3, cpsr /* 6 */ orr r2, r3, #(I32_bit|F32_bit) /* 7 */ - msr cpsr_all, r2 /* 8 */ + msr cpsr_fsxc, r2 /* 8 */ /* We're now 32-byte aligned */ @@ -93,7 +93,7 @@ ENTRY(sa11x0_cpu_sleep) mcr p15, 0, r0, c15, c1, 2 /* re-enable clock switching */ /* Restore interrupts (which will cause them to be serviced). */ - msr cpsr_all, r3 + msr cpsr_fsxc, r3 RET END(sa11x0_cpu_sleep) diff --git a/sys/arm/arm/cpufunc_asm_xscale.S b/sys/arm/arm/cpufunc_asm_xscale.S index 56008dc70e80..e7eda4b60e1e 100644 --- a/sys/arm/arm/cpufunc_asm_xscale.S +++ b/sys/arm/arm/cpufunc_asm_xscale.S @@ -134,9 +134,9 @@ END(xscale_control) */ ENTRY(xscale_setttb) #ifdef CACHE_CLEAN_BLOCK_INTR - mrs r3, cpsr_all + mrs r3, cpsr orr r1, r3, #(I32_bit | F32_bit) - msr cpsr_all, r1 + msr cpsr_fsxc, r1 #else ldr r3, .Lblock_userspace_access ldr r2, [r3] @@ -164,7 +164,7 @@ ENTRY(xscale_setttb) CPWAIT(r0) #ifdef CACHE_CLEAN_BLOCK_INTR - msr cpsr_all, r3 + msr cpsr_fsxc, r3 #else str r2, [r3] #endif @@ -266,12 +266,12 @@ _C_LABEL(xscale_minidata_clean_size): #ifdef CACHE_CLEAN_BLOCK_INTR #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 #else #define XSCALE_CACHE_CLEAN_BLOCK \ ldr r3, .Lblock_userspace_access ; \ diff --git a/sys/arm/arm/cpufunc_asm_xscale_c3.S b/sys/arm/arm/cpufunc_asm_xscale_c3.S index a0494d579cf9..7c39f3520dda 100644 --- a/sys/arm/arm/cpufunc_asm_xscale_c3.S +++ b/sys/arm/arm/cpufunc_asm_xscale_c3.S @@ -121,12 +121,12 @@ __FBSDID("$FreeBSD$"); #ifdef CACHE_CLEAN_BLOCK_INTR #define XSCALE_CACHE_CLEAN_BLOCK \ stmfd sp!, {r4} ; \ - mrs r4, cpsr_all ; \ + mrs r4, cpsr ; \ orr r0, r4, #(I32_bit | F32_bit) ; \ - msr cpsr_all, r0 + msr cpsr_fsxc, r0 #define XSCALE_CACHE_CLEAN_UNBLOCK \ - msr cpsr_all, r4 ; \ + msr cpsr_fsxc, r4 ; \ ldmfd sp!, {r4} #else #define XSCALE_CACHE_CLEAN_BLOCK \ @@ -348,9 +348,9 @@ END(xscalec3_l2cache_flush_rng) */ ENTRY(xscalec3_setttb) #ifdef CACHE_CLEAN_BLOCK_INTR - mrs r3, cpsr_all + mrs r3, cpsr orr r1, r3, #(I32_bit | F32_bit) - msr cpsr_all, r1 + msr cpsr_fsxc, r1 #else ldr r3, .Lblock_userspace_access ldr r2, [r3] @@ -378,7 +378,7 @@ ENTRY(xscalec3_setttb) CPWAIT(r0) #ifdef CACHE_CLEAN_BLOCK_INTR - msr cpsr_all, r3 + msr cpsr_fsxc, r3 #else str r2, [r3] #endif diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S index 55a4f64f4038..3d110e325f62 100644 --- a/sys/arm/arm/exception.S +++ b/sys/arm/arm/exception.S @@ -173,8 +173,8 @@ END(data_abort_entry) * 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!! */ diff --git a/sys/arm/arm/fiq_subr.S b/sys/arm/arm/fiq_subr.S index 7f510b233099..a9df9bf76046 100644 --- a/sys/arm/arm/fiq_subr.S +++ b/sys/arm/arm/fiq_subr.S @@ -52,14 +52,14 @@ __FBSDID("$FreeBSD$"); #endif #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: diff --git a/sys/arm/arm/locore.S b/sys/arm/arm/locore.S index 8a36741cfca2..609c31021128 100644 --- a/sys/arm/arm/locore.S +++ b/sys/arm/arm/locore.S @@ -333,10 +333,10 @@ ASENTRY_NP(mptramp) AP_DEBUG(#1) - mrs r3, cpsr_all + mrs r3, cpsr bic r3, r3, #(PSR_MODE) orr r3, r3, #(PSR_SVC32_MODE) - msr cpsr_all, r3 + msr cpsr_fsxc, r3 mrc p15, 0, r0, c0, c0, 5 and r0, #0x0f /* Get CPU ID */ @@ -446,7 +446,7 @@ ENTRY_NP(cpu_halt) 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] diff --git a/sys/arm/arm/setcpsr.S b/sys/arm/arm/setcpsr.S index ac86ba309eb5..e71e5a20adaf 100644 --- a/sys/arm/arm/setcpsr.S +++ b/sys/arm/arm/setcpsr.S @@ -61,7 +61,7 @@ ENTRY_NP(SetCPSR) mrs r3, cpsr /* Set the CPSR */ bic r2, r3, r0 eor r2, r2, r1 - msr cpsr_all, r2 + msr cpsr_fsxc, r2 mov r0, r3 /* Return the old CPSR */ diff --git a/sys/arm/arm/setstack.s b/sys/arm/arm/setstack.s index f6d412ebf13a..b47a154ab2e1 100644 --- a/sys/arm/arm/setstack.s +++ b/sys/arm/arm/setstack.s @@ -61,14 +61,14 @@ __FBSDID("$FreeBSD$"); */ ENTRY(set_stackptr) - mrs r3, cpsr_all /* Switch to the appropriate mode */ + 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 */ @@ -80,14 +80,14 @@ ENTRY(set_stackptr) */ ENTRY(get_stackptr) - mrs r3, cpsr_all /* Switch to the appropriate mode */ + 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 */ diff --git a/sys/arm/include/asmacros.h b/sys/arm/include/asmacros.h index f8d5b3e5c493..ff92cc64c784 100644 --- a/sys/arm/include/asmacros.h +++ b/sys/arm/include/asmacros.h @@ -70,7 +70,7 @@ add r0, sp, #(4*13); /* Adjust the stack pointer */ \ stmia r0, {r13-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]!; \ ldr r0, =ARM_RAS_START; \ mov r1, #0; \ @@ -86,7 +86,7 @@ add r0, sp, #(4*13); /* Adjust the stack pointer */ \ stmia r0, {r13-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]!; #endif @@ -98,7 +98,7 @@ #ifdef ARM_TP_ADDRESS #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 */ \ @@ -107,7 +107,7 @@ #else #define PULLFRAME \ ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \ - msr spsr_all, r0; \ + msr spsr_fsxc, r0; \ clrex; \ ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \ mov r0, r0; /* NOP for previous instruction */ \ @@ -142,7 +142,7 @@ 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-r12}; /* Push the user mode registers */ \ @@ -161,7 +161,7 @@ ldrne r1, [r0, #16]; /* adjust the saved PC so that */ \ cmpne r4, r1; /* execution later resumes at */ \ strhi r3, [r0, #16]; /* the RAS_START location. */ \ - mrs r0, spsr_all; \ + mrs r0, spsr; \ str r0, [sp, #-4]! #else #define PUSHFRAMEINSVC \ @@ -179,14 +179,14 @@ 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-r12}; /* Push the user mode registers */ \ add r0, sp, #(4*13); /* Adjust the stack pointer */ \ stmia r0, {r13-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]! #endif @@ -200,7 +200,7 @@ #ifdef ARM_TP_ADDRESS #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 */ \ @@ -208,7 +208,7 @@ #else #define PULLFRAMEFROMSVCANDEXIT \ ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \ - msr spsr_all, r0; /* restore SPSR */ \ + msr spsr_fsxc, r0; /* restore SPSR */ \ clrex; \ ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \ mov r0, r0; /* NOP for previous instruction */ \ diff --git a/sys/arm/include/atomic.h b/sys/arm/include/atomic.h index 0db31c73f1e6..d16849873480 100644 --- a/sys/arm/include/atomic.h +++ b/sys/arm/include/atomic.h @@ -450,13 +450,13 @@ atomic_store_rel_long(volatile u_long *p, u_long v) __asm __volatile( \ "mrs %0, cpsr;" \ "orr %1, %0, %2;" \ - "msr cpsr_all, %1;" \ + "msr cpsr_fsxc, %1;" \ : "=r" (cpsr_save), "=r" (tmp) \ : "I" (I32_bit | F32_bit) \ : "cc" ); \ (expr); \ __asm __volatile( \ - "msr cpsr_all, %0" \ + "msr cpsr_fsxc, %0" \ : /* no output */ \ : "r" (cpsr_save) \ : "cc" ); \