Skip to content

Commit

Permalink
subsys: app_memory: Fixed the size calculation for power of 2 MPUs
Browse files Browse the repository at this point in the history
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 <adithya.nagaraj.baglody@intel.com>
  • Loading branch information
AdithyaBaglody authored and nashif committed Sep 20, 2018
1 parent 7e273b2 commit ae92f2b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 12 deletions.
17 changes: 17 additions & 0 deletions include/app_memory/app_memdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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; \
Expand All @@ -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; \
Expand Down
12 changes: 8 additions & 4 deletions include/arch/arm/cortex_m/scripts/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -236,22 +236,26 @@ SECTIONS
#endif

#include <app_data_alignment.ld>

#if defined(CONFIG_APP_SHARED_MEM)
#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#include <app_smem.ld>
#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 <app_smem.ld>
#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),)
{
Expand Down
38 changes: 30 additions & 8 deletions scripts/gen_app_partitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,31 @@
# 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};
"""


Expand Down Expand Up @@ -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)

Expand Down
16 changes: 16 additions & 0 deletions subsys/app_memory/app_memdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
}
}

Expand Down

0 comments on commit ae92f2b

Please sign in to comment.