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