Skip to content

Commit ae2115d

Browse files
authored
[ATfE] Use new bootcode in llvmlibc-support (#394)
This eliminates the need for vector.c, as this is linked in the bootcode. This still needs a bit of work to be bulletproof, but for the samples, it works fine.
1 parent badb956 commit ae2115d

File tree

23 files changed

+1945
-138
lines changed

23 files changed

+1945
-138
lines changed

arm-software/embedded/llvmlibc-samples/src/baremetal-semihosting-llvmlibc/make.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@ if exist hello.hex del /q hello.hex
4040
@exit /B 1
4141

4242
:build_fn
43-
%BIN_PATH%\clang.exe --config=llvmlibc.cfg --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -nostartfiles -lcrt0-semihost -lsemihost -fno-exceptions -fno-rtti -g -T microbit-llvmlibc.ld -lm -o hello.elf hello.c vector.c
43+
%BIN_PATH%\clang.exe --config=llvmlibc.cfg --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -nostartfiles -lcrt0-semihost -lsemihost -fno-exceptions -fno-rtti -g -T microbit-llvmlibc.ld -lm -o hello.elf hello.c
4444
%BIN_PATH%\llvm-objcopy.exe -O ihex hello.elf hello.hex
4545
@exit /B

arm-software/embedded/llvmlibc-samples/src/baremetal-semihosting-llvmlibc/vector.c

Lines changed: 0 additions & 47 deletions
This file was deleted.

arm-software/embedded/llvmlibc-samples/src/cpp-baremetal-semihosting-llvmlibc/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ include ../../Makefile.conf
1010
build: hello.elf
1111

1212
hello.elf: *.cpp
13-
$(BIN_PATH)/clang --config=llvmlibc.cfg $(MICROBIT_TARGET) -c *.c
14-
$(BIN_PATH)/clang++ --config=llvmlibc.cfg $(MICROBIT_TARGET) $(CRT_SEMIHOST) -lm -g -T microbit-llvmlibc.ld *.o -o hello.elf $^
13+
$(BIN_PATH)/clang++ --config=llvmlibc.cfg $(MICROBIT_TARGET) $(CRT_SEMIHOST) -lm -g -T microbit-llvmlibc.ld -o hello.elf $^
1514

1615
%.hex: %.elf
1716
$(BIN_PATH)/llvm-objcopy -O ihex $< $@

arm-software/embedded/llvmlibc-samples/src/cpp-baremetal-semihosting-llvmlibc/make.bat

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ if exist hello.hex del /q hello.hex
4040
@exit /B 1
4141

4242
:build_fn
43-
%BIN_PATH%\clang.exe --config=llvmlibc.cfg --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -g -c vector.c
44-
%BIN_PATH%\clang++.exe --config=llvmlibc.cfg --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -nostartfiles -lcrt0-semihost -lsemihost -fno-exceptions -fno-rtti -g -T microbit-llvmlibc.ld -lm -o hello.elf hello.cpp vector.o
43+
%BIN_PATH%\clang++.exe --config=llvmlibc.cfg --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -nostartfiles -lcrt0-semihost -lsemihost -fno-exceptions -fno-rtti -g -T microbit-llvmlibc.ld -lm -o hello.elf hello.cpp
4544
%BIN_PATH%\llvm-objcopy.exe -O ihex hello.elf hello.hex
4645
@exit /B

arm-software/embedded/llvmlibc-samples/src/cpp-baremetal-semihosting-llvmlibc/vector.c

Lines changed: 0 additions & 47 deletions
This file was deleted.

arm-software/embedded/llvmlibc-support/crt0/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#
77

88
add_library(crt0 STATIC
9-
crt0.c
9+
bootcode.cpp
1010
)
1111

1212
target_include_directories(crt0 PRIVATE
@@ -17,7 +17,7 @@ target_include_directories(crt0 PRIVATE
1717
# This is the exact same implementation, kept for backwards compatibility with
1818
# picolibc in testing.
1919
add_library(crt0-semihost STATIC
20-
crt0.c
20+
bootcode.cpp
2121
)
2222

2323
target_include_directories(crt0-semihost PRIVATE
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//
2+
// Copyright (c) 2025, Arm Limited and affiliates.
3+
//
4+
// Part of the Arm Toolchain project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
9+
#include <stdint.h>
10+
11+
#if __ARM_ARCH_PROFILE == 'A' || __ARM_ARCH_PROFILE == 'R'
12+
#include "exceptions_a.h"
13+
#include "memory_a.h"
14+
#include "misc_a.h"
15+
#include "system_registers_a.h"
16+
#elif __ARM_ARCH_PROFILE == 'M'
17+
#include "exceptions_m.h"
18+
#include "memory_m.h"
19+
#include "misc_m.h"
20+
#include "system_registers_m.h"
21+
#endif
22+
23+
using namespace bootcode;
24+
25+
int main(int argc, const char **argv);
26+
extern "C" void __libc_init_array();
27+
extern "C" void _platform_init();
28+
29+
// Required for exit() on baremetal
30+
// TODO: This is temporary, remove once implemented upstream
31+
extern "C" [[gnu::weak]] void __cxa_finalize(void *) {}
32+
33+
extern char __data_source[];
34+
extern char __data_start[];
35+
extern char __data_size[];
36+
extern char __bss_start[];
37+
extern char __bss_size[];
38+
39+
#ifdef __ARM_FEATURE_PAUTH
40+
// Disable pointer authentication, as it isn't enabled until misc::setup meaning
41+
// the PAC at the beginning would do nothing so the AUT at the end would fail.
42+
__attribute__((target("branch-protection=none")))
43+
#endif
44+
extern "C" void __startup() {
45+
exceptions::setup();
46+
memory::setup();
47+
misc::setup();
48+
49+
// Perform the equivalent of scatterloading
50+
memcpy(__data_start, __data_source, (uintptr_t)__data_size);
51+
memset(__bss_start, '\0', (uintptr_t)__bss_size);
52+
53+
memory::enable_cache();
54+
__libc_init_array();
55+
_platform_init();
56+
exit(main(0, 0));
57+
}
58+
59+
// The entry point sets sp and branches to the main startup function.
60+
#ifdef __ARM_ARCH_ISA_ARM
61+
// If the target supports the A32 instruction set then the entry point has to
62+
// use it.
63+
__attribute__((target("arm")))
64+
#endif
65+
__attribute__((naked)) extern "C" void _start() {
66+
#if __ARM_ARCH_PROFILE != 'M' && __ARM_ARCH >= 8 && !defined(__ARM_ARCH_ISA_A64)
67+
// Check if we're in hypervisor mode
68+
asm("mrs r0, CPSR\n\t"
69+
"and r0, r0, #0x1f\n\t"
70+
"cmp r0, #0x1a\n\t"
71+
"bne after_mode_switch"
72+
:
73+
:
74+
: "r0");
75+
// If so switch to svc mode, which is what we would have started execution in
76+
// if we didn't have hypervisor mode.
77+
asm("adr r0, after_mode_switch\n\t"
78+
"msr ELR_hyp, r0"
79+
:
80+
:
81+
: "r0");
82+
asm("msr SPSR_hyp, %0" : : "r"(0x13));
83+
asm("eret");
84+
asm("after_mode_switch:");
85+
#endif
86+
87+
// Configured through linker script defined symbols
88+
asm("mov sp, %0" : : "r"(&__stack));
89+
asm("bl %0" : : "X"(__startup));
90+
}

arm-software/embedded/llvmlibc-support/crt0/crt0.c

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//
2+
// Copyright (c) 2025, Arm Limited and affiliates.
3+
//
4+
// Part of the Arm Toolchain project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
9+
// ARMv7-A exception handling
10+
11+
#ifndef BOOTCODE_EXCEPTIONS_7A_H
12+
#define BOOTCODE_EXCEPTIONS_7A_H
13+
14+
#include "exceptions_common.h"
15+
#include "system_registers_a.h"
16+
#include <stdlib.h>
17+
18+
namespace bootcode {
19+
namespace exceptions {
20+
21+
using namespace sysreg;
22+
23+
EXFN_ATTR void handle_reset() {
24+
print_str("CPU Exception: Reset\n");
25+
abort();
26+
}
27+
28+
EXFN_ATTR void handle_undefined() {
29+
unsigned pc_val = __arm_rsr("ELR_hyp");
30+
unsigned instr = *(unsigned *)pc_val;
31+
print_str("CPU Exception: Undefined Instruction\n");
32+
print_str(" PC = ");
33+
print_hex(pc_val);
34+
print_str("\n");
35+
print_str(" Instruction = ");
36+
print_hex(instr);
37+
print_str("\n");
38+
abort();
39+
}
40+
41+
EXFN_ATTR void handle_svc_hyp_smc() {
42+
print_str("CPU Exception: SVC, HVC or SMC\n");
43+
print_str(" PC = ");
44+
print_hex(__arm_rsr("ELR_hyp"));
45+
print_str("\n");
46+
abort();
47+
}
48+
49+
EXFN_ATTR void handle_prefetch_abort() {
50+
print_str("CPU Exception: Prefetch Abort\n");
51+
print_str(" PC = ");
52+
print_hex(__arm_rsr("ELR_hyp"));
53+
print_str("\n");
54+
print_str(" IFSR = 0x%08x\n");
55+
print_str(" IFAR = 0x%08x\n");
56+
abort();
57+
}
58+
59+
EXFN_ATTR void handle_data_abort() {
60+
print_str("CPU Exception: Data Abort\n");
61+
print_str(" PC = ");
62+
print_hex(__arm_rsr("ELR_hyp"));
63+
print_str("\n");
64+
print_str(" DFSR = 0x%08x\n");
65+
print_str(" DFAR = 0x%08x\n");
66+
abort();
67+
}
68+
69+
EXFN_ATTR void handle_hyp_trap() {
70+
print_str("CPU Exception: Hypervisor Trap\n");
71+
print_str(" PC = ");
72+
print_hex(__arm_rsr("ELR_hyp"));
73+
print_str("\n");
74+
print_str(" HSR = 0x%08x\n");
75+
abort();
76+
}
77+
78+
EXFN_ATTR void handle_irq() {
79+
print_str("CPU Exception: IRQ\n");
80+
print_str(" PC = ");
81+
print_hex(__arm_rsr("ELR_hyp"));
82+
print_str("\n");
83+
abort();
84+
}
85+
86+
EXFN_ATTR void handle_fiq() {
87+
print_str("CPU Exception: FIQ\n");
88+
print_str(" PC = ");
89+
print_hex(__arm_rsr("ELR_hyp"));
90+
print_str("\n");
91+
abort();
92+
}
93+
94+
// The AArch32 exception vector table has 8 entries, each of which is 4
95+
// bytes long, and contains code. The whole table must be 32-byte aligned.
96+
// The table may also be relocated, so we make it position-independent by
97+
// having a table of handler addresses and loading the address to pc.
98+
__attribute__((naked, section(".vectors"), aligned(32))) void vector_table() {
99+
asm("LDR pc, [pc, #24]");
100+
asm("LDR pc, [pc, #24]");
101+
asm("LDR pc, [pc, #24]");
102+
asm("LDR pc, [pc, #24]");
103+
asm("LDR pc, [pc, #24]");
104+
asm("LDR pc, [pc, #24]");
105+
asm("LDR pc, [pc, #24]");
106+
asm("LDR pc, [pc, #24]");
107+
asm(".word %0" : : "X"(handle_reset));
108+
asm(".word %0" : : "X"(handle_undefined));
109+
asm(".word %0" : : "X"(handle_svc_hyp_smc));
110+
asm(".word %0" : : "X"(handle_prefetch_abort));
111+
asm(".word %0" : : "X"(handle_data_abort));
112+
asm(".word %0" : : "X"(handle_hyp_trap));
113+
asm(".word %0" : : "X"(handle_irq));
114+
asm(".word %0" : : "X"(handle_fiq));
115+
}
116+
117+
} // namespace exceptions
118+
} // namespace bootcode
119+
120+
#endif // BOOTCODE_EXCEPTIONS_7A_H

0 commit comments

Comments
 (0)