Skip to content

Commit a4274f8

Browse files
laurenmurphyx64fabiobaltieri
authored andcommitted
llext: dynamic heap support for harvard arch
Adds support for LLEXT_HEAP_DYNAMIC with Harvard architecture. Signed-off-by: Lauren Murphy <[email protected]>
1 parent 944aa81 commit a4274f8

File tree

5 files changed

+68
-5
lines changed

5 files changed

+68
-5
lines changed

doc/services/llext/config.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ option.
5757
large enough to allow the extension sections to be allocated with the
5858
alignment required by the architecture.
5959

60+
.. note::
61+
On Harvard architectures, applications must call
62+
:c:func:`llext_heap_init_harvard`.
63+
6064
.. _llext_kconfig_type:
6165

6266
ELF object type

include/zephyr/llext/llext.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,27 @@ int llext_get_section_header(struct llext_loader *loader, struct llext *ext,
408408
* @param bytes Size of memory region, in bytes
409409
*
410410
* @returns 0 on success, or a negative error code.
411-
* @retval -ENOSYS Option @kconfig{CONFIG_LLEXT_HEAP_DYNAMIC} is not enabled or supported
411+
* @retval -ENOSYS Option @kconfig{CONFIG_LLEXT_HEAP_DYNAMIC} is not enabled or supported,
412+
* or it is and option @kconfig{CONFIG_HARVARD} is enabled
412413
*/
413414
int llext_heap_init(void *mem, size_t bytes);
414415

416+
/**
417+
* @brief Initialize LLEXT heap dynamically for Harvard architecture
418+
*
419+
* Use the provided memory blocks as the LLEXT heaps at runtime.
420+
*
421+
* @param instr_mem Pointer to instruction memory.
422+
* @param instr_bytes Size of instruction memory region, in bytes
423+
* @param data_mem Pointer to data memory.
424+
* @param data_bytes Size of data memory region, in bytes
425+
*
426+
* @returns 0 on success, or a negative error code.
427+
* @retval -ENOSYS Option @kconfig{CONFIG_LLEXT_HEAP_DYNAMIC} is not enabled or supported,
428+
* or it is and option @kconfig{CONFIG_HARVARD} is not enabled
429+
*/
430+
int llext_heap_init_harvard(void *instr_mem, size_t instr_bytes, void *data_mem, size_t data_bytes);
431+
415432
/**
416433
* @brief Mark LLEXT heap as uninitialized.
417434
*

subsys/llext/llext_mem.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ LOG_MODULE_DECLARE(llext, CONFIG_LLEXT_LOG_LEVEL);
2828
#endif
2929

3030
#ifdef CONFIG_LLEXT_HEAP_DYNAMIC
31+
#ifdef CONFIG_HARVARD
32+
struct k_heap llext_instr_heap;
33+
struct k_heap llext_data_heap;
34+
#else
3135
struct k_heap llext_heap;
36+
#endif
3237
bool llext_heap_inited;
3338
#else
3439
#ifdef CONFIG_HARVARD
@@ -343,17 +348,36 @@ int llext_add_domain(struct llext *ext, struct k_mem_domain *domain)
343348
#endif
344349
}
345350

351+
int llext_heap_init_harvard(void *instr_mem, size_t instr_bytes, void *data_mem, size_t data_bytes)
352+
{
353+
#if !defined(CONFIG_LLEXT_HEAP_DYNAMIC) || !defined(CONFIG_HARVARD)
354+
return -ENOSYS;
355+
#else
356+
if (llext_heap_inited) {
357+
return -EEXIST;
358+
}
359+
360+
k_heap_init(&llext_instr_heap, instr_mem, instr_bytes);
361+
k_heap_init(&llext_data_heap, data_mem, data_bytes);
362+
363+
llext_heap_inited = true;
364+
return 0;
365+
#endif
366+
}
367+
346368
int llext_heap_init(void *mem, size_t bytes)
347369
{
348-
#ifdef CONFIG_LLEXT_HEAP_DYNAMIC
370+
#if !defined(CONFIG_LLEXT_HEAP_DYNAMIC) || defined(CONFIG_HARVARD)
371+
return -ENOSYS;
372+
#else
349373
if (llext_heap_inited) {
350374
return -EEXIST;
351375
}
376+
352377
k_heap_init(&llext_heap, mem, bytes);
378+
353379
llext_heap_inited = true;
354380
return 0;
355-
#else
356-
return -ENOSYS;
357381
#endif
358382
}
359383

tests/subsys/llext/src/test_llext.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,17 +659,33 @@ ZTEST(llext, test_ext_syscall_fail)
659659
}
660660

661661
#ifdef CONFIG_LLEXT_HEAP_DYNAMIC
662+
#ifdef CONFIG_HARVARD
663+
#define TEST_LLEXT_INSTR_HEAP_DYNAMIC_SIZE KB(16)
664+
static uint8_t llext_instr_heap_data[TEST_LLEXT_INSTR_HEAP_DYNAMIC_SIZE] Z_GENERIC_SECTION(.rodata);
665+
#define TEST_LLEXT_DATA_HEAP_DYNAMIC_SIZE KB(48)
666+
static uint8_t llext_data_heap_data[TEST_LLEXT_DATA_HEAP_DYNAMIC_SIZE];
667+
#else
662668
#define TEST_LLEXT_HEAP_DYNAMIC_SIZE KB(64)
663669
static uint8_t llext_heap_data[TEST_LLEXT_HEAP_DYNAMIC_SIZE];
664670
#endif
671+
#endif
665672

666673
static void *ztest_suite_setup(void)
667674
{
668675
#ifdef CONFIG_LLEXT_HEAP_DYNAMIC
676+
#ifdef CONFIG_HARVARD
677+
zassert_ok(llext_heap_init_harvard(llext_instr_heap_data, sizeof(llext_instr_heap_data),
678+
llext_data_heap_data, sizeof(llext_data_heap_data)));
679+
LOG_INF("Allocated LLEXT dynamic instruction heap of size %uKB\n",
680+
(unsigned int)(sizeof(llext_instr_heap_data) / KB(1)));
681+
LOG_INF("Allocated LLEXT dynamic data heap of size %uKB\n",
682+
(unsigned int)(sizeof(llext_data_heap_data) / KB(1)));
683+
#else
669684
/* Test runtime allocation of the LLEXT loader heap */
670685
zassert_ok(llext_heap_init(llext_heap_data, sizeof(llext_heap_data)));
671686
LOG_INF("Allocated LLEXT dynamic heap of size %uKB\n",
672687
(unsigned int)(sizeof(llext_heap_data)/KB(1)));
688+
#endif
673689
#endif
674690
return NULL;
675691
}

tests/subsys/llext/testcase.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ tests:
154154

155155
# Test dynamic heap allocation
156156
llext.dynamic_heap:
157-
arch_allow: arm
157+
arch_allow:
158+
- arm
159+
- arc
158160
filter: not CONFIG_MPU and not CONFIG_MMU
159161
extra_conf_files: ['no_mem_protection.conf']
160162
extra_configs:

0 commit comments

Comments
 (0)