memprot.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /* INTERNAL API
  7. * generic interface to MMU memory protection features
  8. */
  9. #pragma once
  10. #include <stdbool.h>
  11. #include <stdint.h>
  12. #include "esp_attr.h"
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. typedef enum {
  17. MEMPROT_NONE = 0x00000000,
  18. MEMPROT_IRAM0_SRAM = 0x00000001,
  19. MEMPROT_DRAM0_SRAM = 0x00000002,
  20. MEMPROT_IRAM0_RTCFAST = 0x00000004,
  21. MEMPROT_DRAM0_RTCFAST = 0x00000008,
  22. MEMPROT_PERI1_RTCSLOW = 0x00000010,
  23. MEMPROT_PERI2_RTCSLOW_0 = 0x00000020,
  24. MEMPROT_PERI2_RTCSLOW_1 = 0x00000040,
  25. MEMPROT_ALL = 0xFFFFFFFF
  26. } mem_type_prot_t;
  27. /**
  28. * @brief Returns splitting address for required memory region
  29. *
  30. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  31. *
  32. * @return Splitting address for the memory region required.
  33. * The address is given by region-specific global symbol exported from linker script,
  34. * it is not read out from related configuration register.
  35. */
  36. uint32_t *IRAM_ATTR esp_memprot_get_split_addr(mem_type_prot_t mem_type);
  37. /**
  38. * @brief Initializes illegal memory access control (MMU) for required memory section.
  39. *
  40. * All memory access interrupts share ETS_MEMACCESS_ERR_INUM input channel, it is caller's
  41. * responsibility to properly detect actual intr. source as well as possible prioritization in case
  42. * of multiple source reported during one intr.handling routine run
  43. *
  44. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  45. */
  46. void esp_memprot_intr_init(mem_type_prot_t mem_type);
  47. /**
  48. * @brief Enable/disable the memory protection interrupt
  49. *
  50. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  51. * @param enable enable/disable
  52. */
  53. void esp_memprot_intr_ena(mem_type_prot_t mem_type, bool enable);
  54. /**
  55. * @brief Sets a request for clearing interrupt-on flag for specified memory region (register write)
  56. *
  57. * @note When called without actual interrupt-on flag set, subsequent occurrence of related interrupt is ignored.
  58. * Should be used only after the real interrupt appears, typically as the last step in interrupt handler's routine.
  59. *
  60. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  61. */
  62. void esp_memprot_clear_intr(mem_type_prot_t mem_type);
  63. /**
  64. * @brief Detects which memory protection interrupt is active
  65. *
  66. * @note Check order
  67. * MEMPROT_IRAM0_SRAM
  68. * MEMPROT_IRAM0_RTCFAST
  69. * MEMPROT_DRAM0_SRAM
  70. * MEMPROT_DRAM0_RTCFAST
  71. *
  72. * @return Memory protection area type (see mem_type_prot_t enum)
  73. */
  74. mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
  75. /**
  76. * @brief Gets interrupt status register contents for specified memory region
  77. *
  78. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  79. *
  80. * @return Contents of status register
  81. */
  82. uint32_t esp_memprot_get_fault_reg(mem_type_prot_t mem_type);
  83. /**
  84. * @brief Get details of given interrupt status
  85. *
  86. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  87. * @param faulting_address Faulting address causing the interrupt [out]
  88. * @param op_type Operation being processed at the faulting address [out]
  89. * IRAM0: 0 - read, 1 - write
  90. * DRAM0: 0 - read, 1 - write
  91. * @param op_subtype Additional info for op_type [out]
  92. * IRAM0: 0 - instruction segment access, 1 - data segment access
  93. * DRAM0: 0 - non-atomic operation, 1 - atomic operation
  94. */
  95. void IRAM_ATTR esp_memprot_get_fault_status(mem_type_prot_t mem_type, uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype);
  96. /**
  97. * @brief Gets string representation of required memory region identifier
  98. *
  99. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  100. *
  101. * @return mem_type as string
  102. */
  103. const char *IRAM_ATTR esp_memprot_type_to_str(mem_type_prot_t mem_type);
  104. /**
  105. * @brief Detects whether any of the interrupt locks is active (requires digital system reset to unlock)
  106. *
  107. * @return true/false
  108. */
  109. bool esp_memprot_is_locked_any(void);
  110. /**
  111. * @brief Sets lock for specified memory region.
  112. *
  113. * Locks can be unlocked only by digital system reset
  114. *
  115. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  116. */
  117. void esp_memprot_set_lock(mem_type_prot_t mem_type);
  118. /**
  119. * @brief Gets lock status for required memory region
  120. *
  121. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  122. *
  123. * @return true/false (locked/unlocked)
  124. */
  125. bool esp_memprot_get_lock(mem_type_prot_t mem_type);
  126. /**
  127. * @brief Gets permission control configuration register contents for required memory region
  128. *
  129. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  130. *
  131. * @return Permission control register contents
  132. */
  133. uint32_t esp_memprot_get_conf_reg(mem_type_prot_t mem_type);
  134. /**
  135. * @brief Gets interrupt permission settings for unified management block
  136. *
  137. * Gets interrupt permission settings register contents for required memory region, returns settings for unified management blocks
  138. *
  139. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  140. *
  141. * @return Permission settings register contents
  142. */
  143. uint32_t esp_memprot_get_perm_uni_reg(mem_type_prot_t mem_type);
  144. /**
  145. * @brief Gets interrupt permission settings for split management block
  146. *
  147. * Gets interrupt permission settings register contents for required memory region, returns settings for split management blocks
  148. *
  149. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  150. *
  151. * @return Permission settings register contents
  152. */
  153. uint32_t esp_memprot_get_perm_split_reg(mem_type_prot_t mem_type);
  154. /**
  155. * @brief Detects whether any of the memory protection interrupts is enabled
  156. *
  157. * @return true/false
  158. */
  159. bool esp_memprot_is_intr_ena_any(void);
  160. /**
  161. * @brief Gets interrupt-enabled flag for given memory region
  162. *
  163. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  164. *
  165. * @return Interrupt-enabled value
  166. */
  167. uint32_t esp_memprot_get_intr_ena_bit(mem_type_prot_t mem_type);
  168. /**
  169. * @brief Gets interrupt-active flag for given memory region
  170. *
  171. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  172. *
  173. * @return Interrupt-active value
  174. */
  175. uint32_t esp_memprot_get_intr_on_bit(mem_type_prot_t mem_type);
  176. /**
  177. * @brief Gets interrupt-clear request flag for given memory region
  178. *
  179. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  180. *
  181. * @return Interrupt-clear request value
  182. */
  183. uint32_t esp_memprot_get_intr_clr_bit(mem_type_prot_t mem_type);
  184. /**
  185. * @brief Gets read permission value for specified block and memory region
  186. *
  187. * Returns read permission bit value for required unified-management block (0-3) in given memory region.
  188. * Applicable to all memory types.
  189. *
  190. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  191. * @param block Memory block identifier (0-3)
  192. *
  193. * @return Read permission value for required block
  194. */
  195. uint32_t esp_memprot_get_uni_block_read_bit(mem_type_prot_t mem_type, uint32_t block);
  196. /**
  197. * @brief Gets write permission value for specified block and memory region
  198. *
  199. * Returns write permission bit value for required unified-management block (0-3) in given memory region.
  200. * Applicable to all memory types.
  201. *
  202. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  203. * @param block Memory block identifier (0-3)
  204. *
  205. * @return Write permission value for required block
  206. */
  207. uint32_t esp_memprot_get_uni_block_write_bit(mem_type_prot_t mem_type, uint32_t block);
  208. /**
  209. * @brief Gets execute permission value for specified block and memory region
  210. *
  211. * Returns execute permission bit value for required unified-management block (0-3) in given memory region.
  212. * Applicable only to IRAM memory types
  213. *
  214. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  215. * @param block Memory block identifier (0-3)
  216. *
  217. * @return Execute permission value for required block
  218. */
  219. uint32_t esp_memprot_get_uni_block_exec_bit(mem_type_prot_t mem_type, uint32_t block);
  220. /**
  221. * @brief Sets permissions for specified block in DRAM region
  222. *
  223. * Sets Read and Write permission for specified unified-management block (0-3) in given memory region.
  224. * Applicable only to DRAM memory types
  225. *
  226. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  227. * @param block Memory block identifier (0-3)
  228. * @param write_perm Write permission flag
  229. * @param read_perm Read permission flag
  230. */
  231. void esp_memprot_set_uni_block_perm_dram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm);
  232. /**
  233. * @brief Sets permissions for high and low memory segment in DRAM region
  234. *
  235. * Sets Read and Write permission for both low and high memory segments given by splitting address.
  236. * The splitting address must be equal to or higher then beginning of block 5
  237. * Applicable only to DRAM memory types
  238. *
  239. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  240. * @param split_addr Address to split the memory region to lower and higher segment
  241. * @param lw Low segment Write permission flag
  242. * @param lr Low segment Read permission flag
  243. * @param hw High segment Write permission flag
  244. * @param hr High segment Read permission flag
  245. */
  246. void esp_memprot_set_prot_dram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
  247. /**
  248. * @brief Sets permissions for specified block in IRAM region
  249. *
  250. * Sets Read, Write and Execute permission for specified unified-management block (0-3) in given memory region.
  251. * Applicable only to IRAM memory types
  252. *
  253. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  254. * @param block Memory block identifier (0-3)
  255. * @param write_perm Write permission flag
  256. * @param exec_perm Execute permission flag
  257. */
  258. void esp_memprot_set_uni_block_perm_iram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm, bool exec_perm);
  259. /**
  260. * @brief Sets permissions for high and low memory segment in IRAM region
  261. *
  262. * Sets Read, Write and Execute permission for both low and high memory segments given by splitting address.
  263. * The splitting address must be equal to or higher then beginning of block 5
  264. * Applicable only to IRAM memory types
  265. *
  266. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  267. * @param split_addr Address to split the memory region to lower and higher segment
  268. * @param lw Low segment Write permission flag
  269. * @param lr Low segment Read permission flag
  270. * @param lx Low segment Execute permission flag
  271. * @param hw High segment Write permission flag
  272. * @param hr High segment Read permission flag
  273. * @param hx High segment Execute permission flag
  274. */
  275. void esp_memprot_set_prot_iram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
  276. /**
  277. * @brief Activates memory protection for all supported memory region types
  278. *
  279. * @note The feature is disabled when JTAG interface is connected
  280. *
  281. * @param invoke_panic_handler map mem.prot interrupt to ETS_MEMACCESS_ERR_INUM and thus invokes panic handler when fired ('true' not suitable for testing)
  282. * @param lock_feature sets LOCK bit, see esp_memprot_set_lock() ('true' not suitable for testing)
  283. * @param mem_type_mask holds a set of required memory protection types (bitmask built of mem_type_prot_t). NULL means default (MEMPROT_ALL in this version)
  284. */
  285. void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
  286. /**
  287. * @brief Get permission settings bits for IRAM0 split mgmt. Only IRAM0 memory types allowed
  288. *
  289. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  290. * @param lw Low segment Write permission flag
  291. * @param lr Low segment Read permission flag
  292. * @param lx Low segment Execute permission flag
  293. * @param hw High segment Write permission flag
  294. * @param hr High segment Read permission flag
  295. * @param hx High segment Execute permission flag
  296. */
  297. void esp_memprot_get_perm_split_bits_iram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
  298. /**
  299. * @brief Get permission settings bits for DRAM0 split mgmt. Only DRAM0 memory types allowed
  300. *
  301. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  302. * @param lw Low segment Write permission flag
  303. * @param lr Low segment Read permission flag
  304. * @param hw High segment Write permission flag
  305. * @param hr High segment Read permission flag
  306. */
  307. void esp_memprot_get_perm_split_bits_dram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
  308. /**
  309. * @brief Sets permissions for high and low memory segment in PERIBUS1 region
  310. *
  311. * Sets Read and Write permission for both low and high memory segments given by splitting address.
  312. * Applicable only to PERIBUS1 memory types
  313. *
  314. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  315. * @param split_addr Address to split the memory region to lower and higher segment
  316. * @param lw Low segment Write permission flag
  317. * @param lr Low segment Read permission flag
  318. * @param hw High segment Write permission flag
  319. * @param hr High segment Read permission flag
  320. */
  321. void esp_memprot_set_prot_peri1(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
  322. /**
  323. * @brief Get permission settings bits for PERIBUS1 split mgmt. Only PERIBUS1 memory types allowed
  324. *
  325. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  326. * @param lw Low segment Write permission flag
  327. * @param lr Low segment Read permission flag
  328. * @param hw High segment Write permission flag
  329. * @param hr High segment Read permission flag
  330. */
  331. void esp_memprot_get_perm_split_bits_peri1(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
  332. /**
  333. * @brief Get permission settings bits for PERIBUS2 split mgmt. Only PERIBUS2 memory types allowed
  334. *
  335. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  336. * @param lw Low segment Write permission flag
  337. * @param lr Low segment Read permission flag
  338. * @param lx Low segment Execute permission flag
  339. * @param hw High segment Write permission flag
  340. * @param hr High segment Read permission flag
  341. * @param hx High segment Execute permission flag
  342. */
  343. void esp_memprot_get_perm_split_bits_peri2(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
  344. /**
  345. * @brief Sets permissions for high and low memory segment in PERIBUS2 region
  346. *
  347. * Sets Read Write permission for both low and high memory segments given by splitting address.
  348. * Applicable only to PERIBUS2 memory types
  349. *
  350. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  351. * @param split_addr Address to split the memory region to lower and higher segment
  352. * @param lw Low segment Write permission flag
  353. * @param lr Low segment Read permission flag
  354. * @param lx Low segment Execute permission flag
  355. * @param hw High segment Write permission flag
  356. * @param hr High segment Read permission flag
  357. * @param hx High segment Execute permission flag
  358. */
  359. void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
  360. /**
  361. * @brief Get permissions for specified memory type. Irrelevant bits are ignored
  362. *
  363. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  364. * @param lw Low segment Write permission flag
  365. * @param lr Low segment Read permission flag
  366. * @param lx Low segment Execute permission flag
  367. * @param hw High segment Write permission flag
  368. * @param hr High segment Read permission flag
  369. * @param hx High segment Execute permission flag
  370. */
  371. void esp_memprot_get_permissions(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
  372. /**
  373. * @brief Get Read permission settings for low and high regions of given memory type
  374. *
  375. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  376. * @param lr Low segment Read permission flag
  377. * @param hr High segment Read permission flag
  378. */
  379. void esp_memprot_get_perm_read(mem_type_prot_t mem_type, bool *lr, bool *hr);
  380. /**
  381. * @brief Get Write permission settings for low and high regions of given memory type
  382. *
  383. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  384. * @param lr Low segment Write permission flag
  385. * @param hr High segment Write permission flag
  386. */
  387. void esp_memprot_get_perm_write(mem_type_prot_t mem_type, bool *lw, bool *hw);
  388. /**
  389. * @brief Get Execute permission settings for low and high regions of given memory type
  390. * Applicable only to IBUS-compatible memory types
  391. *
  392. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  393. * @param lr Low segment Exec permission flag
  394. * @param hr High segment Exec permission flag
  395. */
  396. void esp_memprot_get_perm_exec(mem_type_prot_t mem_type, bool *lx, bool *hx);
  397. /**
  398. * @brief Returns the lowest address in required memory region
  399. *
  400. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  401. */
  402. uint32_t esp_memprot_get_low_limit(mem_type_prot_t mem_type);
  403. /**
  404. * @brief Returns the highest address in required memory region
  405. *
  406. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  407. */
  408. uint32_t esp_memprot_get_high_limit(mem_type_prot_t mem_type);
  409. /**
  410. * @brief Sets READ permission bit for required memory region
  411. *
  412. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  413. * @param lr Low segment Read permission flag
  414. * @param hr High segment Read permission flag
  415. */
  416. void esp_memprot_set_read_perm(mem_type_prot_t mem_type, bool lr, bool hr);
  417. /**
  418. * @brief Sets WRITE permission bit for required memory region
  419. *
  420. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  421. * @param lr Low segment Write permission flag
  422. * @param hr High segment Write permission flag
  423. */
  424. void esp_memprot_set_write_perm(mem_type_prot_t mem_type, bool lw, bool hw);
  425. /**
  426. * @brief Sets EXECUTE permission bit for required memory region
  427. *
  428. * @param mem_type Memory protection area type (see mem_type_prot_t enum)
  429. * @param lr Low segment Exec permission flag
  430. * @param hr High segment Exec permission flag
  431. */
  432. void esp_memprot_set_exec_perm(mem_type_prot_t mem_type, bool lx, bool hx);
  433. #ifdef __cplusplus
  434. }
  435. #endif