arch: arm: Move ARM code to AArch32 sub-directory

Before introducing the code for ARM64 (AArch64) we need to relocate the
current ARM code to a new AArch32 sub-directory. For now we can assume
that no code is shared between ARM and ARM64.

There are no functional changes. The code is moved to the new location
and the file paths are fixed to reflect this change.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2019-11-09 17:49:36 +00:00 committed by Anas Nashif
commit aec9a8c4be
203 changed files with 199 additions and 196 deletions

View file

@ -0,0 +1,259 @@
/*
* 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/arm/cpu.h)
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ARCH_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_ARCH_H_
/* Add include for DTS generated information */
#include <generated_dts_board.h>
/* ARM GPRs are often designated by two different names */
#define sys_define_gpr_with_alias(name1, name2) union { u32_t name1, name2; }
#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>
#include <arch/common/addr_types.h>
#include <arch/common/ffs.h>
#include <arch/arm/aarch32/nmi.h>
#include <arch/arm/aarch32/asm_inline.h>
#ifdef CONFIG_CPU_CORTEX_M
#include <arch/arm/aarch32/cortex_m/cpu.h>
#include <arch/arm/aarch32/cortex_m/memory_map.h>
#include <arch/common/sys_io.h>
#elif defined(CONFIG_CPU_CORTEX_R)
#include <arch/arm/aarch32/cortex_r/cpu.h>
#include <arch/arm/aarch32/cortex_r/sys_io.h>
#endif
#ifdef __cplusplus
extern "C" {
#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 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
*
* 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 CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
#else
#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
*
* This is used for two different things:
*
* -# Used in checks for stack size to be a multiple of the stack buffer
* alignment
* -# Used to determine the alignment of a stack buffer
*
*/
#define STACK_ALIGN MAX(Z_THREAD_MIN_STACK_ALIGN, Z_MPU_GUARD_ALIGN)
/**
* @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
/**
* @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)))
#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
*/
#define ARCH_THREAD_STACK_RESERVED 0
#else
#define ARCH_THREAD_STACK_RESERVED MPU_GUARD_ALIGN_AND_SIZE
#endif
#if defined(CONFIG_USERSPACE) && \
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define ARCH_THREAD_STACK_DEFINE(sym, size) \
struct _k_thread_stack_element __noinit \
__aligned(POW2_CEIL(size)) sym[POW2_CEIL(size)]
#else
#define ARCH_THREAD_STACK_DEFINE(sym, size) \
struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) \
sym[size+MPU_GUARD_ALIGN_AND_SIZE]
#endif
#if defined(CONFIG_USERSPACE) && \
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define ARCH_THREAD_STACK_LEN(size) (POW2_CEIL(size))
#else
#define ARCH_THREAD_STACK_LEN(size) ((size)+MPU_GUARD_ALIGN_AND_SIZE)
#endif
#if defined(CONFIG_USERSPACE) && \
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
struct _k_thread_stack_element __noinit \
__aligned(POW2_CEIL(size)) \
sym[nmemb][ARCH_THREAD_STACK_LEN(size)]
#else
#define ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
struct _k_thread_stack_element __noinit \
__aligned(STACK_ALIGN) \
sym[nmemb][ARCH_THREAD_STACK_LEN(size)]
#endif
#if defined(CONFIG_USERSPACE) && \
defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define ARCH_THREAD_STACK_MEMBER(sym, size) \
struct _k_thread_stack_element __aligned(POW2_CEIL(size)) \
sym[POW2_CEIL(size)]
#else
#define ARCH_THREAD_STACK_MEMBER(sym, size) \
struct _k_thread_stack_element __aligned(STACK_ALIGN) \
sym[size+MPU_GUARD_ALIGN_AND_SIZE]
#endif
#define ARCH_THREAD_STACK_SIZEOF(sym) (sizeof(sym) - MPU_GUARD_ALIGN_AND_SIZE)
#define ARCH_THREAD_STACK_BUFFER(sym) \
((char *)(sym) + MPU_GUARD_ALIGN_AND_SIZE)
/* Legacy case: retain containing extern "C" with C++ */
#ifdef CONFIG_ARM_MPU
#ifdef CONFIG_CPU_HAS_ARM_MPU
#include <arch/arm/aarch32/cortex_m/mpu/arm_mpu.h>
#endif /* CONFIG_CPU_HAS_ARM_MPU */
#ifdef CONFIG_CPU_HAS_NXP_MPU
#include <arch/arm/aarch32/cortex_m/mpu/nxp_mpu.h>
#endif /* CONFIG_CPU_HAS_NXP_MPU */
#endif /* CONFIG_ARM_MPU */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ARCH_H_ */

View file

@ -0,0 +1,23 @@
/* Intel ARM inline assembler functions and macros for public functions */
/*
* Copyright (c) 2015, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_
/*
* The file must not be included directly
* Include kernel.h instead
*/
#if defined(__GNUC__)
#include <arch/arm/aarch32/asm_inline_gcc.h>
#else
#include <arch/arm/asm_inline_other.h>
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_ */

View file

@ -0,0 +1,115 @@
/* ARM Cortex-M GCC specific public inline assembler functions and macros */
/*
* Copyright (c) 2015, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Either public functions or macros or invoked by public functions */
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_
/*
* The file must not be included directly
* Include arch/cpu.h instead
*/
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
#include <arch/arm/aarch32/exc.h>
#include <irq.h>
#ifdef __cplusplus
extern "C" {
#endif
/* On ARMv7-M and ARMv8-M Mainline CPUs, this function prevents regular
* exceptions (i.e. with interrupt priority lower than or equal to
* _EXC_IRQ_DEFAULT_PRIO) from interrupting the CPU. NMI, Faults, SVC,
* and Zero Latency IRQs (if supported) may still interrupt the CPU.
*
* On ARMv6-M and ARMv8-M Baseline CPUs, this function reads the value of
* PRIMASK which shows if interrupts are enabled, then disables all interrupts
* except NMI.
*/
static ALWAYS_INLINE unsigned int arch_irq_lock(void)
{
unsigned int key;
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
__asm__ volatile("mrs %0, PRIMASK;"
"cpsid i"
: "=r" (key)
:
: "memory");
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
unsigned int tmp;
__asm__ volatile(
"mov %1, %2;"
"mrs %0, BASEPRI;"
"msr BASEPRI, %1;"
"isb;"
: "=r"(key), "=r"(tmp)
: "i"(_EXC_IRQ_DEFAULT_PRIO)
: "memory");
#elif defined(CONFIG_ARMV7_R)
__asm__ volatile("mrs %0, cpsr;"
"cpsid i"
: "=r" (key)
:
: "memory", "cc");
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
return key;
}
/* On Cortex-M0/M0+, this enables all interrupts if they were not
* previously disabled.
*/
static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
{
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
if (key) {
return;
}
__asm__ volatile(
"cpsie i;"
"isb"
: : : "memory");
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
__asm__ volatile(
"msr BASEPRI, %0;"
"isb;"
: : "r"(key) : "memory");
#elif defined(CONFIG_ARMV7_R)
__asm__ volatile("msr cpsr_c, %0"
:
: "r" (key)
: "memory", "cc");
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
}
static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
{
/* This convention works for both PRIMASK and BASEPRI */
return key == 0;
}
#ifdef __cplusplus
}
#endif
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_ */

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief CMSIS interface file
*
* This header contains the interface to the ARM CMSIS Core headers.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_CMSIS_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_CMSIS_H_
#include <soc.h>
#ifdef __cplusplus
extern "C" {
#endif
/* CP10 Access Bits */
#define CPACR_CP10_Pos 20U
#define CPACR_CP10_Msk (3UL << CPACR_CP10_Pos)
#define CPACR_CP10_NO_ACCESS (0UL << CPACR_CP10_Pos)
#define CPACR_CP10_PRIV_ACCESS (1UL << CPACR_CP10_Pos)
#define CPACR_CP10_RESERVED (2UL << CPACR_CP10_Pos)
#define CPACR_CP10_FULL_ACCESS (3UL << CPACR_CP10_Pos)
/* CP11 Access Bits */
#define CPACR_CP11_Pos 22U
#define CPACR_CP11_Msk (3UL << CPACR_CP11_Pos)
#define CPACR_CP11_NO_ACCESS (0UL << CPACR_CP11_Pos)
#define CPACR_CP11_PRIV_ACCESS (1UL << CPACR_CP11_Pos)
#define CPACR_CP11_RESERVED (2UL << CPACR_CP11_Pos)
#define CPACR_CP11_FULL_ACCESS (3UL << CPACR_CP11_Pos)
#define SCB_UFSR (*((__IOM u16_t *) &SCB->CFSR + 1))
#define SCB_BFSR (*((__IOM u8_t *) &SCB->CFSR + 1))
#define SCB_MMFSR (*((__IOM u8_t *) &SCB->CFSR))
/* Fill in CMSIS required values for non-CMSIS compliant SoCs.
* Use __NVIC_PRIO_BITS as it is required and simple to check, but
* ultimately all SoCs will define their own CMSIS types and constants.
*/
#ifndef __NVIC_PRIO_BITS
typedef enum {
Reset_IRQn = -15,
NonMaskableInt_IRQn = -14,
HardFault_IRQn = -13,
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
MemoryManagement_IRQn = -12,
BusFault_IRQn = -11,
UsageFault_IRQn = -10,
#if defined(CONFIG_ARM_SECURE_FIRMWARE)
SecureFault_IRQn = -9,
#endif /* CONFIG_ARM_SECURE_FIRMWARE */
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
SVCall_IRQn = -5,
DebugMonitor_IRQn = -4,
PendSV_IRQn = -2,
SysTick_IRQn = -1,
} IRQn_Type;
#if defined(CONFIG_CPU_CORTEX_M0)
#define __CM0_REV 0
#elif defined(CONFIG_CPU_CORTEX_M0PLUS)
#define __CM0PLUS_REV 0
#elif defined(CONFIG_CPU_CORTEX_M3)
#define __CM3_REV 0
#elif defined(CONFIG_CPU_CORTEX_M4)
#define __CM4_REV 0
#elif defined(CONFIG_CPU_CORTEX_M7)
#define __CM7_REV 0
#elif defined(CONFIG_CPU_CORTEX_M23)
#define __CM23_REV 0
#elif defined(CONFIG_CPU_CORTEX_M33)
#define __CM33_REV 0
#else
#error "Unknown Cortex-M device"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0U
#endif
#define __NVIC_PRIO_BITS DT_NUM_IRQ_PRIO_BITS
#define __Vendor_SysTickConfig 0 /* Default to standard SysTick */
#endif /* __NVIC_PRIO_BITS */
#if __NVIC_PRIO_BITS != DT_NUM_IRQ_PRIO_BITS
#error "DT_NUM_IRQ_PRIO_BITS and __NVIC_PRIO_BITS are not set to the same value"
#endif
#ifdef __cplusplus
}
#endif
#if defined(CONFIG_CPU_CORTEX_M0)
#include <core_cm0.h>
#elif defined(CONFIG_CPU_CORTEX_M0PLUS)
#include <core_cm0plus.h>
#elif defined(CONFIG_CPU_CORTEX_M3)
#include <core_cm3.h>
#elif defined(CONFIG_CPU_CORTEX_M4)
#include <core_cm4.h>
#elif defined(CONFIG_CPU_CORTEX_M7)
#include <core_cm7.h>
#elif defined(CONFIG_CPU_CORTEX_M23)
#include <core_cm23.h>
#elif defined(CONFIG_CPU_CORTEX_M33)
#include <core_cm33.h>
#else
#error "Unknown Cortex-M device"
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_CMSIS_H_ */

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2015, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _CORTEX_M_CPU_H
#define _CORTEX_M_CPU_H
#ifdef _ASMLANGUAGE
#define _SCS_BASE_ADDR _PPB_INT_SCS
#define _SCS_ICSR (_SCS_BASE_ADDR + 0xd04)
#define _SCS_ICSR_PENDSV (1 << 28)
#define _SCS_ICSR_UNPENDSV (1 << 27)
#define _SCS_ICSR_RETTOBASE (1 << 11)
#endif
#endif

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM CORTEX-M memory map
*
* This module contains definitions for the memory map of the CORTEX-M series of
* processors.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MEMORY_MAP_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MEMORY_MAP_H_
#include <sys/util.h>
/* 0x00000000 -> 0x1fffffff: Code in ROM [0.5 GB] */
#define _CODE_BASE_ADDR 0x00000000
#define _CODE_END_ADDR 0x1FFFFFFF
/* 0x20000000 -> 0x3fffffff: SRAM [0.5GB] */
#define _SRAM_BASE_ADDR 0x20000000
#define _SRAM_BIT_BAND_REGION 0x20000000
#define _SRAM_BIT_BAND_REGION_END 0x200FFFFF
#define _SRAM_BIT_BAND_ALIAS 0x22000000
#define _SRAM_BIT_BAND_ALIAS_END 0x23FFFFFF
#define _SRAM_END_ADDR 0x3FFFFFFF
/* 0x40000000 -> 0x5fffffff: Peripherals [0.5GB] */
#define _PERI_BASE_ADDR 0x40000000
#define _PERI_BIT_BAND_REGION 0x40000000
#define _PERI_BIT_BAND_REGION_END 0x400FFFFF
#define _PERI_BIT_BAND_ALIAS 0x42000000
#define _PERI_BIT_BAND_ALIAS_END 0x43FFFFFF
#define _PERI_END_ADDR 0x5FFFFFFF
/* 0x60000000 -> 0x9fffffff: external RAM [1GB] */
#define _ERAM_BASE_ADDR 0x60000000
#define _ERAM_END_ADDR 0x9FFFFFFF
/* 0xa0000000 -> 0xdfffffff: external devices [1GB] */
#define _EDEV_BASE_ADDR 0xA0000000
#define _EDEV_END_ADDR 0xDFFFFFFF
/* 0xe0000000 -> 0xffffffff: varies by processor (see below) */
/* 0xe0000000 -> 0xe00fffff: private peripheral bus */
/* 0xe0000000 -> 0xe003ffff: internal [256KB] */
#define _PPB_INT_BASE_ADDR 0xE0000000
#if defined(CONFIG_CPU_CORTEX_M0) || defined(CONFIG_CPU_CORTEX_M0PLUS)
#define _PPB_INT_RSVD_0 0xE0000000
#define _PPB_INT_DWT 0xE0001000
#define _PPB_INT_BPU 0xE0002000
#define _PPB_INT_RSVD_1 0xE0003000
#define _PPB_INT_SCS 0xE000E000
#define _PPB_INT_RSVD_2 0xE000F000
#elif defined(CONFIG_CPU_CORTEX_M3) || defined(CONFIG_CPU_CORTEX_M4) || defined(CONFIG_CPU_CORTEX_M7)
#define _PPB_INT_ITM 0xE0000000
#define _PPB_INT_DWT 0xE0001000
#define _PPB_INT_FPB 0xE0002000
#define _PPB_INT_RSVD_1 0xE0003000
#define _PPB_INT_SCS 0xE000E000
#define _PPB_INT_RSVD_2 0xE000F000
#elif defined(CONFIG_CPU_CORTEX_M23) || defined(CONFIG_CPU_CORTEX_M33)
#define _PPB_INT_RSVD_0 0xE0000000
#define _PPB_INT_SCS 0xE000E000
#define _PPB_INT_SCB 0xE000ED00
#define _PPB_INT_RSVD_1 0xE002E000
#else
#error Unknown CPU
#endif
#define _PPB_INT_END_ADDR 0xE003FFFF
/* 0xe0000000 -> 0xe00fffff: private peripheral bus */
/* 0xe0040000 -> 0xe00fffff: external [768K] */
#define _PPB_EXT_BASE_ADDR 0xE0040000
#if defined(CONFIG_CPU_CORTEX_M0) || defined(CONFIG_CPU_CORTEX_M0PLUS) \
|| defined(CONFIG_CPU_CORTEX_M23)
#elif defined(CONFIG_CPU_CORTEX_M3) || defined(CONFIG_CPU_CORTEX_M4)
#define _PPB_EXT_TPIU 0xE0040000
#define _PPB_EXT_ETM 0xE0041000
#define _PPB_EXT_PPB 0xE0042000
#define _PPB_EXT_ROM_TABLE 0xE00FF000
#define _PPB_EXT_END_ADDR 0xE00FFFFF
#elif defined(CONFIG_CPU_CORTEX_M33)
#undef _PPB_EXT_BASE_ADDR
#define _PPB_EXT_BASE_ADDR 0xE0044000
#define _PPB_EXT_ROM_TABLE 0xE00FF000
#define _PPB_EXT_END_ADDR 0xE00FFFFF
#elif defined(CONFIG_CPU_CORTEX_M7)
#define _PPB_EXT_BASE_ADDR 0xE0040000
#define _PPB_EXT_RSVD_TPIU 0xE0040000
#define _PPB_EXT_ETM 0xE0041000
#define _PPB_EXT_CTI 0xE0042000
#define _PPB_EXT_PPB 0xE0043000
#define _PPB_EXT_PROC_ROM_TABLE 0xE00FE000
#define _PPB_EXT_PPB_ROM_TABLE 0xE00FF000
#else
#error Unknown CPU
#endif
#define _PPB_EXT_END_ADDR 0xE00FFFFF
/* 0xe0100000 -> 0xffffffff: vendor-specific [0.5GB-1MB or 511MB] */
#define _VENDOR_BASE_ADDR 0xE0100000
#define _VENDOR_END_ADDR 0xFFFFFFFF
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MEMORY_MAP_H_ */

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_
#if defined(CONFIG_CPU_CORTEX_M0PLUS) || \
defined(CONFIG_CPU_CORTEX_M3) || \
defined(CONFIG_CPU_CORTEX_M4) || \
defined(CONFIG_CPU_CORTEX_M7)
#include <arch/arm/aarch32/cortex_m/mpu/arm_mpu_v7m.h>
#elif defined(CONFIG_CPU_CORTEX_M23) || \
defined(CONFIG_CPU_CORTEX_M33)
#include <arch/arm/aarch32/cortex_m/mpu/arm_mpu_v8m.h>
#else
#error "Unsupported ARM CPU"
#endif
#ifndef _ASMLANGUAGE
/* Region definition data structure */
struct arm_mpu_region {
/* Region Base Address */
u32_t base;
/* Region Name */
const char *name;
/* Region Attributes */
arm_mpu_region_attr_t attr;
};
/* MPU configuration data structure */
struct arm_mpu_config {
/* Number of regions */
u32_t num_regions;
/* Regions */
const struct arm_mpu_region *mpu_regions;
};
#define MPU_REGION_ENTRY(_name, _base, _attr) \
{\
.name = _name, \
.base = _base, \
.attr = _attr, \
}
/* Reference to the MPU configuration.
*
* This struct is defined and populated for each SoC (in the SoC definition),
* and holds the build-time configuration information for the fixed MPU
* regions enabled during kernel initialization. Dynamic MPU regions (e.g.
* for Thread Stack, Stack Guards, etc.) are programmed during runtime, thus,
* not kept here.
*/
extern const struct arm_mpu_config mpu_config;
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_ */

View file

@ -0,0 +1,273 @@
/*
* Copyright (c) 2018 Linaro Limited.
* Copyright (c) 2018 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ASMLANGUAGE
#include <arch/arm/aarch32/cortex_m/cmsis.h>
/* Convenience macros to represent the ARMv7-M-specific
* configuration for memory access permission and
* cache-ability attribution.
*/
/* Privileged No Access, Unprivileged No Access */
#define NO_ACCESS 0x0
#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged No Access, Unprivileged No Access */
#define P_NA_U_NA 0x0
#define P_NA_U_NA_Msk ((P_NA_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Write, Unprivileged No Access */
#define P_RW_U_NA 0x1
#define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Write, Unprivileged Read Only */
#define P_RW_U_RO 0x2
#define P_RW_U_RO_Msk ((P_RW_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Write, Unprivileged Read Write */
#define P_RW_U_RW 0x3
#define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Write, Unprivileged Read Write */
#define FULL_ACCESS 0x3
#define FULL_ACCESS_Msk ((FULL_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Only, Unprivileged No Access */
#define P_RO_U_NA 0x5
#define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Only, Unprivileged Read Only */
#define P_RO_U_RO 0x6
#define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Privileged Read Only, Unprivileged Read Only */
#define RO 0x7
#define RO_Msk ((RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
/* Attribute flag for not-allowing execution (eXecute Never) */
#define NOT_EXEC MPU_RASR_XN_Msk
/* The following definitions are for internal use in arm_mpu.h. */
#define STRONGLY_ORDERED_SHAREABLE MPU_RASR_S_Msk
#define DEVICE_SHAREABLE (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#define NORMAL_OUTER_INNER_WRITE_THROUGH_SHAREABLE \
(MPU_RASR_C_Msk | MPU_RASR_S_Msk)
#define NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE MPU_RASR_C_Msk
#define NORMAL_OUTER_INNER_WRITE_BACK_SHAREABLE \
(MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#define NORMAL_OUTER_INNER_WRITE_BACK_NON_SHAREABLE \
(MPU_RASR_C_Msk | MPU_RASR_B_Msk)
#define NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE \
((1 << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk)
#define NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE \
(1 << MPU_RASR_TEX_Pos)
#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_SHAREABLE \
((1 << MPU_RASR_TEX_Pos) |\
MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE \
((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk)
#define DEVICE_NON_SHAREABLE (2 << MPU_RASR_TEX_Pos)
/* Bit-masks to disable sub-regions. */
#define SUB_REGION_0_DISABLED ((0x01 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_1_DISABLED ((0x02 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_2_DISABLED ((0x04 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_3_DISABLED ((0x08 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_4_DISABLED ((0x10 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_5_DISABLED ((0x20 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_6_DISABLED ((0x40 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define SUB_REGION_7_DISABLED ((0x80 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
#define REGION_SIZE(size) ((ARM_MPU_REGION_SIZE_ ## size \
<< MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk)
#define REGION_32B REGION_SIZE(32B)
#define REGION_64B REGION_SIZE(64B)
#define REGION_128B REGION_SIZE(128B)
#define REGION_256B REGION_SIZE(256B)
#define REGION_512B REGION_SIZE(512B)
#define REGION_1K REGION_SIZE(1KB)
#define REGION_2K REGION_SIZE(2KB)
#define REGION_4K REGION_SIZE(4KB)
#define REGION_8K REGION_SIZE(8KB)
#define REGION_16K REGION_SIZE(16KB)
#define REGION_32K REGION_SIZE(32KB)
#define REGION_64K REGION_SIZE(64KB)
#define REGION_128K REGION_SIZE(128KB)
#define REGION_256K REGION_SIZE(256KB)
#define REGION_512K REGION_SIZE(512KB)
#define REGION_1M REGION_SIZE(1MB)
#define REGION_2M REGION_SIZE(2MB)
#define REGION_4M REGION_SIZE(4MB)
#define REGION_8M REGION_SIZE(8MB)
#define REGION_16M REGION_SIZE(16MB)
#define REGION_32M REGION_SIZE(32MB)
#define REGION_64M REGION_SIZE(64MB)
#define REGION_128M REGION_SIZE(128MB)
#define REGION_256M REGION_SIZE(256MB)
#define REGION_512M REGION_SIZE(512MB)
#define REGION_1G REGION_SIZE(1GB)
#define REGION_2G REGION_SIZE(2GB)
#define REGION_4G REGION_SIZE(4GB)
/* Some helper defines for common regions */
#define REGION_RAM_ATTR(size) \
{ \
(NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \
MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk) \
}
#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
#define REGION_FLASH_ATTR(size) \
{ \
(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | \
P_RW_U_RO_Msk) \
}
#else
#define REGION_FLASH_ATTR(size) \
{ \
(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | RO_Msk) \
}
#endif
#define REGION_PPB_ATTR(size) { (STRONGLY_ORDERED_SHAREABLE | size | \
P_RW_U_NA_Msk) }
#define REGION_IO_ATTR(size) { (DEVICE_NON_SHAREABLE | size | P_RW_U_NA_Msk) }
struct arm_mpu_region_attr {
/* Attributes belonging to RASR (including the encoded region size) */
u32_t rasr;
};
typedef struct arm_mpu_region_attr arm_mpu_region_attr_t;
/* Typedef for the k_mem_partition attribute */
typedef struct {
u32_t rasr_attr;
} k_mem_partition_attr_t;
/* Read-Write access permission attributes */
#define _K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC)
#define _K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC)
#define _K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC)
#define _K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC)
#define _K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC)
#define _K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC)
/* Execution-allowed attributes */
#define _K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk)
#define _K_MEM_PARTITION_P_RWX_U_RX (P_RW_U_RO_Msk)
#define _K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO_Msk)
/* Kernel macros for memory attribution
* (access permissions and cache-ability).
*
* The macros are to be stored in k_mem_partition_attr_t
* objects. The format of k_mem_partition_attr_t is an
* "1-1" mapping of the ARMv7-M MPU RASR attribute register
* fields (excluding the <size> and <enable> bit-fields).
*/
/* Read-Write access permission attributes (default cache-ability) */
#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_NA_U_NA | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RW_U_RW | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RW_U_RO | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RW_U_NA | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RO_U_RO | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RO_U_NA | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
/* Execution-allowed attributes (default-cacheability) */
#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RWX_U_RWX | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RWX_U_RX | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
{ _K_MEM_PARTITION_P_RX_U_RX | \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
/*
* @brief Evaluate Write-ability
*
* Evaluate whether the access permissions include write-ability.
*
* @param attr The k_mem_partition_attr_t object holding the
* MPU attributes to be checked against write-ability.
*/
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
({ \
int __is_writable__; \
switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \
case P_RW_U_RW_Msk: \
case P_RW_U_RO_Msk: \
case P_RW_U_NA_Msk: \
__is_writable__ = 1; \
break; \
default: \
__is_writable__ = 0; \
} \
__is_writable__; \
})
/*
* @brief Evaluate Execution allowance
*
* Evaluate whether the access permissions include execution.
*
* @param attr The k_mem_partition_attr_t object holding the
* MPU attributes to be checked against execution
* allowance.
*/
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
(!((attr.rasr_attr) & (NOT_EXEC)))
/* Attributes for no-cache enabling (share-ability is selected by default) */
#define K_MEM_PARTITION_P_NA_U_NA_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_NA_U_NA \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RW_U_RW \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RW_U_RO_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RW_U_RO \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RW_U_NA \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RO_U_RO \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RO_U_NA \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RWX_U_RWX \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RWX_U_RX \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \
{(_K_MEM_PARTITION_P_RX_U_RX \
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
#endif /* _ASMLANGUAGE */
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
BUILD_ASSERT_MSG(!(((size) & ((size) - 1))) && \
(size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \
!((u32_t)(start) & ((size) - 1)), \
"the size of the partition must be power of 2" \
" and greater than or equal to the minimum MPU region size." \
"start address of the partition must align with size.")

View file

@ -0,0 +1,259 @@
/*
* Copyright (c) 2018 Linaro Limited.
* Copyright (c) 2018 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ASMLANGUAGE
#include <arch/arm/aarch32/cortex_m/cmsis.h>
/* Convenience macros to represent the ARMv8-M-specific
* configuration for memory access permission and
* cache-ability attribution.
*/
/* Privileged No Access, Unprivileged No Access */
/*#define NO_ACCESS 0x0 */
/*#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */
/* Privileged No Access, Unprivileged No Access */
/*#define P_NA_U_NA 0x0 */
/*#define P_NA_U_NA_Msk ((P_NA_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */
/* Privileged Read Write, Unprivileged No Access */
#define P_RW_U_NA 0x0
#define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
/* Privileged Read Write, Unprivileged Read Only */
/*#define P_RW_U_RO 0x2 */
/*#define P_RW_U_RO_Msk ((P_RW_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)*/
/* Privileged Read Write, Unprivileged Read Write */
#define P_RW_U_RW 0x1
#define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
/* Privileged Read Write, Unprivileged Read Write */
#define FULL_ACCESS 0x1
#define FULL_ACCESS_Msk ((FULL_ACCESS << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
/* Privileged Read Only, Unprivileged No Access */
#define P_RO_U_NA 0x2
#define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
/* Privileged Read Only, Unprivileged Read Only */
#define P_RO_U_RO 0x3
#define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
/* Privileged Read Only, Unprivileged Read Only */
#define RO 0x3
#define RO_Msk ((RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
/* Attribute flag for not-allowing execution (eXecute Never) */
#define NOT_EXEC MPU_RBAR_XN_Msk
/* Attribute flags for share-ability */
#define NON_SHAREABLE 0x0
#define NON_SHAREABLE_Msk \
((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
#define OUTER_SHAREABLE 0x2
#define OUTER_SHAREABLE_Msk \
((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
#define INNER_SHAREABLE 0x3
#define INNER_SHAREABLE_Msk \
((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
/* Helper define to calculate the region limit address. */
#define REGION_LIMIT_ADDR(base, size) \
(((base & MPU_RBAR_BASE_Msk) + size - 1) & MPU_RLAR_LIMIT_Msk)
/* Attribute flags for cache-ability */
/* Read/Write Allocation Configurations for Cacheable Memory */
#define R_NON_W_NON 0x0 /* Do not allocate Read/Write */
#define R_NON_W_ALLOC 0x1 /* Do not allocate Read, Allocate Write */
#define R_ALLOC_W_NON 0x2 /* Allocate Read, Do not allocate Write */
#define R_ALLOC_W_ALLOC 0x3 /* Allocate Read/Write */
/* Memory Attributes for Normal Memory */
#define NORMAL_O_WT_NT 0x80 /* Normal, Outer Write-through non-transient */
#define NORMAL_O_WB_NT 0xC0 /* Normal, Outer Write-back non-transient */
#define NORMAL_O_NON_C 0x40 /* Normal, Outer Non-Cacheable */
#define NORMAL_I_WT_NT 0x08 /* Normal, Inner Write-through non-transient */
#define NORMAL_I_WB_NT 0x0C /* Normal, Inner Write-back non-transient */
#define NORMAL_I_NON_C 0x04 /* Normal, Inner Non-Cacheable */
#define NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS \
((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) \
| \
(NORMAL_I_WT_NT | R_ALLOC_W_NON)) \
#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS \
((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) \
| \
(NORMAL_I_WB_NT | R_ALLOC_W_ALLOC))
#define NORMAL_OUTER_INNER_NON_CACHEABLE \
((NORMAL_O_NON_C | (R_NON_W_NON << 4)) \
| \
(NORMAL_I_NON_C | R_NON_W_NON))
/* Common cache-ability configuration for Flash, SRAM regions */
#define MPU_CACHE_ATTRIBUTES_FLASH \
NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS
#define MPU_CACHE_ATTRIBUTES_SRAM \
NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS
#define MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE \
NORMAL_OUTER_INNER_NON_CACHEABLE
/* Global MAIR configurations */
#define MPU_MAIR_ATTR_FLASH MPU_CACHE_ATTRIBUTES_FLASH
#define MPU_MAIR_INDEX_FLASH 0
#define MPU_MAIR_ATTR_SRAM MPU_CACHE_ATTRIBUTES_SRAM
#define MPU_MAIR_INDEX_SRAM 1
#define MPU_MAIR_ATTR_SRAM_NOCACHE MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE
#define MPU_MAIR_INDEX_SRAM_NOCACHE 2
/* Some helper defines for common regions.
*
* Note that the ARMv8-M MPU architecture requires that the
* enabled MPU regions are non-overlapping. Therefore, it is
* recommended to use these helper defines only for configuring
* fixed MPU regions at build-time (i.e. regions that are not
* expected to be re-programmed or re-adjusted at run-time so
* that they do not overlap with other MPU regions).
*/
#define REGION_RAM_ATTR(base, size) \
{\
.rbar = NOT_EXEC | \
P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
.r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
}
#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
/* Note that the access permissions allow for un-privileged writes, contrary
* to ARMv7-M where un-privileged code has Read-Only permissions.
*/
#define REGION_FLASH_ATTR(base, size) \
{\
.rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_FLASH, \
.r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
}
#else /* CONFIG_MPU_ALLOW_FLASH_WRITE */
#define REGION_FLASH_ATTR(base, size) \
{\
.rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_FLASH, \
.r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
}
#endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
struct arm_mpu_region_attr {
/* Attributes belonging to RBAR */
u8_t rbar: 5;
/* MAIR index for attribute indirection */
u8_t mair_idx: 3;
/* Region Limit Address value to be written to the RLAR register. */
u32_t r_limit;
};
typedef struct arm_mpu_region_attr arm_mpu_region_attr_t;
/* Typedef for the k_mem_partition attribute */
typedef struct {
u16_t rbar;
u16_t mair_idx;
} k_mem_partition_attr_t;
/* Kernel macros for memory attribution
* (access permissions and cache-ability).
*
* The macros are to be stored in k_mem_partition_attr_t
* objects. The format of a k_mem_partition_attr_t object
* is as follows: field <rbar> contains a direct mapping
* of the <XN> and <AP> bit-fields of the RBAR register;
* field <mair_idx> contains a direct mapping of AttrIdx
* bit-field, stored in RLAR register.
*/
/* Read-Write access permission attributes */
#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
{(P_RW_U_RW_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
{(P_RW_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
{(P_RO_U_RO_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
{(P_RO_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
/* Execution-allowed attributes */
#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \
{(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM})
#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
{(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM})
/*
* @brief Evaluate Write-ability
*
* Evaluate whether the access permissions include write-ability.
*
* @param attr The k_mem_partition_attr_t object holding the
* MPU attributes to be checked against write-ability.
*/
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
({ \
int __is_writable__; \
switch (attr.rbar & MPU_RBAR_AP_Msk) { \
case P_RW_U_RW_Msk: \
case P_RW_U_NA_Msk: \
__is_writable__ = 1; \
break; \
default: \
__is_writable__ = 0; \
} \
__is_writable__; \
})
/*
* @brief Evaluate Execution allowance
*
* Evaluate whether the access permissions include execution.
*
* @param attr The k_mem_partition_attr_t object holding the
* MPU attributes to be checked against execution
* allowance.
*/
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
(!((attr.rbar) & (NOT_EXEC)))
/* Attributes for no-cache enabling (share-ability is selected by default) */
/* Read-Write access permission attributes */
#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \
{(P_RW_U_RW_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
MPU_MAIR_INDEX_SRAM_NOCACHE})
#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \
{(P_RW_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
MPU_MAIR_INDEX_SRAM_NOCACHE})
#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \
{(P_RO_U_RO_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
MPU_MAIR_INDEX_SRAM_NOCACHE})
#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \
{(P_RO_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
MPU_MAIR_INDEX_SRAM_NOCACHE})
/* Execution-allowed attributes */
#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \
{(P_RW_U_RW_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE})
#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \
{(P_RO_U_RO_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE})
#endif /* _ASMLANGUAGE */
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
BUILD_ASSERT_MSG((size > 0) && ((u32_t)start % \
CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0U) && \
((size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0), \
" the start and size of the partition must align " \
"with the minimum MPU region size.")

View file

@ -0,0 +1,273 @@
/*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_NXP_MPU_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_NXP_MPU_H_
#ifndef _ASMLANGUAGE
#include <fsl_common.h>
#define NXP_MPU_BASE SYSMPU_BASE
#define NXP_MPU_REGION_NUMBER 12
/* Bus Master User Mode Access */
#define UM_READ 4
#define UM_WRITE 2
#define UM_EXEC 1
#define BM0_UM_SHIFT 0
#define BM1_UM_SHIFT 6
#define BM2_UM_SHIFT 12
#define BM3_UM_SHIFT 18
/* Bus Master Supervisor Mode Access */
#define SM_RWX_ALLOW 0
#define SM_RX_ALLOW 1
#define SM_RW_ALLOW 2
#define SM_SAME_AS_UM 3
#define BM0_SM_SHIFT 3
#define BM1_SM_SHIFT 9
#define BM2_SM_SHIFT 15
#define BM3_SM_SHIFT 21
#define BM4_WE_SHIFT 24
#define BM4_RE_SHIFT 25
#ifdef CONFIG_USB_KINETIS
#define BM4_PERMISSIONS ((1 << BM4_RE_SHIFT) | (1 << BM4_WE_SHIFT))
#else
#define BM4_PERMISSIONS 0
#endif
/* Read Attribute */
#define MPU_REGION_READ ((UM_READ << BM0_UM_SHIFT) | \
(UM_READ << BM1_UM_SHIFT) | \
(UM_READ << BM2_UM_SHIFT) | \
(UM_READ << BM3_UM_SHIFT))
/* Write Attribute */
#define MPU_REGION_WRITE ((UM_WRITE << BM0_UM_SHIFT) | \
(UM_WRITE << BM1_UM_SHIFT) | \
(UM_WRITE << BM2_UM_SHIFT) | \
(UM_WRITE << BM3_UM_SHIFT))
/* Execute Attribute */
#define MPU_REGION_EXEC ((UM_EXEC << BM0_UM_SHIFT) | \
(UM_EXEC << BM1_UM_SHIFT) | \
(UM_EXEC << BM2_UM_SHIFT) | \
(UM_EXEC << BM3_UM_SHIFT))
/* Super User Attributes */
#define MPU_REGION_SU ((SM_SAME_AS_UM << BM0_SM_SHIFT) | \
(SM_SAME_AS_UM << BM1_SM_SHIFT) | \
(SM_SAME_AS_UM << BM2_SM_SHIFT) | \
(SM_SAME_AS_UM << BM3_SM_SHIFT))
#define MPU_REGION_SU_RX ((SM_RX_ALLOW << BM0_SM_SHIFT) | \
(SM_RX_ALLOW << BM1_SM_SHIFT) | \
(SM_RX_ALLOW << BM2_SM_SHIFT) | \
(SM_RX_ALLOW << BM3_SM_SHIFT))
#define MPU_REGION_SU_RW ((SM_RW_ALLOW << BM0_SM_SHIFT) | \
(SM_RW_ALLOW << BM1_SM_SHIFT) | \
(SM_RW_ALLOW << BM2_SM_SHIFT) | \
(SM_RW_ALLOW << BM3_SM_SHIFT))
#define MPU_REGION_SU_RWX ((SM_RWX_ALLOW << BM0_SM_SHIFT) | \
(SM_RWX_ALLOW << BM1_SM_SHIFT) | \
(SM_RWX_ALLOW << BM2_SM_SHIFT) | \
(SM_RWX_ALLOW << BM3_SM_SHIFT))
/* The ENDADDR field has the last 5 bit reserved and set to 1 */
#define ENDADDR_ROUND(x) (x - 0x1F)
#define REGION_USER_MODE_ATTR {(MPU_REGION_READ | \
MPU_REGION_WRITE | \
MPU_REGION_SU)}
/* Some helper defines for common regions */
#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
#define REGION_RAM_ATTR {((MPU_REGION_SU_RWX) | \
((UM_READ | UM_WRITE | UM_EXEC) << BM3_UM_SHIFT) | \
(BM4_PERMISSIONS))}
#define REGION_FLASH_ATTR {(MPU_REGION_SU_RWX)}
#else
#define REGION_RAM_ATTR {((MPU_REGION_SU_RW) | \
((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | \
(BM4_PERMISSIONS))}
#define REGION_FLASH_ATTR {(MPU_REGION_READ | \
MPU_REGION_EXEC | \
MPU_REGION_SU)}
#endif
#define REGION_IO_ATTR {(MPU_REGION_READ | \
MPU_REGION_WRITE | \
MPU_REGION_EXEC | \
MPU_REGION_SU)}
#define REGION_RO_ATTR {(MPU_REGION_READ | MPU_REGION_SU)}
#define REGION_USER_RO_ATTR {(MPU_REGION_READ | \
MPU_REGION_SU)}
/* ENET (Master 3) and USB (Master 4) devices will not be able
to access RAM when the region is dynamically disabled in NXP MPU.
DEBUGGER (Master 1) can't be disabled in Region 0. */
#define REGION_DEBUGGER_AND_DEVICE_ATTR {((MPU_REGION_SU) | \
((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | \
(BM4_PERMISSIONS))}
#define REGION_DEBUG_ATTR {MPU_REGION_SU}
#define REGION_BACKGROUND_ATTR {MPU_REGION_SU_RW}
struct nxp_mpu_region_attr {
/* NXP MPU region access permission attributes */
u32_t attr;
};
typedef struct nxp_mpu_region_attr nxp_mpu_region_attr_t;
/* Typedef for the k_mem_partition attribute*/
typedef struct {
u32_t ap_attr;
} k_mem_partition_attr_t;
/* Kernel macros for memory attribution
* (access permissions and cache-ability).
*
* The macros are to be stored in k_mem_partition_attr_t
* objects.
*/
/* Read-Write access permission attributes */
#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \
{(MPU_REGION_SU)})
#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
{(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_SU)})
#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \
{(MPU_REGION_READ | MPU_REGION_SU_RW)})
#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
{(MPU_REGION_SU_RW)})
#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
{(MPU_REGION_READ | MPU_REGION_SU)})
#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
{(MPU_REGION_SU_RX)})
/* Execution-allowed attributes */
#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \
{(MPU_REGION_READ | MPU_REGION_WRITE | \
MPU_REGION_EXEC | MPU_REGION_SU)})
#define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \
{(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU_RWX)})
#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
{(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU)})
/*
* @brief Evaluate Write-ability
*
* Evaluate whether the access permissions include write-ability.
*
* @param attr The k_mem_partition_attr_t object holding the
* MPU attributes to be checked against write-ability.
*/
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
({ \
int __is_writable__; \
switch (attr.ap_attr) { \
case MPU_REGION_WRITE: \
case MPU_REGION_SU_RW: \
__is_writable__ = 1; \
break; \
default: \
__is_writable__ = 0; \
} \
__is_writable__; \
})
/*
* @brief Evaluate Execution allowance
*
* Evaluate whether the access permissions include execution.
*
* @param attr The k_mem_partition_attr_t object holding the
* MPU attributes to be checked against execution
* allowance.
*/
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
({ \
int __is_executable__; \
switch (attr.ap_attr) { \
case MPU_REGION_SU_RX: \
case MPU_REGION_EXEC: \
__is_executable__ = 1; \
break; \
default: \
__is_executable__ = 0; \
} \
__is_executable__; \
})
/* Region definition data structure */
struct nxp_mpu_region {
/* Region Base Address */
u32_t base;
/* Region End Address */
u32_t end;
/* Region Name */
const char *name;
/* Region Attributes */
nxp_mpu_region_attr_t attr;
};
#define MPU_REGION_ENTRY(_name, _base, _end, _attr) \
{\
.name = _name, \
.base = _base, \
.end = _end, \
.attr = _attr, \
}
/* MPU configuration data structure */
struct nxp_mpu_config {
/* Number of regions */
u32_t num_regions;
/* Regions */
const struct nxp_mpu_region *mpu_regions;
/* SRAM Region */
u32_t sram_region;
};
/* Reference to the MPU configuration.
*
* This struct is defined and populated for each SoC (in the SoC definition),
* and holds the build-time configuration information for the fixed MPU
* regions enabled during kernel initialization. Dynamic MPU regions (e.g.
* for Thread Stack, Stack Guards, etc.) are programmed during runtime, thus,
* not kept here.
*/
extern const struct nxp_mpu_config mpu_config;
#endif /* _ASMLANGUAGE */
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
BUILD_ASSERT_MSG((size) % \
CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \
(size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \
(u32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \
"the size of the partition must align with minimum MPU \
region size" \
" and greater than or equal to minimum MPU region size." \
"start address of the partition must align with minimum MPU \
region size.")
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_NXP_MPU_H_ */

View file

@ -0,0 +1,459 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Cortex-M platforms.
*/
#include <autoconf.h>
#include <linker/sections.h>
#include <generated_dts_board.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>
/* physical address of RAM */
#ifdef CONFIG_XIP
#define ROMABLE_REGION FLASH
#define RAMABLE_REGION SRAM
#else
#define ROMABLE_REGION SRAM
#define RAMABLE_REGION SRAM
#endif
#if defined(CONFIG_XIP)
#define _DATA_IN_ROM __data_rom_start
#else
#define _DATA_IN_ROM
#endif
#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
#define ROM_ADDR RAM_ADDR
#else
#define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
#endif
#ifdef CONFIG_TI_CCFG_PRESENT
#define CCFG_SIZE 88
#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET - \
CCFG_SIZE)
#define CCFG_ADDR (ROM_ADDR + ROM_SIZE)
#else
#if CONFIG_FLASH_LOAD_SIZE > 0
#define ROM_SIZE CONFIG_FLASH_LOAD_SIZE
#else
#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
#endif
#endif
#if defined(CONFIG_XIP)
#if defined(CONFIG_IS_BOOTLOADER)
#define RAM_SIZE (CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR (CONFIG_SRAM_BASE_ADDRESS + \
(CONFIG_SRAM_SIZE * 1K - RAM_SIZE))
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#if defined(CONFIG_CUSTOM_SECTION_ALIGN)
_region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE;
#else
/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
* to make linker section alignment comply with MPU granularity.
*/
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
#else
/* If building without MPU support, use default 4-byte alignment. */
_region_min_align = 4;
#endif
#endif
#if !defined(CONFIG_CUSTOM_SECTION_ALIGN) && defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align); \
. = ALIGN( 1 << LOG2CEIL(region_size))
#else
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align)
#endif
MEMORY
{
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
#ifdef CONFIG_TI_CCFG_PRESENT
FLASH_CCFG (rwx): ORIGIN = CCFG_ADDR, LENGTH = CCFG_SIZE
#endif
#ifdef DT_CCM_BASE_ADDRESS
CCM (rw) : ORIGIN = DT_CCM_BASE_ADDRESS, LENGTH = DT_CCM_SIZE * 1K
#endif
#ifdef DT_DTCM_BASE_ADDRESS
DTCM (rw) : ORIGIN = DT_DTCM_BASE_ADDRESS, LENGTH = DT_DTCM_SIZE * 1K
#endif
SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
#ifdef CONFIG_BT_STM32_IPM
SRAM1 (rw) : ORIGIN = RAM1_ADDR, LENGTH = RAM1_SIZE
SRAM2 (rw) : ORIGIN = RAM2_ADDR, LENGTH = RAM2_SIZE
#endif
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = (RAM_ADDR + RAM_SIZE), LENGTH = 2K
}
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
#include <linker/rel-sections.ld>
/*
* .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
* before text section.
*/
/DISCARD/ :
{
*(.plt)
}
/DISCARD/ :
{
*(.iplt)
}
GROUP_START(ROMABLE_REGION)
_image_rom_start = ROM_ADDR;
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
{
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-text-start.ld>
} GROUP_LINK_IN(ROMABLE_REGION)
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_relocate.ld>
#endif /* CONFIG_CODE_DATA_RELOCATION */
SECTION_PROLOGUE(_TEXT_SECTION_NAME_2,,)
{
_image_text_start = .;
#include <linker/priv_stacks-text.ld>
#include <linker/kobject-text.ld>
*(.text)
*(".text.*")
*(.gnu.linkonce.t.*)
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* after .gnu.linkonce.t.*
*/
*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
} GROUP_LINK_IN(ROMABLE_REGION)
_image_text_end = .;
#if defined (CONFIG_CPLUSPLUS)
SECTION_PROLOGUE(.ARM.extab,,)
{
/*
* .ARM.extab section containing exception unwinding information.
*/
*(.ARM.extab* .gnu.linkonce.armextab.*)
} GROUP_LINK_IN(ROMABLE_REGION)
#endif
SECTION_PROLOGUE(.ARM.exidx,,)
{
/*
* This section, related to stack and exception unwinding, is placed
* explicitly to prevent it from being shared between multiple regions.
* It must be defined for gcc to support 64-bit math and avoid
* section overlap.
*/
__exidx_start = .;
#if defined (__GCC_LINKER_CMD__)
*(.ARM.exidx* gnu.linkonce.armexidx.*)
#endif
__exidx_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
_image_rodata_start = .;
#include <linker/common-rom.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
{
*(.rodata)
*(".rodata.*")
*(.gnu.linkonce.r.*)
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#ifdef CONFIG_SOC_RODATA_LD
#include <soc-rodata.ld>
#endif
#ifdef CONFIG_CUSTOM_RODATA_LD
/* Located in project source directory */
#include <custom-rodata.ld>
#endif
#include <linker/priv_stacks-rom.ld>
#include <linker/kobject-rom.ld>
/*
* For XIP images, in order to avoid the situation when __data_rom_start
* is 32-bit aligned, but the actual data is placed right after rodata
* section, which may not end exactly at 32-bit border, pad rodata
* section, so __data_rom_start points at data and it is 32-bit aligned.
*
* On non-XIP images this may enlarge image size up to 3 bytes. This
* generally is not an issue, since modern ROM and FLASH memory is
* usually 4k aligned.
*/
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
#include <linker/cplusplus-rom.ld>
_image_rodata_end = .;
MPU_ALIGN(_image_rodata_end -_image_rom_start);
_image_rom_end = .;
GROUP_END(ROMABLE_REGION)
/* Some TI SoCs have a special configuration footer, at the end of flash. */
#ifdef CONFIG_TI_CCFG_PRESENT
SECTION_PROLOGUE(.ti_ccfg,,)
{
KEEP(*(TI_CCFG))
} > FLASH_CCFG
#endif
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* before data section.
*/
/DISCARD/ : {
*(.got.plt)
*(.igot.plt)
*(.got)
*(.igot)
}
GROUP_START(RAMABLE_REGION)
. = RAM_ADDR;
/* Align the start of image SRAM with the
* minimum granularity required by MPU.
*/
. = ALIGN(_region_min_align);
_image_ram_start = .;
#if defined(CONFIG_SOC_SERIES_STM32F0X) && !defined(CONFIG_IS_BOOTLOADER)
/* Must be first in ramable region */
SECTION_PROLOGUE(.st_stm32f0x_vt,(NOLOAD),)
{
_ram_vector_start = .;
. += _vector_end - _vector_start;
_ram_vector_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>
#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN
#include <app_smem.ld>
_app_smem_size = _app_smem_end - _app_smem_start;
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
#endif /* CONFIG_USERSPACE */
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
__kernel_ram_start = .;
*(.bss)
*(".bss.*")
*(COMMON)
*(".kernel_bss.*")
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
{
/*
* This section is used for non-initialized objects that
* will not be cleared during the boot process.
*/
*(.noinit)
*(".noinit.*")
*(".kernel_noinit.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
#ifdef CONFIG_SOC_NOINIT_LD
#include <soc-noinit.ld>
#endif
} GROUP_LINK_IN(RAMABLE_REGION)
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
{
__data_ram_start = .;
*(.data)
*(".data.*")
*(".kernel.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_SOC_RWDATA_LD
#include <soc-rwdata.ld>
#endif
#ifdef CONFIG_CUSTOM_RWDATA_LD
/* Located in project source directory */
#include <custom-rwdata.ld>
#endif
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
__data_rom_start = LOADADDR(_DATA_SECTION_NAME);
#include <linker/common-ram.ld>
#include <linker/priv_stacks.ld>
#include <linker/kobject.ld>
#include <linker/priv_stacks-noinit.ld>
#include <linker/cplusplus-ram.ld>
__data_ram_end = .;
/* Define linker symbols */
_image_ram_end = .;
_end = .; /* end of image */
__kernel_ram_end = RAM_ADDR + RAM_SIZE;
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
GROUP_END(RAMABLE_REGION)
#ifdef DT_DTCM_BASE_ADDRESS
GROUP_START(DTCM)
SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
{
__dtcm_start = .;
__dtcm_bss_start = .;
*(.dtcm_bss)
*(".dtcm_bss.*")
} GROUP_LINK_IN(DTCM)
__dtcm_bss_end = .;
SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4))
{
__dtcm_noinit_start = .;
*(.dtcm_noinit)
*(".dtcm_noinit.*")
} GROUP_LINK_IN(DTCM)
__dtcm_noinit_end = .;
SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(4))
{
__dtcm_data_start = .;
*(.dtcm_data)
*(".dtcm_data.*")
} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
__dtcm_data_end = .;
__dtcm_end = .;
__dtcm_data_rom_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
GROUP_END(DTCM)
#endif /* DT_DTCM_BASE_ADDRESS */
#ifdef CONFIG_CUSTOM_SECTIONS_LD
/* Located in project source directory */
#include <custom-sections.ld>
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>
#include <linker/debug-sections.ld>
/DISCARD/ : { *(.note.GNU-stack) }
SECTION_PROLOGUE(.ARM.attributes, 0,)
{
KEEP(*(.ARM.attributes))
KEEP(*(.gnu.attributes))
}
/* Must be last in romable region */
SECTION_PROLOGUE(.last_section,(NOLOAD),)
{
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
* calculate this value here. */
_flash_used = LOADADDR(.last_section) - _image_rom_start;
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018 Lexmark International, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _CORTEX_R_CPU_H
#define _CORTEX_R_CPU_H
#define MODE_USR 0x10
#define MODE_FIQ 0x11
#define MODE_IRQ 0x12
#define MODE_SVC 0x13
#define MODE_ABT 0x17
#define MODE_UDF 0x1b
#define MODE_SYS 0x1f
#define MODE_MASK 0x1f
#define A_BIT (1 << 8)
#define I_BIT (1 << 7)
#define F_BIT (1 << 6)
#define T_BIT (1 << 5)
#define HIVECS (1 << 13)
#define RET_FROM_SVC 0
#define RET_FROM_IRQ 1
#define __ISB() __asm__ volatile ("isb sy" : : : "memory")
#define __DMB() __asm__ volatile ("dmb sy" : : : "memory")
#endif

View file

@ -0,0 +1,9 @@
/*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Set initial alignment to the 32 byte minimum for all MPUs */
_app_data_align = 32;
. = ALIGN(32);

View file

@ -0,0 +1,419 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Cortex-R platforms.
*/
#include <autoconf.h>
#include <linker/sections.h>
#include <generated_dts_board.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>
/* physical address of RAM */
#ifdef CONFIG_XIP
#define ROMABLE_REGION FLASH
#define RAMABLE_REGION SRAM
#else
#define ROMABLE_REGION SRAM
#define RAMABLE_REGION SRAM
#endif
#if defined(CONFIG_XIP)
#define _DATA_IN_ROM __data_rom_start
#else
#define _DATA_IN_ROM
#endif
#if !defined(SKIP_TO_KINETIS_FLASH_CONFIG)
#define SKIP_TO_KINETIS_FLASH_CONFIG
#endif
#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
#define ROM_ADDR RAM_ADDR
#else
#define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
#endif
#ifdef CONFIG_TI_CCFG_PRESENT
#define CCFG_SIZE 88
#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET - \
CCFG_SIZE)
#define CCFG_ADDR (ROM_ADDR + ROM_SIZE)
#else
#if CONFIG_FLASH_LOAD_SIZE > 0
#define ROM_SIZE CONFIG_FLASH_LOAD_SIZE
#else
#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
#endif
#endif
#if defined(CONFIG_XIP)
#if defined(CONFIG_IS_BOOTLOADER)
#define RAM_SIZE (CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR (CONFIG_SRAM_BASE_ADDRESS + \
(CONFIG_SRAM_SIZE * 1K - RAM_SIZE))
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
* to make linker section alignment comply with MPU granularity.
*/
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
#else
/* If building without MPU support, use default 4-byte alignment. */
_region_min_align = 4;
#endif
#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align); \
. = ALIGN( 1 << LOG2CEIL(region_size))
#else
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align)
#endif
MEMORY
{
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
#ifdef CONFIG_TI_CCFG_PRESENT
FLASH_CCFG (rwx): ORIGIN = CCFG_ADDR, LENGTH = CCFG_SIZE
#endif
#ifdef DT_CCM_BASE_ADDRESS
CCM (rw) : ORIGIN = DT_CCM_BASE_ADDRESS, LENGTH = DT_CCM_SIZE * 1K
#endif
SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
#ifdef CONFIG_BT_STM32_IPM
SRAM1 (rw) : ORIGIN = RAM1_ADDR, LENGTH = RAM1_SIZE
SRAM2 (rw) : ORIGIN = RAM2_ADDR, LENGTH = RAM2_SIZE
#endif
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = (RAM_ADDR + RAM_SIZE), LENGTH = 2K
}
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
#include <linker/rel-sections.ld>
/*
* .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
* before text section.
*/
SECTION_PROLOGUE(.plt,,)
{
*(.plt)
}
SECTION_PROLOGUE(.iplt,,)
{
*(.iplt)
}
GROUP_START(ROMABLE_REGION)
_image_rom_start = ROM_ADDR;
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
{
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-text-start.ld>
} GROUP_LINK_IN(ROMABLE_REGION)
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_relocate.ld>
#endif /* CONFIG_CODE_DATA_RELOCATION */
SECTION_PROLOGUE(_TEXT_SECTION_NAME_2,,)
{
_image_text_start = .;
*(.text)
*(".text.*")
*(.gnu.linkonce.t.*)
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* after .gnu.linkonce.t.*
*/
*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
#include <linker/priv_stacks-text.ld>
#include <linker/kobject-text.ld>
} GROUP_LINK_IN(ROMABLE_REGION)
_image_text_end = .;
#if defined (CONFIG_CPLUSPLUS)
SECTION_PROLOGUE(.ARM.extab,,)
{
/*
* .ARM.extab section containing exception unwinding information.
*/
*(.ARM.extab* .gnu.linkonce.armextab.*)
} GROUP_LINK_IN(ROMABLE_REGION)
#endif
SECTION_PROLOGUE(.ARM.exidx,,)
{
/*
* This section, related to stack and exception unwinding, is placed
* explicitly to prevent it from being shared between multiple regions.
* It must be defined for gcc to support 64-bit math and avoid
* section overlap.
*/
__exidx_start = .;
#if defined (__GCC_LINKER_CMD__)
*(.ARM.exidx* gnu.linkonce.armexidx.*)
#endif
__exidx_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
_image_rodata_start = .;
#include <linker/common-rom.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
{
*(.rodata)
*(".rodata.*")
*(.gnu.linkonce.r.*)
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#ifdef CONFIG_SOC_RODATA_LD
#include <soc-rodata.ld>
#endif
#ifdef CONFIG_CUSTOM_RODATA_LD
/* Located in project source directory */
#include <custom-rodata.ld>
#endif
#include <linker/priv_stacks-rom.ld>
#include <linker/kobject-rom.ld>
/*
* For XIP images, in order to avoid the situation when __data_rom_start
* is 32-bit aligned, but the actual data is placed right after rodata
* section, which may not end exactly at 32-bit border, pad rodata
* section, so __data_rom_start points at data and it is 32-bit aligned.
*
* On non-XIP images this may enlarge image size up to 3 bytes. This
* generally is not an issue, since modern ROM and FLASH memory is
* usually 4k aligned.
*/
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
#include <linker/cplusplus-rom.ld>
_image_rodata_end = .;
MPU_ALIGN(_image_rodata_end -_image_rom_start);
_image_rom_end = .;
GROUP_END(ROMABLE_REGION)
/* Some TI SoCs have a special configuration footer, at the end of flash. */
#ifdef CONFIG_TI_CCFG_PRESENT
SECTION_PROLOGUE(.ti_ccfg,,)
{
KEEP(*(TI_CCFG))
} > FLASH_CCFG
#endif
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* before data section.
*/
SECTION_PROLOGUE(.got,,)
{
*(.got.plt)
*(.igot.plt)
*(.got)
*(.igot)
}
GROUP_START(RAMABLE_REGION)
. = RAM_ADDR;
/* Align the start of image SRAM with the
* minimum granularity required by MPU.
*/
. = ALIGN(_region_min_align);
_image_ram_start = .;
#if defined(CONFIG_SOC_SERIES_STM32F0X) && !defined(CONFIG_IS_BOOTLOADER)
/* Must be first in ramable region */
SECTION_PROLOGUE(.st_stm32f0x_vt,(NOLOAD),)
{
_ram_vector_start = .;
. += _vector_end - _vector_start;
_ram_vector_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>
#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN
#include <app_smem.ld>
_app_smem_size = _app_smem_end - _app_smem_start;
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
#endif /* CONFIG_USERSPACE */
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
__kernel_ram_start = .;
*(.bss)
*(".bss.*")
*(COMMON)
*(".kernel_bss.*")
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
{
/*
* This section is used for non-initialized objects that
* will not be cleared during the boot process.
*/
*(.noinit)
*(".noinit.*")
*(".kernel_noinit.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
#ifdef CONFIG_SOC_NOINIT_LD
#include <soc-noinit.ld>
#endif
} GROUP_LINK_IN(RAMABLE_REGION)
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
{
__data_ram_start = .;
*(.data)
*(".data.*")
*(".kernel.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_SOC_RWDATA_LD
#include <soc-rwdata.ld>
#endif
#ifdef CONFIG_CUSTOM_RWDATA_LD
/* Located in project source directory */
#include <custom-rwdata.ld>
#endif
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
__data_rom_start = LOADADDR(_DATA_SECTION_NAME);
#include <linker/common-ram.ld>
#include <linker/priv_stacks.ld>
#include <linker/kobject.ld>
#include <linker/priv_stacks-noinit.ld>
#include <linker/cplusplus-ram.ld>
__data_ram_end = .;
/* Define linker symbols */
_image_ram_end = .;
_end = .; /* end of image */
__kernel_ram_end = RAM_ADDR + RAM_SIZE;
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
GROUP_END(RAMABLE_REGION)
#ifdef CONFIG_CUSTOM_SECTIONS_LD
/* Located in project source directory */
#include <custom-sections.ld>
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>
#include <linker/debug-sections.ld>
SECTION_PROLOGUE(.ARM.attributes, 0,)
{
KEEP(*(.ARM.attributes))
KEEP(*(.gnu.attributes))
}
/* Must be last in romable region */
SECTION_PROLOGUE(.last_section,(NOLOAD),)
{
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
* calculate this value here. */
_flash_used = LOADADDR(.last_section) - _image_rom_start;
}

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2015, Wind River Systems, Inc.
* Copyright (c) 2017, Oticon A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
/* "Arch" bit manipulation functions in non-arch-specific C code (uses some
* gcc builtins)
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_R_SYS_IO_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_R_SYS_IO_H_
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
#include <sys/sys_io.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Memory mapped registers I/O functions */
static ALWAYS_INLINE u8_t sys_read8(mem_addr_t addr)
{
u8_t val = *(volatile u8_t *)addr;
__DMB();
return val;
}
static ALWAYS_INLINE void sys_write8(u8_t data, mem_addr_t addr)
{
__DMB();
*(volatile u8_t *)addr = data;
}
static ALWAYS_INLINE u16_t sys_read16(mem_addr_t addr)
{
u16_t val = *(volatile u16_t *)addr;
__DMB();
return val;
}
static ALWAYS_INLINE void sys_write16(u16_t data, mem_addr_t addr)
{
__DMB();
*(volatile u16_t *)addr = data;
}
static ALWAYS_INLINE u32_t sys_read32(mem_addr_t addr)
{
u32_t val = *(volatile u32_t *)addr;
__DMB();
return val;
}
static ALWAYS_INLINE void sys_write32(u32_t data, mem_addr_t addr)
{
__DMB();
*(volatile u32_t *)addr = data;
}
/* Memory bit manipulation functions */
static ALWAYS_INLINE void sys_set_bit(mem_addr_t addr, unsigned int bit)
{
u32_t temp = *(volatile u32_t *)addr;
*(volatile u32_t *)addr = temp | (1 << bit);
}
static ALWAYS_INLINE void sys_clear_bit(mem_addr_t addr, unsigned int bit)
{
u32_t temp = *(volatile u32_t *)addr;
*(volatile u32_t *)addr = temp & ~(1 << bit);
}
static ALWAYS_INLINE int sys_test_bit(mem_addr_t addr, unsigned int bit)
{
u32_t temp = *(volatile u32_t *)addr;
return temp & (1 << bit);
}
static ALWAYS_INLINE
void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit)
{
/* Doing memory offsets in terms of 32-bit values to prevent
* alignment issues
*/
sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit)
{
sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit)
{
return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
int sys_test_and_set_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_test_bit(addr, bit);
sys_set_bit(addr, bit);
return ret;
}
static ALWAYS_INLINE
int sys_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_test_bit(addr, bit);
sys_clear_bit(addr, bit);
return ret;
}
static ALWAYS_INLINE
int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_bitfield_test_bit(addr, bit);
sys_bitfield_set_bit(addr, bit);
return ret;
}
static ALWAYS_INLINE
int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_bitfield_test_bit(addr, bit);
sys_bitfield_clear_bit(addr, bit);
return ret;
}
#ifdef __cplusplus
}
#endif
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_R_SYS_IO_H_ */

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Cortex-M public error handling
*
* ARM-specific kernel error handling interface. Included by arm/arch.h.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_
#include <arch/arm/aarch32/syscall.h>
#include <arch/arm/aarch32/exc.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
/* ARMv6 will hard-fault if SVC is called with interrupts locked. Just
* force them unlocked, the thread is in an undefined state anyway
*
* On ARMv7m we won't get a HardFault, but if interrupts were locked the
* thread will continue executing after the exception and forbid PendSV to
* schedule a new thread until they are unlocked which is not what we want.
* Force them unlocked as well.
*/
#define ARCH_EXCEPT(reason_p) \
register u32_t r0 __asm__("r0") = reason_p; \
do { \
__asm__ volatile ( \
"cpsie i\n\t" \
"svc %[id]\n\t" \
: \
: "r" (r0), [id] "i" (_SVC_CALL_RUNTIME_EXCEPT) \
: "memory"); \
} while (false)
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
#define ARCH_EXCEPT(reason_p) do { \
__asm__ volatile ( \
"eors.n r0, r0\n\t" \
"msr BASEPRI, r0\n\t" \
"mov r0, %[reason]\n\t" \
"svc %[id]\n\t" \
: \
: [reason] "i" (reason_p), [id] "i" (_SVC_CALL_RUNTIME_EXCEPT) \
: "memory"); \
} while (false)
#elif defined(CONFIG_ARMV7_R)
/* Pick up the default definition in kernel.h for now */
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_ */

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Cortex-M public exception handling
*
* ARM-specific kernel exception handling interface. Included by arm/arch.h.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_EXC_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_EXC_H_
/* for assembler, only works with constants */
#define Z_EXC_PRIO(pri) (((pri) << (8 - DT_NUM_IRQ_PRIO_BITS)) & 0xff)
#if defined(CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS)
#define _EXCEPTION_RESERVED_PRIO 1
#else
#define _EXCEPTION_RESERVED_PRIO 0
#endif
#define _EXC_FAULT_PRIO 0
#ifdef CONFIG_ZERO_LATENCY_IRQS
#define _EXC_ZERO_LATENCY_IRQS_PRIO 0
#define _EXC_SVC_PRIO 1
#define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + 1)
#else
#define _EXC_SVC_PRIO 0
#define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO)
#endif
#define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET)
#ifdef _ASMLANGUAGE
GTEXT(z_arm_exc_exit);
#else
#include <zephyr/types.h>
#ifdef __cplusplus
extern "C" {
#endif
struct __esf {
struct __basic_sf {
sys_define_gpr_with_alias(a1, r0);
sys_define_gpr_with_alias(a2, r1);
sys_define_gpr_with_alias(a3, r2);
sys_define_gpr_with_alias(a4, r3);
sys_define_gpr_with_alias(ip, r12);
sys_define_gpr_with_alias(lr, r14);
sys_define_gpr_with_alias(pc, r15);
u32_t xpsr;
} basic;
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
float s[16];
u32_t fpscr;
u32_t undefined;
#endif
};
typedef struct __esf z_arch_esf_t;
extern void z_arm_exc_exit(void);
#ifdef __cplusplus
}
#endif
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_EXC_H_ */

View file

@ -0,0 +1,156 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Cortex-M public interrupt handling
*
* ARM-specific kernel interrupt handling interface. Included by arm/arch.h.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
#include <irq.h>
#include <sw_isr_table.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
GTEXT(z_arm_int_exit);
GTEXT(arch_irq_enable)
GTEXT(arch_irq_disable)
GTEXT(arch_irq_is_enabled)
#else
extern void arch_irq_enable(unsigned int irq);
extern void arch_irq_disable(unsigned int irq);
extern int arch_irq_is_enabled(unsigned int irq);
extern void z_arm_int_exit(void);
#if defined(CONFIG_ARMV7_R)
static ALWAYS_INLINE void z_arm_int_lib_init(void)
{
}
#else
extern void z_arm_int_lib_init(void);
#endif
/* macros convert value of it's argument to a string */
#define DO_TOSTR(s) #s
#define TOSTR(s) DO_TOSTR(s)
/* concatenate the values of the arguments into one */
#define DO_CONCAT(x, y) x ## y
#define CONCAT(x, y) DO_CONCAT(x, y)
/* internal routine documented in C file, needed by IRQ_CONNECT() macro */
extern void z_arm_irq_priority_set(unsigned int irq, unsigned int prio,
u32_t flags);
/* Flags for use with IRQ_CONNECT() */
#ifdef CONFIG_ZERO_LATENCY_IRQS
/**
* Set this interrupt up as a zero-latency IRQ. It has a fixed hardware
* priority level (discarding what was supplied in the interrupt's priority
* argument), and will run even if irq_lock() is active. Be careful!
*/
#define IRQ_ZERO_LATENCY BIT(0)
#endif
/* All arguments must be computable by the compiler at build time.
*
* Z_ISR_DECLARE will populate the .intList section with the interrupt's
* parameters, which will then be used by gen_irq_tables.py to create
* the vector table and the software ISR table. This is all done at
* build-time.
*
* We additionally set the priority in the interrupt controller at
* runtime.
*/
#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
({ \
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \
})
#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
({ \
Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \
z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \
})
#ifdef CONFIG_SYS_POWER_MANAGEMENT
extern void _arch_isr_direct_pm(void);
#define ARCH_ISR_DIRECT_PM() _arch_isr_direct_pm()
#else
#define ARCH_ISR_DIRECT_PM() do { } while (false)
#endif
#define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header()
#define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap)
/* arch/arm/core/aarch32/exc_exit.S */
extern void z_arm_int_exit(void);
#ifdef CONFIG_TRACING
extern void sys_trace_isr_enter(void);
extern void sys_trace_isr_exit(void);
#endif
static inline void arch_isr_direct_header(void)
{
#ifdef CONFIG_TRACING
sys_trace_isr_enter();
#endif
}
static inline void arch_isr_direct_footer(int maybe_swap)
{
#ifdef CONFIG_TRACING
sys_trace_isr_exit();
#endif
if (maybe_swap) {
z_arm_int_exit();
}
}
#define ARCH_ISR_DIRECT_DECLARE(name) \
static inline int name##_body(void); \
__attribute__ ((interrupt ("IRQ"))) void name(void) \
{ \
int check_reschedule; \
ISR_DIRECT_HEADER(); \
check_reschedule = name##_body(); \
ISR_DIRECT_FOOTER(check_reschedule); \
} \
static inline int name##_body(void)
/* Spurious interrupt handler. Throws an error if called */
extern void z_irq_spurious(void *unused);
#ifdef CONFIG_GEN_SW_ISR_TABLE
/* Architecture-specific common entry point for interrupts from the vector
* table. Most likely implemented in assembly. Looks up the correct handler
* and parameter from the _sw_isr_table and executes it.
*/
extern void _isr_wrapper(void);
#endif
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_ */

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Cortex-M public kernel miscellaneous
*
* ARM-specific kernel miscellaneous interface. Included by arm/arch.h.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_MISC_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_MISC_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASMLANGUAGE
extern u32_t z_timer_cycle_get_32(void);
static inline u32_t arch_k_cycle_get_32(void)
{
return z_timer_cycle_get_32();
}
static ALWAYS_INLINE void arch_nop(void)
{
__asm__ volatile("nop");
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_MISC_H_ */

View file

@ -0,0 +1,25 @@
/**
* @file
*
* @brief NMI routines for ARM Cortex M series
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_
#ifndef _ASMLANGUAGE
#ifdef CONFIG_RUNTIME_NMI
extern void z_arm_nmi_init(void);
#define NMI_INIT() z_arm_nmi_init()
#else
#define NMI_INIT()
#endif
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_ */

View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2018 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM specific syscall header
*
* This header contains the ARM specific syscall interface. It is
* included by the syscall interface architecture-abstraction header
* (include/arch/syscall.h)
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_SYSCALL_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_SYSCALL_H_
#define _SVC_CALL_CONTEXT_SWITCH 0
#define _SVC_CALL_IRQ_OFFLOAD 1
#define _SVC_CALL_RUNTIME_EXCEPT 2
#define _SVC_CALL_SYSTEM_CALL 3
#ifdef CONFIG_USERSPACE
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
#include <stdbool.h>
#include <arch/arm/aarch32/cortex_m/cmsis.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Syscall invocation macros. arm-specific machine constraints used to ensure
* args land in the proper registers.
*/
static inline uintptr_t arch_syscall_invoke6(uintptr_t arg1, uintptr_t arg2,
uintptr_t arg3, uintptr_t arg4,
uintptr_t arg5, uintptr_t arg6,
uintptr_t call_id)
{
register u32_t ret __asm__("r0") = arg1;
register u32_t r1 __asm__("r1") = arg2;
register u32_t r2 __asm__("r2") = arg3;
register u32_t r3 __asm__("r3") = arg4;
register u32_t r4 __asm__("r4") = arg5;
register u32_t r5 __asm__("r5") = arg6;
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r1), "r" (r2), "r" (r3),
"r" (r4), "r" (r5), "r" (r6)
: "r8", "memory", "ip");
return ret;
}
static inline uintptr_t arch_syscall_invoke5(uintptr_t arg1, uintptr_t arg2,
uintptr_t arg3, uintptr_t arg4,
uintptr_t arg5,
uintptr_t call_id)
{
register u32_t ret __asm__("r0") = arg1;
register u32_t r1 __asm__("r1") = arg2;
register u32_t r2 __asm__("r2") = arg3;
register u32_t r3 __asm__("r3") = arg4;
register u32_t r4 __asm__("r4") = arg5;
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r1), "r" (r2), "r" (r3),
"r" (r4), "r" (r6)
: "r8", "memory", "ip");
return ret;
}
static inline uintptr_t arch_syscall_invoke4(uintptr_t arg1, uintptr_t arg2,
uintptr_t arg3, uintptr_t arg4,
uintptr_t call_id)
{
register u32_t ret __asm__("r0") = arg1;
register u32_t r1 __asm__("r1") = arg2;
register u32_t r2 __asm__("r2") = arg3;
register u32_t r3 __asm__("r3") = arg4;
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r1), "r" (r2), "r" (r3),
"r" (r6)
: "r8", "memory", "ip");
return ret;
}
static inline uintptr_t arch_syscall_invoke3(uintptr_t arg1, uintptr_t arg2,
uintptr_t arg3,
uintptr_t call_id)
{
register u32_t ret __asm__("r0") = arg1;
register u32_t r1 __asm__("r1") = arg2;
register u32_t r2 __asm__("r2") = arg3;
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r1), "r" (r2), "r" (r6)
: "r8", "memory", "r3", "ip");
return ret;
}
static inline uintptr_t arch_syscall_invoke2(uintptr_t arg1, uintptr_t arg2,
uintptr_t call_id)
{
register u32_t ret __asm__("r0") = arg1;
register u32_t r1 __asm__("r1") = arg2;
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r1), "r" (r6)
: "r8", "memory", "r2", "r3", "ip");
return ret;
}
static inline uintptr_t arch_syscall_invoke1(uintptr_t arg1,
uintptr_t call_id)
{
register u32_t ret __asm__("r0") = arg1;
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r6)
: "r8", "memory", "r1", "r2", "r3", "ip");
return ret;
}
static inline uintptr_t arch_syscall_invoke0(uintptr_t call_id)
{
register u32_t ret __asm__("r0");
register u32_t r6 __asm__("r6") = call_id;
__asm__ volatile("svc %[svid]\n"
: "=r"(ret)
: [svid] "i" (_SVC_CALL_SYSTEM_CALL),
"r" (ret), "r" (r6)
: "r8", "memory", "r1", "r2", "r3", "ip");
return ret;
}
static inline bool arch_is_user_context(void)
{
u32_t value;
/* check for handler mode */
__asm__ volatile("mrs %0, IPSR\n\t" : "=r"(value));
if (value) {
return false;
}
/* if not handler mode, return mode information */
__asm__ volatile("mrs %0, CONTROL\n\t" : "=r"(value));
return (value & CONTROL_nPRIV_Msk) ? true : false;
}
#ifdef __cplusplus
}
#endif
#endif /* _ASMLANGUAGE */
#endif /* CONFIG_USERSPACE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_SYSCALL_H_ */

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains definitions for
*
* struct _thread_arch
* struct _callee_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_
#define ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
struct _callee_saved {
u32_t v1; /* r4 */
u32_t v2; /* r5 */
u32_t v3; /* r6 */
u32_t v4; /* r7 */
u32_t v5; /* r8 */
u32_t v6; /* r9 */
u32_t v7; /* r10 */
u32_t v8; /* r11 */
#if defined(CONFIG_CPU_CORTEX_R)
u32_t spsr;/* r12 */
u32_t psp; /* r13 */
u32_t lr; /* r14 */
#else
u32_t psp; /* r13 */
#endif
};
typedef struct _callee_saved _callee_saved_t;
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
struct _preempt_float {
float s16;
float s17;
float s18;
float s19;
float s20;
float s21;
float s22;
float s23;
float s24;
float s25;
float s26;
float s27;
float s28;
float s29;
float s30;
float s31;
};
#endif
struct _thread_arch {
/* interrupt locking key */
u32_t basepri;
/* r0 in stack frame cannot be written to reliably */
u32_t swap_return_value;
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
/*
* No cooperative floating point register set structure exists for
* the Cortex-M as it automatically saves the necessary registers
* in its exception stack frame.
*/
struct _preempt_float preempt_float;
#endif
#if defined(CONFIG_USERSPACE) || defined(CONFIG_FP_SHARING)
u32_t mode;
#if defined(CONFIG_USERSPACE)
u32_t priv_stack_start;
#endif
#endif
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_ */