Introduces Regression for 32 and 64 bit threadx and smp kernel in Debug, MinSizeRel and Release configuration #4

Merged
alex merged 79 commits from feature/test into main 2026-04-02 14:09:29 +01:00
10 changed files with 52 additions and 44 deletions
Showing only changes of commit c16e6b0446 - Show all commits

View File

@@ -61,12 +61,16 @@
#define STORE sd #define STORE sd
#define LOAD ld #define LOAD ld
#define LWU lwu #define LWU lwu
#define AMOSWAP_AQ amoswap.d.aq
#define AMOSWAP_RL amoswap.d.rl
#define LOG_REGBYTES 3 #define LOG_REGBYTES 3
#else #else
#define SLL32 sll #define SLL32 sll
#define STORE sw #define STORE sw
#define LOAD lw #define LOAD lw
#define LWU lw #define LWU lw
#define AMOSWAP_AQ amoswap.w.aq
#define AMOSWAP_RL amoswap.w.rl
#define LOG_REGBYTES 2 #define LOG_REGBYTES 2
#endif #endif
#define REGBYTES (1 << LOG_REGBYTES) #define REGBYTES (1 << LOG_REGBYTES)
@@ -166,7 +170,7 @@ typedef unsigned char UCHAR;
typedef int INT; typedef int INT;
typedef unsigned int UINT; typedef unsigned int UINT;
typedef int LONG; typedef int LONG;
typedef unsigned int ULONG; typedef unsigned long ULONG;
typedef unsigned long long ULONG64; typedef unsigned long long ULONG64;
typedef short SHORT; typedef short SHORT;
typedef unsigned short USHORT; typedef unsigned short USHORT;

View File

@@ -80,13 +80,13 @@ _tx_thread_context_restore:
{ */ { */
csrr t3, mhartid // Pickup current hart ID csrr t3, mhartid // Pickup current hart ID
slli t4, t3, 2 // Build per-hart ULONG offset slli t4, t3, LOG_REGBYTES // Build per-hart ULONG offset
slli t5, t3, LOG_REGBYTES // Build per-hart pointer offset slli t5, t3, LOG_REGBYTES // Build per-hart pointer offset
la t0, _tx_thread_system_state // Pickup base of system-state array la t0, _tx_thread_system_state // Pickup base of system-state array
add t0, t0, t4 // Select this hart's system-state slot add t0, t0, t4 // Select this hart's system-state slot
lw t1, 0(t0) // Pickup nested interrupt count LOAD t1, 0(t0) // Pickup nested interrupt count
addi t1, t1, -1 // Decrement the nested interrupt counter addi t1, t1, -1 // Decrement the nested interrupt counter
sw t1, 0(t0) // Store new nested count STORE t1, 0(t0) // Store new nested count
beqz t1, _tx_thread_not_nested_restore // If 0, not nested restore beqz t1, _tx_thread_not_nested_restore // If 0, not nested restore
/* Interrupts are nested. */ /* Interrupts are nested. */
@@ -202,10 +202,10 @@ _tx_thread_not_nested_restore:
beq t1, t2, _tx_thread_no_preempt_restore // Same thread selected, no preemption beq t1, t2, _tx_thread_no_preempt_restore // Same thread selected, no preemption
la t0, _tx_thread_smp_protection // Pickup protection structure la t0, _tx_thread_smp_protection // Pickup protection structure
lw t2, 4(t0) // Pickup owning hart LOAD t2, 1*REGBYTES(t0) // Pickup owning hart
bne t2, t3, _tx_thread_preempt_restore // If owned by another hart, preempt bne t2, t3, _tx_thread_preempt_restore // If owned by another hart, preempt
LOAD t2, _tx_thread_preempt_disable // Pickup preempt disable flag LWU t2, _tx_thread_preempt_disable // Pickup preempt disable flag
bgtz t2, _tx_thread_no_preempt_restore // If set, restore interrupted thread bgtz t2, _tx_thread_no_preempt_restore // If set, restore interrupted thread
@@ -367,14 +367,14 @@ _tx_thread_preempt_restore:
la t0, _tx_timer_time_slice // Pickup base of time-slice array la t0, _tx_timer_time_slice // Pickup base of time-slice array
add t0, t0, t4 // Select this hart's time-slice slot add t0, t0, t4 // Select this hart's time-slice slot
lw t2, 0(t0) // Pickup time slice LOAD t2, 0(t0) // Pickup time slice
beqz t2, _tx_thread_dont_save_ts // If 0, skip time slice processing beqz t2, _tx_thread_dont_save_ts // If 0, skip time slice processing
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice /* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice
_tx_timer_time_slice = 0; */ _tx_timer_time_slice = 0; */
sw t2, TX_THREAD_TIME_SLICE_OFFSET(t1) // Save current time slice STORE t2, 6*REGBYTES(t1) // Save current time slice
sw x0, 0(t0) // Clear global time slice STORE x0, 0(t0) // Clear global time slice
/* } */ /* } */
@@ -392,7 +392,7 @@ _tx_thread_dont_save_ts:
fence rw, rw // Publish current-thread clear before ready token fence rw, rw // Publish current-thread clear before ready token
addi t0, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address addi t0, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address
li t2, 1 // Rebuild ready token li t2, 1 // Rebuild ready token
amoswap.w.rl x0, t2, (t0) // Set thread ready token for reschedule AMOSWAP_RL x0, t2, (t0) // Set thread ready token for reschedule
/* } */ /* } */
_tx_thread_idle_system_restore: _tx_thread_idle_system_restore:

View File

@@ -77,18 +77,18 @@ _tx_thread_context_save:
STORE x29, 15*REGBYTES(sp) // Save t4 before reusing it STORE x29, 15*REGBYTES(sp) // Save t4 before reusing it
csrr t2, mhartid // Pickup current hart ID csrr t2, mhartid // Pickup current hart ID
slli t3, t2, 2 // Build per-hart ULONG offset slli t3, t2, LOG_REGBYTES // Build per-hart ULONG offset
slli t4, t2, LOG_REGBYTES // Build per-hart pointer offset slli t4, t2, LOG_REGBYTES // Build per-hart pointer offset
la t1, _tx_thread_system_state // Pickup base of system state array la t1, _tx_thread_system_state // Pickup base of system state array
add t0, t1, t3 // Select this hart's system-state slot add t0, t1, t3 // Select this hart's system-state slot
lw t1, 0(t0) // Pickup system state LOAD t1, 0(t0) // Pickup system state
/* Check for a nested interrupt condition. */ /* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++) /* if (_tx_thread_system_state++)
{ */ { */
beqz t1, _tx_thread_not_nested_save // If 0, first interrupt condition beqz t1, _tx_thread_not_nested_save // If 0, first interrupt condition
addi t1, t1, 1 // Increment the interrupt counter addi t1, t1, 1 // Increment the interrupt counter
sw t1, 0(t0) // Store the interrupt counter STORE t1, 0(t0) // Store the interrupt counter
/* Nested interrupt condition. /* Nested interrupt condition.
Save the reset of the scratch registers on the stack and return to the Save the reset of the scratch registers on the stack and return to the
@@ -170,7 +170,7 @@ _tx_thread_not_nested_save:
/* else if (_tx_thread_current_ptr) /* else if (_tx_thread_current_ptr)
{ */ { */
addi t1, t1, 1 // Increment the interrupt counter addi t1, t1, 1 // Increment the interrupt counter
sw t1, 0(t0) // Store the interrupt counter STORE t1, 0(t0) // Store the interrupt counter
/* Not nested: Find the user thread that was running and load our SP */ /* Not nested: Find the user thread that was running and load our SP */

View File

@@ -94,7 +94,7 @@ _tx_thread_schedule_thread:
/* Atomically claim the thread's ready token so only one hart can /* Atomically claim the thread's ready token so only one hart can
dispatch this TCB at a time. */ dispatch this TCB at a time. */
addi t2, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address addi t2, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address
amoswap.w.aq t3, x0, (t2) // Clear it and fetch prior state AMOSWAP_AQ t3, x0, (t2) // Clear it and fetch prior state
beqz t3, _tx_thread_schedule // If not ready, retry scheduling beqz t3, _tx_thread_schedule // If not ready, retry scheduling
/* } /* }
@@ -115,7 +115,7 @@ _tx_thread_schedule_thread:
and restart so the new selection is not missed. */ and restart so the new selection is not missed. */
STORE x0, 0(t5) // Clear current thread pointer STORE x0, 0(t5) // Clear current thread pointer
li t3, 1 // Rebuild ready token li t3, 1 // Rebuild ready token
amoswap.w.rl x0, t3, (t2) // Restore ready token with release ordering AMOSWAP_RL x0, t3, (t2) // Restore ready token with release ordering
j _tx_thread_schedule_loop // Restart scheduling j _tx_thread_schedule_loop // Restart scheduling
_execute_pointer_did_not_change: _execute_pointer_did_not_change:

View File

@@ -8,7 +8,7 @@
_tx_thread_smp_current_state_get: _tx_thread_smp_current_state_get:
csrr t0, mhartid // Pickup current hart ID csrr t0, mhartid // Pickup current hart ID
la t1, _tx_thread_system_state // Base of per-hart system-state array la t1, _tx_thread_system_state // Base of per-hart system-state array
slli t0, t0, 2 // Build offset into array slli t0, t0, LOG_REGBYTES // Build offset into array
add t1, t1, t0 // Select this hart's slot add t1, t1, t0 // Select this hart's slot
LWU a0, 0(t1) // Return current system state LOAD a0, 0(t1) // Return current system state
ret ret

View File

@@ -16,17 +16,21 @@ _tx_thread_smp_initialize_wait:
beqz t0, _tx_thread_smp_initialize_done // Core 0 does not wait beqz t0, _tx_thread_smp_initialize_done // Core 0 does not wait
/* Build per-hart offsets for ULONG and pointer arrays. */ /* Build per-hart offsets for ULONG and pointer arrays. */
slli t1, t0, 2 // ULONG array offset slli t1, t0, LOG_REGBYTES // ULONG array offset
slli t2, t0, LOG_REGBYTES // Pointer array offset slli t2, t0, LOG_REGBYTES // Pointer array offset
/* Wait until ThreadX has acknowledged this hart by setting its /* Wait until ThreadX has acknowledged this hart by setting its
system state to TX_INITIALIZE_IN_PROGRESS. */ system state to TX_INITIALIZE_IN_PROGRESS. */
li t3, 0xF0F0F0F0 // TX_INITIALIZE_IN_PROGRESS li t3, 0xF0F0F0F0 // TX_INITIALIZE_IN_PROGRESS
#if __riscv_xlen == 64
slli t3, t3, 32
srli t3, t3, 32
#endif
la t4, _tx_thread_system_state // Base of system state array la t4, _tx_thread_system_state // Base of system state array
add t5, t4, t1 // This hart's system state slot add t5, t4, t1 // This hart's system state slot
_tx_thread_smp_wait_for_initialize: _tx_thread_smp_wait_for_initialize:
LWU t6, 0(t5) // Pickup current hart's system state LOAD t6, 0(t5) // Pickup current hart's system state
bne t6, t3, _tx_thread_smp_wait_for_initialize bne t6, t3, _tx_thread_smp_wait_for_initialize
/* Save the system stack pointer for this hart. */ /* Save the system stack pointer for this hart. */
@@ -38,15 +42,15 @@ _tx_thread_smp_wait_for_initialize:
la t3, _tx_thread_smp_release_cores_flag // Release flag address la t3, _tx_thread_smp_release_cores_flag // Release flag address
_tx_thread_smp_wait_for_release: _tx_thread_smp_wait_for_release:
LWU t6, 0(t3) // Pickup release flag LOAD t6, 0(t3) // Pickup release flag
beqz t6, _tx_thread_smp_wait_for_release beqz t6, _tx_thread_smp_wait_for_release
/* Acknowledge the release by clearing this hart's system state. */ /* Acknowledge the release by clearing this hart's system state. */
sw x0, 0(t5) // Set this hart's system state to zero STORE x0, 0(t5) // Set this hart's system state to zero
/* Wait for core 0 to finish initialization. */ /* Wait for core 0 to finish initialization. */
_tx_thread_smp_wait_for_core0: _tx_thread_smp_wait_for_core0:
LWU t6, 0(t4) // Pickup core 0 system state LOAD t6, 0(t4) // Pickup core 0 system state
bnez t6, _tx_thread_smp_wait_for_core0 bnez t6, _tx_thread_smp_wait_for_core0
/* Prepare interrupt state */ /* Prepare interrupt state */

View File

@@ -18,23 +18,23 @@ _tx_thread_smp_protect:
la t1, _tx_thread_smp_protection la t1, _tx_thread_smp_protection
/* If this hart already owns protection, just nest the count. */ /* If this hart already owns protection, just nest the count. */
LWU t3, 4(t1) // Pickup owning hart LOAD t3, 1*REGBYTES(t1) // Pickup owning hart
beq t3, t2, _owned // Already owned by this hart beq t3, t2, _owned // Already owned by this hart
/* Try to get the protection. */ /* Try to get the protection. */
LWU t4, 0(t1) // Pickup protection flag LOAD t4, 0(t1) // Pickup protection flag
bnez t4, _protection_busy // If set, protection is busy bnez t4, _protection_busy // If set, protection is busy
li t4, 1 // Build lock value li t4, 1 // Build lock value
amoswap.w.aq t5, t4, (t1) // Attempt to get protection AMOSWAP_AQ t5, t4, (t1) // Attempt to get protection
bnez t5, _protection_busy // If old value != 0, retry bnez t5, _protection_busy // If old value != 0, retry
fence rw, rw // Ensure lock acquisition is visible fence rw, rw // Ensure lock acquisition is visible
sw t2, 4(t1) // Save owning hart STORE t2, 1*REGBYTES(t1) // Save owning hart
_owned: _owned:
LWU t5, 8(t1) // Pickup ownership count LOAD t5, 2*REGBYTES(t1) // Pickup ownership count
addi t5, t5, 1 // Increment ownership count addi t5, t5, 1 // Increment ownership count
sw t5, 8(t1) // Store ownership count STORE t5, 2*REGBYTES(t1) // Store ownership count
fence rw, rw // Publish owner/count before return fence rw, rw // Publish owner/count before return
ret ret

View File

@@ -17,14 +17,14 @@ _tx_thread_smp_unprotect:
la t2, _tx_thread_smp_protection la t2, _tx_thread_smp_protection
/* Only the owning hart may release the protection. */ /* Only the owning hart may release the protection. */
LWU t3, 4(t2) // Pickup owning hart LOAD t3, 1*REGBYTES(t2) // Pickup owning hart
bne t1, t3, _still_protected // Not owner, skip release bne t1, t3, _still_protected // Not owner, skip release
/* Pickup and decrement the protection count. */ /* Pickup and decrement the protection count. */
LWU t3, 8(t2) // Pickup protection count LOAD t3, 2*REGBYTES(t2) // Pickup protection count
beqz t3, _still_protected // Already cleared beqz t3, _still_protected // Already cleared
addi t3, t3, -1 // Decrement protection count addi t3, t3, -1 // Decrement protection count
sw t3, 8(t2) // Store new count STORE t3, 2*REGBYTES(t2) // Store new count
bnez t3, _still_protected // Still nested, stay protected bnez t3, _still_protected // Still nested, stay protected
/* If preemption is disabled, keep protection in force. */ /* If preemption is disabled, keep protection in force. */
@@ -34,8 +34,8 @@ _tx_thread_smp_unprotect:
/* Release the protection. */ /* Release the protection. */
li t3, -1 // Invalid owner value li t3, -1 // Invalid owner value
sw t3, 4(t2) // Mark owning hart invalid STORE t3, 1*REGBYTES(t2) // Mark owning hart invalid
amoswap.w.rl x0, x0, (t2) // Release protection flag AMOSWAP_RL x0, x0, (t2) // Release protection flag
_still_protected: _still_protected:
csrw mstatus, a0 // Restore interrupt posture csrw mstatus, a0 // Restore interrupt posture

View File

@@ -138,7 +138,7 @@ If floating point support:
Stack Bottom: (higher memory address) */ Stack Bottom: (higher memory address) */
LOAD t0, TX_THREAD_STACK_END_OFFSET(a0) // Pickup end of stack area LOAD t0, 4*REGBYTES(a0) // Pickup end of stack area
andi t0, t0, -16 // Ensure 16-byte alignment andi t0, t0, -16 // Ensure 16-byte alignment
/* Actually build the stack frame. */ /* Actually build the stack frame. */
@@ -224,6 +224,6 @@ If floating point support:
STORE t0, 2*REGBYTES(a0) // Save stack pointer in thread's STORE t0, 2*REGBYTES(a0) // Save stack pointer in thread's
addi t1, x0, 1 // Build ready flag addi t1, x0, 1 // Build ready flag
sw t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET(a0) // Set ready flag STORE t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET(a0) // Set ready flag
ret // control block and return ret // control block and return
/* } */ /* } */

View File

@@ -136,7 +136,7 @@ _tx_thread_system_return:
#endif #endif
csrr t5, mhartid // Pickup current hart ID csrr t5, mhartid // Pickup current hart ID
slli t6, t5, 2 // Build per-hart ULONG offset slli t6, t5, LOG_REGBYTES // Build per-hart ULONG offset
slli t5, t5, LOG_REGBYTES // Build per-hart pointer offset slli t5, t5, LOG_REGBYTES // Build per-hart pointer offset
la t0, _tx_thread_current_ptr // Pickup base of current-thread array la t0, _tx_thread_current_ptr // Pickup base of current-thread array
@@ -158,7 +158,7 @@ _tx_thread_system_return:
la t4, _tx_timer_time_slice // Pickup base of time-slice array la t4, _tx_timer_time_slice // Pickup base of time-slice array
add t4, t4, t6 // Select this hart's time-slice slot add t4, t4, t6 // Select this hart's time-slice slot
lw t3, 0(t4) // Pickup time slice value LOAD t3, 0(t4) // Pickup time slice value
la t2, _tx_thread_schedule // Pickup address of scheduling loop 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 beqz t3, _tx_thread_dont_save_ts // If no time-slice, don't save it
@@ -166,8 +166,8 @@ _tx_thread_system_return:
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; /* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */ _tx_timer_time_slice = 0; */
sw t3, TX_THREAD_TIME_SLICE_OFFSET(t1) // Save current time-slice for thread STORE t3, 6*REGBYTES(t1) // Save current time-slice for thread
sw x0, 0(t4) // Clear time-slice variable STORE x0, 0(t4) // Clear time-slice variable
/* } */ /* } */
_tx_thread_dont_save_ts: _tx_thread_dont_save_ts:
@@ -181,18 +181,18 @@ _tx_thread_dont_save_ts:
fence rw, rw // Publish current-thread clear before ready token fence rw, rw // Publish current-thread clear before ready token
addi t3, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address addi t3, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address
li t4, 1 // Build ready token li t4, 1 // Build ready token
amoswap.w.rl x0, t4, (t3) // Restore ready token AMOSWAP_RL x0, t4, (t3) // Restore ready token
/* Clear protection state. */ /* Clear protection state. */
la t3, _tx_thread_preempt_disable // Pickup preempt-disable address la t3, _tx_thread_preempt_disable // Pickup preempt-disable address
sw x0, 0(t3) // Clear preempt disable flag sw x0, 0(t3) // Clear preempt disable flag
la t3, _tx_thread_smp_protection // Pickup protection structure la t3, _tx_thread_smp_protection // Pickup protection structure
sw x0, 8(t3) // Clear protection count STORE x0, 2*REGBYTES(t3) // Clear protection count
li t4, -1 // Build invalid owner value li t4, -1 // Build invalid owner value
sw t4, 4(t3) // Invalidate owning hart STORE t4, 1*REGBYTES(t3) // Invalidate owning hart
fence rw, rw // Ensure shared accesses complete before unlock fence rw, rw // Ensure shared accesses complete before unlock
sw x0, 0(t3) // Clear protection in-force flag STORE x0, 0(t3) // Clear protection in-force flag
jr t2 // Return to thread scheduler jr t2 // Return to thread scheduler
/* } */ /* } */