From ae92f2badf0d86359011c249fbe248056d661851 Mon Sep 17 00:00:00 2001 From: Adithya Baglody Date: Wed, 19 Sep 2018 11:20:09 +0530 Subject: [PATCH] subsys: app_memory: Fixed the size calculation for power of 2 MPUs The size calculation for power of 2 MPUs were incorrect. The calculation was not taking into account the amount of padding the linker does when doing the required alignment. Hence the size being calculated was completely incorrect. With this patch the code now is optimized and the size of partitions is now provided by the linker. Signed-off-by: Adithya Baglody --- include/app_memory/app_memdomain.h | 17 +++++++++ include/arch/arm/cortex_m/scripts/linker.ld | 12 ++++--- scripts/gen_app_partitions.py | 38 ++++++++++++++++----- subsys/app_memory/app_memdomain.c | 16 +++++++++ 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/include/app_memory/app_memdomain.h b/include/app_memory/app_memdomain.h index bea1527843d..62a8eaba36b 100644 --- a/include/app_memory/app_memdomain.h +++ b/include/app_memory/app_memdomain.h @@ -55,7 +55,11 @@ struct app_region { char *dmem_start; char *bmem_start; +#ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT + char *smem_size; +#else u32_t smem_size; +#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */ u32_t dmem_size; u32_t bmem_size; struct k_mem_partition *partition; @@ -66,9 +70,21 @@ struct app_region { * Declares a partition and provides a function to add the * partition to the linke dlist and initialize the partition. */ +#ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT +/* For power of 2 MPUs linker provides support to help us + * calculate the region sizes. + */ +#define smem_size_declare(name) extern char data_smem_##name##_size[] +#define smem_size_assign(name) name.smem_size = data_smem_##name##_size +#else +#define smem_size_declare(name) +#define smem_size_assign(name) +#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */ + #define appmem_partition(name) \ extern char *data_smem_##name; \ extern char *data_smem_##name##b; \ + smem_size_declare(name); \ _app_dmem_pad(name) char name##_dmem_pad; \ _app_bmem_pad(name) char name##_bmem_pad; \ __kernel struct k_mem_partition mem_domain_##name; \ @@ -77,6 +93,7 @@ struct app_region { { \ name.dmem_start = (char *)&data_smem_##name; \ name.bmem_start = (char *)&data_smem_##name##b; \ + smem_size_assign(name); \ sys_dlist_append(&app_mem_list, &name.lnode); \ mem_domain_##name.start = (u32_t) name.dmem_start; \ mem_domain_##name.attr = K_MEM_PARTITION_P_RW_U_RW; \ diff --git a/include/arch/arm/cortex_m/scripts/linker.ld b/include/arch/arm/cortex_m/scripts/linker.ld index 5c8635800f1..3c6730df41c 100644 --- a/include/arch/arm/cortex_m/scripts/linker.ld +++ b/include/arch/arm/cortex_m/scripts/linker.ld @@ -236,22 +236,26 @@ SECTIONS #endif #include + +#if defined(CONFIG_APP_SHARED_MEM) +#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) + #include +#else SECTION_PROLOGUE(_APP_SMEM_SECTION_NAME, (OPTIONAL),) { . = ALIGN(4); _image_ram_start = .; _app_smem_start = .; -#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) - #include -#else APP_SMEM_SECTION() -#endif _app_smem_end = .; _app_smem_size = _app_smem_end - _app_smem_start; . = ALIGN(4); } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */ _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); +#endif /* CONFIG_APP_SHARED_MEM */ + #ifdef CONFIG_APPLICATION_MEMORY SECTION_DATA_PROLOGUE(_APP_DATA_SECTION_NAME, (OPTIONAL),) { diff --git a/scripts/gen_app_partitions.py b/scripts/gen_app_partitions.py index 6bac8c0c0b2..528490bbe7f 100644 --- a/scripts/gen_app_partitions.py +++ b/scripts/gen_app_partitions.py @@ -11,13 +11,31 @@ from elftools.elf.elffile import ELFFile # This script will create linker comands for power of two aligned MPU # when APP_SHARED_MEM is enabled. print_template = """ -/* Auto generated code do not modify */ -. = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0})); -data_smem_{0} = .; -KEEP(*(SORT(data_smem_{0}*))) -. = ALIGN(_app_data_align); -data_smem_{0}b_end = .; -. = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0})); + /* Auto generated code do not modify */ + . = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0})); + data_smem_{0} = .; + KEEP(*(SORT(data_smem_{0}*))) + . = ALIGN(_app_data_align); + . = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0})); + data_smem_{0}b_end = .; +""" +linker_start_seq = """ + SECTION_PROLOGUE(_APP_SMEM_SECTION_NAME, (OPTIONAL),) + { + . = ALIGN(4); + _image_ram_start = .; + _app_smem_start = .; +""" + +linker_end_seq = """ + _app_smem_end = .; + _app_smem_size = _app_smem_end - _app_smem_start; + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +""" + +size_cal_string = """ + data_smem_{0}_size = data_smem_{0}b_end - data_smem_{0}; """ @@ -46,10 +64,14 @@ def cleanup_remove_bss_regions(full_list_of_partitions): return full_list_of_partitions def generate_final_linker(linker_file, full_list_of_partitions): - string= '' + string = linker_start_seq + size_string = '' for partition in full_list_of_partitions: string += print_template.format(partition) + size_string += size_cal_string.format(partition) + string += linker_end_seq + string += size_string with open(linker_file, "w") as fw: fw.write(string) diff --git a/subsys/app_memory/app_memdomain.c b/subsys/app_memory/app_memdomain.c index c089c1633c5..121cdb163f1 100644 --- a/subsys/app_memory/app_memdomain.c +++ b/subsys/app_memory/app_memdomain.c @@ -37,6 +37,7 @@ void app_calc_size(void) SYS_DLIST_FOR_EACH_NODE_SAFE(&app_mem_list, node, next_node) { +#ifndef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT if (sys_dlist_is_tail(&app_mem_list, node)) { struct app_region *region = CONTAINER_OF(node, struct app_region, lnode); @@ -67,6 +68,21 @@ void app_calc_size(void) region->partition[0].size = region->dmem_size + region->bmem_size; } + +#else + /* For power of 2 MPUs linker provides support to help us + * calculate the region sizes. + */ + struct app_region *region = + CONTAINER_OF(node, struct app_region, lnode); + + region->dmem_size = (char *)region->bmem_start - + (char *)region->dmem_start; + region->bmem_size = (char *)region->smem_size - + (char *)region->dmem_size; + + region->partition[0].size = (s32_t)region->smem_size; +#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */ } }