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 <andrew.p.boie@intel.com>
This commit is contained in:
parent
e526a2b80a
commit
c253a686bf
8 changed files with 53 additions and 157 deletions
|
@ -42,13 +42,9 @@ The resulting section name can be seen in the linker.map as
|
||||||
"data_smem_id" and "data_smem_idb".
|
"data_smem_id" and "data_smem_idb".
|
||||||
|
|
||||||
To create a k_mem_partition, call the macro K_APPMEM_PARTITION_DEFINE(part0)
|
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.
|
where "part0" is the name then used to refer to that partition. The
|
||||||
This macro only creates a function and necessary data structures for
|
standard memory domain APIs may be used to add it to domains; the declared
|
||||||
the later "initialization".
|
name is a k_mem_partition symbol.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -64,8 +60,6 @@ Example:
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
appmem_init_part_part0();
|
|
||||||
appmem_init_app_memory();
|
|
||||||
k_mem_domain_init(&dom0, 0, NULL)
|
k_mem_domain_init(&dom0, 0, NULL)
|
||||||
k_mem_domain_add_partition(&dom0, part0);
|
k_mem_domain_add_partition(&dom0, part0);
|
||||||
k_mem_domain_add_thread(&dom0, k_current_get());
|
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);
|
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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,7 @@ struct app_region {
|
||||||
char *dmem_start;
|
char *dmem_start;
|
||||||
char *bmem_start;
|
char *bmem_start;
|
||||||
u32_t smem_size;
|
u32_t smem_size;
|
||||||
u32_t dmem_size;
|
|
||||||
u32_t bmem_size;
|
|
||||||
struct k_mem_partition *partition;
|
struct k_mem_partition *partition;
|
||||||
sys_dnode_t lnode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,10 +78,10 @@ struct app_region {
|
||||||
* calculate the region sizes.
|
* calculate the region sizes.
|
||||||
*/
|
*/
|
||||||
#define smem_size_declare(name) extern char data_smem_##name##_size[]
|
#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
|
#else
|
||||||
#define smem_size_declare(name)
|
#define smem_size_declare(name)
|
||||||
#define smem_size_assign(name)
|
#define smem_size_val(name) 0
|
||||||
#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */
|
#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,34 +102,16 @@ struct app_region {
|
||||||
smem_size_declare(name); \
|
smem_size_declare(name); \
|
||||||
_app_dmem_pad(name) char name##_dmem_pad; \
|
_app_dmem_pad(name) char name##_dmem_pad; \
|
||||||
_app_bmem_pad(name) char name##_bmem_pad; \
|
_app_bmem_pad(name) char name##_bmem_pad; \
|
||||||
__kernel struct k_mem_partition name; \
|
struct k_mem_partition name = { \
|
||||||
__kernel struct app_region name##_region; \
|
.start = (u32_t) &data_smem_##name, \
|
||||||
static inline void appmem_init_part_##name(void) \
|
.attr = K_MEM_PARTITION_P_RW_U_RW \
|
||||||
{ \
|
}; \
|
||||||
name##_region.dmem_start = (char *)&data_smem_##name; \
|
_GENERIC_SECTION(.app_regions.name) \
|
||||||
name##_region.bmem_start = (char *)&data_smem_##name##b; \
|
struct app_region name##_region = { \
|
||||||
smem_size_assign(name); \
|
.dmem_start = (char *)&data_smem_##name, \
|
||||||
sys_dlist_append(&app_mem_list, &name##_region.lnode); \
|
.bmem_start = (char *)&data_smem_##name##b, \
|
||||||
name.start = (u32_t) name##_region.dmem_start; \
|
.smem_size = smem_size_val(name), \
|
||||||
name.attr = K_MEM_PARTITION_P_RW_U_RW; \
|
.partition = &name \
|
||||||
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);
|
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_ */
|
#endif /* ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_ */
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
}
|
}
|
||||||
#endif
|
#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),)
|
SECTION_PROLOGUE (devconfig, (OPTIONAL),)
|
||||||
{
|
{
|
||||||
__devconfig_start = .;
|
__devconfig_start = .;
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
#define APP_INPUT_SECTION(sect) *(MAYBE_EXCLUDE_SOME_FILES sect)
|
#define APP_INPUT_SECTION(sect) *(MAYBE_EXCLUDE_SOME_FILES sect)
|
||||||
#define KERNEL_INPUT_SECTION(sect) *(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 */
|
#ifdef CONFIG_X86 /* LINKER FILES: defines used by linker script */
|
||||||
/* Should be moved to linker-common-defs.h */
|
/* Should be moved to linker-common-defs.h */
|
||||||
|
|
|
@ -105,12 +105,7 @@ void main(void)
|
||||||
k_tid_t tPT, tENC, tCT;
|
k_tid_t tPT, tENC, tCT;
|
||||||
|
|
||||||
k_thread_access_grant(k_current_get(), &allforone);
|
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
|
* create an enc thread init the memory domain and add partitions
|
||||||
* then add the thread to the domain.
|
* then add the thread to the domain.
|
||||||
|
|
|
@ -679,7 +679,7 @@ class SizeCalculator:
|
||||||
"_k_memory_pool", "exceptions", "initshell",
|
"_k_memory_pool", "exceptions", "initshell",
|
||||||
"_static_thread_area", "_k_timer_area",
|
"_static_thread_area", "_k_timer_area",
|
||||||
"_k_mem_slab_area", "_k_mem_pool_area", "sw_isr_table",
|
"_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_fifo_area", "_k_lifo_area", "_k_stack_area",
|
||||||
"_k_msgq_area", "_k_mbox_area", "_k_pipe_area",
|
"_k_msgq_area", "_k_mbox_area", "_k_pipe_area",
|
||||||
"net_if", "net_if_dev", "net_stack", "net_l2_data",
|
"net_if", "net_if_dev", "net_stack", "net_l2_data",
|
||||||
|
|
|
@ -1,97 +1,43 @@
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <init.h>
|
||||||
#include <app_memory/app_memdomain.h>
|
#include <app_memory/app_memdomain.h>
|
||||||
#include <misc/dlist.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <misc/__assert.h>
|
||||||
|
|
||||||
/*
|
extern char __app_shmem_regions_start[];
|
||||||
* Initializes a double linked-list for the calculation of
|
extern char __app_shmem_regions_end[];
|
||||||
* memory subsections.
|
|
||||||
*/
|
|
||||||
sys_dlist_t app_mem_list = SYS_DLIST_STATIC_INIT(&app_mem_list);
|
|
||||||
|
|
||||||
/*
|
static int app_shmem_setup(struct device *unused)
|
||||||
* The following zeroizes each "bss" part of each subsection
|
|
||||||
* as per the entries in the list.
|
|
||||||
*/
|
|
||||||
void app_bss_zero(void)
|
|
||||||
{
|
{
|
||||||
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)
|
end = (struct app_region *)&__app_shmem_regions_end;
|
||||||
{
|
region = (struct app_region *)&__app_shmem_regions_start;
|
||||||
struct app_region *region =
|
|
||||||
CONTAINER_OF(node, struct app_region, lnode);
|
|
||||||
(void)memset(region->bmem_start, 0, region->bmem_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
for ( ; region < end; region++) {
|
||||||
* The following calculates the size of each subsection and adds
|
/* Determine bounds and set partition appropriately */
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
#ifndef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
|
#ifndef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
|
||||||
if (sys_dlist_is_tail(&app_mem_list, node)) {
|
data_size = region->bmem_start - region->dmem_start;
|
||||||
struct app_region *region =
|
if (region == end - 1) {
|
||||||
CONTAINER_OF(node, struct app_region, lnode);
|
bss_size = _app_smem_end - region->bmem_start;
|
||||||
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;
|
|
||||||
} else {
|
} else {
|
||||||
struct app_region *region =
|
struct app_region *next = region + 1;
|
||||||
CONTAINER_OF(node, struct app_region, lnode);
|
|
||||||
struct app_region *nRegion =
|
__ASSERT_NO_MSG(region->bmem_start < next->dmem_start);
|
||||||
CONTAINER_OF(next_node, struct app_region,
|
bss_size = next->dmem_start - region->bmem_start;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* For power of 2 MPUs linker provides support to help us
|
data_size = region->bmem_start - region->dmem_start;
|
||||||
* calculate the region sizes.
|
bss_size = region->smem_size - data_size;
|
||||||
*/
|
#endif
|
||||||
struct app_region *region =
|
region->partition->size = data_size + bss_size;
|
||||||
CONTAINER_OF(node, struct app_region, lnode);
|
|
||||||
|
|
||||||
region->dmem_size = (char *)region->bmem_start -
|
/* Zero out BSS area of each partition */
|
||||||
(char *)region->dmem_start;
|
(void)memset(region->bmem_start, 0, bss_size);
|
||||||
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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
SYS_INIT(app_shmem_setup, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||||
* "Initializes" by calculating subsection sizes and then
|
|
||||||
* zeroizing "bss" regions.
|
|
||||||
*/
|
|
||||||
void appmem_init_app_memory(void)
|
|
||||||
{
|
|
||||||
app_calc_size();
|
|
||||||
app_bss_zero();
|
|
||||||
}
|
|
||||||
|
|
|
@ -689,24 +689,6 @@ void test_main(void)
|
||||||
{
|
{
|
||||||
struct k_mem_partition *parts[] = {&part0, &part1};
|
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_init(&dom0, 2, parts);
|
||||||
k_mem_domain_add_thread(&dom0, k_current_get());
|
k_mem_domain_add_thread(&dom0, k_current_get());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue