aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Meloun <mmel@FreeBSD.org>2015-11-10 13:47:28 +0000
committerMichal Meloun <mmel@FreeBSD.org>2015-11-10 13:47:28 +0000
commit5fcbe89ac996806a05411fa3b76d73ec9c5b4951 (patch)
treee1574b875626964c8d5b44c78712d9eb3687ceb9
parent7c357fe0eeb6e611b3293e04944b0c649316de7f (diff)
downloadsrc-5fcbe89ac996806a05411fa3b76d73ec9c5b4951.tar.gz
src-5fcbe89ac996806a05411fa3b76d73ec9c5b4951.zip
ARM: Refactor interrupt_enable/disable/restore.
Allow manipulation with PSR_A bit on ARMv6+. Remove declaration of unused functions. This effectively enables asynchronous aborts on early bootstrap stage, which previously was not enabled due to an error in enable_interrupts(). PR: 201434 Reported by: Gregory Soutade <soutade at gmail.com> Approved by: kib (mentor)
Notes
Notes: svn path=/head/; revision=290661
-rw-r--r--sys/arm/include/cpufunc.h57
1 files changed, 32 insertions, 25 deletions
diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h
index 6f0e3530001d..e8ba3b2a980f 100644
--- a/sys/arm/include/cpufunc.h
+++ b/sys/arm/include/cpufunc.h
@@ -47,6 +47,7 @@
#ifdef _KERNEL
#include <sys/types.h>
+#include <machine/armreg.h>
#include <machine/cpuconf.h>
#include <machine/katelib.h> /* For in[bwl] and out[bwl] */
@@ -520,45 +521,54 @@ void xscalec3_context_switch (void);
/*
* Macros for manipulating CPU interrupts
*/
-static __inline u_int32_t __set_cpsr_c(u_int bic, u_int eor) __attribute__((__unused__));
+#if __ARM_ARCH < 6
+#define __ARM_INTR_BITS (PSR_I | PSR_F)
+#else
+#define __ARM_INTR_BITS (PSR_I | PSR_F | PSR_A)
+#endif
-static __inline u_int32_t
-__set_cpsr_c(u_int bic, u_int eor)
+static __inline uint32_t
+__set_cpsr(uint32_t bic, uint32_t eor)
{
- u_int32_t tmp, ret;
+ uint32_t tmp, ret;
__asm __volatile(
- "mrs %0, cpsr\n" /* Get the CPSR */
- "bic %1, %0, %2\n" /* Clear bits */
- "eor %1, %1, %3\n" /* XOR bits */
- "msr cpsr_c, %1\n" /* Set the control field of CPSR */
+ "mrs %0, cpsr\n" /* Get the CPSR */
+ "bic %1, %0, %2\n" /* Clear bits */
+ "eor %1, %1, %3\n" /* XOR bits */
+ "msr cpsr_xc, %1\n" /* Set the CPSR */
: "=&r" (ret), "=&r" (tmp)
: "r" (bic), "r" (eor) : "memory");
return ret;
}
-#define ARM_CPSR_F32 (1 << 6) /* FIQ disable */
-#define ARM_CPSR_I32 (1 << 7) /* IRQ disable */
+static __inline uint32_t
+disable_interrupts(uint32_t mask)
+{
-#define disable_interrupts(mask) \
- (__set_cpsr_c((mask) & (ARM_CPSR_I32 | ARM_CPSR_F32), \
- (mask) & (ARM_CPSR_I32 | ARM_CPSR_F32)))
+ return (__set_cpsr(mask & __ARM_INTR_BITS, mask & __ARM_INTR_BITS));
+}
-#define enable_interrupts(mask) \
- (__set_cpsr_c((mask) & (ARM_CPSR_I32 | ARM_CPSR_F32), 0))
+static __inline uint32_t
+enable_interrupts(uint32_t mask)
+{
-#define restore_interrupts(old_cpsr) \
- (__set_cpsr_c((ARM_CPSR_I32 | ARM_CPSR_F32), \
- (old_cpsr) & (ARM_CPSR_I32 | ARM_CPSR_F32)))
+ return (__set_cpsr(mask & __ARM_INTR_BITS, 0));
+}
+
+static __inline uint32_t
+restore_interrupts(uint32_t old_cpsr)
+{
+
+ return (__set_cpsr(__ARM_INTR_BITS, old_cpsr & __ARM_INTR_BITS));
+}
static __inline register_t
intr_disable(void)
{
- register_t s;
- s = disable_interrupts(ARM_CPSR_I32 | ARM_CPSR_F32);
- return (s);
+ return (disable_interrupts(PSR_I | PSR_F));
}
static __inline void
@@ -567,10 +577,7 @@ intr_restore(register_t s)
restore_interrupts(s);
}
-
-/* Functions to manipulate the CPSR. */
-u_int SetCPSR(u_int bic, u_int eor);
-u_int GetCPSR(void);
+#undef __ARM_INTR_BITS
/*
* Functions to manipulate cpu r13