adds hooks in bootup do move smp booting into the smp port lib
This commit is contained in:
@@ -6,20 +6,15 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
//#include <picotls.h>
|
|
||||||
#include <aclint_ipi.h>
|
|
||||||
//#include <tx_port.h>
|
|
||||||
#include <riscv-csr.h>
|
#include <riscv-csr.h>
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define EXTERN_C extern "C"
|
#define EXTERN_C extern "C"
|
||||||
#else
|
#else
|
||||||
#define EXTERN_C extern
|
#define EXTERN_C extern
|
||||||
#endif
|
#endif
|
||||||
#if defined(TX_THREAD_SMP_MAX_CORES) && (TX_THREAD_SMP_MAX_CORES > 1)
|
|
||||||
#define BOOTUP_SMP_ENABLED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Generic C function pointer.
|
// Generic C function pointer.
|
||||||
typedef void(*function_t)(void) ;
|
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.
|
// Entry and exit points as C functions.
|
||||||
EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".text.boot")));
|
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 _exit(int exit_code) __attribute__ ((noreturn,noinline,weak));
|
||||||
|
EXTERN_C void bootup_wake_secondary_cores(void) __attribute__ ((weak));
|
||||||
|
|
||||||
// Standard entry point, no arguments.
|
// Standard entry point, no arguments.
|
||||||
extern int main(void);
|
extern int main(void);
|
||||||
@@ -59,52 +55,6 @@ extern int main(void);
|
|||||||
EXTERN_C void _set_tls(uint8_t*) __attribute__ ((noreturn,section(".text.boot")));
|
EXTERN_C void _set_tls(uint8_t*) __attribute__ ((noreturn,section(".text.boot")));
|
||||||
#endif
|
#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.
|
// The linker script will place this in the reset entry point.
|
||||||
// It will be 'called' with no stack or C runtime configuration.
|
// It will be 'called' with no stack or C runtime configuration.
|
||||||
// tp will not be initialized
|
// tp will not be initialized
|
||||||
@@ -137,11 +87,7 @@ void _start(void) {
|
|||||||
"j 1b;"
|
"j 1b;"
|
||||||
"2:;"
|
"2:;"
|
||||||
"beqz t0, 3f;"
|
"beqz t0, 3f;"
|
||||||
#ifdef BOOTUP_SMP_ENABLED
|
|
||||||
"jal zero, _secondary_initialize;"
|
"jal zero, _secondary_initialize;"
|
||||||
#else
|
|
||||||
"jal zero, _secondary_sleep_forever;"
|
|
||||||
#endif
|
|
||||||
"3:;"
|
"3:;"
|
||||||
"jal zero, _initialize;"
|
"jal zero, _initialize;"
|
||||||
: /* output: none %0 */
|
: /* output: none %0 */
|
||||||
@@ -167,9 +113,7 @@ void _initialize(void) {
|
|||||||
++entry) {
|
++entry) {
|
||||||
(*entry)();
|
(*entry)();
|
||||||
}
|
}
|
||||||
#ifdef BOOTUP_SMP_ENABLED
|
|
||||||
bootup_wake_secondary_cores();
|
bootup_wake_secondary_cores();
|
||||||
#endif
|
|
||||||
#ifdef __THREAD_LOCAL_STORAGE
|
#ifdef __THREAD_LOCAL_STORAGE
|
||||||
_set_tls(__tls_base)
|
_set_tls(__tls_base)
|
||||||
#endif
|
#endif
|
||||||
@@ -183,7 +127,8 @@ void _initialize(void) {
|
|||||||
_exit(rc);
|
_exit(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _secondary_sleep_forever(void) {
|
void _secondary_initialize(void) {
|
||||||
|
// sleep forever
|
||||||
csr_clr_bits_mie(MIE_MTI_BIT_MASK);
|
csr_clr_bits_mie(MIE_MTI_BIT_MASK);
|
||||||
csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK);
|
csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK);
|
||||||
while (1) {
|
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.
|
// This should never be called. Report the exit code through HTIF and idle the CPU.
|
||||||
void _exit(int exit_code) {
|
void _exit(int exit_code) {
|
||||||
uintptr_t htif_exit_code = (((uintptr_t)(unsigned int)exit_code) << 1) | 1u;
|
uintptr_t htif_exit_code = (((uintptr_t)(unsigned int)exit_code) << 1) | 1u;
|
||||||
|
|||||||
@@ -30,13 +30,6 @@ void trap_handler(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) {
|
|||||||
if(OS_IS_INTERRUPT(mcause)) {
|
if(OS_IS_INTERRUPT(mcause)) {
|
||||||
unsigned irq_id = mcause&(__riscv_xlen-1);
|
unsigned irq_id = mcause&(__riscv_xlen-1);
|
||||||
switch(irq_id){
|
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:
|
default:
|
||||||
if(irq_handler[irq_id])
|
if(irq_handler[irq_id])
|
||||||
irq_handler[irq_id]();
|
irq_handler[irq_id]();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
#required for tests to hook into the ISR path
|
||||||
if(NOT DEFINED THREADX_LOW_LEVEL_INIT_SOURCE) #required for tests to hook into the ISR path
|
if(NOT DEFINED THREADX_LOW_LEVEL_INIT_SOURCE)
|
||||||
set(THREADX_LOW_LEVEL_INIT_SOURCE
|
set(THREADX_LOW_LEVEL_INIT_SOURCE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c)
|
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -10,8 +10,16 @@ set(THREADX_SMP_CUSTOM_INC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/inc
|
${CMAKE_CURRENT_SOURCE_DIR}/inc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../moonlight/inc # needed for Moonlight SMP support headers
|
${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
|
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_restore.S
|
||||||
src/tx_thread_context_save.S
|
src/tx_thread_context_save.S
|
||||||
src/tx_thread_interrupt_control.S
|
src/tx_thread_interrupt_control.S
|
||||||
|
|||||||
@@ -7,12 +7,9 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "csr.h"
|
|
||||||
#include "tx_port.h"
|
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
.align 4
|
.align 4
|
||||||
|
#include "tx_port.h"
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FUNCTION RELEASE */
|
/* 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])
|
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 a0, mcause
|
||||||
csrr a1, mepc
|
csrr a1, mepc
|
||||||
csrr a2, mtval
|
csrr a2, mtval
|
||||||
addi sp, sp, -8
|
addi sp, sp, -8
|
||||||
STORE ra, 0(sp)
|
STORE ra, 0(sp)
|
||||||
call trap_handler
|
call trap_handler
|
||||||
LOAD ra, 0(sp)
|
LOAD ra, 0(sp)
|
||||||
addi sp, sp, 8
|
addi sp, sp, 8
|
||||||
call _tx_thread_context_restore
|
call _tx_thread_context_restore
|
||||||
// it will nerver return
|
// it will nerver return
|
||||||
.weak trap_handler
|
.weak trap_handler
|
||||||
trap_handler:
|
trap_handler:
|
||||||
1:
|
1:
|
||||||
j 1b
|
j 1b
|
||||||
|
.section .text
|
||||||
.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
|
|
||||||
113
port/threadx_smp/src/tx_initialize_low_level.c
Normal file
113
port/threadx_smp/src/tx_initialize_low_level.c
Normal 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));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user