arch: aarch32: cortex_m/r: Add arch helper function

Create z_arm_thread_is_user_mode to abstract the implementation
differences between Cortex-M and R to determine if the current thread is
in user or kernel mode.

Signed-off-by: Bradley Bolen <bbolen@lexmark.com>
This commit is contained in:
Bradley Bolen 2021-06-23 10:32:03 -04:00 committed by Christopher Friedt
commit 50a6dafdc5
7 changed files with 48 additions and 5 deletions

View file

@ -13,3 +13,5 @@ zephyr_library_sources(
stacks.c stacks.c
tcm.c tcm.c
) )
zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c)

View file

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Lexmark International, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <arch/arm/aarch32/cortex_a_r/cmsis.h>
bool z_arm_thread_is_in_user_mode(void)
{
uint32_t value;
/*
* For Cortex-R, the mode (lower 5) bits will be 0x10 for user mode.
*/
value = __get_CPSR();
return ((value & CPSR_M_Msk) == CPSR_M_USR);
}

View file

@ -14,6 +14,7 @@ zephyr_library_sources(
thread_abort.c thread_abort.c
) )
zephyr_library_sources_ifdef(CONFIG_USERSPACE thread.c)
zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c)
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S)

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2021 Lexmark International, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <arch/arm/aarch32/cortex_m/cmsis.h>
bool z_arm_thread_is_in_user_mode(void)
{
uint32_t value;
/* return mode information */
value = __get_CONTROL();
return (value & CONTROL_nPRIV_Msk) != 0;
}

View file

@ -396,7 +396,7 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp
#if defined(CONFIG_USERSPACE) #if defined(CONFIG_USERSPACE)
if (thread->arch.priv_stack_start) { if (thread->arch.priv_stack_start) {
/* User thread */ /* User thread */
if ((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0U) { if (z_arm_thread_is_in_user_mode() == false) {
/* User thread in privilege mode */ /* User thread in privilege mode */
if (IS_MPU_GUARD_VIOLATION( if (IS_MPU_GUARD_VIOLATION(
thread->arch.priv_stack_start - guard_len, thread->arch.priv_stack_start - guard_len,

View file

@ -31,6 +31,10 @@ static ALWAYS_INLINE void arch_nop(void)
__asm__ volatile("nop"); __asm__ volatile("nop");
} }
#if defined(CONFIG_USERSPACE)
extern bool z_arm_thread_is_in_user_mode(void);
#endif
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -26,7 +26,7 @@
#include <zephyr/types.h> #include <zephyr/types.h>
#include <stdbool.h> #include <stdbool.h>
#include <arch/arm/aarch32/cortex_m/cmsis.h> #include <arch/arm/aarch32/misc.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -165,6 +165,7 @@ static inline uintptr_t arch_syscall_invoke0(uintptr_t call_id)
static inline bool arch_is_user_context(void) static inline bool arch_is_user_context(void)
{ {
#if defined(CONFIG_CPU_CORTEX_M)
uint32_t value; uint32_t value;
/* check for handler mode */ /* check for handler mode */
@ -172,10 +173,9 @@ static inline bool arch_is_user_context(void)
if (value) { if (value) {
return false; return false;
} }
#endif
/* if not handler mode, return mode information */ return z_arm_thread_is_in_user_mode();
__asm__ volatile("mrs %0, CONTROL\n\t" : "=r"(value));
return (value & CONTROL_nPRIV_Msk) ? true : false;
} }
#ifdef __cplusplus #ifdef __cplusplus