Skip to content

Commit 08057ca

Browse files
llext: add support for arc
Adds compiler flag(s) and some architecture-specific relocations for ARC. No userspace support, doesn't support all relocations. Signed-off-by: Lauren Murphy <[email protected]>
1 parent 8232440 commit 08057ca

File tree

8 files changed

+137
-11
lines changed

8 files changed

+137
-11
lines changed

arch/arc/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ add_subdirectory_ifdef(CONFIG_ARC_CORE_MPU mpu)
3434
add_subdirectory_ifdef(CONFIG_ARC_SECURE_FIRMWARE secureshield)
3535

3636
zephyr_linker_sources(ROM_START SORT_KEY 0x0vectors vector_table.ld)
37+
38+
zephyr_library_sources_ifdef(CONFIG_LLEXT elf.c)

arch/arc/core/elf.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2024 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/llext/elf.h>
8+
#include <zephyr/llext/llext.h>
9+
#include <zephyr/llext/loader.h>
10+
#include <zephyr/logging/log.h>
11+
12+
LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL);
13+
14+
#define R_ARC_32 4
15+
#define R_ARC_B26 5 /* AKA R_ARC_64 */
16+
#define R_ARC_S25W_PCREL 17
17+
#define R_ARC_32_ME 27
18+
19+
/* ARCompact insns packed in memory have Middle Endian encoding */
20+
#define ME(x) ((x & 0xffff0000) >> 16) | ((x & 0xffff) << 16);
21+
22+
/**
23+
* @brief Architecture specific function for relocating shared elf
24+
*
25+
* Elf files contain a series of relocations described in multiple sections.
26+
* These relocation instructions are architecture specific and each architecture
27+
* supporting modules must implement this.
28+
*
29+
* The relocation codes are well documented:
30+
* https://github.com/foss-for-synopsys-dwc-arc-processors/arc-ABI-manual/blob/master/ARCv2_ABI.pdf
31+
* https://github.com/zephyrproject-rtos/binutils-gdb
32+
*/
33+
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr, const char *sym_name,
34+
uintptr_t load_bias)
35+
{
36+
int ret = 0;
37+
uint32_t insn = *(uint32_t *)loc;
38+
uint32_t value;
39+
40+
sym_base_addr += rel->r_addend;
41+
42+
int reloc_type = ELF32_R_TYPE(rel->r_info);
43+
44+
switch (reloc_type) {
45+
case R_ARC_32:
46+
case R_ARC_B26:
47+
*(uint32_t *)loc = sym_base_addr;
48+
break;
49+
case R_ARC_S25W_PCREL:
50+
/* ((S + A) - P) >> 2
51+
* S = symbol address
52+
* A = addend
53+
* P = relative offset to PCL
54+
*/
55+
value = (sym_base_addr + rel->r_addend - (loc & ~0x3)) >> 2;
56+
57+
insn = ME(insn);
58+
59+
/* disp25w */
60+
insn = insn & ~0x7fcffcf;
61+
insn |= ((value >> 0) & 0x01ff) << 18;
62+
insn |= ((value >> 9) & 0x03ff) << 6;
63+
insn |= ((value >> 19) & 0x000f) << 0;
64+
65+
insn = ME(insn);
66+
67+
*(uint32_t *)loc = insn;
68+
break;
69+
case R_ARC_32_ME:
70+
*(uint32_t *)loc = ME(sym_base_addr);
71+
break;
72+
default:
73+
LOG_ERR("unknown relocation: %u\n", reloc_type);
74+
ret = -ENOEXEC;
75+
break;
76+
}
77+
78+
return ret;
79+
}

cmake/compiler/gcc/target_arc.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,16 @@ if(NOT DEFINED GCC_ARC_TUNED_CPU)
88
set(GCC_ARC_TUNED_CPU ${GCC_M_CPU})
99
endif()
1010

11+
# Flags not supported by llext linker
12+
# (regexps are supported and match whole word)
13+
set(LLEXT_REMOVE_FLAGS
14+
-fno-pic
15+
-fno-pie
16+
-ffunction-sections
17+
-fdata-sections
18+
-g.*
19+
-Os
20+
)
21+
1122
list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_ARC_TUNED_CPU})
1223
list(APPEND TOOLCHAIN_LD_FLAGS -mcpu=${GCC_ARC_TUNED_CPU})

doc/services/llext/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ and introspected to some degree, as well as unloaded when no longer needed.
2121
.. note::
2222

2323
The LLEXT subsystem requires architecture-specific support. It is currently
24-
available only on RISC-V, ARM, ARM64 and Xtensa cores.
24+
available only on RISC-V, ARM, ARM64, ARC (experimental) and Xtensa cores.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CONFIG_FILE_SYSTEM=y
2+
CONFIG_FILE_SYSTEM_LITTLEFS=y
3+
CONFIG_FS_LITTLEFS_FMP_DEV=y
4+
CONFIG_FLASH_MAP=y
5+
CONFIG_FLASH=y
6+
CONFIG_FLASH_SIMULATOR=y
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/ {
2+
sim_flash_controller: sim_flash_controller {
3+
compatible = "zephyr,sim-flash";
4+
5+
#address-cells = <1>;
6+
#size-cells = <1>;
7+
erase-value = <0x00>;
8+
9+
flash_sim0: flash_sim@0 {
10+
compatible = "soc-nv-flash";
11+
reg = <0x00000000 0x2000>;
12+
13+
erase-block-size = <1024>;
14+
write-block-size = <4>;
15+
16+
partitions {
17+
compatible = "fixed-partitions";
18+
#address-cells = <1>;
19+
#size-cells = <1>;
20+
21+
storage_partition: partition@0 {
22+
label = "storage_partition";
23+
reg = <0x00000000 0x2000>;
24+
};
25+
};
26+
};
27+
};
28+
};

tests/subsys/llext/simple/no_mem_protection.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
CONFIG_ARM_MPU=n
77
CONFIG_ARM_AARCH32_MMU=n
88
CONFIG_RISCV_PMP=n
9+
CONFIG_ARC_MPU_ENABLE=n

tests/subsys/llext/simple/testcase.yaml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ common:
66
- s32z2xxdc2/s32z270/rtu0 # See commit 18a0660
77
- s32z2xxdc2/s32z270/rtu1 # See commit 18a0660
88
# platforms that are always skipped by the runtime filter
9-
- qemu_arc/qemu_arc_em
10-
- qemu_arc/qemu_arc_hs
11-
- qemu_arc/qemu_arc_hs/xip
12-
- qemu_arc/qemu_arc_hs5x
13-
- qemu_arc/qemu_arc_hs6x
149
- qemu_cortex_m0
1510
- qemu_xtensa/dc233c/mmu
1611
integration_platforms:
@@ -36,7 +31,7 @@ tests:
3631
# most tests include no_mem_protection.conf, which disables memory protection
3732
# hardware completely.
3833
llext.simple.readonly:
39-
arch_allow: arm riscv # Xtensa needs writable storage
34+
arch_allow: arm riscv arc # Xtensa needs writable storage
4035
filter: not CONFIG_MPU and not CONFIG_MMU
4136
extra_conf_files: ['no_mem_protection.conf']
4237
extra_configs:
@@ -57,15 +52,17 @@ tests:
5752
- CONFIG_LLEXT_HEAP_SIZE=128 # qemu_cortex_a9 requires larger heap
5853
- CONFIG_LLEXT_STORAGE_WRITABLE=n
5954
llext.simple.writable:
60-
arch_allow: arm xtensa riscv
55+
arch_allow: arm xtensa riscv arc
6156
integration_platforms:
6257
- qemu_xtensa/dc233c # Xtensa ISA
6358
filter: not CONFIG_MPU and not CONFIG_MMU
6459
extra_conf_files: ['no_mem_protection.conf']
6560
extra_configs:
6661
- CONFIG_LLEXT_STORAGE_WRITABLE=y
6762
llext.simple.writable_relocatable:
68-
arch_allow: arm xtensa riscv
63+
arch_allow: arm xtensa riscv arc
64+
platform_exclude:
65+
- qemu_arc/qemu_arc_hs5x # See #80949
6966
integration_platforms:
7067
- qemu_xtensa/dc233c # Xtensa ISA
7168
filter: not CONFIG_MPU and not CONFIG_MMU
@@ -77,7 +74,7 @@ tests:
7774
# Test the Symbol Link Identifier (SLID) linking feature on writable
7875
# storage to cover both ARM and Xtensa architectures on the same test.
7976
llext.simple.writable_slid_linking:
80-
arch_allow: arm xtensa riscv
77+
arch_allow: arm xtensa riscv arc
8178
integration_platforms:
8279
- qemu_xtensa/dc233c # Xtensa ISA
8380
filter: not CONFIG_MPU and not CONFIG_MMU
@@ -86,7 +83,9 @@ tests:
8683
- CONFIG_LLEXT_STORAGE_WRITABLE=y
8784
- CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID=y
8885
llext.simple.writable_relocatable_slid_linking:
89-
arch_allow: arm xtensa riscv
86+
arch_allow: arm xtensa riscv arc
87+
platform_exclude:
88+
- qemu_arc/qemu_arc_hs5x # See #80949
9089
integration_platforms:
9190
- qemu_xtensa/dc233c # Xtensa ISA
9291
filter: not CONFIG_MPU and not CONFIG_MMU

0 commit comments

Comments
 (0)