summaryrefslogtreecommitdiff
path: root/ports/rxv2/gnu/src/tx_thread_context_save.S
blob: 2ca641992771fd773ad9dee972f9d5ab06964b75 (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
;/**************************************************************************/
;/*                                                                        */
;/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
;/*                                                                        */
;/*       This software is licensed under the Microsoft Software License   */
;/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
;/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
;/*       and in the root directory of this software.                      */
;/*                                                                        */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/**                                                                       */
;/** ThreadX Component                                                     */
;/**                                                                       */
;/**   Thread                                                              */
;/**                                                                       */
;/**************************************************************************/
;/**************************************************************************/

    .global     __tx_thread_system_state
    .global     __tx_thread_current_ptr
    .global     __tx_thread_system_stack_ptr

    .text
;/**************************************************************************/
;/*                                                                        */
;/*  FUNCTION                                               RELEASE        */
;/*                                                                        */
;/*    _tx_thread_context_save                              RXv2/GNURX     */
;/*                                                           6.1.3        */
;/*  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                                                                */
;/*                                                                        */
;/*  RELEASE HISTORY                                                       */
;/*                                                                        */
;/*    DATE              NAME                      DESCRIPTION             */
;/*                                                                        */
;/*  12-31-2020     William E. Lamie         Initial Version 6.1.3         */
;/*                                                                        */
;/**************************************************************************/
;VOID   _tx_thread_context_save(VOID)
;{
    .global __tx_thread_context_save
__tx_thread_context_save:
;
;    /* Upon entry to this routine, it is assumed that interrupts are locked
;       out and the (interrupt) stack frame looks like the following:
;
;           (lower address) SP   ->     [return address of this call]
;                           SP+4 ->     Saved R1
;                           SP+8 ->     Saved R2
;                           SP+12->     Interrupted PC
;                           SP+16->     Interrupted PSW
;
;    /* Check for a nested interrupt condition.  */
;    if (_tx_thread_system_state++)
;    {
;

    MOV.L   #__tx_thread_system_state, R1     ; pick up address of system state
    MOV.L   [R1], R2                           ; pick up system state
    CMP     #0, R2                             ; 0 -> no nesting
    BEQ     __tx_thread_not_nested_save
;
;    /* Nested interrupt condition.  */
;
    ADD   #1, r2                             ; _tx_thread_system_state++
    MOV.L   r2, [r1]

;
;   /* Save the rest of the scratch registers on the interrupt stack and return to the
;       calling ISR.  */
    POP R1                                      ; recuperate return address from stack
    PUSHM   R3-R5
    PUSHM   R14-R15
    PUSHC   FPSW                                ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
    JMP     R1                                  ; return address was preserved in R1

;
__tx_thread_not_nested_save:
;    }
;
;    /* Otherwise, not nested, check to see if a thread was running.  */
;    else if (_tx_thread_current_ptr)
;    {
;
    ADD     #1, R2                                ; _tx_thread_system_state++
    MOV.L   R2, [R1]

    MOV.L   #__tx_thread_current_ptr, R2         ; Pickup current thread pointer
    MOV.L   [R2], R2
    CMP     #0,R2                                ; Is it NULL?
    BEQ      __tx_thread_idle_system_save        ; Yes, idle system is running - idle restore
;
;    /* Move stack frame over to the current threads stack.  */
;    /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW)   */
;
    MVFC    USP, R1                               ; pick up user stack pointer
    MOV.L   16[R0], R2
    MOV.L   R2, [-R1]                             ; save PSW on thread stack
    MOV.L   12[R0], R2
    MOV.L   R2, [-R1]                             ; save PC on thread stack
    MOV.L   8[R0], R2
    MOV.L   R2, [-R1]                             ; save R2 on thread stack
    MOV.L   4[R0], R2
    MOV.L   R2, [-R1]                             ; save R1 on thread stack
    MOV.L   R5, [-R1]                             ; save R5 on thread stack
    MOV.L   R4, [-R1]                             ; save R4 on thread stack
    MOV.L   R3, [-R1]                             ; save R3 on thread stack
    MOV.L   R15, [-R1]                            ; save R15 on thread stack
    MOV.L   R14, [-R1]                            ; save R14 on thread stack
    MVFC    FPSW, R3
    MOV.L   R3, [-R1]                             ; save FPSW on thread stack

    POP     R2                                    ; pick up return address from interrupt stack
    ADD     #16, R0, R0                           ; correct interrupt stack pointer back to the bottom
    MVTC    R1, USP                               ; set user/thread stack pointer
    JMP     R2                                    ; return to ISR

;    }
;    else
;    {
;
__tx_thread_idle_system_save:
;
;        /* Interrupt occurred in the scheduling loop.  */
;
    POP     R1                                   ; pick up return address
    ADD     #16, R0, R0                          ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
    JMP     R1                                   ; return to caller
;
;    }
;}
    .end