]> Zhao Yanbai Git Server - minix.git/commitdiff
ARM: Fix interrupt management 37/337/3
authorLionel Sambuc <lionel@minix3.org>
Fri, 15 Feb 2013 00:07:04 +0000 (01:07 +0100)
committerLionel Sambuc <lionel@minix3.org>
Mon, 18 Feb 2013 08:07:55 +0000 (09:07 +0100)
Interrupts where not correctly masked while in kernel, which
breaks one of the current main assumptions.

Also remove some duplication on ARM asm files, and add a function
to check the status of ARM irqs (not compiled by default)

Change-Id: I3c25d2b388f93fd8fe423998b94b3c4f140ba831

kernel/arch/earm/Makefile.inc
kernel/arch/earm/arch_reset.c
kernel/arch/earm/arch_system.c
kernel/arch/earm/include/cpufunc.h
kernel/arch/earm/io_intr.S [deleted file]
kernel/arch/earm/klib.S
kernel/arch/earm/mpx.S

index a9c8c63676a25d394d5188493294b52e2589717b..141bd2692452255d35933cb5d9267a5d39a24d3e 100644 (file)
@@ -64,7 +64,7 @@ CLEANFILES+= ${ORIG_UNPAGED_OBJS}
 
 SRCS+= mpx.S arch_clock.c arch_do_vmctl.c arch_system.c \
        omap_serial.c omap_timer.c omap_intr.c exception.c \
-       io_intr.S klib.S memory.c \
+       klib.S memory.c \
        protect.c direct_tty_utils.c arch_reset.c \
        pg_utils.c phys_copy.S phys_memset.S exc.S
 OBJS.kernel+=  ${UNPAGED_OBJS}
index 22cc627066af9d0e54d7c6a2ded1064d9ad29c26..2269711f6379068a9324544525b6d9c07dbbb8b3 100644 (file)
@@ -25,6 +25,7 @@ halt_cpu(void)
        asm volatile("dsb");
        asm volatile("cpsie i");
        asm volatile("wfi");
+       asm volatile("cpsid i");
 }
 
 void
index 7d83573614e3782f8da575534565fa12a50a5e87..8d171e484af23c9d58a6cc517dc4c6d4dbe8bc72 100644 (file)
@@ -159,10 +159,8 @@ struct proc * arch_finish_switch_to_user(void)
        p = get_cpulocal_var(proc_ptr);
        *((reg_t *)stk) = (reg_t) p;
 
-       /* make sure I bit is clear in PSR so that interrupts won't be disabled
-        * once p's context is restored. this should not be possible.
-        */
-        assert(!(p->p_reg.psr & PSR_I));
+       /* turn interrupts on */
+        p->p_reg.psr &= ~(PSR_I|PSR_F);
 
        return p;
 }
index 37366204da580f29b0c55d57710d04110ab13ed7..fbdc054a2b0ba4322935f88de27885116cea048d 100644 (file)
@@ -1,6 +1,23 @@
 #ifndef _ARM_CPUFUNC_H
 #define _ARM_CPUFUNC_H
 
+#if 0
+/* check interrupt state */
+static inline void check_int(unsigned int state, int line)
+{
+       unsigned int cpsr = 0;
+
+       asm volatile("mrs %0, cpsr" : "=r" (cpsr));
+
+       if ((cpsr & PSR_F) != (state & PSR_F))
+           printf("%d: FIQs are unexpectedly %s\n", line, (cpsr & PSR_F) ? "MASKED" : "UNMASKED");
+
+       if ((cpsr & PSR_I) != (state & PSR_I))
+           printf("%d: IRQs are unexpectedly %s\n", line, (cpsr & PSR_I) ? "MASKED" : "UNMASKED");
+
+}
+#endif
+
 /* Data memory barrier */
 static inline void dmb(void)
 {
@@ -28,8 +45,29 @@ static inline void barrier(void)
 static inline void refresh_tlb(void)
 {
        dsb();
+
        /* Invalidate entire unified TLB */
-       asm volatile("mcr p15, 0, r0, c8, c7, 0 @ TLBIALL\n\t");
+       asm volatile("mcr p15, 0, %[zero], c8, c7, 0 @ TLBIALL\n\t" : : [zero] "r" (0));
+
+#if 0
+       /* Invalidate entire data TLB */
+       asm volatile("mcr p15, 0, %[zero], c8, c6, 0" : : [zero] "r" (0));
+
+       /* Invalidate entire instruction TLB */
+       asm volatile("mcr p15, 0, %[zero], c8, c5, 0" : : [zero] "r" (0));
+#endif
+
+#if 0
+       /*
+        * Invalidate all instruction caches to PoU.
+        * Also flushes branch target cache.
+        */
+       asm volatile("mcr p15, 0, %[zero], c7, c5, 0" : : [zero] "r" (0));
+
+       /* Invalidate entire branch predictor array */
+       asm volatile("mcr p15, 0, %[zero], c7, c5, 6" : : [zero] "r" (0)); /* flush BTB */
+#endif
+
        dsb();
        isb();
 }
@@ -38,236 +76,269 @@ static inline void refresh_tlb(void)
 /* Read System Control Register */
 static inline u32_t read_sctlr()
 {
-    u32_t ctl;
+       u32_t ctl;
 
-    asm volatile("mrc p15, 0, %[ctl], c1, c0, 0 @ Read SCTLR\n\t"
-                : [ctl] "=r" (ctl));
-    return ctl;
+       asm volatile("mrc p15, 0, %[ctl], c1, c0, 0 @ Read SCTLR\n\t"
+                       : [ctl] "=r" (ctl));
+
+       return ctl;
 }
 
 /* Write System Control Register */
 static inline void write_sctlr(u32_t ctl)
 {
-    asm volatile("mcr p15, 0, %[ctl], c1, c0, 0 @ Write SCTLR\n\t"
-                : : [ctl] "r" (ctl));
+       asm volatile("mcr p15, 0, %[ctl], c1, c0, 0 @ Write SCTLR\n\t"
+                       : : [ctl] "r" (ctl));
+       isb();
 }
 
 /* Read Translation Table Base Register 0 */
 static inline u32_t read_ttbr0()
 {
-    u32_t bar;
+       u32_t bar;
+
+       asm volatile("mrc p15, 0, %[bar], c2, c0, 0 @ Read TTBR0\n\t"
+                       : [bar] "=r" (bar));
 
-    asm volatile("mrc p15, 0, %[bar], c2, c0, 0 @ Read TTBR0\n\t"
-                : [bar] "=r" (bar));
-    return bar;
+       return bar;
 }
 
 /* Write Translation Table Base Register 0 */
 static inline void write_ttbr0(u32_t bar)
 {
-    barrier();
-    asm volatile("mcr p15, 0, %[bar], c2, c0, 0 @ Write TTBR0\n\t"
-                : : [bar] "r" (bar));
-    refresh_tlb();
+       barrier();
+
+       asm volatile("mcr p15, 0, %[bar], c2, c0, 0 @ Write TTBR0\n\t"
+                       : : [bar] "r" (bar));
+
+       refresh_tlb();
 }
 
 /* Reload Translation Table Base Register 0 */
 static inline void reload_ttbr0(void)
 {
-    reg_t ttbr = read_ttbr0();
-    write_ttbr0(ttbr);
-    refresh_tlb();
+       reg_t ttbr = read_ttbr0();
+
+       write_ttbr0(ttbr);
 }
 
 /* Read Translation Table Base Register 1 */
 static inline u32_t read_ttbr1()
 {
-    u32_t bar;
+       u32_t bar;
 
-    asm volatile("mrc p15, 0, %[bar], c2, c0, 1 @ Read TTBR1\n\t"
-                : [bar] "=r" (bar));
-    return bar;
+       asm volatile("mrc p15, 0, %[bar], c2, c0, 1 @ Read TTBR1\n\t"
+                       : [bar] "=r" (bar));
+
+       return bar;
 }
 
 /* Write Translation Table Base Register 1 */
 static inline void write_ttbr1(u32_t bar)
 {
-    barrier();
-    asm volatile("mcr p15, 0, %[bar], c2, c0, 1 @ Write TTBR1\n\t"
-                : : [bar] "r" (bar));
-    refresh_tlb();
+       barrier();
+
+       asm volatile("mcr p15, 0, %[bar], c2, c0, 1 @ Write TTBR1\n\t"
+                       : : [bar] "r" (bar));
+
+       refresh_tlb();
 }
 
 /* Reload Translation Table Base Register 1 */
 static inline void reload_ttbr1(void)
 {
-    reg_t ttbr = read_ttbr1();
-    write_ttbr1(ttbr);
-    refresh_tlb();
+       reg_t ttbr = read_ttbr1();
+
+       write_ttbr1(ttbr);
 }
 
 /* Read Translation Table Base Control Register */
 static inline u32_t read_ttbcr()
 {
-    u32_t bcr;
+       u32_t bcr;
+
+       asm volatile("mrc p15, 0, %[bcr], c2, c0, 2 @ Read TTBCR\n\t"
+                       : [bcr] "=r" (bcr));
 
-    asm volatile("mrc p15, 0, %[bcr], c2, c0, 2 @ Read TTBCR\n\t"
-                : [bcr] "=r" (bcr));
-    return bcr;
+       return bcr;
 }
 
 /* Write Translation Table Base Control Register */
 static inline void write_ttbcr(u32_t bcr)
 {
-    asm volatile("mcr p15, 0, %[bcr], c2, c0, 2 @ Write TTBCR\n\t"
-                : : [bcr] "r" (bcr));
+       asm volatile("mcr p15, 0, %[bcr], c2, c0, 2 @ Write TTBCR\n\t"
+                       : : [bcr] "r" (bcr));
+
+       isb();
 }
 
 /* Read Domain Access Control Register */
 static inline u32_t read_dacr()
 {
-    u32_t dacr;
+       u32_t dacr;
+
+       asm volatile("mrc p15, 0, %[dacr], c3, c0, 0 @ Read DACR\n\t"
+                       : [dacr] "=r" (dacr));
 
-    asm volatile("mrc p15, 0, %[dacr], c3, c0, 0 @ Read DACR\n\t"
-                : [dacr] "=r" (dacr));
-    return dacr;
+       return dacr;
 }
 
 /* Write Domain Access Control Register */
 static inline void write_dacr(u32_t dacr)
 {
-    asm volatile("mcr p15, 0, %[dacr], c3, c0, 0 @ Write DACR\n\t"
-                : : [dacr] "r" (dacr));
+       asm volatile("mcr p15, 0, %[dacr], c3, c0, 0 @ Write DACR\n\t"
+                       : : [dacr] "r" (dacr));
+
+       isb();
 }
 
 /* Read Data Fault Status Register */
 static inline u32_t read_dfsr()
 {
-    u32_t fsr;
+       u32_t fsr;
+
+       asm volatile("mrc p15, 0, %[fsr], c5, c0, 0 @ Read DFSR\n\t"
+                       : [fsr] "=r" (fsr));
 
-    asm volatile("mrc p15, 0, %[fsr], c5, c0, 0 @ Read DFSR\n\t"
-                : [fsr] "=r" (fsr));
-    return fsr;
+       return fsr;
 }
 
 /* Write Data Fault Status Register */
 static inline void write_dfsr(u32_t fsr)
 {
-    asm volatile("mcr p15, 0, %[fsr], c5, c0, 0 @ Write DFSR\n\t"
-                : : [fsr] "r" (fsr));
+       asm volatile("mcr p15, 0, %[fsr], c5, c0, 0 @ Write DFSR\n\t"
+                       : : [fsr] "r" (fsr));
+
+       isb();
 }
 
 /* Read Instruction Fault Status Register */
 static inline u32_t read_ifsr()
 {
-    u32_t fsr;
+       u32_t fsr;
+
+       asm volatile("mrc p15, 0, %[fsr], c5, c0, 1 @ Read IFSR\n\t"
+                       : [fsr] "=r" (fsr));
 
-    asm volatile("mrc p15, 0, %[fsr], c5, c0, 1 @ Read IFSR\n\t"
-                : [fsr] "=r" (fsr));
-    return fsr;
+       return fsr;
 }
 
 /* Write Instruction Fault Status Register */
 static inline void write_ifsr(u32_t fsr)
 {
-    asm volatile("mcr p15, 0, %[fsr], c5, c0, 1 @ Write IFSR\n\t"
-                : : [fsr] "r" (fsr));
+       asm volatile("mcr p15, 0, %[fsr], c5, c0, 1 @ Write IFSR\n\t"
+                       : : [fsr] "r" (fsr));
+
+       isb();
 }
 
 /* Read Data Fault Address Register */
 static inline u32_t read_dfar()
 {
-    u32_t far;
+       u32_t far;
+
+       asm volatile("mrc p15, 0, %[far], c6, c0, 0 @ Read DFAR\n\t"
+                       : [far] "=r" (far));
 
-    asm volatile("mrc p15, 0, %[far], c6, c0, 0 @ Read DFAR\n\t"
-                : [far] "=r" (far));
-    return far;
+       return far;
 }
 
 /* Write Data Fault Address Register */
 static inline void write_dfar(u32_t far)
 {
-    asm volatile("mcr p15, 0, %[far], c6, c0, 0 @ Write DFAR\n\t"
-                : : [far] "r" (far));
+       asm volatile("mcr p15, 0, %[far], c6, c0, 0 @ Write DFAR\n\t"
+                       : : [far] "r" (far));
+
+       isb();
 }
 
 /* Read Instruction Fault Address Register */
 static inline u32_t read_ifar()
 {
-    u32_t far;
+       u32_t far;
+
+       asm volatile("mrc p15, 0, %[far], c6, c0, 2 @ Read IFAR\n\t"
+                       : [far] "=r" (far));
 
-    asm volatile("mrc p15, 0, %[far], c6, c0, 2 @ Read IFAR\n\t"
-                : [far] "=r" (far));
-    return far;
+       return far;
 }
 
 /* Write Instruction Fault Address Register */
 static inline void write_ifar(u32_t far)
 {
-    asm volatile("mcr p15, 0, %[far], c6, c0, 2 @ Write IFAR\n\t"
-                : : [far] "r" (far));
+       asm volatile("mcr p15, 0, %[far], c6, c0, 2 @ Write IFAR\n\t"
+                       : : [far] "r" (far));
+
+       isb();
 }
 
 /* Read Vector Base Address Register */
 static inline u32_t read_vbar()
 {
-    u32_t vbar;
+       u32_t vbar;
+
+       asm volatile("mrc p15, 0, %[vbar], c12, c0, 0 @ Read VBAR\n\t"
+                       : [vbar] "=r" (vbar));
 
-    asm volatile("mrc p15, 0, %[vbar], c12, c0, 0 @ Read VBAR\n\t"
-                : [vbar] "=r" (vbar));
-    return vbar;
+       return vbar;
 }
 
 /* Write Vector Base Address Register */
 static inline void write_vbar(u32_t vbar)
 {
-    asm volatile("mcr p15, 0, %[vbar], c12, c0, 0 @ Write VBAR\n\t"
-                : : [vbar] "r" (vbar));
-    asm volatile("dsb");
+       asm volatile("mcr p15, 0, %[vbar], c12, c0, 0 @ Write VBAR\n\t"
+                       : : [vbar] "r" (vbar));
+
+       isb();
 }
 
 /* Read the Main ID Register  */
 static inline u32_t read_midr()
 {
-    u32_t id;
+       u32_t id;
+
+       asm volatile("mrc p15, 0, %[id], c0, c0, 0 @ read MIDR\n\t"
+                       : [id] "=r" (id));
 
-    asm volatile("mrc p15, 0, %[id], c0, c0, 0 @ read MIDR\n\t"
-                : [id] "=r" (id));
-    return id;
+       return id;
 }
 
 /* Read Auxiliary Control Register */
 static inline u32_t read_actlr()
 {
-    u32_t ctl;
+       u32_t ctl;
+
+       asm volatile("mrc p15, 0, %[ctl], c1, c0, 1 @ Read ACTLR\n\t"
+                       : [ctl] "=r" (ctl));
 
-    asm volatile("mrc p15, 0, %[ctl], c1, c0, 1 @ Read ACTLR\n\t"
-                : [ctl] "=r" (ctl));
-    return ctl;
+       return ctl;
 }
 
 /* Write Auxiliary Control Register */
 static inline void write_actlr(u32_t ctl)
 {
-    asm volatile("mcr p15, 0, %[ctl], c1, c0, 1 @ Write ACTLR\n\t"
-                : : [ctl] "r" (ctl));
+       asm volatile("mcr p15, 0, %[ctl], c1, c0, 1 @ Write ACTLR\n\t"
+                       : : [ctl] "r" (ctl));
+
+       isb();
 }
 
 /* Read Current Program Status Register */
 static inline u32_t read_cpsr()
 {
-    u32_t status;
+       u32_t status;
+
+       asm volatile("mrs %[status], cpsr @ read CPSR"
+                       : [status] "=r" (status));
 
-    asm volatile("mrs %[status], cpsr @ read CPSR"
-                : [status] "=r" (status));
-    return status;
+       return status;
 }
 
 /* Write Current Program Status Register */
 static inline void write_cpsr(u32_t status)
 {
-    asm volatile("msr cpsr_c, %[status] @ write CPSR"
-                : : [status] "r" (status));
+       asm volatile("msr cpsr_c, %[status] @ write CPSR"
+                       : : [status] "r" (status));
 }
 
 #endif /* _ARM_CPUFUNC_H */
diff --git a/kernel/arch/earm/io_intr.S b/kernel/arch/earm/io_intr.S
deleted file mode 100644 (file)
index 60b420e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*     intr_disable(), intr_enable - Disable/Enable hardware interrupts. */
-/*     void intr_disable(void); */
-/*     void intr_enable(void); */
-#include <machine/asm.h>
-
-ENTRY(intr_disable)
-       dsb
-       cpsid i
-       bx lr
-
-ENTRY(intr_enable)
-       dsb
-       cpsie i
-       bx lr
index 95bfa79bc963142f06d983a8d594e3ef1492777d..0294be7dd596c7a596f18260dc86d1ba34ce0a48 100644 (file)
@@ -82,12 +82,14 @@ ENTRY(__user_copy_msg_pointer_failure)
        mov     r0, #-1
        bx      lr
 
+ENTRY(intr_enable)
 ENTRY(interrupts_enable)
        dsb
-       cpsie i
+       cpsie if
        bx lr
 
+ENTRY(intr_disable)
 ENTRY(interrupts_disable)
        dsb
-       cpsid i
+       cpsid if
        bx lr
index bf8b2ed160e9c26dc4710d16eb317699b3cf7962..96bf3f538712edde11c57bd4d1f9892d04a6664b 100644 (file)
@@ -53,6 +53,8 @@ IMPORT(svc_stack)
 .macro test_int_in_kernel, label
        push    {r3}
        ldr     r3, [sp, #8] /* spsr */
+       orr     r3, r3, #(PSR_F | PSR_I) /* mask interrupts on return */
+       str     r3, [sp, #8] /* spsr */
        and     r3, r3, #PSR_MODE_MASK
        cmp     r3, #MODE_USR
        pop     {r3}