From c253a686bf79b190bfeaac61f369d42773cd80fb Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Tue, 29 Jan 2019 12:56:02 -0800 Subject: [PATCH] app_shmem: auto-initialize partitions There are no longer per-partition initialization functions. Instead, we iterate over all of them at boot to set up the derived k_mem_partitions properly. Some ARC-specific hacks that should never have been applied have been removed from the userspace test. Signed-off-by: Andrew Boie --- doc/kernel/usermode/usermode_sharedmem.rst | 19 +-- include/app_memory/app_memdomain.h | 47 +++----- include/linker/common-rom.ld | 7 ++ include/linker/linker-defs.h | 2 +- samples/userspace/shared_mem/src/main.c | 5 - scripts/sanitycheck | 2 +- subsys/app_memory/app_memdomain.c | 110 +++++------------- tests/kernel/mem_protect/userspace/src/main.c | 18 --- 8 files changed, 53 insertions(+), 157 deletions(-) diff --git a/doc/kernel/usermode/usermode_sharedmem.rst b/doc/kernel/usermode/usermode_sharedmem.rst index babdb6d1e20..b4d63564856 100644 --- a/doc/kernel/usermode/usermode_sharedmem.rst +++ b/doc/kernel/usermode/usermode_sharedmem.rst @@ -42,13 +42,9 @@ The resulting section name can be seen in the linker.map as "data_smem_id" and "data_smem_idb". To create a k_mem_partition, call the macro K_APPMEM_PARTITION_DEFINE(part0) -where "part0" is the name then used to refer to that partition. -This macro only creates a function and necessary data structures for -the later "initialization". - -Once the partition is initialized, the standard memory domain APIs may -be used to add it to domains; the declared name is a k_mem_partition -symbol. +where "part0" is the name then used to refer to that partition. The +standard memory domain APIs may be used to add it to domains; the declared +name is a k_mem_partition symbol. Example: @@ -64,8 +60,6 @@ Example: int main() { - appmem_init_part_part0(); - appmem_init_app_memory(); k_mem_domain_init(&dom0, 0, NULL) k_mem_domain_add_partition(&dom0, part0); k_mem_domain_add_thread(&dom0, k_current_get()); @@ -80,10 +74,3 @@ app_macro_support.h: FOR_EACH(K_APPMEM_PARTITION_DEFINE, part0, part1, part2); -Similarly, the appmem_init_part_* can also be used in the macro: - -.. code-block:: c - - FOR_EACH(appmem_init_part, part0, part1, part2); - - diff --git a/include/app_memory/app_memdomain.h b/include/app_memory/app_memdomain.h index 65ceca38463..c7fa6cddad2 100644 --- a/include/app_memory/app_memdomain.h +++ b/include/app_memory/app_memdomain.h @@ -66,10 +66,7 @@ struct app_region { char *dmem_start; char *bmem_start; u32_t smem_size; - u32_t dmem_size; - u32_t bmem_size; struct k_mem_partition *partition; - sys_dnode_t lnode; }; /* @@ -81,10 +78,10 @@ struct app_region { * calculate the region sizes. */ #define smem_size_declare(name) extern char data_smem_##name##_size[] -#define smem_size_assign(name) name##_region.smem_size = (u32_t)&data_smem_##name##_size +#define smem_size_val(name) ((u32_t)&data_smem_##name##_size) #else #define smem_size_declare(name) -#define smem_size_assign(name) +#define smem_size_val(name) 0 #endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */ /** @@ -105,34 +102,16 @@ struct app_region { 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 name; \ - __kernel struct app_region name##_region; \ - static inline void appmem_init_part_##name(void) \ - { \ - name##_region.dmem_start = (char *)&data_smem_##name; \ - name##_region.bmem_start = (char *)&data_smem_##name##b; \ - smem_size_assign(name); \ - sys_dlist_append(&app_mem_list, &name##_region.lnode); \ - name.start = (u32_t) name##_region.dmem_start; \ - name.attr = K_MEM_PARTITION_P_RW_U_RW; \ - name##_region.partition = &name; \ - } - -/* - * The following allows the FOR_EACH macro to call each partition's - * appmem_init_part_##name . Note: semicolon needed or else compiler - * complains as semicolon needed for function call once expanded by - * macro. - */ -#define appmem_init_part(name) \ - appmem_init_part_##name(); - -extern sys_dlist_t app_mem_list; - -extern void app_bss_zero(void); - -extern void app_calc_size(void); - -extern void appmem_init_app_memory(void); + struct k_mem_partition name = { \ + .start = (u32_t) &data_smem_##name, \ + .attr = K_MEM_PARTITION_P_RW_U_RW \ + }; \ + _GENERIC_SECTION(.app_regions.name) \ + struct app_region name##_region = { \ + .dmem_start = (char *)&data_smem_##name, \ + .bmem_start = (char *)&data_smem_##name##b, \ + .smem_size = smem_size_val(name), \ + .partition = &name \ + }; #endif /* ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_ */ diff --git a/include/linker/common-rom.ld b/include/linker/common-rom.ld index aba1d0e5685..5384349c6f6 100644 --- a/include/linker/common-rom.ld +++ b/include/linker/common-rom.ld @@ -42,6 +42,13 @@ } #endif + SECTION_PROLOGUE(app_shmem_regions, (OPTIONAL),) + { + __app_shmem_regions_start = .; + KEEP(*(SORT(".app_regions.*"))); + __app_shmem_regions_end = .; + } GROUP_LINK_IN(ROMABLE_REGION) + SECTION_PROLOGUE (devconfig, (OPTIONAL),) { __devconfig_start = .; diff --git a/include/linker/linker-defs.h b/include/linker/linker-defs.h index 31f37812b45..1dbb3ccb826 100644 --- a/include/linker/linker-defs.h +++ b/include/linker/linker-defs.h @@ -116,7 +116,7 @@ #define APP_INPUT_SECTION(sect) *(MAYBE_EXCLUDE_SOME_FILES sect) #define KERNEL_INPUT_SECTION(sect) *(sect) -#define APP_SMEM_SECTION() KEEP(*(SORT(data_smem_[_a-zA-Z0-9]*))) +#define APP_SMEM_SECTION() KEEP(*(SORT("data_smem_*"))) #ifdef CONFIG_X86 /* LINKER FILES: defines used by linker script */ /* Should be moved to linker-common-defs.h */ diff --git a/samples/userspace/shared_mem/src/main.c b/samples/userspace/shared_mem/src/main.c index 2757eb15d25..90c1f445c45 100644 --- a/samples/userspace/shared_mem/src/main.c +++ b/samples/userspace/shared_mem/src/main.c @@ -105,12 +105,7 @@ void main(void) k_tid_t tPT, tENC, tCT; k_thread_access_grant(k_current_get(), &allforone); - /* initialize the partition structures */ - FOR_EACH(appmem_init_part, part0, part1, part2, part3, part4); - printk("init partitions complete\n"); - appmem_init_app_memory(); - printk("init app memory complete\n"); /* * create an enc thread init the memory domain and add partitions * then add the thread to the domain. diff --git a/scripts/sanitycheck b/scripts/sanitycheck index aa1d1668c97..bb3c6b0a21b 100755 --- a/scripts/sanitycheck +++ b/scripts/sanitycheck @@ -679,7 +679,7 @@ class SizeCalculator: "_k_memory_pool", "exceptions", "initshell", "_static_thread_area", "_k_timer_area", "_k_mem_slab_area", "_k_mem_pool_area", "sw_isr_table", - "_k_sem_area", "_k_mutex_area", + "_k_sem_area", "_k_mutex_area", "app_shmem_regions", "_k_fifo_area", "_k_lifo_area", "_k_stack_area", "_k_msgq_area", "_k_mbox_area", "_k_pipe_area", "net_if", "net_if_dev", "net_stack", "net_l2_data", diff --git a/subsys/app_memory/app_memdomain.c b/subsys/app_memory/app_memdomain.c index 121cdb163f1..200b91690a1 100644 --- a/subsys/app_memory/app_memdomain.c +++ b/subsys/app_memory/app_memdomain.c @@ -1,97 +1,43 @@ +#include +#include #include -#include -#include #include +#include -/* - * Initializes a double linked-list for the calculation of - * memory subsections. - */ -sys_dlist_t app_mem_list = SYS_DLIST_STATIC_INIT(&app_mem_list); +extern char __app_shmem_regions_start[]; +extern char __app_shmem_regions_end[]; -/* - * The following zeroizes each "bss" part of each subsection - * as per the entries in the list. - */ -void app_bss_zero(void) +static int app_shmem_setup(struct device *unused) { - sys_dnode_t *node, *next_node; + struct app_region *region, *end; + size_t bss_size, data_size; - SYS_DLIST_FOR_EACH_NODE_SAFE(&app_mem_list, node, next_node) - { - struct app_region *region = - CONTAINER_OF(node, struct app_region, lnode); - (void)memset(region->bmem_start, 0, region->bmem_size); - } -} + end = (struct app_region *)&__app_shmem_regions_end; + region = (struct app_region *)&__app_shmem_regions_start; -/* - * The following calculates the size of each subsection and adds - * the computed sizes to the region structures. These calculations - * are needed both for zeroizing "bss" parts of the partitions and - * for the creation of the k_mem_partition. - */ -void app_calc_size(void) -{ - sys_dnode_t *node, *next_node; - - SYS_DLIST_FOR_EACH_NODE_SAFE(&app_mem_list, node, next_node) - { + for ( ; region < end; region++) { + /* Determine bounds and set partition appropriately */ #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); - region->bmem_size = - _app_smem_end - - (char *)region->bmem_start; - region->dmem_size = - (char *)region->bmem_start - - (char *)region->dmem_start; - region->smem_size = - region->bmem_size + region->dmem_size; - region->partition[0].size = - region->dmem_size + region->bmem_size; + data_size = region->bmem_start - region->dmem_start; + if (region == end - 1) { + bss_size = _app_smem_end - region->bmem_start; } else { - struct app_region *region = - CONTAINER_OF(node, struct app_region, lnode); - struct app_region *nRegion = - CONTAINER_OF(next_node, struct app_region, - lnode); - region->bmem_size = - (char *)nRegion->dmem_start - - (char *)region->bmem_start; - region->dmem_size = - (char *)region->bmem_start - - (char *)region->dmem_start; - region->smem_size = - region->bmem_size + region->dmem_size; - region->partition[0].size = - region->dmem_size + region->bmem_size; + struct app_region *next = region + 1; + + __ASSERT_NO_MSG(region->bmem_start < next->dmem_start); + bss_size = next->dmem_start - region->bmem_start; } - #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); + data_size = region->bmem_start - region->dmem_start; + bss_size = region->smem_size - data_size; +#endif + region->partition->size = data_size + bss_size; - 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 */ + /* Zero out BSS area of each partition */ + (void)memset(region->bmem_start, 0, bss_size); } + + return 0; } -/* - * "Initializes" by calculating subsection sizes and then - * zeroizing "bss" regions. - */ -void appmem_init_app_memory(void) -{ - app_calc_size(); - app_bss_zero(); -} +SYS_INIT(app_shmem_setup, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index b814b637b11..d7e9043a9a4 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -689,24 +689,6 @@ void test_main(void) { struct k_mem_partition *parts[] = {&part0, &part1}; - /* partitions must be initialized first */ - FOR_EACH(appmem_init_part, part0, part1, part2); - /* - * Next, the app_memory must be initialized in order to - * calculate size of the dynamically created subsections. - */ -#if defined(CONFIG_ARC) - /* - * appmem_init_app_memory will access all partitions - * For CONFIG_ARC_MPU_VER == 3, these partitions are not added - * into MPU now, so need to disable mpu first to do app_bss_zero() - */ - arc_core_mpu_disable(); - appmem_init_app_memory(); - arc_core_mpu_enable(); -#else - appmem_init_app_memory(); -#endif k_mem_domain_init(&dom0, 2, parts); k_mem_domain_add_thread(&dom0, k_current_get());