| /* |
| * Copyright (c) 2018 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/kernel.h> |
| #include <aarch32/cortex_m/cmse.h> |
| |
| int arm_cmse_mpu_region_get(uint32_t addr) |
| { |
| cmse_address_info_t addr_info = cmse_TT((void *)addr); |
| |
| if (addr_info.flags.mpu_region_valid) { |
| return addr_info.flags.mpu_region; |
| } |
| |
| return -EINVAL; |
| } |
| |
| static int arm_cmse_addr_read_write_ok(uint32_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(uint32_t addr, int force_npriv) |
| { |
| return arm_cmse_addr_read_write_ok(addr, force_npriv, 0); |
| } |
| |
| int arm_cmse_addr_readwrite_ok(uint32_t addr, int force_npriv) |
| { |
| return arm_cmse_addr_read_write_ok(addr, force_npriv, 1); |
| } |
| |
| static int arm_cmse_addr_range_read_write_ok(uint32_t addr, uint32_t size, |
| int force_npriv, int rw) |
| { |
| int flags = 0; |
| |
| if (force_npriv != 0) { |
| flags |= CMSE_MPU_UNPRIV; |
| } |
| if (rw) { |
| flags |= CMSE_MPU_READWRITE; |
| } else { |
| flags |= CMSE_MPU_READ; |
| } |
| if (cmse_check_address_range((void *)addr, size, flags) != NULL) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| int arm_cmse_addr_range_read_ok(uint32_t addr, uint32_t size, int force_npriv) |
| { |
| return arm_cmse_addr_range_read_write_ok(addr, size, force_npriv, 0); |
| } |
| |
| int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv) |
| { |
| return arm_cmse_addr_range_read_write_ok(addr, size, force_npriv, 1); |
| } |
| |
| #if defined(CONFIG_ARM_SECURE_FIRMWARE) |
| |
| int arm_cmse_mpu_nonsecure_region_get(uint32_t addr) |
| { |
| cmse_address_info_t addr_info = cmse_TTA((void *)addr); |
| |
| if (addr_info.flags.mpu_region_valid) { |
| return addr_info.flags.mpu_region; |
| } |
| |
| return -EINVAL; |
| } |
| |
| int arm_cmse_sau_region_get(uint32_t addr) |
| { |
| cmse_address_info_t addr_info = cmse_TT((void *)addr); |
| |
| if (addr_info.flags.sau_region_valid) { |
| return addr_info.flags.sau_region; |
| } |
| |
| return -EINVAL; |
| } |
| |
| int arm_cmse_idau_region_get(uint32_t addr) |
| { |
| cmse_address_info_t addr_info = cmse_TT((void *)addr); |
| |
| if (addr_info.flags.idau_region_valid) { |
| return addr_info.flags.idau_region; |
| } |
| |
| return -EINVAL; |
| } |
| |
| int arm_cmse_addr_is_secure(uint32_t addr) |
| { |
| cmse_address_info_t addr_info = cmse_TT((void *)addr); |
| |
| return addr_info.flags.secure; |
| } |
| |
| static int arm_cmse_addr_nonsecure_read_write_ok(uint32_t addr, |
| int force_npriv, int rw) |
| { |
| cmse_address_info_t addr_info; |
| if (force_npriv) { |
| addr_info = cmse_TTAT((void *)addr); |
| } else { |
| addr_info = cmse_TTA((void *)addr); |
| } |
| |
| return rw ? addr_info.flags.nonsecure_readwrite_ok : |
| addr_info.flags.nonsecure_read_ok; |
| } |
| |
| int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv) |
| { |
| return arm_cmse_addr_nonsecure_read_write_ok(addr, force_npriv, 0); |
| } |
| |
| int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv) |
| { |
| return arm_cmse_addr_nonsecure_read_write_ok(addr, force_npriv, 1); |
| } |
| |
| static int arm_cmse_addr_range_nonsecure_read_write_ok(uint32_t addr, uint32_t size, |
| int force_npriv, int rw) |
| { |
| int flags = CMSE_NONSECURE; |
| |
| if (force_npriv != 0) { |
| flags |= CMSE_MPU_UNPRIV; |
| } |
| if (rw) { |
| flags |= CMSE_MPU_READWRITE; |
| } else { |
| flags |= CMSE_MPU_READ; |
| } |
| if (cmse_check_address_range((void *)addr, size, flags) != NULL) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, |
| int force_npriv) |
| { |
| return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, |
| force_npriv, 0); |
| } |
| |
| int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, |
| int force_npriv) |
| { |
| return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, |
| force_npriv, 1); |
| } |
| |
| #endif /* CONFIG_ARM_SECURE_FIRMWARE */ |