2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
|
|
|
*
|
2017-01-18 17:01:01 -08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
2015-12-04 10:09:39 -05:00
|
|
|
/**
|
|
|
|
* @file
|
2016-12-23 07:32:56 -05:00
|
|
|
* @brief ARM specific kernel interface header
|
2015-12-04 10:09:39 -05:00
|
|
|
*
|
2016-12-23 07:32:56 -05:00
|
|
|
* This header contains the ARM specific kernel interface. It is
|
|
|
|
* included by the kernel interface architecture-abstraction header
|
2018-09-24 11:41:42 +02:00
|
|
|
* (include/arm/cpu.h)
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2019-11-09 18:48:15 +00:00
|
|
|
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ARCH_H_
|
|
|
|
#define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ARCH_H_
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2017-02-10 15:31:26 -06:00
|
|
|
/* Add include for DTS generated information */
|
2020-01-16 13:29:53 +01:00
|
|
|
#include <devicetree.h>
|
2017-02-10 15:31:26 -06:00
|
|
|
|
2015-10-23 16:20:25 -04:00
|
|
|
/* ARM GPRs are often designated by two different names */
|
2017-04-21 10:55:34 -05:00
|
|
|
#define sys_define_gpr_with_alias(name1, name2) union { u32_t name1, name2; }
|
2015-10-23 16:20:25 -04:00
|
|
|
|
2019-11-09 17:49:36 +00:00
|
|
|
#include <arch/arm/aarch32/thread.h>
|
|
|
|
#include <arch/arm/aarch32/exc.h>
|
|
|
|
#include <arch/arm/aarch32/irq.h>
|
|
|
|
#include <arch/arm/aarch32/error.h>
|
|
|
|
#include <arch/arm/aarch32/misc.h>
|
2019-06-02 21:44:42 -04:00
|
|
|
#include <arch/common/addr_types.h>
|
2019-06-02 13:07:43 -04:00
|
|
|
#include <arch/common/ffs.h>
|
2019-11-09 17:49:36 +00:00
|
|
|
#include <arch/arm/aarch32/nmi.h>
|
|
|
|
#include <arch/arm/aarch32/asm_inline.h>
|
2018-06-08 16:34:16 -04:00
|
|
|
|
|
|
|
#ifdef CONFIG_CPU_CORTEX_M
|
2019-11-09 17:49:36 +00:00
|
|
|
#include <arch/arm/aarch32/cortex_m/cpu.h>
|
|
|
|
#include <arch/arm/aarch32/cortex_m/memory_map.h>
|
2019-05-29 11:02:14 -04:00
|
|
|
#include <arch/common/sys_io.h>
|
2018-06-25 09:15:14 -04:00
|
|
|
#elif defined(CONFIG_CPU_CORTEX_R)
|
2019-11-09 17:49:36 +00:00
|
|
|
#include <arch/arm/aarch32/cortex_r/cpu.h>
|
|
|
|
#include <arch/arm/aarch32/cortex_r/sys_io.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
2017-08-30 16:19:15 -05:00
|
|
|
|
2018-07-19 14:12:56 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2017-08-30 16:19:15 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Declare the STACK_ALIGN_SIZE
|
|
|
|
*
|
|
|
|
* Denotes the required alignment of the stack pointer on public API
|
|
|
|
* boundaries
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_STACK_ALIGN_DOUBLE_WORD
|
|
|
|
#define STACK_ALIGN_SIZE 8
|
|
|
|
#else
|
|
|
|
#define STACK_ALIGN_SIZE 4
|
|
|
|
#endif
|
|
|
|
|
2019-05-27 12:35:28 +02:00
|
|
|
/**
|
|
|
|
* @brief Declare the minimum alignment for a thread stack
|
|
|
|
*
|
|
|
|
* Denotes the minimum required alignment of a thread stack.
|
|
|
|
*
|
|
|
|
* Note:
|
|
|
|
* User thread stacks must respect the minimum MPU region
|
|
|
|
* alignment requirement.
|
|
|
|
*/
|
|
|
|
#if defined(CONFIG_USERSPACE)
|
|
|
|
#define Z_THREAD_MIN_STACK_ALIGN CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
|
|
|
|
#else
|
|
|
|
#define Z_THREAD_MIN_STACK_ALIGN STACK_ALIGN_SIZE
|
|
|
|
#endif
|
|
|
|
|
2017-08-30 16:19:15 -05:00
|
|
|
/**
|
|
|
|
* @brief Declare a minimum MPU guard alignment and size
|
|
|
|
*
|
2018-09-24 11:41:42 +02:00
|
|
|
* This specifies the minimum MPU guard alignment/size for the MPU. This
|
2017-08-30 16:19:15 -05:00
|
|
|
* will be used to denote the guard section of the stack, if it exists.
|
|
|
|
*
|
|
|
|
* One key note is that this guard results in extra bytes being added to
|
2018-09-24 11:41:42 +02:00
|
|
|
* the stack. APIs which give the stack ptr and stack size will take this
|
2017-08-30 16:19:15 -05:00
|
|
|
* guard size into account.
|
|
|
|
*
|
|
|
|
* Stack is allocated, but initial stack pointer is at the end
|
|
|
|
* (highest address). Stack grows down to the actual allocation
|
|
|
|
* address (lowest address). Stack guard, if present, will comprise
|
|
|
|
* the lowest MPU_GUARD_ALIGN_AND_SIZE bytes of the stack.
|
|
|
|
*
|
|
|
|
* As the stack grows down, it will reach the end of the stack when it
|
|
|
|
* encounters either the stack guard region, or the stack allocation
|
|
|
|
* address.
|
|
|
|
*
|
|
|
|
* ----------------------- <---- Stack allocation address + stack size +
|
|
|
|
* | | MPU_GUARD_ALIGN_AND_SIZE
|
|
|
|
* | Some thread data | <---- Defined when thread is created
|
|
|
|
* | ... |
|
|
|
|
* |---------------------| <---- Actual initial stack ptr
|
|
|
|
* | Initial Stack Ptr | aligned to STACK_ALIGN_SIZE
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | ... |
|
|
|
|
* | Stack Ends |
|
|
|
|
* |---------------------- <---- Stack Buffer Ptr from API
|
|
|
|
* | MPU Guard, |
|
|
|
|
* | if present |
|
|
|
|
* ----------------------- <---- Stack Allocation address
|
|
|
|
*
|
|
|
|
*/
|
2017-06-27 09:02:47 +02:00
|
|
|
#if defined(CONFIG_MPU_STACK_GUARD)
|
2018-11-20 09:58:15 +01:00
|
|
|
#define MPU_GUARD_ALIGN_AND_SIZE CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
|
2017-08-30 16:19:15 -05:00
|
|
|
#else
|
2018-11-20 09:58:15 +01:00
|
|
|
#define MPU_GUARD_ALIGN_AND_SIZE 0
|
2017-08-01 16:48:46 -05:00
|
|
|
#endif
|
2017-06-27 09:02:47 +02:00
|
|
|
|
2019-05-27 12:35:28 +02:00
|
|
|
/**
|
|
|
|
* @brief Declare the MPU guard alignment and size for a thread stack
|
|
|
|
* that is using the Floating Point services.
|
|
|
|
*
|
|
|
|
* For threads that are using the Floating Point services under Shared
|
|
|
|
* Registers (CONFIG_FP_SHARING=y) mode, the exception stack frame may
|
|
|
|
* contain both the basic stack frame and the FP caller-saved context,
|
|
|
|
* upon exception entry. Therefore, a wide guard region is required to
|
|
|
|
* guarantee that stack-overflow detection will always be successful.
|
|
|
|
*/
|
|
|
|
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING) \
|
|
|
|
&& defined(CONFIG_MPU_STACK_GUARD)
|
|
|
|
#define MPU_GUARD_ALIGN_AND_SIZE_FLOAT CONFIG_MPU_STACK_GUARD_MIN_SIZE_FLOAT
|
|
|
|
#else
|
|
|
|
#define MPU_GUARD_ALIGN_AND_SIZE_FLOAT 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Define alignment of an MPU guard
|
|
|
|
*
|
|
|
|
* Minimum alignment of the start address of an MPU guard, depending on
|
|
|
|
* whether the MPU architecture enforces a size (and power-of-two) alignment
|
|
|
|
* requirement.
|
|
|
|
*/
|
|
|
|
#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
|
|
|
#define Z_MPU_GUARD_ALIGN (MAX(MPU_GUARD_ALIGN_AND_SIZE, \
|
|
|
|
MPU_GUARD_ALIGN_AND_SIZE_FLOAT))
|
|
|
|
#else
|
|
|
|
#define Z_MPU_GUARD_ALIGN MPU_GUARD_ALIGN_AND_SIZE
|
|
|
|
#endif
|
|
|
|
|
2017-12-08 12:22:49 -06:00
|
|
|
/**
|
|
|
|
* @brief Define alignment of a stack buffer
|
|
|
|
*
|
|
|
|
* This is used for two different things:
|
2019-11-20 10:12:15 -08:00
|
|
|
*
|
|
|
|
* -# Used in checks for stack size to be a multiple of the stack buffer
|
2017-12-08 12:22:49 -06:00
|
|
|
* alignment
|
2019-11-20 10:12:15 -08:00
|
|
|
* -# Used to determine the alignment of a stack buffer
|
2017-12-08 12:22:49 -06:00
|
|
|
*
|
|
|
|
*/
|
2019-05-27 12:35:28 +02:00
|
|
|
#define STACK_ALIGN MAX(Z_THREAD_MIN_STACK_ALIGN, Z_MPU_GUARD_ALIGN)
|
2017-12-08 12:22:49 -06:00
|
|
|
|
2019-06-13 13:41:16 +02:00
|
|
|
/**
|
|
|
|
* @brief Define alignment of a privilege stack buffer
|
|
|
|
*
|
|
|
|
* This is used to determine the required alignment of threads'
|
|
|
|
* privilege stacks when building with support for user mode.
|
|
|
|
*
|
|
|
|
* @note
|
|
|
|
* The privilege stacks do not need to respect the minimum MPU
|
|
|
|
* region alignment requirement (unless this is enforced via
|
|
|
|
* the MPU Stack Guard feature).
|
|
|
|
*/
|
|
|
|
#if defined(CONFIG_USERSPACE)
|
|
|
|
#define Z_PRIVILEGE_STACK_ALIGN MAX(STACK_ALIGN_SIZE, Z_MPU_GUARD_ALIGN)
|
|
|
|
#endif
|
|
|
|
|
2017-12-08 12:22:49 -06:00
|
|
|
/**
|
|
|
|
* @brief Calculate power of two ceiling for a buffer size input
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#define POW2_CEIL(x) ((1 << (31 - __builtin_clz(x))) < x ? \
|
|
|
|
1 << (31 - __builtin_clz(x) + 1) : \
|
|
|
|
1 << (31 - __builtin_clz(x)))
|
|
|
|
|
2019-03-19 10:42:24 -07:00
|
|
|
#if defined(CONFIG_USERSPACE) && \
|
|
|
|
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
|
|
|
/* Guard is 'carved-out' of the thread stack region, and the supervisor
|
|
|
|
* mode stack is allocated elsewhere by gen_priv_stack.py
|
|
|
|
*/
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_RESERVED 0
|
2019-03-19 10:42:24 -07:00
|
|
|
#else
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_RESERVED MPU_GUARD_ALIGN_AND_SIZE
|
2019-03-19 10:42:24 -07:00
|
|
|
#endif
|
|
|
|
|
2017-12-08 12:22:49 -06:00
|
|
|
#if defined(CONFIG_USERSPACE) && \
|
|
|
|
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_DEFINE(sym, size) \
|
2019-01-31 15:53:24 -08:00
|
|
|
struct _k_thread_stack_element __noinit \
|
2017-12-08 12:22:49 -06:00
|
|
|
__aligned(POW2_CEIL(size)) sym[POW2_CEIL(size)]
|
|
|
|
#else
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_DEFINE(sym, size) \
|
2019-01-31 15:53:24 -08:00
|
|
|
struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) \
|
2017-08-30 16:19:15 -05:00
|
|
|
sym[size+MPU_GUARD_ALIGN_AND_SIZE]
|
2017-12-08 12:22:49 -06:00
|
|
|
#endif
|
2017-06-27 09:02:47 +02:00
|
|
|
|
2018-06-27 13:26:20 +05:30
|
|
|
#if defined(CONFIG_USERSPACE) && \
|
|
|
|
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_LEN(size) (POW2_CEIL(size))
|
2018-06-27 13:26:20 +05:30
|
|
|
#else
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_LEN(size) ((size)+MPU_GUARD_ALIGN_AND_SIZE)
|
2018-06-27 13:26:20 +05:30
|
|
|
#endif
|
|
|
|
|
2017-12-08 12:22:49 -06:00
|
|
|
#if defined(CONFIG_USERSPACE) && \
|
|
|
|
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
2019-01-31 15:53:24 -08:00
|
|
|
struct _k_thread_stack_element __noinit \
|
2017-12-08 12:22:49 -06:00
|
|
|
__aligned(POW2_CEIL(size)) \
|
2019-11-07 12:43:29 -08:00
|
|
|
sym[nmemb][ARCH_THREAD_STACK_LEN(size)]
|
2017-12-08 12:22:49 -06:00
|
|
|
#else
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
2019-01-31 15:53:24 -08:00
|
|
|
struct _k_thread_stack_element __noinit \
|
2017-12-08 12:22:49 -06:00
|
|
|
__aligned(STACK_ALIGN) \
|
2019-11-07 12:43:29 -08:00
|
|
|
sym[nmemb][ARCH_THREAD_STACK_LEN(size)]
|
2017-12-08 12:22:49 -06:00
|
|
|
#endif
|
2017-06-27 09:02:47 +02:00
|
|
|
|
2017-12-08 12:22:49 -06:00
|
|
|
#if defined(CONFIG_USERSPACE) && \
|
|
|
|
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_MEMBER(sym, size) \
|
2017-12-08 12:22:49 -06:00
|
|
|
struct _k_thread_stack_element __aligned(POW2_CEIL(size)) \
|
|
|
|
sym[POW2_CEIL(size)]
|
|
|
|
#else
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_MEMBER(sym, size) \
|
2017-08-02 15:14:49 -05:00
|
|
|
struct _k_thread_stack_element __aligned(STACK_ALIGN) \
|
2017-08-30 16:19:15 -05:00
|
|
|
sym[size+MPU_GUARD_ALIGN_AND_SIZE]
|
2017-12-08 12:22:49 -06:00
|
|
|
#endif
|
2017-06-27 09:02:47 +02:00
|
|
|
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_SIZEOF(sym) (sizeof(sym) - MPU_GUARD_ALIGN_AND_SIZE)
|
2017-06-27 09:02:47 +02:00
|
|
|
|
2019-11-07 12:43:29 -08:00
|
|
|
#define ARCH_THREAD_STACK_BUFFER(sym) \
|
2017-08-30 16:19:15 -05:00
|
|
|
((char *)(sym) + MPU_GUARD_ALIGN_AND_SIZE)
|
2017-06-27 09:02:47 +02:00
|
|
|
|
2019-08-12 12:52:55 -05:00
|
|
|
/* Legacy case: retain containing extern "C" with C++ */
|
2018-11-27 15:45:36 +01:00
|
|
|
#ifdef CONFIG_ARM_MPU
|
2018-09-17 15:03:43 +02:00
|
|
|
#ifdef CONFIG_CPU_HAS_ARM_MPU
|
2019-11-09 17:49:36 +00:00
|
|
|
#include <arch/arm/aarch32/cortex_m/mpu/arm_mpu.h>
|
2018-09-17 15:03:43 +02:00
|
|
|
#endif /* CONFIG_CPU_HAS_ARM_MPU */
|
|
|
|
#ifdef CONFIG_CPU_HAS_NXP_MPU
|
2019-11-09 17:49:36 +00:00
|
|
|
#include <arch/arm/aarch32/cortex_m/mpu/nxp_mpu.h>
|
2018-11-28 10:06:18 +01:00
|
|
|
#endif /* CONFIG_CPU_HAS_NXP_MPU */
|
2018-11-27 15:45:36 +01:00
|
|
|
#endif /* CONFIG_ARM_MPU */
|
2017-07-07 20:29:30 +08:00
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-11-09 18:48:15 +00:00
|
|
|
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ARCH_H_ */
|