Skip to content

Commit 85d0626

Browse files
committed
feat: implement Lazy FPU Stacking and Vector Table
1 parent 6dee013 commit 85d0626

6 files changed

Lines changed: 839 additions & 682 deletions

File tree

ports/risc-v32/gnu/src/tx_initialize_low_level.S

Lines changed: 45 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,12 @@
1919
/**************************************************************************/
2020
/**************************************************************************/
2121

22-
/* Include necessary system files. */
23-
24-
/* #include "tx_api.h"
25-
#include "tx_initialize.h"
26-
#include "tx_thread.h"
27-
#include "tx_timer.h" */
28-
29-
.extern _tx_thread_system_stack_ptr
30-
.extern _tx_initialize_unused_memory
31-
.extern _tx_thread_context_save
32-
.extern _tx_thread_context_restore
33-
.extern _tx_timer_interrupt
34-
35-
.section .bss
36-
.balign 4
37-
.globl __tx_free_memory_start
22+
.section .data
23+
.global __tx_free_memory_start
3824
__tx_free_memory_start:
39-
.space 4
25+
4026

4127
.section .text
42-
.balign 4
4328
/**************************************************************************/
4429
/* */
4530
/* FUNCTION RELEASE */
@@ -49,7 +34,6 @@ __tx_free_memory_start:
4934
/* AUTHOR */
5035
/* */
5136
/* Akif Ejaz, 10xEngineers */
52-
/* Wei-Chen Lai, National Cheng Kung University */
5337
/* */
5438
/* DESCRIPTION */
5539
/* */
@@ -75,64 +59,66 @@ __tx_free_memory_start:
7559
/* */
7660
/* _tx_initialize_kernel_enter ThreadX entry function */
7761
/* */
62+
/* RELEASE HISTORY */
63+
/* */
64+
/* DATE NAME DESCRIPTION */
65+
/* */
66+
/* 23-12-2025 Akif Ejaz Initial Version 6.4.x */
67+
/* */
7868
/**************************************************************************/
79-
8069
/* VOID _tx_initialize_low_level(VOID)
8170
{ */
82-
.globl _tx_initialize_low_level
71+
.global _tx_initialize_low_level
72+
.weak _tx_initialize_low_level
8373
_tx_initialize_low_level:
84-
la t0, _tx_thread_system_stack_ptr
74+
la t0, _tx_thread_system_stack_ptr // Pickup address of system stack ptr
8575
sw sp, 0(t0) // Save system stack pointer
8676

8777
la t0, __tx_free_memory_start // Pickup first free address
88-
la t1, _tx_initialize_unused_memory
78+
la t1, _tx_initialize_unused_memory // Pickup address of unused memory
8979
sw t0, 0(t1) // Save unused memory address
9080

91-
ret
81+
#if defined(__riscv_flen) && ((__riscv_flen == 32) || (__riscv_flen == 64))
82+
li t0, 0x00006000 // Set FS field of mstatus to 3 (Dirty)
83+
csrs mstatus, t0
84+
fscsr x0 // Clear the fcsr
85+
#endif
9286

87+
la t0, _tx_trap_handler // Pickup trap handler address
88+
csrw mtvec, t0 // Store trap handler address
89+
ret
9390

9491
/* Define the actual timer interrupt/exception handler. */
95-
.globl _tx_timer_interrupt_handler
96-
.globl __minterrupt_000007
97-
_tx_timer_interrupt_handler:
98-
__minterrupt_000007:
9992

93+
.global _tx_trap_handler
94+
_tx_trap_handler:
10095
/* Before calling _tx_thread_context_save, we have to allocate an interrupt
10196
stack frame and save the current value of x1 (ra). */
102-
#if defined(__riscv_32e) || defined(__riscv_32rve)
103-
addi sp, sp, -260 // Allocate space for all registers - with floating point enabled
97+
98+
//#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
99+
// addi sp, sp, -520 // Allocate space for all registers - with floating point enabled
100+
//#else
101+
// addi sp, sp, -256 // Allocate space for all registers - without floating point enabled
102+
//#endif
103+
// sd x1, 224(sp) // Store RA
104+
105+
#if defined(__riscv_flen) && ((__riscv_flen == 32) || (__riscv_flen == 64))
106+
addi sp, sp, -65*REGBYTES // Allocate space for all registers - with floating point enabled
104107
#else
105-
addi sp, sp, -128 // Allocate space for all registers - without floating point enabled
108+
addi sp, sp, -32*REGBYTES // Allocate space for all registers - without floating point enabled
106109
#endif
107-
sw x1, 0x70(sp) // Store RA
108-
call _tx_thread_context_save // Call ThreadX context save
109110

111+
STORE x1, 28*REGBYTES(sp)
112+
call _tx_thread_context_save // Call ThreadX context save
113+
csrr t0, mcause // Pickup mcause
114+
li t1, 0x80000007
115+
beq t0, t1, _tx_timer_handler_entry // If mcause is Timer Interrupt, call timer interrupt handler
116+
117+
j _tx_trap_exit
110118
/* Call the ThreadX timer routine. */
111-
call _tx_timer_interrupt // Call timer interrupt handler
119+
_tx_timer_handler_entry:
120+
call _tx_timer_interrupt // Call timer interrupt handler
112121

113122
/* Timer interrupt processing is done, jump to ThreadX context restore. */
114-
tail _tx_thread_context_restore // Jump to ThreadX context restore function. Note: this does not return!
115-
116-
/* Timer Interrupt Handler Note:
117-
Platform-specific implementations must provide their own timer ISR.
118-
The timer interrupt handler should follow this execution flow:
119-
120-
1. Disable interrupts (if not done by hardware exception entry)
121-
2. Allocate interrupt stack frame (65*4 bytes with FP, 32*4 bytes without)
122-
3. Save RA (x1) on the stack at offset 28*4
123-
4. Call _tx_thread_context_save to save thread context
124-
5. Call _tx_timer_interrupt to process the timer tick
125-
6. Call _tx_thread_context_restore to resume execution (does not return)
126-
127-
Example (for CLINT timer):
128-
129-
_tx_timer_interrupt_handler:
130-
addi sp, sp, -32*4
131-
sw ra, 28*4(sp)
132-
call _tx_thread_context_save
133-
call _tx_timer_interrupt
134-
j _tx_thread_context_restore
135-
136-
The port assumes Machine mode (M-mode) execution.
137-
For Supervisor mode (S-mode), use sstatus and SIE/SPIE instead of mstatus.
138-
See the RISC-V Privileged Specification for more details. */
123+
_tx_trap_exit:
124+
j _tx_thread_context_restore // Jump to ThreadX context restore function. Note: this does not return!

0 commit comments

Comments
 (0)