diff --git a/patches/picolibc/0001-Enable-libcxx-builds.patch b/patches/picolibc/0001-Enable-libcxx-builds.patch index 7960ca12..ef76bb9c 100644 --- a/patches/picolibc/0001-Enable-libcxx-builds.patch +++ b/patches/picolibc/0001-Enable-libcxx-builds.patch @@ -1,4 +1,4 @@ -From 028fe75e045951a9d091008a85971523358160db Mon Sep 17 00:00:00 2001 +From bd1dcaa0e3e77260e264cc0c2580bf32f704a0ed Mon Sep 17 00:00:00 2001 From: Simi Pallipurath Date: Thu, 14 Nov 2024 10:07:08 +0000 Subject: Enable libcxx builds @@ -11,10 +11,10 @@ libc++ builds. 2 files changed, 15 insertions(+) diff --git a/meson.build b/meson.build -index 012d664bd..4161d6574 100644 +index b8f43c800..9d3f5c672 100644 --- a/meson.build +++ b/meson.build -@@ -1318,6 +1318,18 @@ if get_option('newlib-retargetable-locking') != get_option('newlib-multithread') +@@ -1319,6 +1319,18 @@ if get_option('newlib-retargetable-locking') != get_option('newlib-multithread') error('newlib-retargetable-locking and newlib-multithread must be set to the same value') endif @@ -48,5 +48,5 @@ index 7b63ba172..cda5e1e7e 100644 KEEP (*(.fini .fini.*)) @PREFIX@__text_end = .; -- -2.39.5 (Apple Git-154) +2.43.0 diff --git a/patches/picolibc/0002-Add-bootcode-for-AArch64-FVPs.patch b/patches/picolibc/0002-Add-bootcode-for-AArch64-FVPs.patch deleted file mode 100644 index 6cd23938..00000000 --- a/patches/picolibc/0002-Add-bootcode-for-AArch64-FVPs.patch +++ /dev/null @@ -1,888 +0,0 @@ -From 58451642e678817d8822b04b8ff07ee4758a8f10 Mon Sep 17 00:00:00 2001 -From: Simi Pallipurath -Date: Thu, 14 Nov 2024 10:12:33 +0000 -Subject: Add bootcode for AArch64 FVPs - -The AArch64 FVP (Fixed Virtual Platform) models differ from QEMU in a -few ways which affect the crt0 code: - -* The memory map is different, so needs different page tables. -* They boot up at EL3, instead of EL1, so we need to set the EL3 versions of the system registers. -* Add option to build crt0 bootcode for different machines -* Build new FVP variants of crt0, instead of replacing QEMU ones -* Split assembly parts of AArch64 crt0 into a separate file -* Make error checking target-specific ---- - meson.build | 1 + - meson_options.txt | 3 + - picocrt/machine/aarch64/crt0.S | 200 +++++++++++++++++++ - picocrt/machine/aarch64/crt0.c | 198 +++---------------- - picocrt/machine/aarch64/meson.build | 9 +- - picocrt/machine/arm/meson.build | 7 + - picocrt/meson.build | 296 ++++++++++++++++------------ - 7 files changed, 411 insertions(+), 303 deletions(-) - create mode 100644 picocrt/machine/aarch64/crt0.S - -diff --git a/meson.build b/meson.build -index 012d664bd..b8f43c800 100644 ---- a/meson.build -+++ b/meson.build -@@ -151,6 +151,7 @@ multilib_exclude = get_option('multilib-exclude') - enable_picolib = get_option('picolib') - enable_picocrt = get_option('picocrt') - enable_picocrt_lib = get_option('picocrt-lib') -+test_machine = get_option('test-machine') - enable_semihost = get_option('semihost') - enable_tests = get_option('tests') - if get_option('tests-cdefs') == 'auto' -diff --git a/meson_options.txt b/meson_options.txt -index e0eacb443..766129ebd 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -132,6 +132,9 @@ option('test-stdin', type: 'boolean', value: false, - description: 'Enable tests that use stdin. This only works on a few targets') - option('fortify-source', type: 'combo', choices: ['none', '1', '2', '3'], value: '3', - description: 'Set _FORTIFY_SOURCE= when building tests') -+option('test-machine', type: 'string', value: 'qemu', -+ description: 'Machine-specific startup code to use when running tests') -+ - - option('tinystdio', type: 'boolean', value: true, - description: 'Use tiny stdio from avr libc') -diff --git a/picocrt/machine/aarch64/crt0.S b/picocrt/machine/aarch64/crt0.S -new file mode 100644 -index 000000000..4cb19854a ---- /dev/null -+++ b/picocrt/machine/aarch64/crt0.S -@@ -0,0 +1,200 @@ -+/************ Page table ************/ -+/* -+ * The smallest VA we can construct is 8GB, which needs 8 block page table -+ * entries, each covering 1GiB. -+ */ -+#define MMU_BLOCK_COUNT 8 -+ -+#define MMU_DESCRIPTOR_VALID (1 << 0) -+#define MMU_DESCRIPTOR_BLOCK (0 << 1) -+#define MMU_DESCRIPTOR_TABLE (1 << 1) -+ -+#define MMU_BLOCK_XN (1LL << 54) -+#define MMU_BLOCK_PXN (1LL << 53) -+#define MMU_BLOCK_CONTIG (1LL << 52) -+#define MMU_BLOCK_DBM (1LL << 51) -+#define MMU_BLOCK_GP (1LL << 50) -+ -+#define MMU_BLOCK_NT (1 << 16) -+#define MMU_BLOCK_OA_BIT 12 -+#define MMU_BLOCK_NG (1 << 11) -+#define MMU_BLOCK_AF (1 << 10) -+#define MMU_BLOCK_SH_BIT 8 -+#define MMU_BLOCK_SH_NS (0 << MMU_BLOCK_SH_BIT) -+#define MMU_BLOCK_SH_OS (2 << MMU_BLOCK_SH_BIT) -+#define MMU_BLOCK_SH_IS (3 << MMU_BLOCK_SH_BIT) -+#define MMU_BLOCK_AP_BIT 6 -+#define MMU_BLOCK_NS (1 << 5) -+#define MMU_BLOCK_ATTR_BIT 2 -+ -+#define MMU_NORMAL_FLAGS (MMU_DESCRIPTOR_VALID | \ -+ MMU_DESCRIPTOR_BLOCK | \ -+ MMU_BLOCK_AF | \ -+ MMU_BLOCK_SH_IS | \ -+ (0 << MMU_BLOCK_ATTR_BIT)) -+ -+#define MMU_DEVICE_FLAGS (MMU_DESCRIPTOR_VALID | \ -+ MMU_DESCRIPTOR_BLOCK | \ -+ MMU_BLOCK_AF | \ -+ (1 << MMU_BLOCK_ATTR_BIT)) -+ -+#define MMU_INVALID_FLAGS 0 -+ -+ .macro start_page_table -+ .section .rodata -+ .global __identity_page_table -+ .balign 65536 -+__identity_page_table: -+ .set block_num, 0 -+ .endm -+ -+ .macro page_table_entries count, flags -+ .rept \count -+ .8byte (block_num << 30) | \flags -+ .set block_num, block_num + 1 -+ .endr -+ .endm -+ -+ .macro end_page_table -+ .size __identity_page_table, MMU_BLOCK_COUNT * 8 -+ .if block_num != MMU_BLOCK_COUNT -+ .error "Wrong number of page table entries" -+ .endif -+ .endm -+ -+#if defined(MACHINE_qemu) -+ start_page_table -+ // [0x0000_0000,0x8000_0000): 2GiB normal memory -+ page_table_entries 2, MMU_NORMAL_FLAGS -+ // [0x8000_0000,0x1_0000_0000): 2GiB device memory -+ page_table_entries 2, MMU_DEVICE_FLAGS -+ // [0x1_0000_0000,0x2_0000_0000): 4GiB un-mapped -+ page_table_entries 4, MMU_INVALID_FLAGS -+ end_page_table -+#elif defined(MACHINE_fvp) -+ start_page_table -+ // [0x0000_0000,0x8000_0000): 2GiB unmapped. This actually contains a lot -+ // of different memory regions and devices, but we don't need any of them -+ // for testing. -+ page_table_entries 2, MMU_INVALID_FLAGS -+ // [0x8000_0000,0x1_0000_0000): 2GiB normal memory -+ page_table_entries 2, MMU_NORMAL_FLAGS -+ // [0x1_0000_0000,0x2_0000_0000): 4GiB un-mapped -+ page_table_entries 4, MMU_INVALID_FLAGS -+ end_page_table -+#else -+#error "Unknown machine type" -+#endif -+ -+ -+/************ Entry point ************/ -+ -+ // Defined in crt0.c -+ .global _cstart -+ .type cstart, %function -+ -+ // _start: Main entry point function, sets up the hardware to the point where -+ // we can execute C code. -+ .section .text.init.enter, "ax", %progbits -+ .global _start -+ .type _start, %function -+_start: -+ /* Use EL-banked stack pointer */ -+ msr SPSel, #1 -+ -+ /* Initialize stack */ -+ adrp x1, __stack -+ add x1, x1, :lo12:__stack -+ mov sp, x1 -+ -+ /* Enable FPU */ -+#if __ARM_FP -+#if defined(MACHINE_qemu) -+ mov x1, #(0x3 << 20) -+ msr CPACR_EL1, x1 -+#elif defined(MACHINE_fvp) -+ mrs x0, CPTR_EL3 -+ /* Clear CPTR_ELx.TFP, to enable FP/SIMD instructions at EL0 and EL1. */ -+ and x0, x0, #~(1<<10) -+ /* Set CPTR_ELx.EZ and .ESM, to enable SVE and SME instructions at EL3. These -+ * bits are ignored for cores which don't have the relevant feature. */ -+ ORR x0, x0, #1<<8 -+ ORR x0, x0, #1<<12 -+ msr CPTR_EL3, x0 -+#else -+#error "Unknown machine type" -+#endif -+#endif // __ARM_FP -+ -+ /* Jump into C code */ -+ bl _cstart -+ .size _start, .-_start -+ -+ -+ -+/************ Exception handlers ************/ -+#ifdef CRT0_SEMIHOST -+ -+ .macro vector_common -+ sub sp, sp, #256 -+ str x0, [sp, #0] -+ str x1, [sp, #8] -+ str x2, [sp, #16] -+ str x3, [sp, #24] -+ str x4, [sp, #32] -+ str x5, [sp, #40] -+ str x6, [sp, #48] -+ str x7, [sp, #56] -+ str x8, [sp, #64] -+ str x9, [sp, #72] -+ str x10, [sp, #80] -+ str x11, [sp, #88] -+ str x12, [sp, #96] -+ str x13, [sp, #104] -+ str x14, [sp, #112] -+ str x15, [sp, #120] -+ str x16, [sp, #128] -+ str x17, [sp, #136] -+ str x18, [sp, #144] -+ str x19, [sp, #152] -+ str x20, [sp, #160] -+ str x21, [sp, #168] -+ str x22, [sp, #176] -+ str x23, [sp, #184] -+ str x24, [sp, #192] -+ str x25, [sp, #200] -+ str x26, [sp, #208] -+ str x27, [sp, #216] -+ str x28, [sp, #224] -+ str x29, [sp, #232] -+ str x30, [sp, #240] -+#if defined(MACHINE_qemu) -+ mrs x0, ELR_EL1 -+#elif defined(MACHINE_fvp) -+ mrs x0, ELR_EL3 -+#else -+#error "Unknown machine type" -+#endif -+ str x0, [sp, #248] -+ mov x0, sp -+ .endm -+ -+ .global aarch64_fault -+ .type aarch64_fault, %function -+ -+ .macro exception_handler name, number -+ .section .init, "ax", %progbits -+ .global aarch64_\name\()_vector -+ .type aarch64_\name\()_vector, %function -+aarch64_\name\()_vector: -+ vector_common -+ mov x1, #\number -+ b aarch64_fault -+ .endm -+ -+ exception_handler sync, 0 -+ exception_handler irq, 1 -+ exception_handler fiq, 2 -+ exception_handler serror, 3 -+ -+#endif // CRT0_SEMIHOST -diff --git a/picocrt/machine/aarch64/crt0.c b/picocrt/machine/aarch64/crt0.c -index affb41fa9..dfe838111 100644 ---- a/picocrt/machine/aarch64/crt0.c -+++ b/picocrt/machine/aarch64/crt0.c -@@ -60,75 +60,11 @@ _set_tls(void *tls) - - #include "../../crt0.h" - --/* -- * We need 4 1GB mappings to cover the usual Normal memory space, -- * which runs from 0x00000000 to 0x7fffffff along with the usual -- * Device space which runs from 0x80000000 to 0xffffffff. However, -- * it looks like the smallest VA we can construct is 8GB, so we'll -- * pad the space with invalid PTEs -- */ --#define MMU_NORMAL_COUNT 2 --#define MMU_DEVICE_COUNT 2 --#define MMU_INVALID_COUNT 4 --extern uint64_t __identity_page_table[MMU_NORMAL_COUNT + MMU_DEVICE_COUNT + MMU_INVALID_COUNT]; -- --#define MMU_DESCRIPTOR_VALID (1 << 0) --#define MMU_DESCRIPTOR_BLOCK (0 << 1) --#define MMU_DESCRIPTOR_TABLE (1 << 1) -- --#define MMU_BLOCK_XN (1LL << 54) --#define MMU_BLOCK_PXN (1LL << 53) --#define MMU_BLOCK_CONTIG (1LL << 52) --#define MMU_BLOCK_DBM (1LL << 51) --#define MMU_BLOCK_GP (1LL << 50) -- --#define MMU_BLOCK_NT (1 << 16) --#define MMU_BLOCK_OA_BIT 12 --#define MMU_BLOCK_NG (1 << 11) --#define MMU_BLOCK_AF (1 << 10) --#define MMU_BLOCK_SH_BIT 8 --#define MMU_BLOCK_SH_NS (0 << MMU_BLOCK_SH_BIT) --#define MMU_BLOCK_SH_OS (2 << MMU_BLOCK_SH_BIT) --#define MMU_BLOCK_SH_IS (3 << MMU_BLOCK_SH_BIT) --#define MMU_BLOCK_AP_BIT 6 --#define MMU_BLOCK_NS (1 << 5) --#define MMU_BLOCK_ATTR_BIT 2 -- --#define MMU_NORMAL_FLAGS (MMU_DESCRIPTOR_VALID | \ -- MMU_DESCRIPTOR_BLOCK | \ -- MMU_BLOCK_AF | \ -- MMU_BLOCK_SH_IS | \ -- (0 << MMU_BLOCK_ATTR_BIT)) -- --#define MMU_DEVICE_FLAGS (MMU_DESCRIPTOR_VALID | \ -- MMU_DESCRIPTOR_BLOCK | \ -- MMU_BLOCK_AF | \ -- (1 << MMU_BLOCK_ATTR_BIT)) -- --#define MMU_INVALID_FLAGS 0 -- --__asm__( -- ".section .rodata\n" -- ".global __identity_page_table\n" -- ".balign 65536\n" -- "__identity_page_table:\n" -- ".set _i, 0\n" -- ".rept " __XSTRING(MMU_NORMAL_COUNT) "\n" -- " .8byte (_i << 30) |" __XSTRING(MMU_NORMAL_FLAGS) "\n" -- " .set _i, _i + 1\n" -- ".endr\n" -- ".set _i, 0\n" -- ".rept " __XSTRING(MMU_DEVICE_COUNT) "\n" -- " .8byte (1 << 31) | (_i << 30) |" __XSTRING(MMU_DEVICE_FLAGS) "\n" -- " .set _i, _i + 1\n" -- ".endr\n" -- ".set _i, 0\n" -- ".rept " __XSTRING(MMU_INVALID_COUNT) "\n" -- " .8byte " __XSTRING(MMU_INVALID_FLAGS) "\n" -- " .set _i, _i + 1\n" -- ".endr\n" -- ".size __identity_page_table, " __XSTRING((MMU_NORMAL_COUNT + MMU_DEVICE_COUNT + MMU_INVALID_COUNT) * 8) "\n" --); -+/* Defined in crt0.S */ -+#define MMU_BLOCK_COUNT 8 -+extern uint64_t __identity_page_table[MMU_BLOCK_COUNT]; -+extern void _start(void); -+extern const void *__vector_table[]; - - #define SCTLR_MMU (1 << 0) - #define SCTLR_A (1 << 1) -@@ -159,12 +95,19 @@ __asm__( - #define TCR_IPS_BIT 32 - #define TCR_IPS_4GB (0LL << TCR_IPS_BIT) - --extern const void *__vector_table[]; -+/* QEMU boots into EL1, and FVPs boot into EL3, so we need to use the correct -+ * system registers. */ -+#if defined(MACHINE_qemu) -+#define BOOT_EL "EL1" -+#elif defined(MACHINE_fvp) -+#define BOOT_EL "EL3" -+#else -+#error "Unknown machine type" -+#endif - --static void __attribute((used)) --_cstart(void) -+void _cstart(void) - { -- uint64_t sctlr_el1; -+ uint64_t sctlr; - - /* Invalidate the cache */ - __asm__("ic iallu"); -@@ -174,7 +117,7 @@ _cstart(void) - * Set up the TCR register to provide a 33bit VA space using - * 4kB pages over 4GB of PA - */ -- __asm__("msr tcr_el1, %x0" :: -+ __asm__("msr tcr_"BOOT_EL", %x0" :: - "r" ((0x1f << TCR_T0SZ_BIT) | - TCR_IRGN0_WB_WA | - TCR_ORGN0_WB_WA | -@@ -184,7 +127,7 @@ _cstart(void) - TCR_IPS_4GB)); - - /* Load the page table base */ -- __asm__("msr ttbr0_el1, %x0" :: "r" (__identity_page_table)); -+ __asm__("msr ttbr0_"BOOT_EL", %x0" :: "r" (__identity_page_table)); - - /* - * Set the memory attributions in the MAIR register: -@@ -192,42 +135,24 @@ _cstart(void) - * Region 0 is Normal memory - * Region 1 is Device memory - */ -- __asm__("msr mair_el1, %x0" :: -+ __asm__("msr mair_"BOOT_EL", %x0" :: - "r" ((0xffLL << 0) | (0x00LL << 8))); - - /* - * Enable caches, and the MMU, disable alignment requirements - * and write-implies-XN - */ -- __asm__("mrs %x0, sctlr_el1" : "=r" (sctlr_el1)); -- sctlr_el1 |= SCTLR_ICACHE | SCTLR_C | SCTLR_MMU; -- sctlr_el1 &= ~(SCTLR_A | SCTLR_WXN); -- __asm__("msr sctlr_el1, %x0" :: "r" (sctlr_el1)); -+ __asm__("mrs %x0, sctlr_"BOOT_EL"" : "=r" (sctlr)); -+ sctlr |= SCTLR_ICACHE | SCTLR_C | SCTLR_MMU; -+ sctlr &= ~(SCTLR_A | SCTLR_WXN); -+ __asm__("msr sctlr_"BOOT_EL", %x0" :: "r" (sctlr)); - __asm__("isb\n"); - - /* Set the vector base address register */ -- __asm__("msr vbar_el1, %x0" :: "r" (__vector_table)); -+ __asm__("msr vbar_"BOOT_EL", %x0" :: "r" (__vector_table)); - __start(); - } - --void __section(".text.init.enter") --_start(void) --{ -- /* Switch to EL1 */ -- __asm__("msr SPSel, #1"); -- -- /* Initialize stack */ -- __asm__("adrp x1, __stack"); -- __asm__("add x1, x1, :lo12:__stack"); -- __asm__("mov sp, x1"); --#if __ARM_FP -- /* Enable FPU */ -- __asm__("mov x1, #(0x3 << 20)"); -- __asm__("msr cpacr_el1,x1"); --#endif -- /* Jump into C code */ -- __asm__("bl _cstart"); --} - - #ifdef CRT0_SEMIHOST - -@@ -269,13 +194,9 @@ static const char *const reasons[] = { - "serror\n" - }; - --#define REASON_SYNC 0 --#define REASON_IRQ 1 --#define REASON_FIQ 2 --#define REASON_SERROR 3 -- --static void __attribute__((used)) --aarch64_fault(struct fault *f, int reason) -+/* Called from assembly wrappers in crt0.S, which fills *f with the register -+ * values at the point the fault happened. */ -+void aarch64_fault(struct fault *f, int reason) - { - int r; - fputs("AARCH64 fault: ", stdout); -@@ -292,69 +213,4 @@ aarch64_fault(struct fault *f, int reason) - _exit(1); - } - --#define VECTOR_COMMON \ -- __asm__("sub sp, sp, #256"); \ -- __asm__("str x0, [sp, #0]"); \ -- __asm__("str x1, [sp, #8]"); \ -- __asm__("str x2, [sp, #16]"); \ -- __asm__("str x3, [sp, #24]"); \ -- __asm__("str x4, [sp, #32]"); \ -- __asm__("str x5, [sp, #40]"); \ -- __asm__("str x6, [sp, #48]"); \ -- __asm__("str x7, [sp, #56]"); \ -- __asm__("str x8, [sp, #64]"); \ -- __asm__("str x9, [sp, #72]"); \ -- __asm__("str x10, [sp, #80]"); \ -- __asm__("str x11, [sp, #88]"); \ -- __asm__("str x12, [sp, #96]"); \ -- __asm__("str x13, [sp, #104]"); \ -- __asm__("str x14, [sp, #112]"); \ -- __asm__("str x15, [sp, #120]"); \ -- __asm__("str x16, [sp, #128]"); \ -- __asm__("str x17, [sp, #136]"); \ -- __asm__("str x18, [sp, #144]"); \ -- __asm__("str x19, [sp, #152]"); \ -- __asm__("str x20, [sp, #160]"); \ -- __asm__("str x21, [sp, #168]"); \ -- __asm__("str x22, [sp, #176]"); \ -- __asm__("str x23, [sp, #184]"); \ -- __asm__("str x24, [sp, #192]"); \ -- __asm__("str x25, [sp, #200]"); \ -- __asm__("str x26, [sp, #208]"); \ -- __asm__("str x27, [sp, #216]"); \ -- __asm__("str x28, [sp, #224]"); \ -- __asm__("str x29, [sp, #232]"); \ -- __asm__("str x30, [sp, #240]"); \ -- __asm__("mrs x0, ELR_EL1\n"); \ -- __asm__("str x0, [sp, #248]"); \ -- __asm__("mrs x0, ESR_EL1\n"); \ -- __asm__("str x0, [sp, #256]"); \ -- __asm__("mrs x0, FAR_EL1\n"); \ -- __asm__("str x0, [sp, #264]"); \ -- __asm__("mov x0, sp") -- --void __section(".init") --aarch64_sync_vector(void) --{ -- VECTOR_COMMON; -- __asm__("mov x1, #" REASON(REASON_SYNC)); -- __asm__("b aarch64_fault"); --} -- --void __section(".init") --aarch64_irq_vector(void) --{ -- VECTOR_COMMON; -- __asm__("mov x1, #" REASON(REASON_IRQ)); -- __asm__("b aarch64_fault"); --} -- --void __section(".init") --aarch64_fiq_vector(void) --{ -- VECTOR_COMMON; -- __asm__("mov x1, #" REASON(REASON_FIQ)); -- __asm__("b aarch64_fault"); --} -- - #endif /* CRT0_SEMIHOST */ -diff --git a/picocrt/machine/aarch64/meson.build b/picocrt/machine/aarch64/meson.build -index 808d691a5..923d32c3b 100644 ---- a/picocrt/machine/aarch64/meson.build -+++ b/picocrt/machine/aarch64/meson.build -@@ -32,4 +32,11 @@ - # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # OF THE POSSIBILITY OF SUCH DAMAGE. - # --src_picocrt += files('crt0.c') -+src_picocrt += files('crt0.c', 'crt0.S') -+ -+picocrt_machines += [ -+ { -+ 'name': 'fvp', -+ 'suffix': '-fvp', -+ }, -+] -diff --git a/picocrt/machine/arm/meson.build b/picocrt/machine/arm/meson.build -index 808d691a5..ecc9a485b 100644 ---- a/picocrt/machine/arm/meson.build -+++ b/picocrt/machine/arm/meson.build -@@ -33,3 +33,10 @@ - # OF THE POSSIBILITY OF SUCH DAMAGE. - # - src_picocrt += files('crt0.c') -+ -+picocrt_machines += [ -+ { -+ 'name': 'fvp', -+ 'suffix': '-fvp', -+ }, -+] -diff --git a/picocrt/meson.build b/picocrt/meson.build -index 76965990f..be8f875be 100644 ---- a/picocrt/meson.build -+++ b/picocrt/meson.build -@@ -36,6 +36,17 @@ - src_picocrt = [] - src_picocrt_none = files('crt0-none.c') - -+# Machine-specific crt0 variants to build. -+picocrt_machines = [ -+ { -+ # Must match a valid value of the 'test-machine' option, and will cause the -+ # MACHINE_ preprocessor macro to be defined when compiling crt0. -+ 'name': 'qemu', -+ # Suffix used on file names, QEMU's is empty because it is the default. -+ 'suffix': '', -+ }, -+] -+ - machine_dir = 'machine' / host_cpu_family - picocrt_march_add='' - if fs.is_dir(machine_dir) -@@ -44,6 +55,16 @@ else - src_picocrt = files('shared/crt0.c') - endif - -+machine_found = false -+foreach machine : picocrt_machines -+ if machine['name'] == test_machine -+ machine_found = true -+ endif -+endforeach -+if not machine_found -+ error(test_machine + ': requested test machine not found') -+endif -+ - foreach target : targets - value = get_variable('target_' + target) - -@@ -60,150 +81,163 @@ foreach target : targets - value = [value[0], new_cflags] - endif - -- if target == '' -- crt_name = 'crt0.o' -- crt_hosted_name = 'crt0-hosted.o' -- crt_minimal_name = 'crt0-minimal.o' -- crt_semihost_name = 'crt0-semihost.o' -- crt_none_name = 'crt0-none.o' -- libcrt_name = 'crt0' -- libcrt_hosted_name = 'crt0-hosted' -- libcrt_minimal_name = 'crt0-minimal' -- libcrt_semihost_name = 'crt0-semihost' -- libcrt_none_name = 'crt0-none' -- else -- crt_name = join_paths(target, 'crt0.o') -- crt_hosted_name = join_paths(target, 'crt0-hosted.o') -- crt_minimal_name = join_paths(target, 'crt0-minimal.o') -- crt_semihost_name = join_paths(target, 'crt0-semihost.o') -- crt_none_name = join_paths(target, 'crt0-none.o') -- libcrt_name = join_paths(target, 'libcrt0') -- libcrt_hosted_name = join_paths(target, 'libcrt0-hosted') -- libcrt_minimal_name = join_paths(target, 'libcrt0-minimal') -- libcrt_semihost_name = join_paths(target, 'libcrt0-semihost') -- libcrt_none_name = join_paths(target, 'libcrt0-none') -- endif -+ foreach machine : picocrt_machines -+ suffix = machine['suffix'] -+ if target == '' -+ crt_name = 'crt0' + suffix + '.o' -+ crt_hosted_name = 'crt0-hosted' + suffix + '.o' -+ crt_minimal_name = 'crt0-minimal' + suffix + '.o' -+ crt_semihost_name = 'crt0-semihost' + suffix + '.o' -+ crt_none_name = 'crt0-none' + suffix + '.o' -+ libcrt_name = 'crt0' + suffix -+ libcrt_hosted_name = 'crt0-hosted' + suffix -+ libcrt_minimal_name = 'crt0-minimal' + suffix -+ libcrt_semihost_name = 'crt0-semihost' + suffix -+ libcrt_none_name = 'crt0-none' + suffix -+ else -+ crt_name = join_paths(target, 'crt0' + suffix + '.o') -+ crt_hosted_name = join_paths(target, 'crt0-hosted' + suffix + '.o') -+ crt_minimal_name = join_paths(target, 'crt0-minimal' + suffix + '.o') -+ crt_semihost_name = join_paths(target, 'crt0-semihost' + suffix + '.o') -+ crt_none_name = join_paths(target, 'crt0-none' + suffix + '.o') -+ libcrt_name = join_paths(target, 'libcrt0' + suffix) -+ libcrt_hosted_name = join_paths(target, 'libcrt0-hosted' + suffix) -+ libcrt_minimal_name = join_paths(target, 'libcrt0-minimal' + suffix) -+ libcrt_semihost_name = join_paths(target, 'libcrt0-semihost' + suffix) -+ libcrt_none_name = join_paths(target, 'libcrt0-none' + suffix) -+ endif - -- crt0_name = 'crt0' + target -- crt0_hosted_name = 'crt0_hosted' + target -- crt0_minimal_name = 'crt0_minimal' + target -- crt0_semihost_name = 'crt0_semihost' + target -- crt0_none_name = 'crt0_none' + target -- -- _c_args = value[1] + arg_fnobuiltin + ['-ffreestanding'] -- _link_args = value[1] + ['-r', '-ffreestanding'] -- -- # The normal variant does not call 'exit' after return from main (c lingo: freestanding execution environment) -- _crt = executable(crt_name, -- src_picocrt, -- include_directories : inc, -- install : true, -- install_dir : instdir, -- c_args : _c_args, -- link_args : _link_args) -- -- set_variable(crt0_name, -- _crt.extract_objects(src_picocrt) -- ) -- -- if enable_picocrt_lib -- static_library(libcrt_name, -- [], -- include_directories : inc, -- install : true, -- install_dir : instdir, -- c_args : _c_args, -- objects: get_variable(crt0_name), -- pic: false) -- endif -+ crt0_name = 'crt0' + target -+ crt0_hosted_name = 'crt0_hosted' + target -+ crt0_minimal_name = 'crt0_minimal' + target -+ crt0_semihost_name = 'crt0_semihost' + target -+ crt0_none_name = 'crt0_none' + target -+ -+ _c_args = value[1] + arg_fnobuiltin + ['-ffreestanding', '-DMACHINE_' + machine['name']] -+ _link_args = value[1] + ['-r', '-ffreestanding'] -+ -+ # The normal variant does not call 'exit' after return from main (c lingo: freestanding execution environment) -+ _crt = executable(crt_name, -+ src_picocrt, -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ c_args : _c_args, -+ link_args : _link_args) -+ -+ if machine['name'] == test_machine -+ set_variable(crt0_name, -+ _crt.extract_objects(src_picocrt) -+ ) -+ endif - -- # The 'hosted' variant calls 'exit' after return from main (c lingo: hosted execution environment) -- _crt = executable(crt_hosted_name, -- src_picocrt, -- include_directories : inc, -- install : true, -- install_dir : instdir, -- c_args : _c_args + ['-DCRT0_EXIT'], -- link_args : _link_args) -- -- set_variable(crt0_hosted_name, -- _crt.extract_objects(src_picocrt) -- ) -- -- if enable_picocrt_lib -- static_library(libcrt_hosted_name, -- [], -- include_directories : inc, -- install : true, -- install_dir : instdir, -- pic: false, -- objects: get_variable(crt0_hosted_name), -- c_args : value[1] + ['-DCRT0_EXIT']) -- endif -+ if enable_picocrt_lib -+ static_library(libcrt_name, -+ [], -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ c_args : _c_args, -+ objects: _crt.extract_objects(src_picocrt), -+ pic: false) -+ endif - -- # The 'minimal' variant doesn't call exit, nor does it invoke any constructors -- _crt = executable(crt_minimal_name, -- src_picocrt, -- include_directories : inc, -- install : true, -- install_dir : instdir, -- c_args : _c_args + ['-DCONSTRUCTORS=0'], -- link_args : _link_args) -- -- set_variable(crt0_minimal_name, -- _crt.extract_objects(src_picocrt) -- ) -- -- if enable_picocrt_lib -- static_library(libcrt_minimal_name, -- [], -- include_directories : inc, -- install : true, -- install_dir : instdir, -- pic: false, -- objects: get_variable(crt0_minimal_name), -- c_args : _c_args + ['-DCONSTRUCTORS=0']) -- endif -+ # The 'hosted' variant calls 'exit' after return from main (c lingo: hosted execution environment) -+ _crt = executable(crt_hosted_name, -+ src_picocrt, -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ c_args : _c_args + ['-DCRT0_EXIT'], -+ link_args : _link_args) -+ -+ if machine['name'] == test_machine -+ set_variable(crt0_hosted_name, -+ _crt.extract_objects(src_picocrt) -+ ) -+ endif - -- if has_arm_semihost -- # The 'semihost' variant calls sys_semihost_get_cmdline to build argv -- # and calls exit when main returns -- _crt = executable(crt_semihost_name, -- src_picocrt, -- include_directories : inc, -- install : true, -- install_dir : instdir, -- c_args : _c_args + ['-DCRT0_EXIT', '-DCRT0_SEMIHOST'], -- link_args : _link_args) -- -- set_variable(crt0_semihost_name, -- _crt.extract_objects(src_picocrt) -- ) -+ if enable_picocrt_lib -+ static_library(libcrt_hosted_name, -+ [], -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ pic: false, -+ objects: _crt.extract_objects(src_picocrt), -+ c_args : value[1] + ['-DCRT0_EXIT']) -+ endif -+ -+ # The 'minimal' variant doesn't call exit, nor does it invoke any constructors -+ _crt = executable(crt_minimal_name, -+ src_picocrt, -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ c_args : _c_args + ['-DCONSTRUCTORS=0'], -+ link_args : _link_args) -+ -+ if machine['name'] == test_machine -+ set_variable(crt0_minimal_name, -+ _crt.extract_objects(src_picocrt) -+ ) -+ endif - - if enable_picocrt_lib -- static_library(libcrt_semihost_name, -+ static_library(libcrt_minimal_name, - [], -- include_directories : inc, -+ include_directories : inc, - install : true, - install_dir : instdir, - pic: false, -- objects: get_variable(crt0_semihost_name), -- c_args : value[1] + ['-DCRT0_EXIT', '-DCRT0_SEMIHOST']) -+ objects: _crt.extract_objects(src_picocrt), -+ c_args : _c_args + ['-DCONSTRUCTORS=0']) - endif -- endif - -- # The 'none' variant is completely empty -- _crt = executable(crt_none_name, -- src_picocrt_none, -- include_directories : inc, -- install : true, -- install_dir : instdir, -- c_args : _c_args, -- link_args : _link_args) -+ if has_arm_semihost -+ # The 'semihost' variant calls sys_semihost_get_cmdline to build argv -+ # and calls exit when main returns -+ _crt = executable(crt_semihost_name, -+ src_picocrt, -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ c_args : _c_args + ['-DCRT0_EXIT', '-DCRT0_SEMIHOST'], -+ link_args : _link_args) -+ -+ if machine['name'] == test_machine -+ set_variable(crt0_semihost_name, -+ _crt.extract_objects(src_picocrt) -+ ) -+ endif - -- set_variable(crt0_none_name, -- _crt.extract_objects(src_picocrt_none) -- ) -+ if enable_picocrt_lib -+ static_library(libcrt_semihost_name, -+ [], -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ pic: false, -+ objects: _crt.extract_objects(src_picocrt), -+ c_args : value[1] + ['-DCRT0_EXIT', '-DCRT0_SEMIHOST']) -+ endif -+ endif -+ -+ # The 'none' variant is completely empty -+ _crt = executable(crt_none_name, -+ src_picocrt_none, -+ include_directories : inc, -+ install : true, -+ install_dir : instdir, -+ c_args : _c_args, -+ link_args : _link_args) -+ -+ if machine['name'] == test_machine -+ set_variable(crt0_none_name, -+ _crt.extract_objects(src_picocrt_none) -+ ) -+ endif - -+ endforeach - - endforeach --- -2.34.1 diff --git a/patches/picolibc/0002-Define-picocrt_machines-for-AArch32-builds-as-well-a.patch b/patches/picolibc/0002-Define-picocrt_machines-for-AArch32-builds-as-well-a.patch new file mode 100644 index 00000000..a18166df --- /dev/null +++ b/patches/picolibc/0002-Define-picocrt_machines-for-AArch32-builds-as-well-a.patch @@ -0,0 +1,29 @@ +From c9a704b1322aec5f699e2962368bbffd286eb010 Mon Sep 17 00:00:00 2001 +From: Simi Pallipurath +Date: Thu, 14 Nov 2024 10:12:33 +0000 +Subject: Define picocrt_machines for AArch32 builds as well as 64. + +Our cmake build command for picolibc unconditionally includes +`-Dtest-machine=...`, which depends on this being defined. +--- + picocrt/machine/arm/meson.build | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/picocrt/machine/arm/meson.build b/picocrt/machine/arm/meson.build +index 808d691a5..ecc9a485b 100644 +--- a/picocrt/machine/arm/meson.build ++++ b/picocrt/machine/arm/meson.build +@@ -33,3 +33,10 @@ + # OF THE POSSIBILITY OF SUCH DAMAGE. + # + src_picocrt += files('crt0.c') ++ ++picocrt_machines += [ ++ { ++ 'name': 'fvp', ++ 'suffix': '-fvp', ++ }, ++] +-- +2.43.0 + diff --git a/patches/picolibc/0003-Add-support-for-strict-align-no-unaligned-access-in-.patch b/patches/picolibc/0003-Add-support-for-strict-align-no-unaligned-access-in-.patch index eb366cc6..1b30ab50 100644 --- a/patches/picolibc/0003-Add-support-for-strict-align-no-unaligned-access-in-.patch +++ b/patches/picolibc/0003-Add-support-for-strict-align-no-unaligned-access-in-.patch @@ -1,4 +1,4 @@ -From 79f3ce1b5f730b0293e8452d4e028e34c0e71736 Mon Sep 17 00:00:00 2001 +From ef4378c3f62947b9ce1eac19b717ac44d5aeecb7 Mon Sep 17 00:00:00 2001 From: Lucas Prates Date: Mon, 11 Nov 2024 16:37:04 +0000 Subject: Add support for strict-align/no-unaligned-access in AArch64 @@ -427,5 +427,5 @@ index 1fccba9f8..2f0cdc0c7 100644 #else -- -2.39.5 (Apple Git-154) +2.43.0 diff --git a/patches/picolibc/0004-ARM-AARCH64-BootCode-Changes-to-enable-the-Alignment.patch b/patches/picolibc/0004-ARM-AARCH64-BootCode-Changes-to-enable-the-Alignment.patch index 0a0bd275..69f8930d 100644 --- a/patches/picolibc/0004-ARM-AARCH64-BootCode-Changes-to-enable-the-Alignment.patch +++ b/patches/picolibc/0004-ARM-AARCH64-BootCode-Changes-to-enable-the-Alignment.patch @@ -1,8 +1,8 @@ -From 11abbd6533eeacbb000fc19bd07316e11fcb6fea Mon Sep 17 00:00:00 2001 +From e6a1281ca4e08c0fe4da97e2dbb8d2bd1f049b1b Mon Sep 17 00:00:00 2001 From: Simi Pallipurath Date: Tue, 26 Nov 2024 15:20:50 +0000 -Subject: [ARM/AARCH64] BootCode Changes to enable the Alignment Check - bit and disable the unaligned access bit +Subject: [ARM/AARCH64] BootCode Changes to enable the Alignment Check bit and + disable the unaligned access bit We need changes in both Arm/AArch64 bootcode in order for the -mno-unaligned-access to work. @@ -64,5 +64,5 @@ index 60efafc9c..e27ccb6a9 100644 __asm__("mcr p15, 0, %0, c1, c0, 0\n" :: "r" (sctlr)); __asm__("isb\n"); -- -2.34.1 +2.43.0