arch: arm: Define & implement API for test target (Non-Secure)

This commit defines and implements an internal ARMv8-M API
that allows the user to evaluate access permissions of memory
locations, based on the ARMv8-M Test Target (TT) instruction
support.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
Ioannis Glaropoulos 2018-03-28 15:30:40 +02:00 committed by Andrew Boie
parent 2b73c97d68
commit c842f32ddd
5 changed files with 151 additions and 0 deletions

View File

@ -23,3 +23,4 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S)
add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M cortex_m)
add_subdirectory_ifdef(CONFIG_CPU_HAS_MPU cortex_m/mpu)
add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M_HAS_CMSE cortex_m/cmse)

View File

@ -166,6 +166,12 @@ config CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP
This option signifies the Cortex-M0 has some mechanisms that can map
the vector table to SRAM
config CPU_CORTEX_M_HAS_CMSE
bool
default n
help
This option signifies the Cortex-M CPU has the CMSE intrinsics.
config ARMV6_M_ARMV8_M_BASELINE
bool
# Omit prompt to signify "hidden" option

View File

@ -0,0 +1 @@
zephyr_sources(arm_core_cmse.c)

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <cortex_m/cmse.h>
int arm_cmse_mpu_region_get(u32_t addr, u8_t *p_region)
{
cmse_address_info_t addr_info = cmse_TT((void *)addr);
if (addr_info.flags.mpu_region_valid) {
*p_region = addr_info.flags.mpu_region;
}
return addr_info.flags.mpu_region_valid;
}
static int arm_cmse_addr_read_write_ok(u32_t addr, int force_npriv, int rw)
{
cmse_address_info_t addr_info;
if (force_npriv) {
addr_info = cmse_TTT((void *)addr);
} else {
addr_info = cmse_TT((void *)addr);
}
return rw ? addr_info.flags.readwrite_ok : addr_info.flags.read_ok;
}
int arm_cmse_addr_read_ok(u32_t addr, int force_npriv)
{
return arm_cmse_addr_read_write_ok(addr, force_npriv, 0);
}
int arm_cmse_addr_readwrite_ok(u32_t addr, int force_npriv)
{
return arm_cmse_addr_read_write_ok(addr, force_npriv, 1);
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM Core CMSE API
*
* CMSE API for Cortex-M23/M33 CPUs.
*/
#ifndef _ARM_CORTEXM_CMSE__H_
#define _ARM_CORTEXM_CMSE__H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
/* nothing */
#else
#include <arm_cmse.h>
#include <stdint.h>
/*
* Address information retrieval based on the TT instructions.
*
* The TT instructions are used to check the access permissions that different
* security states and privilege levels have on memory at a specified address
*/
/**
* @brief Get the MPU region number of an address
*
* Get the MPU region that the address maps to. Return non-zero
* to indicate that a valid MPU region was retrieved, and store the
* MPU region information in the supplied location.
*
* Note:
* Obtained region is valid only if:
* - the function is called from privileged mode
* - the MPU is implemented and enabled
* - the given address matches a single, enabled MPU region
*
* @param addr The address for which the MPU region is requested
* @param p_region Output pointer to the location to store the MPU region
*
* @return non-zero if @ref region contains a valid MPU region, otherwise 0.
*/
int arm_cmse_mpu_region_get(u32_t addr, u8_t *p_region);
/**
* @brief Read accessibility of an address
*
* Evaluates whether a specified memory location can be read according to the
* permissions of the current state MPU and the specified operation mode.
*
* This function shall always return zero:
* - if executed from an unprivileged mode,
* - if the address matches multiple MPU regions.
*
* @param addr The address for which the readability is requested
* @param force_npriv Instruct to return the readability of the address
* for unprivileged access, regardless of whether the current
* mode is privileged or unprivileged.
*
* @return 1 if address is readable, 0 otherwise.
*/
int arm_cmse_addr_read_ok(u32_t addr, int force_npriv);
/**
* @brief Read and Write accessibility of an address
*
* Evaluates whether a specified memory location can be read/written according
* to the permissions of the current state MPU and the specified operation
* mode.
*
* This function shall always return zero:
* - if executed from an unprivileged mode,
* - if the address matches multiple MPU regions.
*
* @param addr The address for which the RW ability is requested
* @param force_npriv Instruct to return the RW ability of the address
* for unprivileged access, regardless of whether the current
* mode is privileged or unprivileged.
*
* @return 1 if address is Read and Writable, 0 otherwise.
*/
int arm_cmse_addr_readwrite_ok(u32_t addr, int force_npriv);
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* _ARM_CORTEXM_CMSE__H_ */