You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2022/01/11 21:08:10 UTC

[mynewt-core] branch master updated: kernel/os: Fix os_arch_in_isr for pic32

This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 79099c7  kernel/os: Fix os_arch_in_isr for pic32
79099c7 is described below

commit 79099c75e1b999e378920e2abb2e1a2aec60986c
Author: Jerzy Kasenberg <je...@apache.org>
AuthorDate: Sat Nov 27 10:01:32 2021 +0100

    kernel/os: Fix os_arch_in_isr for pic32
    
    Code was checking STATUS register EXL bit to check if CPU is in ISR.
    This is true when CPU starts handling interrupt, but normal code
    generated by xc32-gcc turns off this bit in ISR code before
    user code is executed.
    
    void __attribute__((interrupt(IPL3AUTO), vector(_TIMER_2_VECTOR))) timer2_isr(void)
    {
    9d008198:	415de800 	rdpgpr	sp,sp
    9d00819c:	401b7000 	mfc0	k1,c0_epc
    9d0081a0:	401a6002 	mfc0	k0,c0_srsctl
    9d0081a4:	27bdfed0 	addiu	sp,sp,-304
    9d0081a8:	afbb012c 	sw	k1,300(sp)
    9d0081ac:	401b6000 	mfc0	k1,c0_status  // k1 has STATUS with EXL bit set
    9d0081b0:	afba0124 	sw	k0,292(sp)
    9d0081b4:	afbb0128 	sw	k1,296(sp)
    9d0081b8:	7c1b7844 	ins	k1,zero,0x1,0xf   // k1 has now only IE preserved (which is 1 since code is in ISR), EXL is cleared
    9d0081bc:	377b0c00 	ori	k1,k1,0xc00       // k1 IPL is set to 3 (from IPL3AUTO)
    9d0081c0:	409b6000 	mtc0	k1,c0_status  // status has now IE 1 and IPL > 0, EXL is 0 to allow nested interrupts
    
    EXL bit is cleared to allow nested interrupts so to check if code is in interrupt
    EXL can be checked but also IPL > 0 indicates that code is in ISR handler
---
 kernel/os/include/os/arch/pic32/os/os_arch.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/os/include/os/arch/pic32/os/os_arch.h b/kernel/os/include/os/arch/pic32/os/os_arch.h
index 7b78d61..2584949 100644
--- a/kernel/os/include/os/arch/pic32/os/os_arch.h
+++ b/kernel/os/include/os/arch/pic32/os/os_arch.h
@@ -46,8 +46,8 @@ typedef uint32_t os_stack_t;
 static inline int
 os_arch_in_isr(void)
 {
-    /* check the EXL bit */
-    return (_CP0_GET_STATUS() & _CP0_STATUS_EXL_MASK) ? 1 : 0;
+    /* CPU handles interrupt when EXL is set or IPL > 0 */
+    return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) ? 1 : 0;
 }
 
 /* Include common arch definitions and APIs */