From 82ee8403b62ab5258c11dd80776250961f18b100 Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 13 Feb 2023 19:12:44 +0800 Subject: [PATCH] mmu: mmu_hal_check_valid_ext_vaddr_region --- .../bootloader_flash/src/bootloader_flash.c | 2 +- components/hal/cache_hal.c | 3 ++- components/hal/esp32/include/hal/mmu_ll.h | 21 +++++++++++++------ components/hal/esp32c2/include/hal/mmu_ll.h | 15 +++++++++++-- components/hal/esp32c3/include/hal/mmu_ll.h | 15 +++++++++++-- components/hal/esp32c6/include/hal/mmu_ll.h | 4 +++- components/hal/esp32h2/include/hal/mmu_ll.h | 4 +++- components/hal/esp32h4/include/hal/mmu_ll.h | 15 +++++++++++-- components/hal/esp32s2/include/hal/mmu_ll.h | 16 ++++++++------ components/hal/esp32s3/include/hal/mmu_ll.h | 15 +++++++++++-- components/hal/include/hal/mmu_hal.h | 14 +++++++++++++ components/hal/include/hal/mmu_types.h | 8 +++---- components/hal/mmu_hal.c | 11 +++++++--- 13 files changed, 112 insertions(+), 31 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 6cd8fbf0fd..bfa0f3097b 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -180,7 +180,7 @@ const void *bootloader_mmap(uint32_t src_paddr, uint32_t size) * Now simply check if it's valid vaddr, didn't check if it's readable, writable or executable. * TODO: IDF-4710 */ - if (mmu_ll_check_valid_ext_vaddr_region(0, MMU_BLOCK0_VADDR, size_after_paddr_aligned) == 0) { + if (mmu_ll_check_valid_ext_vaddr_region(0, MMU_BLOCK0_VADDR, size_after_paddr_aligned, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION) == 0) { ESP_EARLY_LOGE(TAG, "vaddr not valid"); return NULL; } diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index db7db4b573..41a58666e0 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.c @@ -12,6 +12,7 @@ #include "hal/cache_hal.h" #include "hal/cache_types.h" #include "hal/cache_ll.h" +#include "hal/mmu_hal.h" #include "hal/mmu_ll.h" #include "soc/soc_caps.h" @@ -117,6 +118,6 @@ void cache_hal_enable(cache_type_t type) void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size) { //Now only esp32 has 2 MMUs, this file doesn't build on esp32 - HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(0, vaddr, size)); + HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(0, vaddr, size, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION)); Cache_Invalidate_Addr(vaddr, size); } diff --git a/components/hal/esp32/include/hal/mmu_ll.h b/components/hal/esp32/include/hal/mmu_ll.h index 8d0dfd10d2..8a572a5455 100644 --- a/components/hal/esp32/include/hal/mmu_ll.h +++ b/components/hal/esp32/include/hal/mmu_ll.h @@ -86,21 +86,30 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; uint32_t vaddr_end = vaddr_start + len - 1; + bool valid = false; - return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || - (ADDRESS_IN_IRAM1_CACHE(vaddr_start) && ADDRESS_IN_IRAM1_CACHE(vaddr_end)) || - (ADDRESS_IN_IROM0_CACHE(vaddr_start) && ADDRESS_IN_IROM0_CACHE(vaddr_end)) || - (ADDRESS_IN_DRAM1_CACHE(vaddr_start) && ADDRESS_IN_DRAM1_CACHE(vaddr_end)) || - (ADDRESS_IN_DROM0_CACHE(vaddr_start) && ADDRESS_IN_DROM0_CACHE(vaddr_end)); + if (type & MMU_VADDR_DATA) { + valid |= (ADDRESS_IN_DRAM1_CACHE(vaddr_start) && ADDRESS_IN_DRAM1_CACHE(vaddr_end)) || + (ADDRESS_IN_DROM0_CACHE(vaddr_start) && ADDRESS_IN_DROM0_CACHE(vaddr_end)); + } + + if (type & MMU_VADDR_INSTRUCTION) { + valid |= (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || + (ADDRESS_IN_IRAM1_CACHE(vaddr_start) && ADDRESS_IN_IRAM1_CACHE(vaddr_end)) || + (ADDRESS_IN_IROM0_CACHE(vaddr_start) && ADDRESS_IN_IROM0_CACHE(vaddr_end)); + } + + return valid; } /** diff --git a/components/hal/esp32c2/include/hal/mmu_ll.h b/components/hal/esp32c2/include/hal/mmu_ll.h index 572d79aa00..eaf4a1bb78 100644 --- a/components/hal/esp32c2/include/hal/mmu_ll.h +++ b/components/hal/esp32c2/include/hal/mmu_ll.h @@ -84,16 +84,27 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; uint32_t vaddr_end = vaddr_start + len - 1; - return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + bool valid = false; + + if (type & MMU_VADDR_INSTRUCTION) { + valid |= (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)); + } + + if (type & MMU_VADDR_DATA) { + valid |= (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + } + + return valid; } /** diff --git a/components/hal/esp32c3/include/hal/mmu_ll.h b/components/hal/esp32c3/include/hal/mmu_ll.h index 62ed027c55..4e4440ee03 100644 --- a/components/hal/esp32c3/include/hal/mmu_ll.h +++ b/components/hal/esp32c3/include/hal/mmu_ll.h @@ -85,16 +85,27 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; uint32_t vaddr_end = vaddr_start + len - 1; - return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + bool valid = false; + + if (type & MMU_VADDR_INSTRUCTION) { + valid |= (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)); + } + + if (type & MMU_VADDR_DATA) { + valid |= (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + } + + return valid; } /** diff --git a/components/hal/esp32c6/include/hal/mmu_ll.h b/components/hal/esp32c6/include/hal/mmu_ll.h index 6bdd0db22d..89096800fb 100644 --- a/components/hal/esp32c6/include/hal/mmu_ll.h +++ b/components/hal/esp32c6/include/hal/mmu_ll.h @@ -92,14 +92,16 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; + (void)type; uint32_t vaddr_end = vaddr_start + len; return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); } diff --git a/components/hal/esp32h2/include/hal/mmu_ll.h b/components/hal/esp32h2/include/hal/mmu_ll.h index a01c324676..22b97d3db5 100644 --- a/components/hal/esp32h2/include/hal/mmu_ll.h +++ b/components/hal/esp32h2/include/hal/mmu_ll.h @@ -95,14 +95,16 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; + (void)type; uint32_t vaddr_end = vaddr_start + len; return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); } diff --git a/components/hal/esp32h4/include/hal/mmu_ll.h b/components/hal/esp32h4/include/hal/mmu_ll.h index c17910716f..45ad59928f 100644 --- a/components/hal/esp32h4/include/hal/mmu_ll.h +++ b/components/hal/esp32h4/include/hal/mmu_ll.h @@ -85,16 +85,27 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; uint32_t vaddr_end = vaddr_start + len - 1; - return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + bool valid = false; + + if (type & MMU_VADDR_INSTRUCTION) { + valid |= (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)); + } + + if (type & MMU_VADDR_DATA) { + valid |= (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + } + + return valid; } /** diff --git a/components/hal/esp32s2/include/hal/mmu_ll.h b/components/hal/esp32s2/include/hal/mmu_ll.h index a9017f8430..6c067dd1ae 100644 --- a/components/hal/esp32s2/include/hal/mmu_ll.h +++ b/components/hal/esp32s2/include/hal/mmu_ll.h @@ -85,23 +85,27 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; uint32_t vaddr_end = vaddr_start + len - 1; + bool valid = false; - //DROM0 is an alias of the IBUS2 - bool on_ibus = ((vaddr_start >= DROM0_ADDRESS_LOW) && (vaddr_end < DROM0_ADDRESS_HIGH)) || - ((vaddr_start >= IRAM0_CACHE_ADDRESS_LOW) && (vaddr_end < IRAM1_ADDRESS_HIGH)); + if (type & MMU_VADDR_DATA) { + valid |= ((vaddr_start >= DROM0_ADDRESS_LOW) && (vaddr_end < DROM0_ADDRESS_HIGH)) || ((vaddr_start >= DPORT_CACHE_ADDRESS_LOW) && (vaddr_end < DRAM0_CACHE_ADDRESS_HIGH)); + } - bool on_dbus = (vaddr_start >= DPORT_CACHE_ADDRESS_LOW) && (vaddr_end < DRAM0_CACHE_ADDRESS_HIGH); + if (type & MMU_VADDR_INSTRUCTION) { + valid |= ((vaddr_start >= IRAM0_CACHE_ADDRESS_LOW) && (vaddr_end < IRAM1_ADDRESS_HIGH)); + } - return (on_ibus || on_dbus); + return valid; } /** diff --git a/components/hal/esp32s3/include/hal/mmu_ll.h b/components/hal/esp32s3/include/hal/mmu_ll.h index aaa51bd7e7..04186dd3d8 100644 --- a/components/hal/esp32s3/include/hal/mmu_ll.h +++ b/components/hal/esp32s3/include/hal/mmu_ll.h @@ -85,16 +85,27 @@ static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size) * @param mmu_id MMU ID * @param vaddr_start start of the virtual address * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` * * @return * True for valid */ __attribute__((always_inline)) -static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len) +static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) { (void)mmu_id; uint32_t vaddr_end = vaddr_start + len - 1; - return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + bool valid = false; + + if (type & MMU_VADDR_INSTRUCTION) { + valid |= (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)); + } + + if (type & MMU_VADDR_DATA) { + valid |= (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); + } + + return valid; } /** diff --git a/components/hal/include/hal/mmu_hal.h b/components/hal/include/hal/mmu_hal.h index bd1287f1f4..13a611e105 100644 --- a/components/hal/include/hal/mmu_hal.h +++ b/components/hal/include/hal/mmu_hal.h @@ -99,6 +99,20 @@ bool mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_paddr */ bool mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target, mmu_vaddr_t type, uint32_t *out_vaddr); + +/** + * Check if the vaddr region is valid + * + * @param mmu_id MMU ID + * @param vaddr_start start of the virtual address + * @param len length, in bytes + * @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t` + * + * @return + * True for valid + */ +bool mmu_hal_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type); + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/mmu_types.h b/components/hal/include/hal/mmu_types.h index 2f4562b686..ea41a8e1f7 100644 --- a/components/hal/include/hal/mmu_types.h +++ b/components/hal/include/hal/mmu_types.h @@ -24,18 +24,18 @@ typedef enum { * MMU Page size */ typedef enum { - MMU_PAGE_8KB = 0x2000, + MMU_PAGE_8KB = 0x2000, MMU_PAGE_16KB = 0x4000, MMU_PAGE_32KB = 0x8000, MMU_PAGE_64KB = 0x10000, } mmu_page_size_t; /** - * MMU virtual address type + * MMU virtual address flags type */ typedef enum { - MMU_VADDR_DATA, - MMU_VADDR_INSTRUCTION, + MMU_VADDR_DATA = BIT(0), + MMU_VADDR_INSTRUCTION = BIT(1), } mmu_vaddr_t; /** diff --git a/components/hal/mmu_hal.c b/components/hal/mmu_hal.c index d619ce5cb2..d6101599ad 100644 --- a/components/hal/mmu_hal.c +++ b/components/hal/mmu_hal.c @@ -67,7 +67,7 @@ void mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr, HAL_ASSERT(vaddr % page_size_in_bytes == 0); HAL_ASSERT(paddr % page_size_in_bytes == 0); HAL_ASSERT(mmu_ll_check_valid_paddr_region(mmu_id, paddr, len)); - HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr, len)); + HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(mmu_id, vaddr, len, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION)); uint32_t page_num = (len + page_size_in_bytes - 1) / page_size_in_bytes; uint32_t entry_id = 0; @@ -89,7 +89,7 @@ void mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len) { uint32_t page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1); HAL_ASSERT(vaddr % page_size_in_bytes == 0); - HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr, len)); + HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(mmu_id, vaddr, len, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION)); uint32_t page_num = (len + page_size_in_bytes - 1) / page_size_in_bytes; uint32_t entry_id = 0; @@ -103,7 +103,7 @@ void mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len) bool mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_paddr, mmu_target_t *out_target) { - HAL_ASSERT(mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr, 1)); + HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(mmu_id, vaddr, 1, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION)); uint32_t entry_id = mmu_ll_get_entry_id(mmu_id, vaddr); if (!mmu_ll_check_entry_valid(mmu_id, entry_id)) { return false; @@ -139,3 +139,8 @@ bool mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target return true; } + +bool mmu_hal_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type) +{ + return mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr_start, len, type); +}