mpu.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. #ifndef __MPU_H__
  11. #define __MPU_H__
  12. #ifdef RT_USING_MEM_PROTECTION
  13. #include <board.h>
  14. #include <mprotect.h>
  15. #define MPU_MIN_REGION_SIZE 32U
  16. #define RT_ARM_DEFAULT_MAIR_ATTR (0xF0U)
  17. /* MPU attributes for configuring data region permission*/
  18. /* Privileged Read Write, Unprivileged No Access */
  19. #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)
  20. #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)
  21. #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)
  22. /* Privileged Read Write, Unprivileged Read Write */
  23. #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)
  24. #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)
  25. #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)
  26. /* Privileged Read Only, Unprivileged No Access */
  27. #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)
  28. #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)
  29. #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)
  30. /* Privileged Read Only, Unprivileged Read Only */
  31. #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)
  32. #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)
  33. #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)
  34. /* MPU attributes for configuring code region permission */
  35. #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))
  36. #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))
  37. #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))
  38. /* Privileged Read Write Execute, Unprivileged Read Write Execute */
  39. #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))
  40. #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))
  41. #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))
  42. /* Privileged Read Execute, Unprivileged No Access */
  43. #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))
  44. #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))
  45. #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))
  46. /* Privileged Read Execute, Unprivileged Read Execute */
  47. #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))
  48. #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))
  49. #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))
  50. typedef struct
  51. {
  52. rt_thread_t thread; /* Thread that triggered exception */
  53. void *addr; /* Address of faulting memory access */
  54. rt_mem_region_t region; /* Configurations of the memory region containing the address */
  55. rt_uint8_t mmfsr; /* Content of MemManage Status Register */
  56. } rt_mem_exception_info_t;
  57. typedef void (*rt_hw_mpu_exception_hook_t)(rt_mem_exception_info_t *);
  58. #define RT_ARM_MEM_ATTR(perm, type) ((rt_mem_attr_t){ .rbar = (perm), .mair_attr = (type) })
  59. /* Convenient macros for configuring data region attributes with default memory type */
  60. #define RT_MEM_REGION_P_RW_U_NA RT_ARM_MEM_ATTR(P_RW_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  61. #define RT_MEM_REGION_P_RW_U_RW RT_ARM_MEM_ATTR(P_RW_U_RW_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  62. #define RT_MEM_REGION_P_RO_U_NA RT_ARM_MEM_ATTR(P_RO_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  63. #define RT_MEM_REGION_P_RO_U_RO RT_ARM_MEM_ATTR(P_RO_U_RO_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  64. /* ARM-V8M does not support P_NA_U_NA.
  65. For compatibility with rt_mprotect_add_exclusive_region,
  66. define RT_MEM_REGION_P_NA_U_NA as the lowest privilege supported.
  67. */
  68. #define RT_MEM_REGION_P_NA_U_NA RT_MEM_REGION_P_RO_U_NA
  69. /* Convenient macros for configuring code region attributes with default memory type and shareability */
  70. #define RT_MEM_REGION_P_RWX_U_NA RT_ARM_MEM_ATTR(P_RWX_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  71. #define RT_MEM_REGION_P_RWX_U_RWX RT_ARM_MEM_ATTR(P_RWX_U_RWX_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  72. #define RT_MEM_REGION_P_RX_U_NA RT_ARM_MEM_ATTR(P_RX_U_NA_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  73. #define RT_MEM_REGION_P_RX_U_RX RT_ARM_MEM_ATTR(P_RX_U_RX_NON_SHAREABLE, RT_ARM_DEFAULT_MAIR_ATTR)
  74. rt_bool_t rt_hw_mpu_region_valid(rt_mem_region_t *region);
  75. rt_err_t rt_hw_mpu_init(void);
  76. rt_err_t rt_hw_mpu_add_region(rt_thread_t thread, rt_mem_region_t *region);
  77. rt_err_t rt_hw_mpu_delete_region(rt_thread_t thread, rt_mem_region_t *region);
  78. rt_err_t rt_hw_mpu_update_region(rt_thread_t thread, rt_mem_region_t *region);
  79. rt_err_t rt_hw_mpu_exception_set_hook(rt_hw_mpu_exception_hook_t hook);
  80. #endif /* RT_USING_MEM_PROTECTION */
  81. #endif /* __MPU_H__ */