99#include <sys/param.h>
1010#include <sys/queue.h>
1111#include <inttypes.h>
12+ #include <sys/lock.h>
1213#include "sdkconfig.h"
1314#include "esp_attr.h"
1415#include "esp_log.h"
@@ -106,6 +107,10 @@ typedef struct {
106107 * Only the first `num_regions` items are valid
107108 */
108109 mem_region_t mem_regions [SOC_MMU_LINEAR_ADDRESS_REGION_NUM ];
110+ /**
111+ * driver layer mutex lock
112+ */
113+ _lock_t mutex ;
109114} mmu_ctx_t ;
110115
111116static mmu_ctx_t s_mmu_ctx ;
@@ -443,17 +448,15 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target,
443448 ESP_RETURN_ON_FALSE ((paddr_start % CONFIG_MMU_PAGE_SIZE == 0 ), ESP_ERR_INVALID_ARG , TAG , "paddr must be rounded up to the nearest multiple of CONFIG_MMU_PAGE_SIZE" );
444449 ESP_RETURN_ON_ERROR (s_mem_caps_check (caps ), TAG , "invalid caps" );
445450
451+ _lock_acquire (& s_mmu_ctx .mutex );
452+ mem_block_t * dummy_head = NULL ;
453+ mem_block_t * dummy_tail = NULL ;
446454 size_t aligned_size = ALIGN_UP_BY (size , CONFIG_MMU_PAGE_SIZE );
447455 int32_t found_region_id = s_find_available_region (s_mmu_ctx .mem_regions , s_mmu_ctx .num_regions , aligned_size , caps , target );
448- if (found_region_id == -1 ) {
449- ESP_EARLY_LOGE (TAG , "no such vaddr range" );
450- return ESP_ERR_NOT_FOUND ;
451- }
456+ ESP_GOTO_ON_FALSE (found_region_id != -1 , ESP_ERR_NOT_FOUND , err , TAG , "no such vaddr range" );
452457
453458 //Now we're sure we can find an available block inside a certain region
454459 mem_region_t * found_region = & s_mmu_ctx .mem_regions [found_region_id ];
455- mem_block_t * dummy_head = NULL ;
456- mem_block_t * dummy_tail = NULL ;
457460 mem_block_t * new_block = NULL ;
458461
459462 if (TAILQ_EMPTY (& found_region -> mem_block_head )) {
@@ -502,7 +505,6 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target,
502505 }
503506
504507 if (is_enclosed ) {
505- ESP_LOGW (TAG , "paddr block is mapped already, vaddr_start: %p, size: 0x%x" , (void * )mem_block -> vaddr_start , mem_block -> size );
506508 /*
507509 * This condition is triggered when `s_is_enclosed` is true and hence
508510 * we are sure that `paddr_start` >= `mem_block->paddr_start`.
@@ -512,12 +514,11 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target,
512514 */
513515 const uint32_t new_paddr_offset = paddr_start - mem_block -> paddr_start ;
514516 * out_ptr = (void * )mem_block -> vaddr_start + new_paddr_offset ;
515- return ESP_ERR_INVALID_STATE ;
517+ ESP_GOTO_ON_FALSE (false, ESP_ERR_INVALID_STATE , err , TAG , "paddr block is mapped already, vaddr_start: %p, size: 0x%x" , ( void * ) mem_block -> vaddr_start , mem_block -> size ) ;
516518 }
517519
518520 if (!allow_overlap && is_overlapped ) {
519- ESP_LOGE (TAG , "paddr block is overlapped with an already mapped paddr block" );
520- return ESP_ERR_INVALID_ARG ;
521+ ESP_GOTO_ON_FALSE (false, ESP_ERR_INVALID_ARG , err , TAG , "paddr block is overlapped with an already mapped paddr block" );
521522 }
522523#endif //#if ENABLE_PADDR_CHECK
523524
@@ -552,7 +553,6 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target,
552553 assert (found );
553554 //insert the to-be-mapped new block to the list
554555 TAILQ_INSERT_BEFORE (found_block , new_block , entries );
555-
556556 //Finally, we update the max_slot_size
557557 found_region -> max_slot_size = max_slot_len ;
558558
@@ -574,6 +574,7 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target,
574574 //do mapping
575575 s_do_mapping (target , new_block -> vaddr_start , paddr_start , aligned_size );
576576 * out_ptr = (void * )new_block -> vaddr_start ;
577+ _lock_release (& s_mmu_ctx .mutex );
577578
578579 return ESP_OK ;
579580
@@ -584,6 +585,7 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target,
584585 if (dummy_head ) {
585586 free (dummy_head );
586587 }
588+ _lock_release (& s_mmu_ctx .mutex );
587589
588590 return ret ;
589591}
@@ -626,19 +628,21 @@ esp_err_t esp_mmu_unmap(void *ptr)
626628{
627629 ESP_RETURN_ON_FALSE (ptr , ESP_ERR_INVALID_ARG , TAG , "null pointer" );
628630
631+ esp_err_t ret = ESP_FAIL ;
629632 mem_region_t * region = NULL ;
630633 mem_block_t * mem_block = NULL ;
631634 uint32_t ptr_laddr = mmu_ll_vaddr_to_laddr ((uint32_t )ptr );
632635 size_t slot_len = 0 ;
633636
637+ _lock_acquire (& s_mmu_ctx .mutex );
634638 for (int i = 0 ; i < s_mmu_ctx .num_regions ; i ++ ) {
635639 ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE ("-Wanalyzer-out-of-bounds" )
636640 if (ptr_laddr >= s_mmu_ctx .mem_regions [i ].free_head && ptr_laddr < s_mmu_ctx .mem_regions [i ].end ) {
637641 region = & s_mmu_ctx .mem_regions [i ];
638642 }
639643 ESP_COMPILER_DIAGNOSTIC_POP ("-Wanalyzer-out-of-bounds" )
640644 }
641- ESP_RETURN_ON_FALSE (region , ESP_ERR_NOT_FOUND , TAG , "munmap target pointer is outside external memory regions" );
645+ ESP_GOTO_ON_FALSE (region , ESP_ERR_NOT_FOUND , err , TAG , "munmap target pointer is outside external memory regions" );
642646
643647 bool found = false;
644648 mem_block_t * found_block = NULL ;
@@ -659,15 +663,23 @@ esp_err_t esp_mmu_unmap(void *ptr)
659663 }
660664 }
661665
662- ESP_RETURN_ON_FALSE (found , ESP_ERR_NOT_FOUND , TAG , "munmap target pointer isn't mapped yet" );
666+ if (found ) {
667+ TAILQ_REMOVE (& region -> mem_block_head , found_block , entries );
668+ }
669+ ESP_GOTO_ON_FALSE (found , ESP_ERR_NOT_FOUND , err , TAG , "munmap target pointer isn't mapped yet" );
663670
664671 //do unmap
665672 s_do_unmapping (mem_block -> vaddr_start , mem_block -> size );
666- //remove the already unmapped block from the list
667- TAILQ_REMOVE (& region -> mem_block_head , found_block , entries );
668673 free (found_block );
669674
675+ _lock_release (& s_mmu_ctx .mutex );
676+
670677 return ESP_OK ;
678+
679+ err :
680+
681+ _lock_release (& s_mmu_ctx .mutex );
682+ return ret ;
671683}
672684
673685esp_err_t esp_mmu_map_dump_mapped_blocks (FILE * stream )
0 commit comments