mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-16 05:41:55 +00:00
This patch fixes a couple of issues with the stack guard size and properly constructs the STACK_ALIGN and STACK_ALIGN_SIZE definitions. The ARM AAPCS requires that the stack pointers be 8 byte aligned. The STACK_ALIGN_SIZE definition is meant to contain the stack pointer alignment requirements. This is the required alignment at public API boundaries (ie stack frames). The STACK_ALIGN definition is the required alignment for the start address for stack buffer storage. STACK_ALIGN is used to validate the allocation sizes for stack buffers. The MPU_GUARD_ALIGN_AND_SIZE definition is the minimum alignment and size for the MPU. The minimum size and alignment just so happen to be 32 bytes for vanilla ARM MPU implementations. When defining stack buffers, the stack guard alignment requirements must be taken into consideration when allocating the stack memory. The __align() must be filled in with either STACK_ALIGN_SIZE or the align/size of the MPU stack guard. The align/size for the guard region will be 0 when CONFIG_MPU_STACK_GUARD is not set, and 32 bytes when it is. The _ARCH_THREAD_STACK_XXXXXX APIs need to know the minimum alignment requirements for the stack buffer memory and the stack guard size to correctly allocate and reference the stack memory. This is reflected in the macros with the use of the STACK_ALIGN definition and the MPU_GUARD_ALIGN_AND_SIZE definition. Signed-off-by: Andy Gross <andy.gross@linaro.org>
208 lines
6.6 KiB
C
208 lines
6.6 KiB
C
/*
|
|
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief ARM specific kernel interface header
|
|
*
|
|
* This header contains the ARM specific kernel interface. It is
|
|
* included by the kernel interface architecture-abstraction header
|
|
* (include/arc/cpu.h)
|
|
*/
|
|
|
|
#ifndef _ARM_ARCH__H_
|
|
#define _ARM_ARCH__H_
|
|
|
|
/* Add include for DTS generated information */
|
|
#include <generated_dts_board.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* ARM GPRs are often designated by two different names */
|
|
#define sys_define_gpr_with_alias(name1, name2) union { u32_t name1, name2; }
|
|
|
|
/* APIs need to support non-byte addressable architectures */
|
|
|
|
#define OCTET_TO_SIZEOFUNIT(X) (X)
|
|
#define SIZEOFUNIT_TO_OCTET(X) (X)
|
|
|
|
#ifdef CONFIG_CPU_CORTEX_M
|
|
#include <arch/arm/cortex_m/exc.h>
|
|
#include <arch/arm/cortex_m/irq.h>
|
|
#include <arch/arm/cortex_m/error.h>
|
|
#include <arch/arm/cortex_m/misc.h>
|
|
#include <arch/arm/cortex_m/memory_map.h>
|
|
#include <arch/arm/cortex_m/asm_inline.h>
|
|
#include <arch/arm/cortex_m/addr_types.h>
|
|
#include <arch/arm/cortex_m/sys_io.h>
|
|
#include <arch/arm/cortex_m/nmi.h>
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @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
|
|
|
|
/**
|
|
* @brief Declare a minimum MPU guard alignment and size
|
|
*
|
|
* This specifies the minimum MPU guard alignment/size for the MPU. This
|
|
* 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
|
|
* the stack. APIs which give the stack ptr and stack size will take this
|
|
* 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
|
|
*
|
|
*/
|
|
#if defined(CONFIG_MPU_STACK_GUARD)
|
|
#define MPU_GUARD_ALIGN_AND_SIZE 32
|
|
#else
|
|
#define MPU_GUARD_ALIGN_AND_SIZE 0
|
|
#endif
|
|
|
|
/**
|
|
* @brief Define alignment of a stack buffer
|
|
*
|
|
* This is used for two different things:
|
|
* 1) Used in checks for stack size to be a multiple of the stack buffer
|
|
* alignment
|
|
* 2) Used to determine the alignment of a stack buffer
|
|
*
|
|
*/
|
|
#define STACK_ALIGN max(STACK_ALIGN_SIZE, MPU_GUARD_ALIGN_AND_SIZE)
|
|
|
|
/**
|
|
* @brief Declare a toplevel thread stack memory region
|
|
*
|
|
* This declares a region of memory suitable for use as a thread's stack.
|
|
*
|
|
* This is the generic, historical definition. Align to STACK_ALIGN_SIZE and
|
|
* put in * 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* The declared symbol will always be a character array which can be passed to
|
|
* k_thread_create, but should otherwise not be manipulated.
|
|
*
|
|
* It is legal to precede this definition with the 'static' keyword.
|
|
*
|
|
* It is NOT legal to take the sizeof(sym) and pass that to the stackSize
|
|
* parameter of k_thread_create(), it may not be the same as the
|
|
* 'size' parameter. Use K_THREAD_STACK_SIZEOF() instead.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define _ARCH_THREAD_STACK_DEFINE(sym, size) \
|
|
struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) \
|
|
sym[size+MPU_GUARD_ALIGN_AND_SIZE]
|
|
|
|
/**
|
|
* @brief Declare a toplevel array of thread stack memory regions
|
|
*
|
|
* Create an array of equally sized stacks. See K_THREAD_STACK_DEFINE
|
|
* definition for additional details and constraints.
|
|
*
|
|
* This is the generic, historical definition. Align to STACK_ALIGN_SIZE and
|
|
* put in * 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) \
|
|
sym[nmemb][size+MPU_GUARD_ALIGN_AND_SIZE]
|
|
|
|
/**
|
|
* @brief Declare an embedded stack memory region
|
|
*
|
|
* Used for stacks embedded within other data structures. Use is highly
|
|
* discouraged but in some cases necessary. For memory protection scenarios,
|
|
* it is very important that any RAM preceding this member not be writable
|
|
* by threads else a stack overflow will lead to silent corruption. In other
|
|
* words, the containing data structure should live in RAM owned by the kernel.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define _ARCH_THREAD_STACK_MEMBER(sym, size) \
|
|
struct _k_thread_stack_element __aligned(STACK_ALIGN) \
|
|
sym[size+MPU_GUARD_ALIGN_AND_SIZE]
|
|
|
|
/**
|
|
* @brief Return the size in bytes of a stack memory region
|
|
*
|
|
* Convenience macro for passing the desired stack size to k_thread_create()
|
|
* since the underlying implementation may actually create something larger
|
|
* (for instance a guard area).
|
|
*
|
|
* The value returned here is guaranteed to match the 'size' parameter
|
|
* passed to K_THREAD_STACK_DEFINE and related macros.
|
|
*
|
|
* @param sym Stack memory symbol
|
|
* @return Size of the stack
|
|
*/
|
|
#define _ARCH_THREAD_STACK_SIZEOF(sym) (sizeof(sym) - MPU_GUARD_ALIGN_AND_SIZE)
|
|
|
|
/**
|
|
* @brief Get a pointer to the physical stack buffer
|
|
*
|
|
* Convenience macro to get at the real underlying stack buffer used by
|
|
* the CPU. Guaranteed to be a character pointer of size K_THREAD_STACK_SIZEOF.
|
|
* This is really only intended for diagnostic tools which want to examine
|
|
* stack memory contents.
|
|
*
|
|
* @param sym Declared stack symbol name
|
|
* @return The buffer itself, a char *
|
|
*/
|
|
#define _ARCH_THREAD_STACK_BUFFER(sym) \
|
|
((char *)(sym) + MPU_GUARD_ALIGN_AND_SIZE)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _ARM_ARCH__H_ */
|