Skip to content
Permalink
Browse files

arch: arm: re-organize thread stack macro defines in arch.h

This commit re-organizes the macro definitions in arch.h for
the ARM architecture. In particular, the commit:
- defines the minimum alignment requirement for thread stacks,
  that is, excluding alignment requirement for (possible)
  MPU stack guards.
- defines convenience macros for the MPU stack guard align and
  size for threads using the FP services under Shared registers
  mode (CONFIG_FP_SHARING=y). For that, a hidden Kconfig option
  is defined in arch/arm/core/cortex_m/mpu/Kconfig.
- enforces stack alignment with a wide MPU stack guard (128
  bytes) under CONFIG_FP_SHARING=y for the ARMv7-M architecture,
  which requires start address alignment with power-of-two and
  region size.

The commit does not change the amount of stack that is reserved
with K_THREAD_STACK_DEFINE; it only determines the stack buffer
alignment as explained above.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
  • Loading branch information...
ioannisg authored and andrewboie committed May 27, 2019
1 parent ef736f7 commit e0db39447bc53ee1b3734a2451697b293cb234bb
Showing with 68 additions and 7 deletions.
  1. +21 −2 arch/arm/core/cortex_m/mpu/Kconfig
  2. +47 −5 include/arch/arm/arch.h
@@ -32,16 +32,35 @@ config ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
A minimum 4-byte alignment is enforced in ARM builds without
support for Memory Protection.

if ARM_MPU

config MPU_STACK_GUARD
bool "Thread Stack Guards"
depends on ARM_MPU
help
Enable Thread Stack Guards via MPU

if MPU_STACK_GUARD

config MPU_STACK_GUARD_MIN_SIZE_FLOAT
int
depends on FP_SHARING
default 128
help
Minimum size (and alignment when applicable) of an ARM MPU
region, which guards the stack of a thread that is using the
Floating Point (FP) context. The width of the guard is set to
128, to accommodate the length of a Cortex-M exception stack
frame when the floating point context is active. The FP context
is only stacked in sharing FP registers mode, therefore, the
option is applicable only when FP_SHARING is selected.

endif # MPU_STACK_GUARD

config MPU_ALLOW_FLASH_WRITE
bool "Add MPU access to write to flash"
depends on ARM_MPU
help
Enable this to allow MPU RWX access to flash memory

endif # ARM_MPU

endif # CPU_HAS_MPU
@@ -52,6 +52,21 @@ extern "C" {
#define STACK_ALIGN_SIZE 4
#endif

/**
* @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

/**
* @brief Declare a minimum MPU guard alignment and size
*
@@ -98,6 +113,37 @@ extern "C" {
#define MPU_GUARD_ALIGN_AND_SIZE 0
#endif

/**
* @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

/**
* @brief Define alignment of a stack buffer
*
@@ -107,11 +153,7 @@ extern "C" {
* 2) Used to determine the alignment of a stack buffer
*
*/
#if defined(CONFIG_USERSPACE)
#define STACK_ALIGN CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
#else
#define STACK_ALIGN MAX(STACK_ALIGN_SIZE, MPU_GUARD_ALIGN_AND_SIZE)
#endif
#define STACK_ALIGN MAX(Z_THREAD_MIN_STACK_ALIGN, Z_MPU_GUARD_ALIGN)

/**
* @brief Calculate power of two ceiling for a buffer size input

0 comments on commit e0db394

Please sign in to comment.
You can’t perform that action at this time.