adjust SMP port to also use ULONG = 8 bytes
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
/* } */
|
/* } */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
/* } */
|
/* } */
|
||||||
|
|||||||
Reference in New Issue
Block a user