diff --git a/drivers/mm/Kconfig b/drivers/mm/Kconfig index f53312b847036..001dd2bb9fa7b 100644 --- a/drivers/mm/Kconfig +++ b/drivers/mm/Kconfig @@ -44,6 +44,13 @@ config MM_DRV_INTEL_ADSP_TLB Driver for the translation lookup buffer on Intel Audio DSP hardware. +config MM_DRV_INTEL_VIRTUAL_REGION_COUNT + int "Maximum number of regions defined in virtual memory" + depends on MM_DRV_INTEL_ADSP_MTL_TLB + default 1 + help + This options defines a table size keeping all virtual memory region + config EXTERNAL_ADDRESS_TRANSLATION bool "Support for external address translation modules" depends on !MMU diff --git a/drivers/mm/mm_drv_intel_adsp.h b/drivers/mm/mm_drv_intel_adsp.h index 133e5a2f9d150..040554d766c08 100644 --- a/drivers/mm/mm_drv_intel_adsp.h +++ b/drivers/mm/mm_drv_intel_adsp.h @@ -79,13 +79,4 @@ static inline uintptr_t tlb_entry_to_pa(uint16_t tlb_entry) CONFIG_MM_DRV_PAGE_SIZE) + TLB_PHYS_BASE); } -/** - * Calculate virtual memory regions allocation based on - * info from linker script. - * - * @param End address of staticaly allocated memory. - * @return Error Code. - */ -int calculate_memory_regions(uintptr_t static_alloc_end_ptr); - #endif /* ZEPHYR_DRIVERS_SYSTEM_MM_DRV_INTEL_MTL_ */ diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index e2c369cb90436..d6515b2ef34aa 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -62,6 +62,11 @@ SYS_MEM_BLOCKS_DEFINE_WITH_EXT_BUF( L2_SRAM_PAGES_NUM, (uint8_t *) L2_SRAM_BASE); +uintptr_t adsp_mm_get_unused_l2_start_aligned(void) +{ + return UNUSED_L2_START_ALIGNED; +} + /** * Calculate the index to the TLB table. * @@ -738,10 +743,6 @@ static int sys_mm_drv_mm_init(const struct device *dev) L2_PHYS_SRAM_REGION.info.num_blocks = avalible_memory_size / CONFIG_MM_DRV_PAGE_SIZE; - ret = calculate_memory_regions(UNUSED_L2_START_ALIGNED); - CHECKIF(ret != 0) { - return ret; - } /* * Initialize memblocks that will store physical * page usage. Initially all physical pages are diff --git a/drivers/mm/mm_drv_intel_adsp_regions.c b/drivers/mm/mm_drv_intel_adsp_regions.c index 05919a9fcde5c..c3e4b2206c62e 100644 --- a/drivers/mm/mm_drv_intel_adsp_regions.c +++ b/drivers/mm/mm_drv_intel_adsp_regions.c @@ -12,48 +12,50 @@ #include "mm_drv_intel_adsp.h" + +/* virtual memory regions table, last item is an end marker */ struct sys_mm_drv_region -virtual_memory_regions[CONFIG_MP_MAX_NUM_CPUS + VIRTUAL_REGION_COUNT] = { {0} }; +virtual_memory_regions[CONFIG_MM_DRV_INTEL_VIRTUAL_REGION_COUNT+1] = { {0} }; const struct sys_mm_drv_region *sys_mm_drv_query_memory_regions(void) { return (const struct sys_mm_drv_region *) virtual_memory_regions; } -static inline void append_region(void *address, uint32_t mem_size, - uint32_t attributes, uint32_t position, uint32_t *total_size) +int adsp_add_virtual_memory_region(uintptr_t region_address, uint32_t region_size, uint32_t attr) { - virtual_memory_regions[position].addr = address; - virtual_memory_regions[position].size = mem_size; - virtual_memory_regions[position].attr = attributes; - total_size += mem_size; -} + struct sys_mm_drv_region *region; + uint32_t pos = 0; + uintptr_t new_region_end = region_address + region_size; -int calculate_memory_regions(uintptr_t static_alloc_end_ptr) -{ - int i, total_size = 0; + /* check if the region fits to virtual memory */ + if (region_address < L2_VIRTUAL_SRAM_BASE || + new_region_end > L2_VIRTUAL_SRAM_BASE + L2_VIRTUAL_SRAM_SIZE) { + return -EINVAL; + } + + /* find an empty slot, verify if the region is not overlapping */ + SYS_MM_DRV_MEMORY_REGION_FOREACH(virtual_memory_regions, region) { + uintptr_t region_start = (uintptr_t)region->addr; + uintptr_t region_end = region_start + region->size; - for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { - append_region((void *)(static_alloc_end_ptr + i * CORE_HEAP_SIZE), - CORE_HEAP_SIZE, MEM_REG_ATTR_CORE_HEAP, i, &total_size); + /* check region overlapping */ + if (region_address < region_end && new_region_end > region_start) { + return -EINVAL; + } + pos++; } - append_region((void *)((uintptr_t)virtual_memory_regions[i - 1].addr + - virtual_memory_regions[i - 1].size), - CORE_HEAP_SIZE, MEM_REG_ATTR_SHARED_HEAP, i, &total_size); - i++; - append_region((void *)((uintptr_t)virtual_memory_regions[i - 1].addr + - virtual_memory_regions[i - 1].size), - OPPORTUNISTIC_REGION_SIZE, MEM_REG_ATTR_OPPORTUNISTIC_MEMORY, i, &total_size); - i++; - /* Apending last region as 0 so iterators know where table is over - * check is for size = 0; - */ - append_region(NULL, 0, 0, i, &total_size); - - if (total_size > L2_VIRTUAL_SRAM_SIZE) { - return -EINVAL; + /* SYS_MM_DRV_MEMORY_REGION_FOREACH exits when an empty slot is found */ + if (pos == CONFIG_MM_DRV_INTEL_VIRTUAL_REGION_COUNT) { + /* no more free slots */ + return -ENOMEM; } + /* add new region */ + virtual_memory_regions[pos].addr = (void *)region_address; + virtual_memory_regions[pos].size = region_size; + virtual_memory_regions[pos].attr = attr; + return 0; } diff --git a/include/zephyr/drivers/mm/mm_drv_intel_adsp_mtl_tlb.h b/include/zephyr/drivers/mm/mm_drv_intel_adsp_mtl_tlb.h index 22f81098fbc9d..19ee066d74fbc 100644 --- a/include/zephyr/drivers/mm/mm_drv_intel_adsp_mtl_tlb.h +++ b/include/zephyr/drivers/mm/mm_drv_intel_adsp_mtl_tlb.h @@ -44,6 +44,11 @@ typedef uint32_t (*mm_get_storage_size)(void); */ void adsp_mm_restore_context(void *storage_buffer); +/* + * This procedure return a pointer to a first unused address in L2 virtual memory + */ +uintptr_t adsp_mm_get_unused_l2_start_aligned(void); + struct intel_adsp_tlb_api { mm_save_context save_context; mm_get_storage_size get_storage_size; diff --git a/soc/intel/intel_adsp/ace/include/adsp_memory_regions.h b/soc/intel/intel_adsp/ace/include/adsp_memory_regions.h index 912a225588b30..0c209037ad21b 100644 --- a/soc/intel/intel_adsp/ace/include/adsp_memory_regions.h +++ b/soc/intel/intel_adsp/ace/include/adsp_memory_regions.h @@ -6,22 +6,21 @@ #ifndef ZEPHYR_SOC_INTEL_ADSP_MEMORY_REGIONS_H_ #define ZEPHYR_SOC_INTEL_ADSP_MEMORY_REGIONS_H_ -/* Define amount of regions other than core heaps that virtual memory will be split to - * currently includes shared heap and oma region and one regions set to 0 as for table - * iterator end value. +/** + * Add a virtual memory region to the table + * + * @param virtual_address an address of a new region + * @param region_size a size of a new region + * @param attr an attribute of a new region, may not be unique + * + * @return 0 success + * @return -ENOMEM if there are no empty slots for virtual memory regions + * @return -EINVAL if virtual memory region overlaps with existing ones or exceeds memory size */ -#define VIRTUAL_REGION_COUNT 3 - -#define CORE_HEAP_SIZE 0x100000 -#define SHARED_HEAP_SIZE 0x100000 -#define OPPORTUNISTIC_REGION_SIZE 0x100000 +int adsp_add_virtual_memory_region(uintptr_t region_address, uint32_t region_size, uint32_t attr); /* size of TLB table */ #define TLB_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, intel_adsp_mtl_tlb), 0) -/* Attribiutes for memory regions */ -#define MEM_REG_ATTR_CORE_HEAP 1U -#define MEM_REG_ATTR_SHARED_HEAP 2U -#define MEM_REG_ATTR_OPPORTUNISTIC_MEMORY 4U #endif /* ZEPHYR_SOC_INTEL_ADSP_MEMORY_REGIONS_H_ */