improve port robustness, portability, and CSR handling

- removed tx_port.h dependency from .S files
- replaced tx_timer_interrupt.c with tx_timer_interrupt.S
-  made some cleanups, formatting to better readability
- removed macros (LOAD/STORE/REGBYTES)
  changed register nomenclature to use RISC-V ABI
  names (ra, sp, t0, etc.)
- added readme_threadx.txt

Signed-off-by: Akif Ejaz <akif.ejaz@10xengineers.ai>
This commit is contained in:
Akif Ejaz
2026-01-26 15:48:46 +05:00
parent 12dac1d67d
commit 6c25effb40
12 changed files with 1466 additions and 869 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ target_sources(${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S
# {{END_TARGET_SOURCES}}
)
+13 -39
View File
@@ -53,26 +53,6 @@
#ifndef TX_PORT_H
#define TX_PORT_H
#ifdef __ASSEMBLER__
#if __riscv_xlen == 64
# define SLL32 sllw
# define STORE sd
# define LOAD ld
# define LWU lwu
# define LOG_REGBYTES 3
#else
# define SLL32 sll
# define STORE sw
# define LOAD lw
# define LWU lw
# define LOG_REGBYTES 2
#endif
#define REGBYTES (1 << LOG_REGBYTES)
#else /*not __ASSEMBLER__ */
/* Include for memset. */
#include <string.h>
@@ -86,10 +66,7 @@
alternately be defined on the command line. */
#include "tx_user.h"
#endif
/* Define compiler library include files. */
#endif /* TX_INCLUDE_USER_DEFINE_FILE */
/* Define ThreadX basic types for this port. */
@@ -105,8 +82,6 @@ typedef unsigned long long ULONG64;
typedef short SHORT;
typedef unsigned short USHORT;
#define ULONG64_DEFINED
#define ALIGN_TYPE_DEFINED
#define ALIGN_TYPE ULONG64
@@ -253,25 +228,25 @@ typedef unsigned short USHORT;
is used to define a local function save area for the disable and restore
macros. */
/* Expose helper used to perform an atomic read/modify/write of mstatus.
The helper composes and returns the posture per ThreadX contract. */
UINT _tx_thread_interrupt_control(UINT new_posture);
#ifdef TX_DISABLE_INLINE
ULONG64 _tx_thread_interrupt_control(unsigned int new_posture);
#define TX_INTERRUPT_SAVE_AREA register ULONG64 interrupt_save;
#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
#else
#define TX_INTERRUPT_SAVE_AREA ULONG64 interrupt_save;
/* Atomically read mstatus into interrupt_save and clear bit 3 of mstatus. */
#define TX_DISABLE {__asm__ ("csrrci %0, mstatus, 0x08" : "=r" (interrupt_save) : );};
/* We only care about mstatus.mie (bit 3), so mask interrupt_save and write to mstatus. */
#define TX_RESTORE {register ULONG64 __tempmask = interrupt_save & 0x08; \
__asm__ ("csrrs x0, mstatus, %0 \n\t" : : "r" (__tempmask) : );};
#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
#endif
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
#endif /* TX_DISABLE_INLINE */
/* Define the interrupt lockout macros for each ThreadX object. */
@@ -291,7 +266,6 @@ CHAR _tx_version_id[] =
"Copyright (c) 2024 Microsoft Corporation. * ThreadX RISC-V64/GNU Version 6.4.2 *";
#else
extern CHAR _tx_version_id[];
#endif
#endif /* TX_THREAD_INIT */
#endif /*not __ASSEMBLER__ */
#endif
#endif /* TX_PORT_H */
File diff suppressed because it is too large Load Diff
@@ -71,41 +71,45 @@ __tx_free_memory_start:
.global _tx_initialize_low_level
.weak _tx_initialize_low_level
_tx_initialize_low_level:
sd sp, _tx_thread_system_stack_ptr, t0 // Save system stack pointer
/* Save the system stack pointer. */
/* _tx_thread_system_stack_ptr = sp; */
la t0, _tx_thread_system_stack_ptr
sd sp, 0(t0) /* Save system stack pointer */
la t0, __tx_free_memory_start // Pickup first free address
sd t0, _tx_initialize_unused_memory, t1 // Save unused memory address
/* Pickup first free address. */
/* _tx_initialize_unused_memory(__tx_free_memory_start); */
la t0, __tx_free_memory_start /* Pickup first free address */
la t1, _tx_initialize_unused_memory
sd t0, 0(t1) /* Save unused memory address */
/* Initialize floating point control/status register if floating point is enabled. */
#ifdef __riscv_flen
fscsr x0
li t0, 0
csrw fcsr, t0 /* Clear FP control/status register */
#endif
ret
/* Define the actual timer interrupt/exception handler. */
.global timer1_plic_IRQHandler
//.global __minterrupt_000007
//EXTWEAK __require_minterrupt_vector_table
timer1_plic_IRQHandler:
//__minterrupt_000007:
//REQUIRE __require_minterrupt_vector_table
/* Before calling _tx_thread_context_save, we have to allocate an interrupt
stack frame and save the current value of x1 (ra). */
//#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
// addi sp, sp, -520 // Allocate space for all registers - with floating point enabled
//#else
// addi sp, sp, -256 // Allocate space for all registers - without floating point enabled
//#endif
// sd x1, 224(sp) // Store RA
// call _tx_thread_context_save // Call ThreadX context save
/* Call the ThreadX timer routine. */
call _tx_timer_interrupt // Call timer interrupt handler
call timer1_interrupt
ret
/* Timer interrupt processing is done, jump to ThreadX context restore. */
// j _tx_thread_context_restore // Jump to ThreadX context restore function. Note: this does not return!
/* Timer Interrupt Handler Note:
Platform-specific implementations must provide their own timer ISR.
The timer interrupt handler should follow this execution flow:
1. Disable interrupts (if not done by hardware exception entry)
2. Allocate interrupt stack frame (65*8 bytes with FP, 32*8 bytes without)
3. Save RA (x1) on the stack at offset 28*8
4. Call _tx_thread_context_save to save thread context
5. Call _tx_timer_interrupt to process the timer tick
6. Call _tx_thread_context_restore to resume execution (does not return)
Example (for CLINT timer):
_tx_timer_interrupt_handler:
addi sp, sp, -32*8
sd ra, 28*8(sp)
call _tx_thread_context_save
call _tx_timer_interrupt
j _tx_thread_context_restore
The port assumes Machine mode (M-mode) execution.
For Supervisor mode (S-mode), use sstatus and SIE/SPIE instead of mstatus.
See the RISC-V Privileged Specification for more details. */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -19,8 +19,8 @@
/**************************************************************************/
/**************************************************************************/
RETURN_MASK = 0x000000000000000F
SET_SR_MASK = 0xFFFFFFFFFFFFFFF0
/* Define which mstatus bits this function will modify/return. */
/* MSTATUS_MIE bit 3 = Machine Interrupt Enable */
.section .text
/**************************************************************************/
@@ -66,16 +66,20 @@
.global _tx_thread_interrupt_control
_tx_thread_interrupt_control:
/* Pickup current interrupt lockout posture. */
/* old_mstatus = mstatus; */
csrr t0, mstatus
mv t1, t0 // Save original mstatus for return
mv t1, t0 /* Save original mstatus for return */
/* Apply the new interrupt posture. */
li t2, SET_SR_MASK // Build set SR mask
and t0, t0, t2 // Isolate interrupt lockout bits
or t0, t0, a0 // Put new lockout bits in
/* Apply the new interrupt posture while preserving unrelated mstatus bits. */
/* Only modify the MIE bit (bit 3) */
/* mstatus = (mstatus & ~MIE) | (new_posture & MIE); */
li t2, ~0x08 /* Build mask to clear MIE */
and t0, t0, t2 /* Clear MIE bit */
and a0, a0, 0x08 /* Mask incoming to only MIE bit */
or t0, t0, a0 /* Set requested MIE state */
csrw mstatus, t0
andi a0, t1, RETURN_MASK // Return original mstatus.
andi a0, t1, 0x08 /* Return original MIE bit */
ret
/* } */
File diff suppressed because it is too large Load Diff
+75 -77
View File
@@ -19,8 +19,6 @@
/**************************************************************************/
/**************************************************************************/
#include "tx_port.h"
.section .text
/**************************************************************************/
/* */
@@ -43,7 +41,7 @@
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to return function */
/* */
/* OUTPUT */
/* OUTPUT */
/* */
/* None */
/* */
@@ -138,91 +136,91 @@ If floating point support:
Stack Bottom: (higher memory address) */
LOAD t0, 4*REGBYTES(a0) // Pickup end of stack area
li t1, ~15 // Build 16-byte alignment mask
and t0, t0, t1 // Make sure 16-byte alignment
ld t0, 32(a0) /* Pickup end of stack area */
li t1, ~15 /* Build 16-byte alignment mask */
and t0, t0, t1 /* Make sure 16-byte alignment */
/* Actually build the stack frame. */
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
addi t0, t0, -65*REGBYTES
addi t0, t0, -65*8
#else
addi t0, t0, -32*REGBYTES // Allocate space for the stack frame
addi t0, t0, -32*8 /* Allocate space for the stack frame */
#endif
li t1, 1 // Build stack type
STORE t1, 0*REGBYTES(t0) // Place stack type on the top
STORE x0, 1*REGBYTES(t0) // Initial s11
STORE x0, 2*REGBYTES(t0) // Initial s10
STORE x0, 3*REGBYTES(t0) // Initial s9
STORE x0, 4*REGBYTES(t0) // Initial s8
STORE x0, 5*REGBYTES(t0) // Initial s7
STORE x0, 6*REGBYTES(t0) // Initial s6
STORE x0, 7*REGBYTES(t0) // Initial s5
STORE x0, 8*REGBYTES(t0) // Initial s4
STORE x0, 9*REGBYTES(t0) // Initial s3
STORE x0, 10*REGBYTES(t0) // Initial s2
STORE x0, 11*REGBYTES(t0) // Initial s1
STORE x0, 12*REGBYTES(t0) // Initial s0
STORE x0, 13*REGBYTES(t0) // Initial t6
STORE x0, 14*REGBYTES(t0) // Initial t5
STORE x0, 15*REGBYTES(t0) // Initial t4
STORE x0, 16*REGBYTES(t0) // Initial t3
STORE x0, 17*REGBYTES(t0) // Initial t2
STORE x0, 18*REGBYTES(t0) // Initial t1
STORE x0, 19*REGBYTES(t0) // Initial t0
STORE x0, 20*REGBYTES(t0) // Initial a7
STORE x0, 21*REGBYTES(t0) // Initial a6
STORE x0, 22*REGBYTES(t0) // Initial a5
STORE x0, 23*REGBYTES(t0) // Initial a4
STORE x0, 24*REGBYTES(t0) // Initial a3
STORE x0, 25*REGBYTES(t0) // Initial a2
STORE x0, 26*REGBYTES(t0) // Initial a1
STORE x0, 27*REGBYTES(t0) // Initial a0
STORE x0, 28*REGBYTES(t0) // Initial ra
STORE a1, 30*REGBYTES(t0) // Initial mepc
li t1, 1 /* Build stack type */
sd t1, 0*8(t0) /* Place stack type on the top */
sd zero, 1*8(t0) /* Initial s11 */
sd zero, 2*8(t0) /* Initial s10 */
sd zero, 3*8(t0) /* Initial s9 */
sd zero, 4*8(t0) /* Initial s8 */
sd zero, 5*8(t0) /* Initial s7 */
sd zero, 6*8(t0) /* Initial s6 */
sd zero, 7*8(t0) /* Initial s5 */
sd zero, 8*8(t0) /* Initial s4 */
sd zero, 9*8(t0) /* Initial s3 */
sd zero, 10*8(t0) /* Initial s2 */
sd zero, 11*8(t0) /* Initial s1 */
sd zero, 12*8(t0) /* Initial s0 */
sd zero, 13*8(t0) /* Initial t6 */
sd zero, 14*8(t0) /* Initial t5 */
sd zero, 15*8(t0) /* Initial t4 */
sd zero, 16*8(t0) /* Initial t3 */
sd zero, 17*8(t0) /* Initial t2 */
sd zero, 18*8(t0) /* Initial t1 */
sd zero, 19*8(t0) /* Initial t0 */
sd zero, 20*8(t0) /* Initial a7 */
sd zero, 21*8(t0) /* Initial a6 */
sd zero, 22*8(t0) /* Initial a5 */
sd zero, 23*8(t0) /* Initial a4 */
sd zero, 24*8(t0) /* Initial a3 */
sd zero, 25*8(t0) /* Initial a2 */
sd zero, 26*8(t0) /* Initial a1 */
sd zero, 27*8(t0) /* Initial a0 */
sd zero, 28*8(t0) /* Initial ra */
sd a1, 30*8(t0) /* Initial mepc (thread entry point) */
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
STORE x0, 31*REGBYTES(t0) // Inital ft0
STORE x0, 32*REGBYTES(t0) // Inital ft1
STORE x0, 33*REGBYTES(t0) // Inital ft2
STORE x0, 34*REGBYTES(t0) // Inital ft3
STORE x0, 35*REGBYTES(t0) // Inital ft4
STORE x0, 36*REGBYTES(t0) // Inital ft5
STORE x0, 37*REGBYTES(t0) // Inital ft6
STORE x0, 38*REGBYTES(t0) // Inital ft7
STORE x0, 39*REGBYTES(t0) // Inital fs0
STORE x0, 40*REGBYTES(t0) // Inital fs1
STORE x0, 41*REGBYTES(t0) // Inital fa0
STORE x0, 42*REGBYTES(t0) // Inital fa1
STORE x0, 43*REGBYTES(t0) // Inital fa2
STORE x0, 44*REGBYTES(t0) // Inital fa3
STORE x0, 45*REGBYTES(t0) // Inital fa4
STORE x0, 46*REGBYTES(t0) // Inital fa5
STORE x0, 47*REGBYTES(t0) // Inital fa6
STORE x0, 48*REGBYTES(t0) // Inital fa7
STORE x0, 49*REGBYTES(t0) // Inital fs2
STORE x0, 50*REGBYTES(t0) // Inital fs3
STORE x0, 51*REGBYTES(t0) // Inital fs4
STORE x0, 52*REGBYTES(t0) // Inital fs5
STORE x0, 53*REGBYTES(t0) // Inital fs6
STORE x0, 54*REGBYTES(t0) // Inital fs7
STORE x0, 55*REGBYTES(t0) // Inital fs8
STORE x0, 56*REGBYTES(t0) // Inital fs9
STORE x0, 57*REGBYTES(t0) // Inital fs10
STORE x0, 58*REGBYTES(t0) // Inital fs11
STORE x0, 59*REGBYTES(t0) // Inital ft8
STORE x0, 60*REGBYTES(t0) // Inital ft9
STORE x0, 61*REGBYTES(t0) // Inital ft10
STORE x0, 62*REGBYTES(t0) // Inital ft11
csrr a1, fcsr // Read fcsr and use it for initial value for each thread
STORE a1, 63*REGBYTES(t0) // Initial fscr
STORE x0, 64*REGBYTES(t0) // Reserved word (0)
sd zero, 31*8(t0) /* Initial ft0 */
sd zero, 32*8(t0) /* Initial ft1 */
sd zero, 33*8(t0) /* Initial ft2 */
sd zero, 34*8(t0) /* Initial ft3 */
sd zero, 35*8(t0) /* Initial ft4 */
sd zero, 36*8(t0) /* Initial ft5 */
sd zero, 37*8(t0) /* Initial ft6 */
sd zero, 38*8(t0) /* Initial ft7 */
sd zero, 39*8(t0) /* Initial fs0 */
sd zero, 40*8(t0) /* Initial fs1 */
sd zero, 41*8(t0) /* Initial fa0 */
sd zero, 42*8(t0) /* Initial fa1 */
sd zero, 43*8(t0) /* Initial fa2 */
sd zero, 44*8(t0) /* Initial fa3 */
sd zero, 45*8(t0) /* Initial fa4 */
sd zero, 46*8(t0) /* Initial fa5 */
sd zero, 47*8(t0) /* Initial fa6 */
sd zero, 48*8(t0) /* Initial fa7 */
sd zero, 49*8(t0) /* Initial fs2 */
sd zero, 50*8(t0) /* Initial fs3 */
sd zero, 51*8(t0) /* Initial fs4 */
sd zero, 52*8(t0) /* Initial fs5 */
sd zero, 53*8(t0) /* Initial fs6 */
sd zero, 54*8(t0) /* Initial fs7 */
sd zero, 55*8(t0) /* Initial fs8 */
sd zero, 56*8(t0) /* Initial fs9 */
sd zero, 57*8(t0) /* Initial fs10 */
sd zero, 58*8(t0) /* Initial fs11 */
sd zero, 59*8(t0) /* Initial ft8 */
sd zero, 60*8(t0) /* Initial ft9 */
sd zero, 61*8(t0) /* Initial ft10 */
sd zero, 62*8(t0) /* Initial ft11 */
csrr a1, fcsr /* Read fcsr for initial value */
sd a1, 63*8(t0) /* Initial fcsr */
sd zero, 64*8(t0) /* Reserved word (0) */
#else
STORE x0, 31*REGBYTES(t0) // Reserved word (0)
sd zero, 31*8(t0) /* Reserved word (0) */
#endif
/* Setup stack pointer. */
/* thread_ptr -> tx_thread_stack_ptr = t0; */
STORE t0, 2*REGBYTES(a0) // Save stack pointer in thread's
ret // control block and return
sd t0, 16(a0) /* Save stack pointer in thread's */
ret /* control block and return */
/* } */
@@ -19,8 +19,6 @@
/**************************************************************************/
/**************************************************************************/
#include "tx_port.h"
.section .text
/**************************************************************************/
/* */
@@ -68,99 +66,100 @@
_tx_thread_system_return:
/* Save minimal context on the stack. */
/* sp -= sizeof(stack_frame); */
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
addi sp, sp, -29*REGBYTES // Allocate space on the stack - with floating point enabled
addi sp, sp, -29*8 /* Allocate space on the stack - with floating point enabled */
#else
addi sp, sp, -16*REGBYTES // Allocate space on the stack - without floating point enabled
addi sp, sp, -16*8 /* Allocate space on the stack - without floating point enabled */
#endif
/* Store floating point preserved registers. */
#if defined(__riscv_float_abi_single)
fsw f8, 15*REGBYTES(sp) // Store fs0
fsw f9, 16*REGBYTES(sp) // Store fs1
fsw f18, 17*REGBYTES(sp) // Store fs2
fsw f19, 18*REGBYTES(sp) // Store fs3
fsw f20, 19*REGBYTES(sp) // Store fs4
fsw f21, 20*REGBYTES(sp) // Store fs5
fsw f22, 21*REGBYTES(sp) // Store fs6
fsw f23, 22*REGBYTES(sp) // Store fs7
fsw f24, 23*REGBYTES(sp) // Store fs8
fsw f25, 24*REGBYTES(sp) // Store fs9
fsw f26, 25*REGBYTES(sp) // Store fs10
fsw f27, 26*REGBYTES(sp) // Store fs11
fsw f8, 15*8(sp) /* Store fs0 */
fsw f9, 16*8(sp) /* Store fs1 */
fsw f18, 17*8(sp) /* Store fs2 */
fsw f19, 18*8(sp) /* Store fs3 */
fsw f20, 19*8(sp) /* Store fs4 */
fsw f21, 20*8(sp) /* Store fs5 */
fsw f22, 21*8(sp) /* Store fs6 */
fsw f23, 22*8(sp) /* Store fs7 */
fsw f24, 23*8(sp) /* Store fs8 */
fsw f25, 24*8(sp) /* Store fs9 */
fsw f26, 25*8(sp) /* Store fs10 */
fsw f27, 26*8(sp) /* Store fs11 */
csrr t0, fcsr
STORE t0, 27*REGBYTES(sp) // Store fcsr
sd t0, 27*8(sp) /* Store fcsr */
#elif defined(__riscv_float_abi_double)
fsd f8, 15*REGBYTES(sp) // Store fs0
fsd f9, 16*REGBYTES(sp) // Store fs1
fsd f18, 17*REGBYTES(sp) // Store fs2
fsd f19, 18*REGBYTES(sp) // Store fs3
fsd f20, 19*REGBYTES(sp) // Store fs4
fsd f21, 20*REGBYTES(sp) // Store fs5
fsd f22, 21*REGBYTES(sp) // Store fs6
fsd f23, 22*REGBYTES(sp) // Store fs7
fsd f24, 23*REGBYTES(sp) // Store fs8
fsd f25, 24*REGBYTES(sp) // Store fs9
fsd f26, 25*REGBYTES(sp) // Store fs10
fsd f27, 26*REGBYTES(sp) // Store fs11
fsd f8, 15*8(sp) /* Store fs0 */
fsd f9, 16*8(sp) /* Store fs1 */
fsd f18, 17*8(sp) /* Store fs2 */
fsd f19, 18*8(sp) /* Store fs3 */
fsd f20, 19*8(sp) /* Store fs4 */
fsd f21, 20*8(sp) /* Store fs5 */
fsd f22, 21*8(sp) /* Store fs6 */
fsd f23, 22*8(sp) /* Store fs7 */
fsd f24, 23*8(sp) /* Store fs8 */
fsd f25, 24*8(sp) /* Store fs9 */
fsd f26, 25*8(sp) /* Store fs10 */
fsd f27, 26*8(sp) /* Store fs11 */
csrr t0, fcsr
STORE t0, 27*REGBYTES(sp) // Store fcsr
sd t0, 27*8(sp) /* Store fcsr */
#endif
STORE x0, 0(sp) // Solicited stack type
STORE x1, 13*REGBYTES(sp) // Save RA
STORE x8, 12*REGBYTES(sp) // Save s0
STORE x9, 11*REGBYTES(sp) // Save s1
STORE x18, 10*REGBYTES(sp) // Save s2
STORE x19, 9*REGBYTES(sp) // Save s3
STORE x20, 8*REGBYTES(sp) // Save s4
STORE x21, 7*REGBYTES(sp) // Save s5
STORE x22, 6*REGBYTES(sp) // Save s6
STORE x23, 5*REGBYTES(sp) // Save s7
STORE x24, 4*REGBYTES(sp) // Save s8
STORE x25, 3*REGBYTES(sp) // Save s9
STORE x26, 2*REGBYTES(sp) // Save s10
STORE x27, 1*REGBYTES(sp) // Save s11
csrr t0, mstatus // Pickup mstatus
STORE t0, 14*REGBYTES(sp) // Save mstatus
sd zero, 0(sp) /* Solicited stack type */
sd ra, 13*8(sp) /* Save return address */
sd s0, 12*8(sp) /* Save s0 */
sd s1, 11*8(sp) /* Save s1 */
sd s2, 10*8(sp) /* Save s2 */
sd s3, 9*8(sp) /* Save s3 */
sd s4, 8*8(sp) /* Save s4 */
sd s5, 7*8(sp) /* Save s5 */
sd s6, 6*8(sp) /* Save s6 */
sd s7, 5*8(sp) /* Save s7 */
sd s8, 4*8(sp) /* Save s8 */
sd s9, 3*8(sp) /* Save s9 */
sd s10, 2*8(sp) /* Save s10 */
sd s11, 1*8(sp) /* Save s11 */
csrr t0, mstatus /* Pickup mstatus */
sd t0, 14*8(sp) /* Save mstatus */
/* Lockout interrupts. - will be enabled in _tx_thread_schedule */
/* Lockout interrupts. will be enabled in _tx_thread_schedule */
csrci mstatus, 0xF
csrci mstatus, 0x08 /* Disable interrupts (MIE bit 3) */
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
call _tx_execution_thread_exit // Call the thread execution exit function
call _tx_execution_thread_exit /* Call the thread execution exit function */
#endif
la t0, _tx_thread_current_ptr // Pickup address of pointer
LOAD t1, 0(t0) // Pickup current thread pointer
la t2,_tx_thread_system_stack_ptr // Pickup stack pointer address
la t0, _tx_thread_current_ptr /* Pickup address of pointer */
ld t1, 0(t0) /* Pickup current thread pointer */
la t2, _tx_thread_system_stack_ptr /* Pickup stack pointer address */
/* Save current stack and switch to system stack. */
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
SP = _tx_thread_system_stack_ptr; */
STORE sp, 2*REGBYTES(t1) // Save stack pointer
LOAD sp, 0(t2) // Switch to system stack
sd sp, 16(t1) /* Save stack pointer */
ld sp, 0(t2) /* Switch to system stack */
/* Determine if the time-slice is active. */
/* if (_tx_timer_time_slice)
{ */
la t4, _tx_timer_time_slice // Pickup time slice variable addr
LOAD t3, 0(t4) // Pickup time slice value
la t2, _tx_thread_schedule // Pickup address of scheduling loop
beqz t3, _tx_thread_dont_save_ts // If no time-slice, don't save it
la t4, _tx_timer_time_slice /* Pickup time slice variable addr */
ld t3, 0(t4) /* Pickup time slice value */
la t2, _tx_thread_schedule /* Pickup address of scheduling loop */
beqz t3, _tx_thread_dont_save_ts /* If no time-slice, don't save it */
/* Save time-slice for the thread and clear the current time-slice. */
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */
STORE t3, 6*REGBYTES(t1) // Save current time-slice for thread
STORE x0, 0(t4) // Clear time-slice variable
sd t3, 48(t1) /* Save current time-slice for thread */
sd zero, 0(t4) /* Clear time-slice variable */
/* } */
_tx_thread_dont_save_ts:
@@ -168,7 +167,7 @@ _tx_thread_dont_save_ts:
/* Clear the current thread pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
STORE x0, 0(t0) // Clear current thread pointer
sd x0, 0(t0) // Clear current thread pointer
jr t2 // Return to thread scheduler
/* } */
File diff suppressed because it is too large Load Diff
-134
View File
@@ -1,134 +0,0 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Timer */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_timer.h"
#include "tx_thread.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt RISC-V64/GNU */
/* 6.2.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the hardware timer interrupt. This */
/* processing includes incrementing the system clock and checking for */
/* time slice and/or timer expiration. If either is found, the */
/* interrupt context save/restore functions are called along with the */
/* expiration functions. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_timer_expiration_process Timer expiration processing */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 03-08-2023 Scott Larson Initial Version 6.2.1 */
/* */
/**************************************************************************/
VOID _tx_timer_interrupt(VOID)
{
/* Increment system clock. */
_tx_timer_system_clock++;
/* Test for time-slice expiration. */
if (_tx_timer_time_slice)
{
/* Decrement the time_slice. */
_tx_timer_time_slice--;
/* Check for expiration. */
if (_tx_timer_time_slice == 0)
{
/* Set the time-slice expired flag. */
_tx_timer_expired_time_slice = TX_TRUE;
}
}
/* Test for timer expiration. */
if (*_tx_timer_current_ptr)
{
/* Set expiration flag. */
_tx_timer_expired = TX_TRUE;
}
else
{
/* No timer expired, increment the timer pointer. */
_tx_timer_current_ptr++;
/* Check for wrap-around. */
if (_tx_timer_current_ptr == _tx_timer_list_end)
{
/* Wrap to beginning of list. */
_tx_timer_current_ptr = _tx_timer_list_start;
}
}
/* See if anything has expired. */
if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
{
/* Did a timer expire? */
if (_tx_timer_expired)
{
/* Process timer expiration. */
_tx_timer_expiration_process();
}
/* Did time slice expire? */
if (_tx_timer_expired_time_slice)
{
/* Time slice interrupted thread. */
_tx_thread_time_slice();
}
}
}