tests: arch: arm: interrupt: add test-case for user mode IRQ locking
We add a simple test to cover the case of invoking IRQ lock()/unlock() from ARM Cortex-M user mode. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
parent
e93ccd9973
commit
937c9c215f
5 changed files with 115 additions and 3 deletions
|
@ -1,11 +1,17 @@
|
|||
Title: Test to verify code fault handling in ISR execution context (ARM Only)
|
||||
Title: Test to verify code fault handling in ISR execution context
|
||||
and the behavior of irq_lock() and irq_unlock() when invoked
|
||||
from User Mode. (ARM Only)
|
||||
|
||||
Description:
|
||||
|
||||
This test verifies that we can handle system fault conditions
|
||||
The first test verifies that we can handle system fault conditions
|
||||
while running in handler mode (i.e. in an ISR). Only for ARM
|
||||
Cortex-M targets.
|
||||
|
||||
The second test verifies that threads in user mode, despite being able to call
|
||||
the irq_lock() and irq_unlock() functions without triggering a CPU fault,
|
||||
they won't be able to read or modify the current IRQ locking status.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
@ -62,6 +68,13 @@ Sample Output:
|
|||
|
||||
PASS - test_arm_interrupt
|
||||
===================================================================
|
||||
starting test - test_arm_user_interrupt
|
||||
PASS - test_arm_user_interrupt
|
||||
===================================================================
|
||||
Test suite arm_interrupt succeeded
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
||||
|
||||
Test suite arm_interrupt succeeded
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_DYNAMIC_INTERRUPTS=y
|
||||
CONFIG_TEST_USERSPACE=y
|
||||
CONFIG_APPLICATION_DEFINED_SYSCALL=y
|
||||
|
|
|
@ -114,6 +114,86 @@ void test_arm_interrupt(void)
|
|||
zassert_true(post_flag == j, "Test flag not set by ISR\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
#include <syscall_handler.h>
|
||||
#include "test_syscalls.h"
|
||||
|
||||
void z_impl_test_arm_user_interrupt_syscall(void)
|
||||
{
|
||||
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
|
||||
/* Confirm IRQs are not locked */
|
||||
zassert_false(__get_PRIMASK(), "PRIMASK is set\n");
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
|
||||
static bool first_call = 1;
|
||||
|
||||
if (first_call == 1) {
|
||||
|
||||
/* First time the syscall is invoked */
|
||||
first_call = 0;
|
||||
|
||||
/* Lock IRQs in supervisor mode */
|
||||
int key = irq_lock();
|
||||
|
||||
/* Verify that IRQs were not already locked */
|
||||
zassert_false(key, "IRQs locked in system call\n");
|
||||
}
|
||||
|
||||
/* Confirm IRQs are still locked */
|
||||
zassert_true(__get_BASEPRI(), "BASEPRI not set\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void z_vrfy_test_arm_user_interrupt_syscall(void)
|
||||
{
|
||||
z_impl_test_arm_user_interrupt_syscall();
|
||||
}
|
||||
#include <syscalls/test_arm_user_interrupt_syscall_mrsh.c>
|
||||
|
||||
void test_arm_user_interrupt(void)
|
||||
{
|
||||
/* Test thread executing in user mode */
|
||||
zassert_true(arch_is_user_context(),
|
||||
"Test thread not running in user mode\n");
|
||||
|
||||
/* Attempt to lock IRQs in user mode */
|
||||
irq_lock();
|
||||
/* Attempt to lock again should return non-zero value of previous
|
||||
* locking attempt, if that were to be successful.
|
||||
*/
|
||||
int lock = irq_lock();
|
||||
|
||||
zassert_false(lock, "IRQs shown locked in user mode\n");
|
||||
|
||||
/* Generate a system call to manage the IRQ locking */
|
||||
test_arm_user_interrupt_syscall();
|
||||
|
||||
/* Attempt to unlock IRQs in user mode */
|
||||
irq_unlock(0);
|
||||
|
||||
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
/* The first system call has left the IRQs locked.
|
||||
* Generate a second system call to inspect the IRQ locking.
|
||||
*
|
||||
* In Cortex-M Baseline system calls cannot be invoked
|
||||
* with interrupts locked, so we skip this part of the
|
||||
* test.
|
||||
*/
|
||||
test_arm_user_interrupt_syscall();
|
||||
|
||||
/* Verify that thread is not able to infer that IRQs are locked. */
|
||||
zassert_false(irq_lock(), "IRQs are shown to be locked\n");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void test_arm_user_interrupt(void)
|
||||
{
|
||||
TC_PRINT("Skipped\n");
|
||||
}
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
#include <ztest.h>
|
||||
|
||||
extern void test_arm_interrupt(void);
|
||||
extern void test_arm_user_interrupt(void);
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(arm_interrupt,
|
||||
ztest_unit_test(test_arm_interrupt));
|
||||
ztest_unit_test(test_arm_interrupt),
|
||||
ztest_user_unit_test(test_arm_user_interrupt));
|
||||
ztest_run_test_suite(arm_interrupt);
|
||||
}
|
||||
|
|
15
tests/arch/arm/arm_interrupt/src/test_syscalls.h
Normal file
15
tests/arch/arm/arm_interrupt/src/test_syscalls.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _TEST_SYSCALLS_H_
|
||||
#define _TEST_SYSCALLS_H_
|
||||
#include <zephyr.h>
|
||||
|
||||
__syscall void test_arm_user_interrupt_syscall(void);
|
||||
|
||||
#include <syscalls/test_syscalls.h>
|
||||
|
||||
#endif /* _TEST_SYSCALLS_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue