1 /* 2 * Copyright (c) 2019 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_ 7 #define ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_ 8 9 #include <zephyr/linker/linker-defs.h> 10 #include <zephyr/sys/dlist.h> 11 #include <zephyr/kernel.h> 12 13 /** 14 * @brief Application memory domain APIs 15 * @defgroup mem_domain_apis_app Application memory domain APIs 16 * @ingroup mem_domain_apis 17 * @{ 18 */ 19 20 #ifdef CONFIG_USERSPACE 21 22 /** 23 * @brief Name of the data section for a particular partition 24 * 25 * Useful for defining memory pools, or any other macro that takes a 26 * section name as a parameter. 27 * 28 * @param id Partition name 29 */ 30 #define K_APP_DMEM_SECTION(id) data_smem_##id##_data 31 32 /** 33 * @brief Name of the bss section for a particular partition 34 * 35 * Useful for defining memory pools, or any other macro that takes a 36 * section name as a parameter. 37 * 38 * @param id Partition name 39 */ 40 #define K_APP_BMEM_SECTION(id) data_smem_##id##_bss 41 42 /** 43 * @brief Place data in a partition's data section 44 * 45 * Globals tagged with this will end up in the data section for the 46 * specified memory partition. This data should be initialized to some 47 * desired value. 48 * 49 * @param id Name of the memory partition to associate this data 50 */ 51 #define K_APP_DMEM(id) Z_GENERIC_SECTION(K_APP_DMEM_SECTION(id)) 52 53 /** 54 * @brief Place data in a partition's bss section 55 * 56 * Globals tagged with this will end up in the bss section for the 57 * specified memory partition. This data will be zeroed at boot. 58 * 59 * @param id Name of the memory partition to associate this data 60 */ 61 #define K_APP_BMEM(id) Z_GENERIC_SECTION(K_APP_BMEM_SECTION(id)) 62 63 struct z_app_region { 64 void *bss_start; 65 size_t bss_size; 66 }; 67 68 #define Z_APP_START(id) z_data_smem_##id##_part_start 69 #define Z_APP_SIZE(id) z_data_smem_##id##_part_size 70 #define Z_APP_BSS_START(id) z_data_smem_##id##_bss_start 71 #define Z_APP_BSS_SIZE(id) z_data_smem_##id##_bss_size 72 73 /* If a partition is declared with K_APPMEM_PARTITION, but never has any 74 * data assigned to its contents, then no symbols with its prefix will end 75 * up in the symbol table. This prevents gen_app_partitions.py from detecting 76 * that the partition exists, and the linker symbols which specify partition 77 * bounds will not be generated, resulting in build errors. 78 * 79 * What this inline assembly code does is define a symbol with no data. 80 * This should work for all arches that produce ELF binaries, see 81 * https://sourceware.org/binutils/docs/as/Section.html 82 * 83 * We don't know what active flags/type of the pushed section were, so we are 84 * specific: "aw" indicates section is allocatable and writable, 85 * and "@progbits" indicates the section has data. 86 */ 87 #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) 88 /* ARM has a quirk in that '@' denotes a comment, so we have to send 89 * %progbits to the assembler instead. 90 */ 91 #define Z_PROGBITS_SYM "%" 92 #else 93 #define Z_PROGBITS_SYM "@" 94 #endif 95 96 #if defined(CONFIG_ARC) && defined(__CCAC__) 97 /* ARC MWDT assembler has slightly different pushsection/popsection directives 98 * names. 99 */ 100 #define Z_PUSHSECTION_DIRECTIV ".pushsect" 101 #define Z_POPSECTION_DIRECTIVE ".popsect" 102 #else 103 #define Z_PUSHSECTION_DIRECTIV ".pushsection" 104 #define Z_POPSECTION_DIRECTIVE ".popsection" 105 #endif 106 107 #define Z_APPMEM_PLACEHOLDER(name) \ 108 __asm__ ( \ 109 Z_PUSHSECTION_DIRECTIV " " STRINGIFY(K_APP_DMEM_SECTION(name)) \ 110 ",\"aw\"," Z_PROGBITS_SYM "progbits\n\t" \ 111 ".global " STRINGIFY(name) "_placeholder\n\t" \ 112 STRINGIFY(name) "_placeholder:\n\t" \ 113 Z_POPSECTION_DIRECTIVE "\n\t") 114 115 /** 116 * @brief Define an application memory partition with linker support 117 * 118 * Defines a k_mem_paritition with the provided name. 119 * This name may be used with the K_APP_DMEM and K_APP_BMEM macros to 120 * place globals automatically in this partition. 121 * 122 * NOTE: placeholder char variable is defined here to prevent build errors 123 * if a partition is defined but nothing ever placed in it. 124 * 125 * @param name Name of the k_mem_partition to declare 126 */ 127 #define K_APPMEM_PARTITION_DEFINE(name) \ 128 extern char Z_APP_START(name)[]; \ 129 extern char Z_APP_SIZE(name)[]; \ 130 struct k_mem_partition name = { \ 131 .start = (uintptr_t) &Z_APP_START(name), \ 132 .size = (size_t) &Z_APP_SIZE(name), \ 133 .attr = K_MEM_PARTITION_P_RW_U_RW \ 134 }; \ 135 extern char Z_APP_BSS_START(name)[]; \ 136 extern char Z_APP_BSS_SIZE(name)[]; \ 137 Z_GENERIC_SECTION(.app_regions.name) \ 138 const struct z_app_region name##_region = { \ 139 .bss_start = &Z_APP_BSS_START(name), \ 140 .bss_size = (size_t) &Z_APP_BSS_SIZE(name) \ 141 }; \ 142 Z_APPMEM_PLACEHOLDER(name) 143 #else 144 145 #define K_APP_BMEM(ptn) 146 #define K_APP_DMEM(ptn) 147 #define K_APP_DMEM_SECTION(ptn) .data 148 #define K_APP_BMEM_SECTION(ptn) .bss 149 #define K_APPMEM_PARTITION_DEFINE(name) 150 151 #endif /* CONFIG_USERSPACE */ 152 153 /** 154 * @} 155 */ 156 157 #endif /* ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_ */ 158