mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-20 15:24:25 +00:00
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.
This commit is contained in:
parent
8279efe54e
commit
37211e7bcd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=261393
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 ; \
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 ; \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!! */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */ \
|
||||
|
|
|
@ -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" ); \
|
||||
|
|
Loading…
Reference in a new issue