summaryrefslogtreecommitdiff
path: root/ports/arc_hs/metaware/src/tx_thread_context_save.s
blob: 27ee25b52195c82b28933bf6576f3051fe1f25c9 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
; *
; * 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                                                              */
;/**                                                                       */
;/**************************************************************************/
;/**************************************************************************/
#ifdef TX_INCLUDE_USER_DEFINE_FILE
#include "tx_user.h"
#endif

    .equ    BTA, 0x412

;/**************************************************************************/
;/*                                                                        */
;/*  FUNCTION                                               RELEASE        */
;/*                                                                        */
;/*    _tx_thread_context_save                           ARC_HS/MetaWare   */
;/*                                                           6.2.1        */
;/*  AUTHOR                                                                */
;/*                                                                        */
;/*    William E. Lamie, Microsoft Corporation                             */
;/*                                                                        */
;/*  DESCRIPTION                                                           */
;/*                                                                        */
;/*    This function saves the context of an executing thread in the       */
;/*    beginning of interrupt processing.  The function also ensures that  */
;/*    the system stack is used upon return to the calling ISR.            */
;/*                                                                        */
;/*  INPUT                                                                 */
;/*                                                                        */
;/*    None                                                                */
;/*                                                                        */
;/*  OUTPUT                                                                */
;/*                                                                        */
;/*    None                                                                */
;/*                                                                        */
;/*  CALLS                                                                 */
;/*                                                                        */
;/*    None                                                                */
;/*                                                                        */
;/*  CALLED BY                                                             */
;/*                                                                        */
;/*    ISRs                                                                */
;/*                                                                        */
;/**************************************************************************/
;VOID   _tx_thread_context_save(VOID)
;{
    .global _tx_thread_context_save
    .type   _tx_thread_context_save, @function
_tx_thread_context_save:
;
;    /* Upon entry to this routine, it is assumed that an interrupt stack frame
;       has already been allocated, and the interrupted blink register is already saved.  */
;
    clri                                                ; Disable interrupts
    st      r1, [sp, 128]                               ; Save r1
    st      r0, [sp, 132]                               ; Save r0
;
;    /* Check for a nested interrupt condition.  */
;    if (_tx_thread_system_state++)
;    {
;
    ld      r0, [gp, _tx_thread_system_state@sda]       ; Pickup system state
    st      r3, [sp, 120]                               ; Save r3
    st      r2, [sp, 124]                               ; Save r2
    breq    r0, 0, __tx_thread_not_nested_save          ; If 0, we are not in a nested
                                                        ;   condition
;
;    /* Nested interrupt condition.  */
;
    add     r0, r0, 1                                   ; Increment the nested interrupt count
    st      r0, [gp, _tx_thread_system_state@sda]       ; Update system state
;
;   /* Save the rest of the scratch registers on the stack and return to the
;      calling ISR.  */
;
__tx_thread_nested_save:                                ; Label is for special nested interrupt case from idle system save below
    st      r30, [sp, 136]                              ; Save r30
    st      r25, [sp, 32]                               ; Save r25
    st      r12, [sp, 84]                               ; Save r12
    st      r11, [sp, 88]                               ; Save r11
    st      r10, [sp, 92]                               ; Save r10
    st      r9,  [sp, 96]                               ; Save r9
    st      r8,  [sp, 100]                              ; Save r8
    st      r7,  [sp, 104]                              ; Save r7
    st      r6,  [sp, 108]                              ; Save r6
    st      r5,  [sp, 112]                              ; Save r5
    st      r4,  [sp, 116]                              ; Save r4
    lr      r10, [LP_START]                             ; Pickup LP_START
    lr      r9,  [LP_END]                               ; Pickup LP_END
    st      LP_COUNT, [sp, 12]                          ; Save LP_COUNT
    st      r10, [sp, 4]                                ; Save LP_START
    st      r9,  [sp, 8]                                ; Save LP_END
    .ifdef   TX_ENABLE_ACC
    st      r58, [sp, 140]                              ; Save r58
    st      r59, [sp, 144]                              ; Save r59
    .endif
    lr      r0,  [BTA]                                  ; Pickup BTA
    st      r0,  [sp, 156]                              ; Save BTA

;
;    /* Return to the ISR.  */
;
    .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
;    /* Call the ISR enter function to indicate an ISR is executing.  */
;
    sub     sp, sp, 32                                  ; Allocating some space on the stack
    st      blink, [sp, 16]                             ; Save blink
    bl.d    _tx_execution_isr_enter                     ; Call the ISR enter function
    nop                                                 ; Delay slot
    ld      blink, [sp, 16]                             ; Recover blink
    add     sp, sp, 32                                  ; Recover the stack space
    .endif
;

    j.d     [blink]                                     ; Return to Level 1 ISR
    st      ilink, [sp, 20]                             ; Save ilink
;
__tx_thread_not_nested_save:
;    }
;
;    /* Otherwise, not nested, check to see if a thread was running.  */
;    else if (_tx_thread_current_ptr)
;    {
;
    add     r0, r0, 1                                   ; Increment the nested interrupt count
    st      r0, [gp, _tx_thread_system_state@sda]       ; Update system state
    ld      r1, [gp, _tx_thread_current_ptr@sda]        ; Pickup current thread pointer
    st      r30, [sp, 136]                              ; Save r30
    st      r25, [sp, 32]                               ; Save r25
    st      r12, [sp, 84]                               ; Save r12
    st      r11, [sp, 88]                               ; Save r11
    breq    r1, 0, __tx_thread_idle_system_save         ; If no thread is running, idle system was
                                                        ;   interrupted.
;
;    /* Save minimal context of interrupted thread.  */
;
    st      r10, [sp, 92]                               ; Save r10
    st      r9,  [sp, 96]                               ; Save r9
    st      r8,  [sp, 100]                              ; Save r8
    st      r7,  [sp, 104]                              ; Save r7
    st      r6,  [sp, 108]                              ; Save r6
    st      r5,  [sp, 112]                              ; Save r5
    st      r4,  [sp, 116]                              ; Save r4
    lr      r10, [LP_START]                             ; Pickup LP_START
    lr      r9,  [LP_END]                               ; Pickup LP_END
    st      LP_COUNT, [sp, 12]                          ; Save LP_COUNT
    st      r10, [sp, 4]                                ; Save LP_START
    st      r9,  [sp, 8]                                ; Save LP_END
    st      ilink, [sp, 20]                             ; Save ilink
    .ifdef   TX_ENABLE_ACC
    st      r58, [sp, 140]                              ; Save r58
    st      r59, [sp, 144]                              ; Save r59
    .endif
    lr      r0,  [BTA]                                  ; Pickup BTA
    st      r0,  [sp, 156]                              ; Save BTA
;
;    /* Save the current stack pointer in the thread's control block.  */
;    _tx_thread_current_ptr -> tx_thread_stack_ptr =  sp;
;
    st      sp, [r1, 8]                                 ; Save thread's stack pointer

    .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
;    /* Call the ISR enter function to indicate an ISR is executing.  */
;
    sub     sp, sp, 32                                  ; Allocating some space on the stack
    st      blink, [sp, 16]                             ; Save blink
    bl.d    _tx_execution_isr_enter                     ; Call the ISR enter function
    nop                                                 ; Delay slot
    ld      blink, [sp, 16]                             ; Recover blink
    add     sp, sp, 32                                  ; Recover the stack space
    .endif

;
;    /* Switch to the system stack.  */
;    sp =  _tx_thread_system_stack_ptr;
;
    j_s.d   [blink]                                     ; Return to calling ISR
    ld      sp, [gp, _tx_thread_system_stack_ptr@sda]   ; Switch to system stack
;
;    }
;    else
;    {
;
__tx_thread_idle_system_save:
;
;    /* Interrupt occurred in the scheduling loop.  */
;
    .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
;    /* Call the ISR enter function to indicate an ISR is executing.  */
;
    sub     sp, sp, 32                                  ; Allocating some space on the stack
    st      blink, [sp, 16]                             ; Save blink
    bl.d    _tx_execution_isr_enter                     ; Call the ISR enter function
    nop                                                 ; Delay slot
    ld      blink, [sp, 16]                             ; Recover blink
    add     sp, sp, 32                                  ; Recover the stack space
    .endif
;
;     /* See if we have a special nesting condition.  This happens when the higher priority
;        interrupt occurs before the nested interrupt logic is valid.  */
;
    lr      r0, [AUX_IRQ_ACT]                           ; Pickup the interrupt active register
    neg     r1, r0                                      ; Negate
    and     r1, r0, r1                                  ; See if there are any other interrupts present
    brne    r0, r1, __tx_thread_nested_save             ; If more interrupts, go into the nested interrupt save logic
;
;    /* Not much to do here, just adjust the stack pointer, and return to
;       ISR processing.  */
;
    j_s.d   [blink]                                     ; Return to ISR
    add     sp, sp, 160                                 ; Recover stack space
;
;    }
;}
    .end