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 <adithya.nagaraj.baglody@intel.com>
This commit is contained in:
Adithya Baglody 2018-09-19 11:20:09 +05:30 committed by Anas Nashif
commit ae92f2badf
4 changed files with 71 additions and 12 deletions

View file

@ -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; \

View file

@ -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),)
{

View file

@ -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)

View file

@ -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 */
}
}