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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/***************************************************************************
* 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_protect MIPS32_interAptiv/GNU */
/* 6.2.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets protection for running inside the ThreadX */
/* source. This is ccomplished by a combination of a test-and-set */
/* flag and periodically disabling interrupts. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Previous Status Register */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/**************************************************************************/
.globl _tx_thread_smp_protect
_tx_thread_smp_protect:
di $2 # Disable interrupts
ehb #
sync
mfc0 $25, UserLocal # Pickup VPE ID
la $10, _tx_thread_smp_protection # Build address to protection structure
lw $9, ($10) # Pickup the protection
bne $9, $0, _already_owned # If non-zero, then the protection is already in force
nop #
ll $11, ($10) # Pickup the protection in force flag
bne $11, $0, _get_retry # Is the protection still available?
li $11, 1 # Build protection in force flag
sc $11, ($10) # Attempt to get the semaphore
beq $11, $0, _get_retry # If successful, we got the protection!
sync
sw $25, 8($10) # Save VPE
sw $11, 12($10) # Setup the initial count
#ifdef TX_THREAD_SMP_DEBUG_ENABLE
sll $13, $25, 2 # Build index based on VPE number
la $12, _tx_thread_current_ptr # Pickup the current thread pointer
addu $12, $12, $13 # Build address of current thread pointer for this VPE
lw $9, ($12) # Pickup current thread pointer
sw $31, 16($10) # Save caller info
sw $2, 20($10) # Save SR
sw $9, 4($10) # Save the current thread pointer
#endif
j $31 # Return to caller
nop
_get_retry:
mtc0 $2, C0_Status # Restore interrupt posture
ehb #
b _tx_thread_smp_protect # Try to get the protection again
nop #
_already_owned:
lw $9, 8($10) # Pickup the owned VPE
beq $9, $25, _have_the_protection # If equal, we already have the protection
lw $12, 12($10) # Pickup protection count
mtc0 $2, C0_Status # Restore interrupt posture
ehb #
b _tx_thread_smp_protect # Try to get the protection again
nop #
_have_the_protection:
addu $12, $12, 1 # Increment
j $31 # Return to caller
sw $12, 12($10) # Store back the protection count
|