mmu_hal.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <sys/param.h>
  7. #include <stdint.h>
  8. #include <stdbool.h>
  9. #include "sdkconfig.h"
  10. #include "esp_err.h"
  11. #include "esp_attr.h"
  12. #include "hal/assert.h"
  13. #include "hal/mmu_hal.h"
  14. #include "hal/mmu_ll.h"
  15. #if CONFIG_IDF_TARGET_ESP32
  16. #include "esp32/rom/cache.h"
  17. #include "soc/dport_reg.h"
  18. #elif CONFIG_IDF_TARGET_ESP32S2
  19. #include "esp32s2/rom/cache.h"
  20. #elif CONFIG_IDF_TARGET_ESP32S3
  21. #include "esp32s3/rom/cache.h"
  22. #elif CONFIG_IDF_TARGET_ESP32C3
  23. #include "esp32c3/rom/cache.h"
  24. #elif CONFIG_IDF_TARGET_ESP32C2
  25. #include "esp32c2/rom/cache.h"
  26. #elif CONFIG_IDF_TARGET_ESP32H2
  27. #include "esp32h2/rom/cache.h"
  28. #endif
  29. void mmu_hal_init(void)
  30. {
  31. #if CONFIG_IDF_TARGET_ESP32
  32. mmu_init(0);
  33. #if !CONFIG_FREERTOS_UNICORE
  34. /**
  35. * The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are necessary to work around a hardware bug.
  36. * See ESP32 Errata 3.1
  37. */
  38. DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
  39. mmu_init(1);
  40. DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
  41. #endif
  42. #else //!esp32
  43. Cache_MMU_Init();
  44. #endif
  45. }
  46. #if !CONFIG_IDF_TARGET_ESP32
  47. //If decided, add a jira ticket for implementing these APIs on ESP32
  48. uint32_t mmu_hal_pages_to_bytes(uint32_t mmu_id, uint32_t page_num)
  49. {
  50. mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
  51. uint32_t shift_code = 0;
  52. switch (page_size) {
  53. case MMU_PAGE_64KB:
  54. shift_code = 16;
  55. break;
  56. case MMU_PAGE_32KB:
  57. shift_code = 15;
  58. break;
  59. case MMU_PAGE_16KB:
  60. shift_code = 14;
  61. break;
  62. default:
  63. HAL_ASSERT(shift_code);
  64. }
  65. return page_num << shift_code;
  66. }
  67. uint32_t mmu_hal_bytes_to_pages(uint32_t mmu_id, uint32_t bytes)
  68. {
  69. mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
  70. uint32_t shift_code = 0;
  71. switch (page_size) {
  72. case MMU_PAGE_64KB:
  73. shift_code = 16;
  74. break;
  75. case MMU_PAGE_32KB:
  76. shift_code = 15;
  77. break;
  78. case MMU_PAGE_16KB:
  79. shift_code = 14;
  80. break;
  81. default:
  82. HAL_ASSERT(shift_code);
  83. }
  84. return bytes >> shift_code;
  85. }
  86. void mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr, uint32_t paddr, uint32_t len, uint32_t *out_len)
  87. {
  88. uint32_t page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1);
  89. HAL_ASSERT(vaddr % page_size_in_bytes == 0);
  90. HAL_ASSERT(paddr % page_size_in_bytes == 0);
  91. HAL_ASSERT((paddr + len) <= mmu_hal_pages_to_bytes(mmu_id, MMU_MAX_ENTRY_NUM));
  92. HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr, len));
  93. uint32_t page_num = (len + page_size_in_bytes - 1) / page_size_in_bytes;
  94. uint32_t entry_id = 0;
  95. uint32_t mmu_val; //This is the physical address in the format that MMU supported
  96. *out_len = mmu_hal_pages_to_bytes(mmu_id, page_num);
  97. entry_id = mmu_ll_get_entry_id(mmu_id, vaddr);
  98. mmu_val = mmu_ll_format_paddr(mmu_id, paddr);
  99. while (page_num) {
  100. mmu_ll_write_entry(mmu_id, entry_id, mmu_val, mem_type);
  101. entry_id++;
  102. mmu_val++;
  103. page_num--;
  104. }
  105. }
  106. #endif //#if !CONFIG_IDF_TARGET_ESP32