adjust SMP port to also use ULONG = 8 bytes

This commit is contained in:
2026-04-02 10:48:43 +02:00
parent eda2a85dc1
commit c16e6b0446
10 changed files with 52 additions and 44 deletions

View File

@@ -80,13 +80,13 @@ _tx_thread_context_restore:
{ */
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
la t0, _tx_thread_system_state // Pickup base of system-state array
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
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
/* 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
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
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
@@ -367,14 +367,14 @@ _tx_thread_preempt_restore:
la t0, _tx_timer_time_slice // Pickup base of time-slice array
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
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice
_tx_timer_time_slice = 0; */
sw t2, TX_THREAD_TIME_SLICE_OFFSET(t1) // Save current time slice
sw x0, 0(t0) // Clear global time slice
STORE t2, 6*REGBYTES(t1) // Save current 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
addi t0, t1, TX_THREAD_SMP_LOCK_READY_BIT_OFFSET // Pickup lock/ready-bit address
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:

View File

@@ -77,18 +77,18 @@ _tx_thread_context_save:
STORE x29, 15*REGBYTES(sp) // Save t4 before reusing it
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
la t1, _tx_thread_system_state // Pickup base of system state array
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. */
/* if (_tx_thread_system_state++)
{ */
beqz t1, _tx_thread_not_nested_save // If 0, first interrupt condition
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.
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)
{ */
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 */

View File

@@ -94,7 +94,7 @@ _tx_thread_schedule_thread:
/* Atomically claim the thread's ready token so only one hart can
dispatch this TCB at a time. */
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
/* }
@@ -115,7 +115,7 @@ _tx_thread_schedule_thread:
and restart so the new selection is not missed. */
STORE x0, 0(t5) // Clear current thread pointer
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
_execute_pointer_did_not_change:

View File

@@ -8,7 +8,7 @@
_tx_thread_smp_current_state_get:
csrr t0, mhartid // Pickup current hart ID
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
LWU a0, 0(t1) // Return current system state
LOAD a0, 0(t1) // Return current system state
ret

View File

@@ -16,17 +16,21 @@ _tx_thread_smp_initialize_wait:
beqz t0, _tx_thread_smp_initialize_done // Core 0 does not wait
/* 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
/* Wait until ThreadX has acknowledged this hart by setting its
system state to 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
add t5, t4, t1 // This hart's system state slot
_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
/* 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
_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
/* 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. */
_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
/* Prepare interrupt state */

View File

@@ -18,23 +18,23 @@ _tx_thread_smp_protect:
la t1, _tx_thread_smp_protection
/* 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
/* 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
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
fence rw, rw // Ensure lock acquisition is visible
sw t2, 4(t1) // Save owning hart
STORE t2, 1*REGBYTES(t1) // Save owning hart
_owned:
LWU t5, 8(t1) // Pickup ownership count
LOAD t5, 2*REGBYTES(t1) // Pickup 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
ret

View File

@@ -17,14 +17,14 @@ _tx_thread_smp_unprotect:
la t2, _tx_thread_smp_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
/* 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
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
/* If preemption is disabled, keep protection in force. */
@@ -34,8 +34,8 @@ _tx_thread_smp_unprotect:
/* Release the protection. */
li t3, -1 // Invalid owner value
sw t3, 4(t2) // Mark owning hart invalid
amoswap.w.rl x0, x0, (t2) // Release protection flag
STORE t3, 1*REGBYTES(t2) // Mark owning hart invalid
AMOSWAP_RL x0, x0, (t2) // Release protection flag
_still_protected:
csrw mstatus, a0 // Restore interrupt posture

View File

@@ -138,7 +138,7 @@ If floating point support:
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
/* Actually build the stack frame. */
@@ -224,6 +224,6 @@ If floating point support:
STORE t0, 2*REGBYTES(a0) // Save stack pointer in thread's
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
/* } */

View File

@@ -136,7 +136,7 @@ _tx_thread_system_return:
#endif
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
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
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
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_timer_time_slice = 0; */
sw t3, TX_THREAD_TIME_SLICE_OFFSET(t1) // Save current time-slice for thread
sw x0, 0(t4) // Clear time-slice variable
STORE t3, 6*REGBYTES(t1) // Save current time-slice for thread
STORE x0, 0(t4) // Clear time-slice variable
/* } */
_tx_thread_dont_save_ts:
@@ -181,18 +181,18 @@ _tx_thread_dont_save_ts:
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
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. */
la t3, _tx_thread_preempt_disable // Pickup preempt-disable address
sw x0, 0(t3) // Clear preempt disable flag
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
sw t4, 4(t3) // Invalidate owning hart
STORE t4, 1*REGBYTES(t3) // Invalidate owning hart
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
/* } */