adds hooks in bootup do move smp booting into the smp port lib

This commit is contained in:
2026-04-10 14:40:21 +02:00
parent d97e71ca83
commit ba39d23a18
6 changed files with 143 additions and 156 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 <stdio.h>
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));
}