Skip to content

Commit ae13c5b

Browse files
committed
feat: use macros for stack offsets and enhance verification framework
1 parent fedd124 commit ae13c5b

9 files changed

Lines changed: 897 additions & 552 deletions

build_qemu/test_cmds.gdb

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11

2-
target remote :63370
2+
target remote :65299
33
file /Users/winston/Documents/碩二/CA/threadx/build_qemu/kernel.elf
4+
set pagination off
5+
set confirm off
6+
7+
# Setup Breakpoints
48
break tx_application_define
59
break thread_0_entry
610
break thread_6_and_7_entry
711
break _tx_timer_interrupt
12+
13+
# Execute to Application Definition
814
continue
15+
16+
# Verify Lazy FPU Context (Expect FS=Initial)
917
continue
1018
print/x $mstatus
19+
20+
# Verify FPU Logic and Register State
1121
continue
1222
finish
1323
step
@@ -16,5 +26,107 @@ step
1626
print/x $mstatus
1727
info registers float
1828
print fpu_test_val
29+
30+
# Await Timer Interrupt
31+
continue
32+
print "Hit Timer Interrupt"
33+
34+
# Verify MEPC Integrity - Save State
35+
print/x $mepc
36+
set $saved_pc = $mepc
37+
38+
# Verify System Timer Before ISR
39+
set $clock_before = _tx_timer_system_clock
40+
print $clock_before
41+
42+
# Configure Time-Slice Test Conditions
43+
set _tx_timer_time_slice = 1
44+
set _tx_timer_expired_time_slice = 0
45+
set $ts_handler_called = 0
46+
47+
# Set Breakpoint at Time-Slice Handler with Auto-Continue
48+
tbreak _tx_thread_time_slice
49+
commands
50+
set $ts_handler_called = 1
51+
continue
52+
end
53+
54+
# Set Breakpoint at ISR Return Address
55+
set $ret_addr = $ra
56+
tbreak *$ret_addr
1957
continue
58+
59+
# Verify Time-Slice Handler Was Called
60+
if $ts_handler_called == 1
61+
print "SUCCESS: Time-slice handler called."
62+
else
63+
print "FAILURE: Time-slice handler NOT called."
64+
end
65+
66+
# Verify System Timer Increment (Monotonicity)
67+
set $clock_after = _tx_timer_system_clock
68+
print $clock_after
69+
70+
if $clock_after > $clock_before
71+
print "SUCCESS: System timer incremented."
72+
else
73+
print "FAILURE: System timer did not increment."
74+
end
75+
76+
# Verify MEPC Restoration Post-ISR
77+
tbreak *$saved_pc
78+
continue
79+
80+
print "Back from ISR"
81+
print/x $pc
82+
set $diff = (long)$pc - (long)$saved_pc
83+
if $diff == 0
84+
print "SUCCESS: MEPC restored correctly."
85+
else
86+
print "FAILURE: PC does not match saved MEPC."
87+
end
88+
89+
# Verify Preemption Logic (Thread Priority)
90+
break tx_thread_context_restore.S:320
91+
92+
set $max_loops = 5
93+
set $loop_cnt = 0
94+
set $found_preemption = 0
95+
96+
while $loop_cnt < $max_loops
97+
continue
98+
set $loop_cnt = $loop_cnt + 1
99+
100+
print "Hit Preemption Restore Path"
101+
102+
set $curr_ptr = _tx_thread_current_ptr
103+
set $exec_ptr = _tx_thread_execute_ptr
104+
105+
if $curr_ptr != 0 && $exec_ptr != 0
106+
set $curr_prio = $curr_ptr->tx_thread_priority
107+
set $exec_prio = $exec_ptr->tx_thread_priority
108+
109+
print $curr_prio
110+
print $exec_prio
111+
112+
if $exec_prio < $curr_prio
113+
print "SUCCESS: Thread Preemption Verified."
114+
set $found_preemption = 1
115+
loop_break
116+
end
117+
118+
if $exec_prio > $curr_prio
119+
print "FAILURE: Preemption logic error - Lower priority running."
120+
loop_break
121+
end
122+
else
123+
print "FAILURE: Null thread pointers."
124+
loop_break
125+
end
126+
end
127+
128+
if $found_preemption == 0
129+
print "FAILURE: Preemption not observed."
130+
end
131+
20132
quit

ports/risc-v32/gnu/inc/tx_port.h

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,121 @@
4848
#ifndef TX_PORT_H
4949
#define TX_PORT_H
5050

51-
#ifndef __ASSEMBLER__
51+
#ifdef __ASSEMBLER__
52+
53+
54+
#if __riscv_xlen == 64
55+
# define SLL32 sllw
56+
# define STORE sd
57+
# define LOAD ld
58+
# define LWU lwu
59+
# define LOG_REGBYTES 3
60+
#else
61+
# define SLL32 sll
62+
# define STORE sw
63+
# define LOAD lw
64+
# define LWU lw
65+
# define LOG_REGBYTES 2
66+
#endif
67+
#define REGBYTES (1 << LOG_REGBYTES)
68+
69+
/* Define stack frame offsets for thread context save/restore.
70+
These offsets correspond to the layout used in tx_thread_context_save.S
71+
and tx_thread_context_restore.S. */
72+
73+
/* General Purpose Registers */
74+
#define TX_STACK_OFFSET_X1 (28 * REGBYTES) /* ra */
75+
#define TX_STACK_OFFSET_X5 (19 * REGBYTES) /* t0 */
76+
#define TX_STACK_OFFSET_X6 (18 * REGBYTES) /* t1 */
77+
#define TX_STACK_OFFSET_X7 (17 * REGBYTES) /* t2 */
78+
#define TX_STACK_OFFSET_X8 (12 * REGBYTES) /* s0/fp */
79+
#define TX_STACK_OFFSET_X9 (11 * REGBYTES) /* s1 */
80+
#define TX_STACK_OFFSET_X10 (27 * REGBYTES) /* a0 */
81+
#define TX_STACK_OFFSET_X11 (26 * REGBYTES) /* a1 */
82+
#define TX_STACK_OFFSET_X12 (25 * REGBYTES) /* a2 */
83+
#define TX_STACK_OFFSET_X13 (24 * REGBYTES) /* a3 */
84+
#define TX_STACK_OFFSET_X14 (23 * REGBYTES) /* a4 */
85+
#define TX_STACK_OFFSET_X15 (22 * REGBYTES) /* a5 */
86+
#define TX_STACK_OFFSET_X16 (21 * REGBYTES) /* a6 */
87+
#define TX_STACK_OFFSET_X17 (20 * REGBYTES) /* a7 */
88+
#define TX_STACK_OFFSET_X18 (10 * REGBYTES) /* s2 */
89+
#define TX_STACK_OFFSET_X19 (9 * REGBYTES) /* s3 */
90+
#define TX_STACK_OFFSET_X20 (8 * REGBYTES) /* s4 */
91+
#define TX_STACK_OFFSET_X21 (7 * REGBYTES) /* s5 */
92+
#define TX_STACK_OFFSET_X22 (6 * REGBYTES) /* s6 */
93+
#define TX_STACK_OFFSET_X23 (5 * REGBYTES) /* s7 */
94+
#define TX_STACK_OFFSET_X24 (4 * REGBYTES) /* s8 */
95+
#define TX_STACK_OFFSET_X25 (3 * REGBYTES) /* s9 */
96+
#define TX_STACK_OFFSET_X26 (2 * REGBYTES) /* s10 */
97+
#define TX_STACK_OFFSET_X27 (1 * REGBYTES) /* s11 */
98+
#define TX_STACK_OFFSET_X28 (16 * REGBYTES) /* t3 */
99+
#define TX_STACK_OFFSET_X29 (15 * REGBYTES) /* t4 */
100+
#define TX_STACK_OFFSET_X30 (14 * REGBYTES) /* t5 */
101+
#define TX_STACK_OFFSET_X31 (13 * REGBYTES) /* t6 */
102+
103+
/* Special Registers */
104+
#define TX_STACK_OFFSET_MSTATUS (29 * REGBYTES)
105+
#define TX_STACK_OFFSET_MEPC (30 * REGBYTES)
106+
#define TX_STACK_OFFSET_FCSR (63 * REGBYTES)
107+
108+
/* Stack Frame Offsets */
109+
#define TX_STACK_OFFSET_TYPE (0 * REGBYTES)
110+
111+
/* Floating Point Registers (F0-F31) */
112+
/* Note: Base offset for FPU regs is 31 * REGBYTES */
113+
/* Floating Point Registers (F0-F31) */
114+
/* Note: Base offset for FPU regs is 31 * REGBYTES */
115+
#define TX_STACK_OFFSET_F0 (31 * REGBYTES)
116+
#define TX_STACK_OFFSET_F1 (32 * REGBYTES)
117+
#define TX_STACK_OFFSET_F2 (33 * REGBYTES)
118+
#define TX_STACK_OFFSET_F3 (34 * REGBYTES)
119+
#define TX_STACK_OFFSET_F4 (35 * REGBYTES)
120+
#define TX_STACK_OFFSET_F5 (36 * REGBYTES)
121+
#define TX_STACK_OFFSET_F6 (37 * REGBYTES)
122+
#define TX_STACK_OFFSET_F7 (38 * REGBYTES)
123+
#define TX_STACK_OFFSET_F8 (39 * REGBYTES)
124+
#define TX_STACK_OFFSET_F9 (40 * REGBYTES)
125+
#define TX_STACK_OFFSET_F10 (41 * REGBYTES)
126+
#define TX_STACK_OFFSET_F11 (42 * REGBYTES)
127+
#define TX_STACK_OFFSET_F12 (43 * REGBYTES)
128+
#define TX_STACK_OFFSET_F13 (44 * REGBYTES)
129+
#define TX_STACK_OFFSET_F14 (45 * REGBYTES)
130+
#define TX_STACK_OFFSET_F15 (46 * REGBYTES)
131+
#define TX_STACK_OFFSET_F16 (47 * REGBYTES)
132+
#define TX_STACK_OFFSET_F17 (48 * REGBYTES)
133+
#define TX_STACK_OFFSET_F18 (49 * REGBYTES)
134+
#define TX_STACK_OFFSET_F19 (50 * REGBYTES)
135+
#define TX_STACK_OFFSET_F20 (51 * REGBYTES)
136+
#define TX_STACK_OFFSET_F21 (52 * REGBYTES)
137+
#define TX_STACK_OFFSET_F22 (53 * REGBYTES)
138+
#define TX_STACK_OFFSET_F23 (54 * REGBYTES)
139+
#define TX_STACK_OFFSET_F24 (55 * REGBYTES)
140+
#define TX_STACK_OFFSET_F25 (56 * REGBYTES)
141+
#define TX_STACK_OFFSET_F26 (57 * REGBYTES)
142+
#define TX_STACK_OFFSET_F27 (58 * REGBYTES)
143+
#define TX_STACK_OFFSET_F28 (59 * REGBYTES)
144+
#define TX_STACK_OFFSET_F29 (60 * REGBYTES)
145+
#define TX_STACK_OFFSET_F30 (61 * REGBYTES)
146+
#define TX_STACK_OFFSET_F31 (62 * REGBYTES)
147+
148+
/* FCSR is stored after F31 */
149+
/* FCSR is stored after F31 */
150+
#define TX_STACK_OFFSET_FCSR (63 * REGBYTES)
151+
152+
/* Thread Control Block (TX_THREAD) Offsets */
153+
#define TX_THREAD_RUN_COUNT (1 * REGBYTES)
154+
#define TX_THREAD_STACK_PTR (2 * REGBYTES)
155+
#define TX_THREAD_STACK_END (4 * REGBYTES)
156+
#define TX_THREAD_TIME_SLICE (6 * REGBYTES)
157+
158+
/* Stack Frame Sizes */
159+
/* FPU Enabled: 65 Registers (x0-x31, f0-f31, fcsr) + Alignment */
160+
#define TX_THREAD_FRAME_SIZE_FPU (65 * REGBYTES)
161+
/* FPU Disabled: 32 Registers (x0-x31) + Alignment */
162+
#define TX_THREAD_FRAME_SIZE_INT (32 * REGBYTES)
163+
164+
165+
#else /*not __ASSEMBLER__ */
52166

53167
/* Include for memset. */
54168
#include <string.h>

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ _tx_trap_handler:
105105
// sd x1, 224(sp) // Store RA
106106

107107
#if defined(__riscv_flen) && ((__riscv_flen == 32) || (__riscv_flen == 64))
108-
addi sp, sp, -65*REGBYTES // Allocate space for all registers - with floating point enabled
108+
addi sp, sp, -TX_THREAD_FRAME_SIZE_FPU // Allocate space for all registers - with floating point enabled
109109
#else
110-
addi sp, sp, -32*REGBYTES // Allocate space for all registers - without floating point enabled
110+
addi sp, sp, -TX_THREAD_FRAME_SIZE_INT // Allocate space for all registers - without floating point enabled
111111
#endif
112112

113-
STORE x1, 28*REGBYTES(sp)
113+
STORE x1, TX_STACK_OFFSET_X1(sp)
114114
call _tx_thread_context_save // Call ThreadX context save
115115
csrr t0, mcause // Pickup mcause
116116
li t1, 0x80000007

0 commit comments

Comments
 (0)