summaryrefslogtreecommitdiff
path: root/ports_smp/mips32_interaptiv_smp/gnu/src/tx_thread_smp_protect.S
blob: 19b8d598b85b721ef74f0d2a127406e56f7fda67 (plain)
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