43 lines
1.8 KiB
ArmAsm
43 lines
1.8 KiB
ArmAsm
#include "tx_port.h"
|
|
|
|
.section .text
|
|
.align 2
|
|
|
|
.global _tx_thread_smp_unprotect
|
|
.type _tx_thread_smp_unprotect, @function
|
|
_tx_thread_smp_unprotect:
|
|
|
|
/* Lockout interrupts while protection state is updated. */
|
|
csrci mstatus, 0x08 // Lockout interrupts
|
|
|
|
/* Pickup the current hart ID. */
|
|
csrr t1, mhartid // Pickup hart ID
|
|
|
|
/* Build address of protection structure. */
|
|
la t2, _tx_thread_smp_protection
|
|
|
|
/* Only the owning hart may release the protection. */
|
|
LOAD t3, 1*REGBYTES(t2) // Pickup owning hart
|
|
bne t1, t3, _still_protected // Not owner, skip release
|
|
|
|
/* Pickup and decrement the protection count. */
|
|
LOAD t3, 2*REGBYTES(t2) // Pickup protection count
|
|
beqz t3, _still_protected // Already cleared
|
|
addi t3, t3, -1 // Decrement protection 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. */
|
|
la t4, _tx_thread_preempt_disable
|
|
LWU t5, 0(t4) // Pickup preempt disable
|
|
bnez t5, _still_protected // Skip protection release
|
|
|
|
/* Release the protection. */
|
|
li t3, -1 // Invalid owner value
|
|
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
|
|
ret
|