diff --git a/arch/arm/include/aarch32/cortex_r/exc.h b/arch/arm/include/aarch32/cortex_r/exc.h index 05b0235204ba..5d965d6bb32b 100644 --- a/arch/arm/include/aarch32/cortex_r/exc.h +++ b/arch/arm/include/aarch32/cortex_r/exc.h @@ -42,7 +42,9 @@ static ALWAYS_INLINE bool arch_is_in_isr(void) : "=r" (status) : : "memory", "cc"); status &= MODE_MASK; - return (status == MODE_FIQ) || (status == MODE_IRQ); + return (status == MODE_FIQ) || + (status == MODE_IRQ) || + (status == MODE_SVC); } /** diff --git a/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml b/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml index 10140ff2c50a..2ae4d72dd23a 100644 --- a/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml +++ b/boards/arm/qemu_cortex_r5/qemu_cortex_r5.yaml @@ -13,8 +13,6 @@ testing: default: true ignore_tags: - benchmark - - cmsis_rtos - interrupt - - kernel - memory_protection - userspace diff --git a/include/arch/arm/aarch32/asm_inline_gcc.h b/include/arch/arm/aarch32/asm_inline_gcc.h index f2d881d656b0..2ff8e45c0d33 100644 --- a/include/arch/arm/aarch32/asm_inline_gcc.h +++ b/include/arch/arm/aarch32/asm_inline_gcc.h @@ -22,6 +22,10 @@ #include #include +#if defined(CONFIG_CPU_CORTEX_R) +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -58,8 +62,10 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) : "i"(_EXC_IRQ_DEFAULT_PRIO) : "memory"); #elif defined(CONFIG_ARMV7_R) - __asm__ volatile("mrs %0, cpsr;" - "cpsid i" + __asm__ volatile( + "mrs %0, cpsr;" + "and %0, #" TOSTR(I_BIT) ";" + "cpsid i;" : "=r" (key) : : "memory", "cc"); @@ -91,10 +97,12 @@ static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) "isb;" : : "r"(key) : "memory"); #elif defined(CONFIG_ARMV7_R) - __asm__ volatile("msr cpsr_c, %0" - : - : "r" (key) - : "memory", "cc"); + if (key) { + return; + } + __asm__ volatile( + "cpsie i;" + : : : "memory", "cc"); #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ diff --git a/tests/kernel/sleep/src/main.c b/tests/kernel/sleep/src/main.c index ac7ec2fe2764..7651a74f77b5 100644 --- a/tests/kernel/sleep/src/main.c +++ b/tests/kernel/sleep/src/main.c @@ -24,6 +24,17 @@ #define ONE_SECOND_ALIGNED \ (u32_t)(k_ticks_to_ms_floor64(k_ms_to_ticks_ceil32(ONE_SECOND) + _TICK_ALIGN)) +#if defined(CONFIG_SOC_XILINX_ZYNQMP) +/* + * The Xilinx QEMU, used to emulate the Xilinx ZynqMP platform, is particularly + * unstable in terms of timing. The tick margin of at least 5 is necessary to + * allow this test to pass with a reasonable repeatability. + */ +#define TICK_MARGIN 5 +#else +#define TICK_MARGIN 1 +#endif + static struct k_sem test_thread_sem; static struct k_sem helper_thread_sem; static struct k_sem task_sem; @@ -88,7 +99,7 @@ static int sleep_time_valid(u32_t start, u32_t end, u32_t dur) { u32_t dt = end - start; - return dt >= dur && dt <= (dur + 1); + return dt >= dur && dt <= (dur + TICK_MARGIN); } static void test_thread(int arg1, int arg2) @@ -120,7 +131,7 @@ static void test_thread(int arg1, int arg2) k_sleep(ONE_SECOND); end_tick = k_uptime_get_32(); - if (end_tick - start_tick > 1) { + if (end_tick - start_tick > TICK_MARGIN) { TC_ERROR(" *** k_wakeup() took too long (%d ticks)\n", end_tick - start_tick); return; @@ -134,7 +145,7 @@ static void test_thread(int arg1, int arg2) k_sleep(ONE_SECOND); end_tick = k_uptime_get_32(); - if (end_tick - start_tick > 1) { + if (end_tick - start_tick > TICK_MARGIN) { TC_ERROR(" *** k_wakeup() took too long (%d ticks)\n", end_tick - start_tick); return; @@ -148,7 +159,7 @@ static void test_thread(int arg1, int arg2) k_sleep(ONE_SECOND); /* Task will execute */ end_tick = k_uptime_get_32(); - if (end_tick - start_tick > 1) { + if (end_tick - start_tick > TICK_MARGIN) { TC_ERROR(" *** k_wakeup() took too long (%d ticks) at LAST\n", end_tick - start_tick); return;