mmu.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. * 2019-03-25 quanzhao the first version
  9. * 2023-10-10 Shell Add permission control API
  10. */
  11. #ifndef __MMU_H_
  12. #define __MMU_H_
  13. #include <rtthread.h>
  14. #include <mm_aspace.h>
  15. /**
  16. * Level 1 translation table entry format
  17. *
  18. * It has 4 types:
  19. * Fault type: bit[1:0] = 0b00
  20. * Point L2 page type: bit[1:0] = 0b01
  21. * Section type: bit[1:0] = 0b10 and bit[18] = 0
  22. * Supersection type: bit[1:0] = 0b10 and bit[18] = 1
  23. *
  24. * The following defines are for section type entry
  25. * bit[01:00]: 0b10
  26. * bit[02] : B
  27. * bit[03] : C
  28. * bit[04] : XN
  29. * bit[08:05]: Domain
  30. * bit[09] : P
  31. * bit[11:10]: AP
  32. * bit[14:12]: TEX
  33. * bit[15] : APX
  34. * bit[16] : S
  35. * bit[17] : nG
  36. * bit[18] : 0
  37. * bit[19] : SBZ
  38. * bit[31:20]: Section Bass Address
  39. */
  40. #define DESC_SEC (0x2) /* for section type */
  41. /* memory types and attributes(TEX C B) */
  42. #define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */
  43. #define MEMWB (3<<2) /* write back, no write allocate */
  44. #define MEMWT (2<<2) /* write through, no write allocate */
  45. #define SHAREDEVICE (1<<2) /* shared device */
  46. #define STRONGORDER (0<<2) /* strong ordered */
  47. #define XN (1<<4)
  48. /* memory access permissions(AP APX) */
  49. #ifdef RT_USING_SMART
  50. #define AP_RW (1<<10) /* supervisor=RW, user=No */
  51. #define AP_RO ((1<<10) | (1 << 15)) /* supervisor=RO, user=No */
  52. #else
  53. #define AP_RW (3<<10) /* supervisor=RW, user=RW */
  54. #define AP_RO (2<<10) /* supervisor=RW, user=RO */
  55. #endif
  56. #define SHARED (1 << 16)
  57. /* DACR, Domain n access permission */
  58. #define DOMAIN_FAULT (0x0) /* 0b00: No access */
  59. #define DOMAIN_CHK (0x1) /* 0b01: Client */
  60. #define DOMAIN_NOTCHK (0x3) /* 0b11: No check */
  61. /* Domain */
  62. #define DOMAIN0 (0x0<<5)
  63. #define DOMAIN1 (0x1<<5)
  64. /* DACR */
  65. #define DOMAIN0_ATTR (DOMAIN_CHK<<0) /* domain0 use client mode */
  66. #define DOMAIN1_ATTR (DOMAIN_FAULT<<2) /* domain1 use no access mode */
  67. /* Memory types */
  68. #define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN)
  69. #define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC)
  70. #define STRONG_ORDER_MEM (SHARED|AP_RO|XN|DESC_SEC)
  71. struct mem_desc
  72. {
  73. rt_uint32_t vaddr_start;
  74. rt_uint32_t vaddr_end;
  75. rt_uint32_t paddr_start;
  76. rt_uint32_t attr;
  77. struct rt_varea varea;
  78. };
  79. /**
  80. * Level 2 translation table entry format
  81. *
  82. * It has 3 types:
  83. * Fault: bit[1:0] = 0b00
  84. * Larger page: bit[1:0] = 0b01
  85. * Small page: bit[1:0] = 0b1x
  86. *
  87. * The following defines are for small page type entry
  88. * bit[00]: XN
  89. * bit[01]: 1
  90. * bit[02]: B
  91. * bit[03]: C
  92. * bit[05:04]: AP
  93. * bit[08:06]: TEX
  94. * bit[09]: APX
  95. * bit[10]: S
  96. * bit[11]: nG
  97. * bit[31:12]: Small Page Base Address
  98. */
  99. #define MMU_MAP_MTBL_XN (1<<0)
  100. #define MMU_MAP_MTBL_A (1<<1)
  101. #define MMU_MAP_MTBL_B (1<<2)
  102. #define MMU_MAP_MTBL_C (1<<3)
  103. #define MMU_MAP_MTBL_AP01(x) (x<<4)
  104. #define MMU_MAP_MTBL_TEX(x) (x<<6)
  105. #define MMU_MAP_MTBL_AP2(x) (x<<9)
  106. #define MMU_MAP_MTBL_SHARE (1<<10)
  107. #define MMU_MAP_MTBL_NG(x) (x<<11)
  108. #define MMU_MAP_K_ROCB ((MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE))
  109. #define MMU_MAP_K_RO ((MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE))
  110. #define MMU_MAP_K_RWCB ((MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE))
  111. #define MMU_MAP_K_RW ((MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE))
  112. #define MMU_MAP_K_DEVICE ((MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE))
  113. #define MMU_MAP_U_ROCB ((MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(2)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE))
  114. #define MMU_MAP_U_RO ((MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(2)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE))
  115. #define MMU_MAP_U_RWCB ((MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE))
  116. #define MMU_MAP_U_RW ((MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE))
  117. #define MMU_MAP_U_DEVICE ((MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE))
  118. #define MMU_MAP_TRACE(attr) (attr)
  119. #define ARCH_SECTION_SHIFT 20
  120. #define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT)
  121. #define ARCH_SECTION_MASK (ARCH_SECTION_SIZE - 1)
  122. #define ARCH_PAGE_SHIFT 12
  123. #define ARCH_PAGE_SIZE (1 << ARCH_PAGE_SHIFT)
  124. #define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1)
  125. #define ARCH_PAGE_TBL_SHIFT 10
  126. #define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT)
  127. #define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1)
  128. #define ARCH_MMU_USED_MASK 3
  129. #define ARCH_TYPE_SUPERSECTION (1 << 18)
  130. #define ARCH_ADDRESS_WIDTH_BITS 32
  131. #define ARCH_VADDR_WIDTH 32
  132. /**
  133. * *info it's possible to map (-1ul & ~ARCH_PAGE_MASK) but a not aligned -1 is
  134. * never returned on a successful mapping
  135. */
  136. #define ARCH_MAP_FAILED ((void *)-1)
  137. #define RT_HW_MMU_PROT_READ 1
  138. #define RT_HW_MMU_PROT_WRITE 2
  139. #define RT_HW_MMU_PROT_EXECUTE 4
  140. #define RT_HW_MMU_PROT_KERNEL 8
  141. #define RT_HW_MMU_PROT_USER 16
  142. #define RT_HW_MMU_PROT_CACHE 32
  143. int rt_hw_mmu_ioremap_init(struct rt_aspace *aspace, void *v_address, size_t size);
  144. void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size);
  145. void rt_hw_mmu_setup(struct rt_aspace *aspace, struct mem_desc *mdesc, int desc_nr);
  146. void rt_hw_mmu_init(void);
  147. int rt_hw_mmu_map_init(struct rt_aspace *aspace, void *v_address, size_t size, size_t *vtable, size_t pv_off);
  148. void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr, size_t size, size_t attr);
  149. void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size);
  150. void rt_hw_aspace_switch(struct rt_aspace *aspace);
  151. void rt_hw_mmu_switch(void *tbl);
  152. void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr);
  153. void *rt_hw_mmu_tbl_get(void);
  154. int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size, enum rt_mmu_cntl cmd);
  155. void *rt_hw_mmu_pgtbl_create(void);
  156. void rt_hw_mmu_pgtbl_delete(void *pgtbl);
  157. #define AP_APX_MASK (MMU_MAP_MTBL_AP2(0x1) | MMU_MAP_MTBL_AP01(0x3))
  158. #define AP_APX_URW_KRW (MMU_MAP_MTBL_AP2(0x0) | MMU_MAP_MTBL_AP01(0x3))
  159. #define AP_APX_URO_KRO (MMU_MAP_MTBL_AP2(0x1) | MMU_MAP_MTBL_AP01(0x2))
  160. /**
  161. * @brief Remove permission from attribution
  162. *
  163. * @param attr architecture specified mmu attribution
  164. * @param prot protect that will be removed
  165. * @return size_t returned attribution
  166. */
  167. rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot)
  168. {
  169. switch (prot)
  170. {
  171. /* remove write permission for user */
  172. case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
  173. if ((attr & AP_APX_MASK) == AP_APX_URW_KRW)
  174. attr &= ~MMU_MAP_MTBL_AP01(0x1);
  175. break;
  176. case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_KERNEL:
  177. switch (attr & AP_APX_MASK)
  178. {
  179. case MMU_MAP_MTBL_AP01(0):
  180. break;
  181. case MMU_MAP_MTBL_AP01(3):
  182. attr = (attr & AP_APX_MASK) | AP_APX_URO_KRO;
  183. default:
  184. attr |= MMU_MAP_MTBL_AP2(0x1);
  185. break;
  186. }
  187. break;
  188. default:
  189. RT_ASSERT(0);
  190. }
  191. return attr;
  192. }
  193. /**
  194. * @brief Add permission from attribution
  195. *
  196. * @param attr architecture specified mmu attribution
  197. * @param prot protect that will be added
  198. * @return size_t returned attribution
  199. */
  200. rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot)
  201. {
  202. switch (prot)
  203. {
  204. /* add write permission for user */
  205. case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
  206. case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_KERNEL:
  207. attr |= MMU_MAP_MTBL_AP01(0x3);
  208. attr &= ~MMU_MAP_MTBL_AP2(0x1);
  209. break;
  210. default:
  211. RT_ASSERT(0);
  212. }
  213. return attr;
  214. }
  215. /**
  216. * @brief Test permission from attribution
  217. *
  218. * @param attr architecture specified mmu attribution
  219. * @param prot protect that will be test
  220. * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE
  221. */
  222. rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot)
  223. {
  224. rt_bool_t rc = 0;
  225. switch (prot)
  226. {
  227. /* test write permission for user */
  228. case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
  229. rc = (AP_APX_MASK & attr) == (AP_APX_URW_KRW);
  230. break;
  231. default:
  232. RT_ASSERT(0);
  233. }
  234. return rc;
  235. }
  236. #endif