1 /*
2 * Copyright (c) 2024 Arduino SA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_SUBSYS_LLEXT_PRIV_H_
8 #define ZEPHYR_SUBSYS_LLEXT_PRIV_H_
9
10 #include <zephyr/kernel.h>
11 #include <zephyr/llext/llext.h>
12 #include <zephyr/llext/llext_internal.h>
13 #include <zephyr/sys/slist.h>
14 #include <zephyr/device.h>
15 #include <zephyr/devicetree.h>
16
17 /*
18 * Macro to determine if section / region is in instruction memory
19 * Will need to be updated if any non-ARC boards using Harvard architecture is added
20 */
21 #if CONFIG_HARVARD && CONFIG_ARC
22 #define IN_NODE(inst, compat, base_addr, alloc) \
23 (((uintptr_t)(base_addr) >= DT_REG_ADDR(DT_INST(inst, compat)) && \
24 (uintptr_t)(base_addr + alloc) <= \
25 DT_REG_ADDR(DT_INST(inst, compat)) + DT_REG_SIZE(DT_INST(inst, compat)))) ||
26 #define INSTR_FETCHABLE(base_addr, alloc) \
27 DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(arc_iccm, IN_NODE, base_addr, alloc) false
28 #elif CONFIG_HARVARD && !CONFIG_ARC
29 /* Unknown if section / region is in instruction memory; warn or compensate */
30 #define INSTR_FETCHABLE(base_addr, alloc) false
31 #else /* all non-Harvard architectures */
32 #define INSTR_FETCHABLE(base_addr, alloc) true
33 #endif
34
35 /*
36 * Global extension list
37 */
38
39 extern sys_slist_t llext_list;
40 extern struct k_mutex llext_lock;
41
42 /*
43 * Memory management (llext_mem.c)
44 */
45
46 int llext_copy_strings(struct llext_loader *ldr, struct llext *ext,
47 const struct llext_load_param *ldr_parm);
48 int llext_copy_regions(struct llext_loader *ldr, struct llext *ext,
49 const struct llext_load_param *ldr_parm);
50 void llext_free_regions(struct llext *ext);
51 void llext_adjust_mmu_permissions(struct llext *ext);
52
53 #ifdef CONFIG_HARVARD
54 extern struct k_heap llext_instr_heap;
55 extern struct k_heap llext_data_heap;
56 #else
57 extern struct k_heap llext_heap;
58 #define llext_instr_heap llext_heap
59 #define llext_data_heap llext_heap
60 #endif
61
llext_heap_is_inited(void)62 static inline bool llext_heap_is_inited(void)
63 {
64 #ifdef CONFIG_LLEXT_HEAP_DYNAMIC
65 extern bool llext_heap_inited;
66
67 return llext_heap_inited;
68 #else
69 return true;
70 #endif
71 }
72
llext_alloc_data(size_t bytes)73 static inline void *llext_alloc_data(size_t bytes)
74 {
75 if (!llext_heap_is_inited()) {
76 return NULL;
77 }
78
79 /* Used for LLEXT metadata */
80 return k_heap_alloc(&llext_data_heap, bytes, K_NO_WAIT);
81 }
82
llext_aligned_alloc_data(size_t align,size_t bytes)83 static inline void *llext_aligned_alloc_data(size_t align, size_t bytes)
84 {
85 if (!llext_heap_is_inited()) {
86 return NULL;
87 }
88
89 /* Used for LLEXT metadata OR non-executable section */
90 return k_heap_aligned_alloc(&llext_data_heap, align, bytes, K_NO_WAIT);
91 }
92
llext_free(void * ptr)93 static inline void llext_free(void *ptr)
94 {
95 if (!llext_heap_is_inited()) {
96 return;
97 }
98
99 k_heap_free(&llext_data_heap, ptr);
100 }
101
llext_aligned_alloc_instr(size_t align,size_t bytes)102 static inline void *llext_aligned_alloc_instr(size_t align, size_t bytes)
103 {
104 if (!llext_heap_is_inited()) {
105 return NULL;
106 }
107
108 return k_heap_aligned_alloc(&llext_instr_heap, align, bytes, K_NO_WAIT);
109 }
110
llext_free_instr(void * ptr)111 static inline void llext_free_instr(void *ptr)
112 {
113 if (!llext_heap_is_inited()) {
114 return;
115 }
116
117 k_heap_free(&llext_instr_heap, ptr);
118 }
119
120 /*
121 * ELF parsing (llext_load.c)
122 */
123
124 int do_llext_load(struct llext_loader *ldr, struct llext *ext,
125 const struct llext_load_param *ldr_parm);
126
127 /*
128 * Relocation (llext_link.c)
129 */
130
131 int llext_link(struct llext_loader *ldr, struct llext *ext,
132 const struct llext_load_param *ldr_parm);
133 ssize_t llext_file_offset(struct llext_loader *ldr, uintptr_t offset);
134 void llext_dependency_remove_all(struct llext *ext);
135
136 #endif /* ZEPHYR_SUBSYS_LLEXT_PRIV_H_ */
137