esp_mmu_map.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include "esp_err.h"
  10. #include "esp_bit_defs.h"
  11. #include "hal/mmu_types.h"
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. /**
  16. * MMU Memory Mapping Driver APIs for MMU supported memory
  17. *
  18. *
  19. * Driver Backgrounds:
  20. *
  21. * --------------------------------------------------------------------------------------------------------
  22. * Memory Pool |
  23. * --------------------------------------------------------------------------------------------------------
  24. * | Memory Region 0 | Memory Region 1 | ... |
  25. * --------------------------------------------------------------------------------------------------------
  26. * | Block 0 | Slot 0 | Block 1 | Block 2 | ... | Slot 1 (final slot) | ... |
  27. * --------------------------------------------------------------------------------------------------------
  28. *
  29. * - A memory pool stands for the whole virtual address range that can be mapped to physical memory
  30. * - A memory region is a range of virtual address with same attributes
  31. * - A block is a piece of vaddr range that is dynamically mapped.
  32. * - A Slot is the vaddr range between 2 blocks.
  33. */
  34. /**
  35. * MMAP flags
  36. */
  37. /**
  38. * @brief Share this mapping
  39. *
  40. * - If this flag is set, a paddr block can be mapped to multiple vaddr blocks.
  41. * 1. This happens when:
  42. * - the to-be-mapped paddr block is overlapped with an already mapped paddr block.
  43. * - the to-be-mapped paddr block encloses an already mapped paddr block.
  44. * 2. If the to-be-mapped paddr block is enclosed by an already mapped paddr block, no new mapping will happen, return ESP_ERR_INVALID_STATE. The out pointer will be the already mapped paddr corresponding vaddr.
  45. * 3. If the to-be-mapped paddr block is identical with an already mapped paddr block, no new mapping will happen, return ESP_ERR_INVALID_STATE. The out pointer will be the corresponding vaddr.
  46. *
  47. * - If this flag isn't set, overlapped, enclosed or same to-be-mapped paddr block will lead to ESP_ERR_INVALID_ARG.
  48. */
  49. #define ESP_MMU_MMAP_FLAG_PADDR_SHARED BIT(0)
  50. /**
  51. * @brief Physical memory type
  52. */
  53. typedef uint32_t esp_paddr_t;
  54. /**
  55. * @brief Map a physical memory block to external virtual address block, with given capabilities.
  56. *
  57. * @note This API does not guarantee thread safety
  58. *
  59. * @param[in] paddr_start Start address of the physical memory block
  60. * @param[in] size Size to be mapped. Size will be rounded up by to the nearest multiple of MMU page size
  61. * @param[in] target Physical memory target you're going to map to, see `mmu_target_t`
  62. * @param[in] caps Memory capabilities, see `mmu_mem_caps_t`
  63. * @param[in] flags Mmap flags
  64. * @param[out] out_ptr Start address of the mapped virtual memory
  65. *
  66. * @return
  67. * - ESP_OK
  68. * - ESP_ERR_INVALID_ARG: Invalid argument, see printed logs
  69. * - ESP_ERR_NOT_SUPPORTED: Only on ESP32, PSRAM is not a supported physical memory target
  70. * - ESP_ERR_NOT_FOUND: No enough size free block to use
  71. * - ESP_ERR_NO_MEM: Out of memory, this API will allocate some heap memory for internal usage
  72. * - ESP_ERR_INVALID_STATE: Paddr is mapped already, this API will return corresponding vaddr_start of the previously mapped block.
  73. * Only to-be-mapped paddr block is totally enclosed by a previously mapped block will lead to this error. (Identical scenario will behave similarly)
  74. * new_block_start new_block_end
  75. * |-------- New Block --------|
  76. * |--------------- Block ---------------|
  77. * block_start block_end
  78. *
  79. */
  80. esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target, mmu_mem_caps_t caps, int flags, void **out_ptr);
  81. /**
  82. * @brief Unmap a previously mapped virtual memory block
  83. *
  84. * @note This API does not guarantee thread safety
  85. *
  86. * @param[in] ptr Start address of the virtual memory
  87. *
  88. * @return
  89. * - ESP_OK
  90. * - ESP_ERR_INVALID_ARG: Null pointer
  91. * - ESP_ERR_NOT_FOUND: Vaddr is not in external memory, or it's not mapped yet
  92. */
  93. esp_err_t esp_mmu_unmap(void *ptr);
  94. /**
  95. * @brief Get largest consecutive free external virtual memory block size, with given capabilities and given physical target
  96. *
  97. * @param[in] caps Bitwise OR of MMU_MEM_CAP_* flags indicating the memory block
  98. * @param[in] target Physical memory target you're going to map to, see `mmu_target_t`.
  99. * @param[out] out_len Largest free block length, in bytes.
  100. *
  101. * @return
  102. * - ESP_OK
  103. * - ESP_ERR_INVALID_ARG: Invalid arguments, could be null pointer
  104. */
  105. esp_err_t esp_mmu_map_get_max_consecutive_free_block_size(mmu_mem_caps_t caps, mmu_target_t target, size_t *out_len);
  106. /**
  107. * Dump all the previously mapped blocks
  108. *
  109. * @note This API shall not be called from an ISR.
  110. * @note This API does not guarantee thread safety
  111. *
  112. * @param stream stream to print information to; use stdout or stderr to print
  113. * to the console; use fmemopen/open_memstream to print to a
  114. * string buffer.
  115. * @return
  116. * - ESP_OK
  117. */
  118. esp_err_t esp_mmu_map_dump_mapped_blocks(FILE* stream);
  119. /**
  120. * @brief Convert virtual address to physical address
  121. *
  122. * @param[in] vaddr Virtual address
  123. * @param[out] out_paddr Physical address
  124. * @param[out] out_target Physical memory target, see `mmu_target_t`
  125. *
  126. * @return
  127. * - ESP_OK
  128. * - ESP_ERR_INVALID_ARG: Null pointer, or vaddr is not within external memory
  129. * - ESP_ERR_NOT_FOUND: Vaddr is not mapped yet
  130. */
  131. esp_err_t esp_mmu_vaddr_to_paddr(void *vaddr, esp_paddr_t *out_paddr, mmu_target_t *out_target);
  132. /**
  133. * @brief Convert physical address to virtual address
  134. *
  135. * @param[in] paddr Physical address
  136. * @param[in] target Physical memory target, see `mmu_target_t`
  137. * @param[in] type Virtual address type, could be either instruction or data
  138. * @param[out] out_vaddr Virtual address
  139. *
  140. * @return
  141. * - ESP_OK
  142. * - ESP_ERR_INVALID_ARG: Null pointer
  143. * - ESP_ERR_NOT_FOUND: Paddr is not mapped yet
  144. */
  145. esp_err_t esp_mmu_paddr_to_vaddr(esp_paddr_t paddr, mmu_target_t target, mmu_vaddr_t type, void **out_vaddr);
  146. /**
  147. * @brief If the physical address is mapped, this API will provide the capabilities of the virtual address where the physical address is mapped to.
  148. *
  149. * @note: Only return value is ESP_OK(which means physically address is successfully mapped), then caps you get make sense.
  150. * @note This API only check one page (see CONFIG_MMU_PAGE_SIZE), starting from the `paddr`
  151. *
  152. * @param[in] paddr Physical address
  153. * @param[out] out_caps Bitwise OR of MMU_MEM_CAP_* flags indicating the capabilities of a virtual address where the physical address is mapped to.
  154. * @return
  155. * - ESP_OK: Physical address successfully mapped.
  156. * - ESP_ERR_INVALID_ARG: Null pointer
  157. * - ESP_ERR_NOT_FOUND: Physical address is not mapped successfully.
  158. */
  159. esp_err_t esp_mmu_paddr_find_caps(const esp_paddr_t paddr, mmu_mem_caps_t *out_caps);
  160. #ifdef __cplusplus
  161. }
  162. #endif