100 lines
6.4 KiB
C
100 lines
6.4 KiB
C
|
/*
|
||
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2023-09-25 tangzz98 the first version
|
||
|
*/
|
||
|
|
||
|
#ifndef __MPU_H__
|
||
|
#define __MPU_H__
|
||
|
|
||
|
#ifdef RT_USING_MEM_PROTECTION
|
||
|
|
||
|
#include <board.h>
|
||
|
#include <mprotect.h>
|
||
|
|
||
|
#define MPU_MIN_REGION_SIZE 32U
|
||
|
|
||
|
#define RT_ARM_DEFAULT_MAIR_ATTR (0xF0U)
|
||
|
|
||
|
/* MPU attributes for configuring data region permission*/
|
||
|
/* Privileged Read Write, Unprivileged No Access */
|
||
|
#define P_RW_U_NA_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x0 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RW_U_NA_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x0 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RW_U_NA_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x0 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
/* Privileged Read Write, Unprivileged Read Write */
|
||
|
#define P_RW_U_RW_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x1 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RW_U_RW_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x1 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RW_U_RW_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x1 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
/* Privileged Read Only, Unprivileged No Access */
|
||
|
#define P_RO_U_NA_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x2 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RO_U_NA_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x2 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RO_U_NA_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x2 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
/* Privileged Read Only, Unprivileged Read Only */
|
||
|
#define P_RO_U_RO_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x3 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RO_U_RO_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x3 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
#define P_RO_U_RO_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x3 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | MPU_RBAR_XN_Msk)
|
||
|
|
||
|
/* MPU attributes for configuring code region permission */
|
||
|
#define P_RWX_U_NA_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x0 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RWX_U_NA_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x0 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RWX_U_NA_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x0 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
|
||
|
/* Privileged Read Write Execute, Unprivileged Read Write Execute */
|
||
|
#define P_RWX_U_RWX_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x1 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RWX_U_RWX_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x1 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RWX_U_RWX_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x1 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
|
||
|
/* Privileged Read Execute, Unprivileged No Access */
|
||
|
#define P_RX_U_NA_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x2 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RX_U_NA_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x2 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RX_U_NA_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x2 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
|
||
|
/* Privileged Read Execute, Unprivileged Read Execute */
|
||
|
#define P_RX_U_RX_NON_SHAREABLE (((0x0 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x3 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RX_U_RX_OUTER_SHAREABLE (((0x2 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x3 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
#define P_RX_U_RX_INNER_SHAREABLE (((0x3 << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | ((0x3 << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk))
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
rt_thread_t thread; /* Thread that triggered exception */
|
||
|
void *addr; /* Address of faulting memory access */
|
||
|
rt_mem_region_t region; /* Configurations of the memory region containing the address */
|
||
|
rt_uint8_t mmfsr; /* Content of MemManage Status Register */
|
||
|
} rt_mem_exception_info_t;
|
||
|
|
||
|
typedef void (*rt_hw_mpu_exception_hook_t)(rt_mem_exception_info_t *);
|
||
|
|
||
|
#define RT_ARM_MEM_ATTR(perm, type) ((rt_mem_attr_t){ .rbar = (perm), .mair_attr = (type) })
|
||
|
|
||
|
/* Convenient macros for configuring data region attributes with default memory type */
|
||
|
#define RT_MEM_REGION_P_RW_U_NA RT_ARM_MEM_ATTR(P_RW_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
#define RT_MEM_REGION_P_RW_U_RW RT_ARM_MEM_ATTR(P_RW_U_RW_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
#define RT_MEM_REGION_P_RO_U_NA RT_ARM_MEM_ATTR(P_RO_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
#define RT_MEM_REGION_P_RO_U_RO RT_ARM_MEM_ATTR(P_RO_U_RO_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
/* ARM-V8M does not support P_NA_U_NA.
|
||
|
For compatibility with rt_mprotect_add_exclusive_region,
|
||
|
define RT_MEM_REGION_P_NA_U_NA as the lowest privilege supported.
|
||
|
*/
|
||
|
#define RT_MEM_REGION_P_NA_U_NA RT_MEM_REGION_P_RO_U_NA
|
||
|
|
||
|
/* Convenient macros for configuring code region attributes with default memory type and shareability */
|
||
|
#define RT_MEM_REGION_P_RWX_U_NA RT_ARM_MEM_ATTR(P_RWX_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
#define RT_MEM_REGION_P_RWX_U_RWX RT_ARM_MEM_ATTR(P_RWX_U_RWX_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
#define RT_MEM_REGION_P_RX_U_NA RT_ARM_MEM_ATTR(P_RX_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
#define RT_MEM_REGION_P_RX_U_RX RT_ARM_MEM_ATTR(P_RX_U_RX_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
|
||
|
|
||
|
rt_bool_t rt_hw_mpu_region_valid(rt_mem_region_t *region);
|
||
|
rt_err_t rt_hw_mpu_init(void);
|
||
|
rt_err_t rt_hw_mpu_add_region(rt_thread_t thread, rt_mem_region_t *region);
|
||
|
rt_err_t rt_hw_mpu_delete_region(rt_thread_t thread, rt_mem_region_t *region);
|
||
|
rt_err_t rt_hw_mpu_update_region(rt_thread_t thread, rt_mem_region_t *region);
|
||
|
rt_err_t rt_hw_mpu_exception_set_hook(rt_hw_mpu_exception_hook_t hook);
|
||
|
|
||
|
#endif /* RT_USING_MEM_PROTECTION */
|
||
|
|
||
|
#endif /* __MPU_H__ */
|