From 023274dd4f8ccb95e01d526731225cd2f40abd2d Mon Sep 17 00:00:00 2001 From: Daniel Rossier Date: Mon, 29 Sep 2025 14:07:03 +0200 Subject: [PATCH 1/4] Fix use of bad stack in EL1 mode --- so3/arch/arm64/exception.S | 4 ++-- so3/arch/arm64/head.S | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/so3/arch/arm64/exception.S b/so3/arch/arm64/exception.S index bde52f61b..4688b0b6e 100644 --- a/so3/arch/arm64/exception.S +++ b/so3/arch/arm64/exception.S @@ -226,7 +226,7 @@ ENTRY(pre_ret_to_el1_with_spin) // Set the CPU in EL1 mode to proceed with // the bootstrap of the domain - mov x2, #PSR_MODE_EL1t + mov x2, #PSR_MODE_EL1h // Make sure no interrupt coming from CPU #0 is // interferring with other CPU bootstrap @@ -271,7 +271,7 @@ ENTRY(pre_ret_to_el1) // Set the CPU in EL1 mode to proceed with // the bootstrap of the domain - mov x2, #PSR_MODE_EL1t + mov x2, #PSR_MODE_EL1h // Make sure no interrupt coming from CPU #0 is // interferring with other CPU bootstrap diff --git a/so3/arch/arm64/head.S b/so3/arch/arm64/head.S index 640803d88..1996af76e 100644 --- a/so3/arch/arm64/head.S +++ b/so3/arch/arm64/head.S @@ -424,7 +424,7 @@ install_el2_stub: msr vbar_el2, x0 /* spsr */ - mov x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL1t) + mov x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL1h) msr spsr_el2, x0 msr elr_el2, lr mov w0, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2 From 5777f59b847fffbfd03b8dfd77b9310dafe28c8a Mon Sep 17 00:00:00 2001 From: Daniel Rossier Date: Mon, 29 Sep 2025 16:20:15 +0200 Subject: [PATCH 2/4] Remove call to __stdio_exit() in libc (dabt crash randomly) --- so3/arch/arm64/traps.c | 7 ++++++- so3/kernel/schedule.c | 3 ++- usr/lib/libc/exit/exit.c | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/so3/arch/arm64/traps.c b/so3/arch/arm64/traps.c index b94ea34bd..5501e7de6 100644 --- a/so3/arch/arm64/traps.c +++ b/so3/arch/arm64/traps.c @@ -118,6 +118,8 @@ typedef void (*vector_fn_t)(cpu_regs_t *); void trap_handle(cpu_regs_t *regs) { + int ret = 0; + #ifndef CONFIG_AVZ syscall_args_t sys_args; #endif @@ -141,7 +143,9 @@ void trap_handle(cpu_regs_t *regs) switch (ESR_ELx_EC(esr)) { case ESR_ELx_EC_DABT_LOW: - dabt_handle(regs, esr); + ret = dabt_handle(regs, esr); + if (ret == -1) + goto __err; break; /* SVC used for syscalls */ @@ -247,6 +251,7 @@ void trap_handle(cpu_regs_t *regs) #endif default: +__err: lprintk("### On CPU %d: ESR_Elx_EC(esr): 0x%lx\n", smp_processor_id(), ESR_ELx_EC(esr)); trap_handle_error(regs->lr); kernel_panic(); diff --git a/so3/kernel/schedule.c b/so3/kernel/schedule.c index 6cb12fa2a..2fb62fc73 100644 --- a/so3/kernel/schedule.c +++ b/so3/kernel/schedule.c @@ -444,7 +444,8 @@ void schedule(void) LOG_DEBUG("Now scheduling thread ID: %d name: %s PID: %d prio: %d\n", next->tid, next->name, ((next->pcb != NULL) ? next->pcb->pid : -1), next->prio); if (prev) - LOG_DEBUG("Previous was threadID: %d name: %s PID: %d\n", prev->tid, prev->name); + LOG_DEBUG("Previous was threadID: %d name: %s PID: %d\n", prev->tid, prev->name, + (next->pcb != NULL) ? next->pcb->pid : -1); /* * The current threads (here prev) can be in different states, not only running; it may be in *waiting* or *zombie* diff --git a/usr/lib/libc/exit/exit.c b/usr/lib/libc/exit/exit.c index 42feb6703..5d786a3f7 100644 --- a/usr/lib/libc/exit/exit.c +++ b/usr/lib/libc/exit/exit.c @@ -29,6 +29,15 @@ _Noreturn void exit(int code) { __funcs_on_exit(); __libc_exit_fini(); + +#warning __stdio_exit() issue + /* + * Currently, this function causes a data abort fault randomly. The effect + * is visible on RPi4 (64-bit) more rarely on virt64 + */ +#if 0 __stdio_exit(); +#endif /* 0 */ + _Exit(code); } From b5e7040800a171ec8470f31c9899570a5bd4fc01 Mon Sep 17 00:00:00 2001 From: Daniel Rossier Date: Mon, 29 Sep 2025 16:27:14 +0200 Subject: [PATCH 3/4] Remove other functions in exit() which also lead to crash --- usr/lib/libc/exit/exit.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/usr/lib/libc/exit/exit.c b/usr/lib/libc/exit/exit.c index 5d786a3f7..a436c19d3 100644 --- a/usr/lib/libc/exit/exit.c +++ b/usr/lib/libc/exit/exit.c @@ -27,15 +27,14 @@ weak_alias(libc_exit_fini, __libc_exit_fini); _Noreturn void exit(int code) { - __funcs_on_exit(); - __libc_exit_fini(); - -#warning __stdio_exit() issue + #warning exit() issue /* - * Currently, this function causes a data abort fault randomly. The effect + * Currently, the following code leads to data abort fault randomly. The effect * is visible on RPi4 (64-bit) more rarely on virt64 */ #if 0 + __funcs_on_exit(); + __libc_exit_fini(); __stdio_exit(); #endif /* 0 */ From 3f5516b74fee6a430331298432ae3c21f3a0a852 Mon Sep 17 00:00:00 2001 From: Daniel Rossier Date: Mon, 29 Sep 2025 17:12:57 +0200 Subject: [PATCH 4/4] Fix LOG_DEBUG issue in early booting --- so3/arch/arm64/mmu.c | 8 ++++++-- so3/mm/memory.c | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/so3/arch/arm64/mmu.c b/so3/arch/arm64/mmu.c index c9cb5161a..b219a2604 100644 --- a/so3/arch/arm64/mmu.c +++ b/so3/arch/arm64/mmu.c @@ -30,6 +30,10 @@ #include #include +/* We disable these logs here because the UART is difficult to manage during the I/O re-mapping. */ +#undef LOG_DEBUG +#define LOG_DEBUG(fmt, ...) + void *__current_pgtable = NULL; void *current_pgtable(void) @@ -675,8 +679,8 @@ void mmu_configure(addr_t fdt_addr) /* Early mapping I/O for UART. Here, the UART is supposed to be in a different L1 entry than the RAM. */ #ifdef CONFIG_VA_BITS_48 - __sys_idmap_l1pgtable[l1pte_index(CONFIG_UART_LL_PADDR)] = CONFIG_UART_LL_PADDR & TTB_L1_BLOCK_ADDR_MASK; - set_pte_block(&__sys_idmap_l1pgtable[l1pte_index(CONFIG_UART_LL_PADDR)], DCACHE_OFF); + __sys_idmap_l1pgtable[l1pte_index(CONFIG_UART_LL_PADDR)] = CONFIG_UART_LL_PADDR & TTB_L1_BLOCK_ADDR_MASK; + set_pte_block(&__sys_idmap_l1pgtable[l1pte_index(CONFIG_UART_LL_PADDR)], DCACHE_OFF); #elif CONFIG_VA_BITS_39 __sys_root_pgtable[l1pte_index(CONFIG_UART_LL_PADDR)] = CONFIG_UART_LL_PADDR & TTB_L1_BLOCK_ADDR_MASK; set_pte_block(&__sys_root_pgtable[l1pte_index(CONFIG_UART_LL_PADDR)], DCACHE_OFF); diff --git a/so3/mm/memory.c b/so3/mm/memory.c index 0eae06078..bd0d103a0 100644 --- a/so3/mm/memory.c +++ b/so3/mm/memory.c @@ -54,6 +54,13 @@ static uint32_t kernel_size; /* Current available I/O range address */ struct list_head io_maplist; +/** + * @brief This function is called early during the bootstrap by head.S + * There is no MMU activated and all adresses are physical. + * DO NOT PRINT ANYTHING IN THIS FUNCTION. + * + * @param fdt_paddr + */ void early_memory_init(void *fdt_paddr) { int offset; @@ -65,8 +72,6 @@ void early_memory_init(void *fdt_paddr) __fdt_addr = (void *) __va(fdt_paddr); #endif - if (offset >= 0) - LOG_DEBUG("Found %d MB of RAM at 0x%08X", mem_info.size / SZ_1M, mem_info.phys_base); } uint32_t get_kernel_size(void)