From ba39d23a189f3ba017deedfa497d95565e6e2ec5 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Fri, 10 Apr 2026 14:40:21 +0200 Subject: [PATCH] adds hooks in bootup do move smp booting into the smp port lib --- port/moonlight/src/bootup.c | 70 ++--------- port/moonlight/src/trap_non_vectored.c | 7 -- port/threadx/CMakeLists.txt | 4 +- port/threadx_smp/CMakeLists.txt | 10 +- ...tx_initialize_low_level.S => trap_entry.S} | 95 ++------------- .../threadx_smp/src/tx_initialize_low_level.c | 113 ++++++++++++++++++ 6 files changed, 143 insertions(+), 156 deletions(-) rename port/threadx_smp/src/{tx_initialize_low_level.S => trap_entry.S} (50%) create mode 100644 port/threadx_smp/src/tx_initialize_low_level.c diff --git a/port/moonlight/src/bootup.c b/port/moonlight/src/bootup.c index af34dcd..998cf41 100644 --- a/port/moonlight/src/bootup.c +++ b/port/moonlight/src/bootup.c @@ -6,20 +6,15 @@ */ +#include #include #include -//#include -#include -//#include #include #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C extern #endif -#if defined(TX_THREAD_SMP_MAX_CORES) && (TX_THREAD_SMP_MAX_CORES > 1) -#define BOOTUP_SMP_ENABLED -#endif // Generic C function pointer. typedef void(*function_t)(void) ; @@ -49,8 +44,9 @@ EXTERN_C void _start(void) __attribute__ ((naked,section(".text.boot"))); // Entry and exit points as C functions. EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".text.boot"))); -EXTERN_C void _secondary_sleep_forever(void) __attribute__ ((noreturn,section(".text.boot"))); +EXTERN_C void _secondary_initialize(void) __attribute__ ((noreturn,section(".text.boot"),weak)); EXTERN_C void _exit(int exit_code) __attribute__ ((noreturn,noinline,weak)); +EXTERN_C void bootup_wake_secondary_cores(void) __attribute__ ((weak)); // Standard entry point, no arguments. extern int main(void); @@ -59,52 +55,6 @@ extern int main(void); EXTERN_C void _set_tls(uint8_t*) __attribute__ ((noreturn,section(".text.boot"))); #endif -#if defined BOOTUP_SMP_ENABLED -EXTERN_C void _secondary_initialize(void) __attribute__ ((noreturn,section(".text.boot"))); -EXTERN_C void _secondary_ipi_trap(void) __attribute__ ((naked,noreturn,section(".text.boot"))); -EXTERN_C void _tx_thread_smp_initialize_wait(void) __attribute__ ((noreturn)); - -void _secondary_initialize(void) { - csr_write_mtvec((uint_xlen_t)_secondary_ipi_trap); - csr_set_bits_mie(MIE_MSI_BIT_MASK); - csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK); - - __asm__ volatile ("wfi"); - - csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK); - - _tx_thread_smp_initialize_wait(); -} - -void _secondary_ipi_trap(void) { -#if __riscv_xlen == 64 - __asm__ volatile ("addi sp, sp, -16;" - "sd ra, 8(sp);" - "call bootup_ipi_clear_handler;" - "ld ra, 8(sp);" - "addi sp, sp, 16;" - "mret"); -#else - __asm__ volatile ("addi sp, sp, -8;" - "sw ra, 4(sp);" - "call bootup_ipi_clear_handler;" - "lw ra, 4(sp);" - "addi sp, sp, 8;" - "mret"); -#endif -} - -static void bootup_wake_secondary_cores(void) { - for (UINT core = 1; core < TX_THREAD_SMP_MAX_CORES; ++core) { - send_ipi(core); - } -} - -__attribute__((used)) void bootup_ipi_clear_handler(void) { - set_aclint_msip(aclint, csr_read_mhartid(), 0); -} -#endif - // The linker script will place this in the reset entry point. // It will be 'called' with no stack or C runtime configuration. // tp will not be initialized @@ -137,11 +87,7 @@ void _start(void) { "j 1b;" "2:;" "beqz t0, 3f;" -#ifdef BOOTUP_SMP_ENABLED "jal zero, _secondary_initialize;" -#else - "jal zero, _secondary_sleep_forever;" -#endif "3:;" "jal zero, _initialize;" : /* output: none %0 */ @@ -167,9 +113,7 @@ void _initialize(void) { ++entry) { (*entry)(); } -#ifdef BOOTUP_SMP_ENABLED bootup_wake_secondary_cores(); -#endif #ifdef __THREAD_LOCAL_STORAGE _set_tls(__tls_base) #endif @@ -183,7 +127,8 @@ void _initialize(void) { _exit(rc); } -void _secondary_sleep_forever(void) { +void _secondary_initialize(void) { + // sleep forever csr_clr_bits_mie(MIE_MTI_BIT_MASK); csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK); while (1) { @@ -191,6 +136,9 @@ void _secondary_sleep_forever(void) { } } +void bootup_wake_secondary_cores(void) { +} + // This should never be called. Report the exit code through HTIF and idle the CPU. void _exit(int exit_code) { uintptr_t htif_exit_code = (((uintptr_t)(unsigned int)exit_code) << 1) | 1u; @@ -201,4 +149,4 @@ void _exit(int exit_code) { while (1) { __asm__ volatile ("wfi"); } -} \ No newline at end of file +} diff --git a/port/moonlight/src/trap_non_vectored.c b/port/moonlight/src/trap_non_vectored.c index 51ef423..f045c16 100644 --- a/port/moonlight/src/trap_non_vectored.c +++ b/port/moonlight/src/trap_non_vectored.c @@ -30,13 +30,6 @@ void trap_handler(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) { if(OS_IS_INTERRUPT(mcause)) { unsigned irq_id = mcause&(__riscv_xlen-1); switch(irq_id){ -/* -#ifdef TX_THREAD_SMP_INTER_CORE_INTERRUPT - case RISCV_INT_MSI: - set_aclint_msip(aclint, csr_read_mhartid(), 0); - break; -#endif -*/ default: if(irq_handler[irq_id]) irq_handler[irq_id](); diff --git a/port/threadx/CMakeLists.txt b/port/threadx/CMakeLists.txt index c33c86e..648dfae 100644 --- a/port/threadx/CMakeLists.txt +++ b/port/threadx/CMakeLists.txt @@ -1,5 +1,5 @@ - -if(NOT DEFINED THREADX_LOW_LEVEL_INIT_SOURCE) #required for tests to hook into the ISR path +#required for tests to hook into the ISR path +if(NOT DEFINED THREADX_LOW_LEVEL_INIT_SOURCE) set(THREADX_LOW_LEVEL_INIT_SOURCE ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c) endif() diff --git a/port/threadx_smp/CMakeLists.txt b/port/threadx_smp/CMakeLists.txt index 6095b7e..302ded8 100644 --- a/port/threadx_smp/CMakeLists.txt +++ b/port/threadx_smp/CMakeLists.txt @@ -10,8 +10,16 @@ set(THREADX_SMP_CUSTOM_INC ${CMAKE_CURRENT_SOURCE_DIR}/inc ${CMAKE_CURRENT_SOURCE_DIR}/../moonlight/inc # needed for Moonlight SMP support headers ) + +#required for tests to hook into the ISR path +if(NOT DEFINED THREADX_LOW_LEVEL_INIT_SOURCE) + set(THREADX_LOW_LEVEL_INIT_SOURCE + ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c) +endif() + set(THREADX_SMP_CUSTOM_SRC - src/tx_initialize_low_level.S + src/trap_entry.S + ${THREADX_LOW_LEVEL_INIT_SOURCE} src/tx_thread_context_restore.S src/tx_thread_context_save.S src/tx_thread_interrupt_control.S diff --git a/port/threadx_smp/src/tx_initialize_low_level.S b/port/threadx_smp/src/trap_entry.S similarity index 50% rename from port/threadx_smp/src/tx_initialize_low_level.S rename to port/threadx_smp/src/trap_entry.S index 5a4951f..d7ae196 100644 --- a/port/threadx_smp/src/tx_initialize_low_level.S +++ b/port/threadx_smp/src/trap_entry.S @@ -7,12 +7,9 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ - -#include "csr.h" -#include "tx_port.h" - .section .text .align 4 + #include "tx_port.h" /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -73,92 +70,20 @@ STORE x1, 28*REGBYTES(sp) // Store RA, 28*REGBYTES(because call will override ra [ra is a calle register in riscv]) - call _tx_thread_context_save + call _tx_thread_context_save csrr a0, mcause csrr a1, mepc csrr a2, mtval addi sp, sp, -8 - STORE ra, 0(sp) - call trap_handler - LOAD ra, 0(sp) - addi sp, sp, 8 + STORE ra, 0(sp) + call trap_handler + LOAD ra, 0(sp) + addi sp, sp, 8 call _tx_thread_context_restore // it will nerver return .weak trap_handler - trap_handler: - 1: - j 1b - -.section .text -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _tx_initialize_low_level RISC-V64/GNU */ -/* 6.2.1 */ -/* AUTHOR */ -/* */ -/* Scott Larson, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function is responsible for any low-level processor */ -/* initialization, including setting up interrupt vectors, setting */ -/* up a periodic timer interrupt source, saving the system stack */ -/* pointer for use in ISR processing later, and finding the first */ -/* available RAM memory address for tx_application_define. */ -/* */ -/* INPUT */ -/* */ -/* None */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* None */ -/* */ -/* CALLED BY */ -/* */ -/* _tx_initialize_kernel_enter ThreadX entry function */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ -/* */ -/**************************************************************************/ -/* VOID _tx_initialize_low_level(VOID) -*/ - .global _tx_initialize_low_level - .weak _tx_initialize_low_level - .extern __heap_start - .extern board_init -_tx_initialize_low_level: - STORE sp, _tx_thread_system_stack_ptr, t0 // Save system stack pointer - - la t0, __heap_start // Pickup first free address - STORE t0, _tx_initialize_unused_memory, t1 // Save unused memory address - li t0, MSTATUS_MIE - csrrc zero, mstatus, t0 // clear MSTATUS_MIE bit - li t0, (MSTATUS_MPP_M | MSTATUS_MPIE ) - csrrs zero, mstatus, t0 // set MSTATUS_MPP, MPIE bit - li t0, (MIE_MTIE | MIE_MSIE | MIE_MEIE) - csrrs zero, mie, t0 // set mie -#ifdef __riscv_flen - li t0, MSTATUS_FS - csrrs zero, mstatus, t0 // set MSTATUS_FS bit to open f/d isa in riscv - fscsr x0 -#endif - addi sp, sp, -8 - STORE ra, 0(sp) - call board_init - LOAD ra, 0(sp) - addi sp, sp, 8 - la t0, trap_entry - csrw mtvec, t0 - ret +trap_handler: +1: + j 1b + .section .text \ No newline at end of file diff --git a/port/threadx_smp/src/tx_initialize_low_level.c b/port/threadx_smp/src/tx_initialize_low_level.c new file mode 100644 index 0000000..e091edd --- /dev/null +++ b/port/threadx_smp/src/tx_initialize_low_level.c @@ -0,0 +1,113 @@ + +#include "aclint.h" +#include "aclint_ipi.h" +#include "board.h" +#include "csr.h" +#include "hwtimer.h" +#include "riscv-csr.h" +#include "riscv-traps.h" +#include "tx_port.h" +#include + +extern CHAR __heap_start; +extern void trap_entry(void); +extern void _tx_timer_interrupt(void); + +extern ULONG* _tx_thread_system_stack_ptr; +extern ULONG* _tx_initialize_unused_memory; +extern void _tx_thread_smp_initialize_wait(void) __attribute__((noreturn)); + +void handle_RISCV_INT_MTI(void) +{ + hwtimer_handler(); + _tx_timer_interrupt(); +} + +void handle_RISCV_INT_MEI() +{ + puts("[INTERRUPT]: handler ext irq error!\n"); + while (1) + ; +} + +#ifdef TX_THREAD_SMP_INTER_CORE_INTERRUPT +void handle_RISCV_INT_MSI() +{ + set_aclint_msip(aclint, csr_read_mhartid(), 0); +} +#endif + +static void __attribute__((used)) bootup_ipi_clear_handler(void) +{ + set_aclint_msip(aclint, csr_read_mhartid(), 0); +} + +void _secondary_ipi_trap(void) __attribute__((naked, noreturn, section(".text.boot"))); +void _secondary_initialize(void) __attribute__((noreturn, section(".text.boot"))); +void bootup_wake_secondary_cores(void); + +void _secondary_initialize(void) +{ + csr_write_mtvec((uint_xlen_t)_secondary_ipi_trap); + csr_set_bits_mie(MIE_MSI_BIT_MASK); + csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK); + + __asm__ volatile("wfi"); + + csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK); + + _tx_thread_smp_initialize_wait(); +} + +void _secondary_ipi_trap(void) +{ +#if __riscv_xlen == 64 + __asm__ volatile("addi sp, sp, -16;" + "sd ra, 8(sp);" + "call bootup_ipi_clear_handler;" + "ld ra, 8(sp);" + "addi sp, sp, 16;" + "mret"); +#else + __asm__ volatile("addi sp, sp, -8;" + "sw ra, 4(sp);" + "call bootup_ipi_clear_handler;" + "lw ra, 4(sp);" + "addi sp, sp, 8;" + "mret"); +#endif +} + +void bootup_wake_secondary_cores(void) +{ + for (UINT core = 1; core < TX_THREAD_SMP_MAX_CORES; ++core) { + send_ipi(core); + } +} + +VOID _tx_initialize_low_level(VOID) +{ + _tx_thread_system_stack_ptr = (VOID*)(ULONG)riscv_get_sp(); + _tx_initialize_unused_memory = (VOID*)&__heap_start; + + // disable interrupts + asm volatile("csrrc zero, mstatus, %0" : : "r"(MSTATUS_MIE)); + // set previous interrupt enable and previous priv mode to be set when executing "mret" + asm volatile("csrrs zero, mstatus, %0" : : "r"(MSTATUS_MPP_M | MSTATUS_MPIE)); + // enable timer, software and external interrupts + asm volatile("csrrs zero, mie, %0" : : "r"(MIE_MTIE | MIE_MSIE | MIE_MEIE)); + +#ifdef __riscv_flen + // enable f extension and reset state + asm volatile("csrrs zero, mstatus, %0" : : "r"(MSTATUS_FS)); + asm volatile("fscsr x0"); +#endif + + board_init(); + register_irq_handler(RISCV_INT_MTI, handle_RISCV_INT_MTI); + register_irq_handler(RISCV_INT_MEI, handle_RISCV_INT_MEI); +#ifdef TX_THREAD_SMP_INTER_CORE_INTERRUPT + register_irq_handler(RISCV_INT_MSI, handle_RISCV_INT_MSI); +#endif + asm volatile("csrw mtvec, %0" : : "r"((uintptr_t)trap_entry)); +}