1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
#define UserLocal $4,2
#define C0_Status $12
.text
.set noreorder
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_unprotect MIPS32_interAptiv/GNU */
/* 6.2.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function releases previously obtained protection. The supplied */
/* previous SR is restored. If the value of _tx_thread_system_state */
/* and _tx_thread_preempt_disable are both zero, then multithreading */
/* is enabled as well. */
/* */
/* INPUT */
/* */
/* Previous Status Register */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/**************************************************************************/
.globl _tx_thread_smp_unprotect
_tx_thread_smp_unprotect:
di # Disable interrupts
ehb #
sync
mfc0 $25, UserLocal # Pickup VPE ID
la $10, _tx_thread_smp_protection # Build address of protection structure
lw $9, 8($10) # Pickup owning VPE
bne $9, $25, _still_protected # Not the same VPE, protection is in force somewhere else
lw $12, 12($10) # Pickup protection count
beq $12, $0, _still_protected # If zero, protection is not in force anymore
subu $12, $12, 1 # Decrement
sw $12, 12($10) # Store back the protection count
bne $12, $0, _still_protected # If non-zero, nested protection condition
nop #
la $11, _tx_thread_preempt_disable # Build address of preempt disable flag
lw $12, ($11) # Pickup preempt disable flag
bne $12, $0, _still_protected # Don't release protection if preempt disable flag is set
li $8, 0xFFFFFFFF # Setup invalid value
sw $8, 8($10) # Mark VPE as invalid
#ifdef TX_THREAD_SMP_DEBUG_ENABLE
sw $31, 24($10) # Remember the caller of the unprotect
#endif
_release_protect_loop:
sync
sw $0, ($10) # Clear protection
sync
_still_protected:
mtc0 $4, C0_Status # Restore interrupt posture
jr.hb $31 # Return to caller
nop #
|