1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-09-25     tangzz98     the first version
9  */
10 
11 #ifndef __MPU_H__
12 #define __MPU_H__
13 
14 #ifdef RT_USING_MEM_PROTECTION
15 
16 #include <board.h>
17 
18 #define MPU_MIN_REGION_SIZE 32U
19 
20 /* MPU attributes for configuring data region permission */
21 /* Privileged No Access, Unprivileged No Access */
22 #define P_NA_U_NA       ((0x0 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk | MPU_RASR_XN_Msk)
23 /* Privileged Read Write, Unprivileged No Access */
24 #define P_RW_U_NA       ((0x1 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk | MPU_RASR_XN_Msk)
25 /* Privileged Read Write, Unprivileged Read Only */
26 #define P_RW_U_RO       ((0x2 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk | MPU_RASR_XN_Msk)
27 /* Privileged Read Write, Unprivileged Read Write */
28 #define P_RW_U_RW       ((0x3 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk | MPU_RASR_XN_Msk)
29 /* Privileged Read Only, Unprivileged No Access */
30 #define P_RO_U_NA       ((0x5 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk | MPU_RASR_XN_Msk)
31 /* Privileged Read Only, Unprivileged Read Only */
32 #define P_RO_U_RO       ((0x6 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk | MPU_RASR_XN_Msk)
33 
34 /* MPU attributes for configuring code region permission */
35 /* Privileged Read Write Execute, Unprivileged Read Write Execute */
36 #define P_RWX_U_RWX     ((0x3 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
37 /* Privileged Read Write Execute, Unprivileged Read Execute */
38 #define P_RWX_U_RX      ((0x2 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
39 /* Privileged Read Write Execute, Unprivileged No Access */
40 #define P_RWX_U_NA      ((0x1 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
41 /* Privileged Read Execute, Unprivileged Read Execute */
42 #define P_RX_U_RX       ((0x6 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
43 /* Privileged Read Execute, Unprivileged No Access */
44 #define P_RX_U_NA       ((0x5 << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
45 
46 /* MPU attributes for configuring memory type, cacheability and shareability */
47 #define STRONGLY_ORDERED_SHAREABLE      MPU_RASR_S_Msk
48 #define DEVICE_SHAREABLE                (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
49 #define NORMAL_OUTER_INNER_WRITE_THROUGH_SHAREABLE \
50         (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
51 #define NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE  MPU_RASR_C_Msk
52 #define NORMAL_OUTER_INNER_WRITE_BACK_SHAREABLE \
53         (MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk)
54 #define NORMAL_OUTER_INNER_WRITE_BACK_NON_SHAREABLE \
55         (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
56 #define NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE \
57         ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk)
58 #define NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE \
59         (1 << MPU_RASR_TEX_Pos)
60 #define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_SHAREABLE \
61     ((1 << MPU_RASR_TEX_Pos) |\
62      MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk)
63 #define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE \
64     ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk)
65 #define DEVICE_NON_SHAREABLE            (2 << MPU_RASR_TEX_Pos)
66 #define RESERVED                        ((2 << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk)
67 
68 typedef struct
69 {
70     rt_thread_t thread;     /* Thread that triggered exception */
71     void *addr;             /* Address of faulting memory access */
72     rt_mem_region_t region; /* Configurations of the memory region containing the address */
73     rt_uint8_t mmfsr;       /* Content of MemManage Status Register */
74 } rt_mem_exception_info_t;
75 
76 typedef void (*rt_hw_mpu_exception_hook_t)(rt_mem_exception_info_t *);
77 
78 #define RT_ARM_MEM_ATTR(perm, type) ((rt_mem_attr_t){ (perm) | (type)})
79 
80 /* Convenient macros for configuring data region attributes with default memory type */
81 #define RT_MEM_REGION_P_NA_U_NA RT_ARM_MEM_ATTR(P_NA_U_NA, RESERVED)
82 #define RT_MEM_REGION_P_RW_U_RW RT_ARM_MEM_ATTR(P_RW_U_RW, RESERVED)
83 #define RT_MEM_REGION_P_RW_U_RO RT_ARM_MEM_ATTR(P_RW_U_RO, RESERVED)
84 #define RT_MEM_REGION_P_RW_U_NA RT_ARM_MEM_ATTR(P_RW_U_NA, RESERVED)
85 #define RT_MEM_REGION_P_RO_U_RO RT_ARM_MEM_ATTR(P_RO_U_RO, RESERVED)
86 #define RT_MEM_REGION_P_RO_U_NA RT_ARM_MEM_ATTR(P_RO_U_NA, RESERVED)
87 
88 /* Convenient macros for configuring code region attributes with default memory type */
89 #define RT_MEM_REGION_P_RWX_U_RWX   RT_ARM_MEM_ATTR(P_RWX_U_RWX, RESERVED)
90 #define RT_MEM_REGION_P_RWX_U_RX    RT_ARM_MEM_ATTR(P_RWX_U_RX, RESERVED)
91 #define RT_MEM_REGION_P_RWX_U_NA    RT_ARM_MEM_ATTR(P_RWX_U_NA, RESERVED)
92 #define RT_MEM_REGION_P_RX_U_RX     RT_ARM_MEM_ATTR(P_RX_U_RX, RESERVED)
93 #define RT_MEM_REGION_P_RX_U_NA     RT_ARM_MEM_ATTR(P_RX_U_NA, RESERVED)
94 
95 rt_bool_t rt_hw_mpu_region_valid(rt_mem_region_t *region);
96 rt_err_t rt_hw_mpu_init(void);
97 rt_err_t rt_hw_mpu_add_region(rt_thread_t thread, rt_mem_region_t *region);
98 rt_err_t rt_hw_mpu_delete_region(rt_thread_t thread, rt_mem_region_t *region);
99 rt_err_t rt_hw_mpu_update_region(rt_thread_t thread, rt_mem_region_t *region);
100 rt_err_t rt_hw_mpu_exception_set_hook(rt_hw_mpu_exception_hook_t hook);
101 
102 #endif /* RT_USING_MEM_PROTECTION */
103 
104 #endif /* __MPU_H__ */
105