1;/**************************************************************************/
2;/*                                                                        */
3;/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4;/*                                                                        */
5;/*       This software is licensed under the Microsoft Software License   */
6;/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7;/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8;/*       and in the root directory of this software.                      */
9;/*                                                                        */
10;/**************************************************************************/
11;
12;
13;/**************************************************************************/
14;/**************************************************************************/
15;/**                                                                       */
16;/** ThreadX Component                                                     */
17;/**                                                                       */
18;/**   Timer                                                               */
19;/**                                                                       */
20;/**************************************************************************/
21;/**************************************************************************/
22;
23;#define TX_SOURCE_CODE
24;
25;
26;/* Include necessary system files.  */
27;
28;#include "tx_api.h"
29;#include "tx_timer.h"
30;#include "tx_thread.h"
31;
32FP          .set    A15
33DP          .set    B14
34SP          .set    B15
35;
36;Define Assembly language external references...
37;
38    .global     _tx_timer_time_slice
39    .global     _tx_timer_system_clock
40    .global     _tx_timer_current_ptr
41    .global     _tx_timer_list_start
42    .global     _tx_timer_list_end
43    .global     _tx_timer_expired_time_slice
44    .global     _tx_timer_expired
45    .global     _tx_timer_expiration_process
46    .global     _tx_thread_time_slice
47    .global     _tx_thread_context_save
48    .global     _tx_thread_context_restore
49;
50;
51    .sect   ".text"
52;/**************************************************************************/
53;/*                                                                        */
54;/*  FUNCTION                                               RELEASE        */
55;/*                                                                        */
56;/*    _tx_timer_interrupt                                 C667x/TI        */
57;/*                                                           6.1          */
58;/*  AUTHOR                                                                */
59;/*                                                                        */
60;/*    William E. Lamie, Microsoft Corporation                             */
61;/*                                                                        */
62;/*  DESCRIPTION                                                           */
63;/*                                                                        */
64;/*    This function processes the hardware timer interrupt.  This         */
65;/*    processing includes incrementing the system clock and checking for  */
66;/*    time slice and/or timer expiration.  If either is found, the        */
67;/*    interrupt context save/restore functions are called along with the  */
68;/*    expiration functions.                                               */
69;/*                                                                        */
70;/*  INPUT                                                                 */
71;/*                                                                        */
72;/*    None                                                                */
73;/*                                                                        */
74;/*  OUTPUT                                                                */
75;/*                                                                        */
76;/*    None                                                                */
77;/*                                                                        */
78;/*  CALLS                                                                 */
79;/*                                                                        */
80;/*    _tx_thread_context_save               Context save                  */
81;/*    _tx_thread_context_restore            Context restore               */
82;/*    _tx_thread_time_slice                 Time slice interrupted thread */
83;/*    _tx_timer_expiration_process          Timer expiration processing   */
84;/*                                                                        */
85;/*  CALLED BY                                                             */
86;/*                                                                        */
87;/*    interrupt vector                                                    */
88;/*                                                                        */
89;/*  RELEASE HISTORY                                                       */
90;/*                                                                        */
91;/*    DATE              NAME                      DESCRIPTION             */
92;/*                                                                        */
93;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
94;/*                                                                        */
95;/**************************************************************************/
96;VOID   _tx_timer_interrupt(VOID)
97;{
98    .global _tx_timer_interrupt
99_tx_timer_interrupt:
100;
101;    /* Upon entry to this routine, it is assumed that registers B3, A0-A4 have
102;       already been saved and the space for saving additional registers has
103;       already been reserved.  In addition, interrupts are locked out and must
104;       remain so until context save returns.  */
105;
106;    /* Increment the system clock.  */
107;    _tx_timer_system_clock++;
108;
109        MVKL        _tx_timer_system_clock,A0           ; Build address of system clock
110        MVKH        _tx_timer_system_clock,A0           ;
111        LDW         *A0,A2                              ; Pickup system clock
112        MVKL        _tx_timer_time_slice,A3             ; Build address of time slice
113        MVKH        _tx_timer_time_slice,A3             ;
114        LDW         *A3,A1                              ; Pickup time slice
115        NOP         2                                   ; Delay
116        ADD         1,A2,A2                             ; Increment the system clock
117        STW         A2,*A0                              ; Store it back in memory
118;
119;    /* Test for time-slice expiration.  */
120;    if (_tx_timer_time_slice)
121;    {
122;
123 [!A1]  B           _tx_timer_no_time_slice             ; If 0, skip time slice processing
124        SUB         A1,1,A1                             ; Decrement time-slice value
125        NOP         4                                   ; Delay slots
126;
127;       /* Decrement the time_slice.  */
128;       _tx_timer_time_slice--;
129;
130;       /* Check for expiration.  */
131;       if (_tx_timer_time_slice == 0)
132;
133 [A1]   B           _tx_timer_no_time_slice             ; If non-zero, not expired yet
134        STW         A1,*A3                              ; Store new time-slice
135        MVKL        _tx_timer_expired_time_slice,A0     ; Build address of expired flag
136        MVKH        _tx_timer_expired_time_slice,A0     ;
137        MVKL        1,A4                                ; Expired flag
138        NOP                                             ; Delay
139;
140;       /* Set the time-slice expired flag.  */
141;       _tx_timer_expired_time_slice =  TX_TRUE;
142;
143        STW         A4,*A0                              ; Set expired flag
144;    }
145;
146_tx_timer_no_time_slice:
147;
148;    /* Test for timer expiration.  */
149;    if (*_tx_timer_current_ptr)
150;    {
151;
152        MVKL        _tx_timer_current_ptr,A2            ; Build address of current timer pointer
153        MVKH        _tx_timer_current_ptr,A2            ;
154        LDW         *A2,A0                              ; Pickup timer list address
155        MVKL        _tx_timer_expired,A3                ; Build address of expired flag
156        MVKH        _tx_timer_expired,A3                ;
157        NOP         2                                   ; Delay slots
158        LDW         *A0,A1                              ; Pickup current timer entry
159        ADD         4,A0,A0                             ; Increment the current pointer
160        NOP         3                                   ; Delay slots
161 [A1]   B           _tx_timer_done                      ; If non-NULL, something has expired
162;
163;
164;        /* Set expiration flag.  */
165;        _tx_timer_expired =  TX_TRUE;
166;
167        MVKL        1,A4                                ; Build expired flag
168 [A1]   STW         A4,*A3                              ; Set expired flag
169        NOP         3                                   ; Delay slots
170;
171;    }
172;    else
173;    {
174_tx_timer_no_timer:
175;
176;        /* No timer expired, increment the timer pointer.  */
177;        _tx_timer_current_ptr++;
178;
179;        /* Check for wrap-around.  */
180;        if (_tx_timer_current_ptr == _tx_timer_list_end)
181;
182        MVKL        _tx_timer_list_end,A3               ; Build timer list end address
183        MVKH        _tx_timer_list_end,A3               ;
184        LDW         *A3,A4                              ; Pickup list end address
185        MVKL        _tx_timer_list_start,A3             ; Build timer list start address
186        MVKH        _tx_timer_list_start,A3             ;
187        NOP         2                                   ; Delay slots
188        CMPEQ       A4,A0,A1                            ; Compare current pointer with end
189 [A1]   LDW         *A3,A0                              ; If at the end, pickup timer list start
190        NOP         4                                   ; Delay slots
191;
192;            /* Wrap to beginning of list.  */
193;            _tx_timer_current_ptr =  _tx_timer_list_start;
194;
195_tx_timer_skip_wrap:
196;
197;
198        STW         A0,*A2                              ; Store current timer pointer
199;    }
200;
201_tx_timer_done:
202;
203;
204;    /* See if anything has expired.  */
205;    if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
206;    {
207;
208        MVKL        _tx_timer_expired_time_slice,A3     ; Build time-slice expired flag
209        MVKH        _tx_timer_expired_time_slice,A3     ;
210        LDW         *A3,A4                              ; Pickup time-slice expired flag
211        MVKL        _tx_timer_expired,A0                ; Build timer expired flag
212        MVKH        _tx_timer_expired,A0                ;
213        LDW         *A0,A2                              ; Pickup timer expired flag
214        NOP         4                                   ; Delay slots
215        OR          A2,A4,A1                            ; Combine expired flags
216 [!A1]  B           _tx_timer_nothing_expired
217        NOP         5                                   ; Delay slots
218;
219_tx_something_expired:
220;
221;
222;    /* Something expired, call context save.  */
223;    _tx_thread_context_save();
224;
225        B           _tx_thread_context_save             ; Call context save routine
226        MVKL        _tx_timer_ISR_return,B3             ; Build return address
227        MVKH        _tx_timer_ISR_return,B3             ;
228        NOP         3                                   ; Delay slots
229_tx_timer_ISR_return:
230;
231;    /* Did a timer expire?  */
232;    if (_tx_timer_expired)
233;    {
234;
235        MVKL        _tx_timer_expired,A0                ; Build timer expired address
236        MVKH        _tx_timer_expired,A0                ;
237        LDW         *A0,A1                              ; Pickup expired flag
238        NOP         4                                   ; Delay slots
239 [!A1]  B           _tx_timer_dont_activate             ; If not set, skip timer activation
240        NOP         5                                   ; Delay slots
241;
242;        /* Process timer expiration.  */
243;        _tx_timer_expiration_process();
244;
245        B           _tx_timer_expiration_process        ; Process timer expiration
246        MVKL        _tx_timer_ISR_return_1,B3           ; Build return address
247        MVKH        _tx_timer_ISR_return_1,B3           ;
248        NOP         3                                   ; Delay slots
249_tx_timer_ISR_return_1:
250;
251;    }
252_tx_timer_dont_activate:
253;
254;    /* Did time slice expire?  */
255;    if (_tx_timer_expired_time_slice)
256;    {
257;
258        MVKL        _tx_timer_expired_time_slice,A0     ; Build address of expired flag
259        MVKH        _tx_timer_expired_time_slice,A0     ;
260        LDW         *A0,A1                              ; Pickup expired flag
261        NOP         4                                   ; Delay slots
262 [!A1]  B           _tx_timer_not_ts_expiration         ; If not set, skip time-slice processing
263        NOP         5                                   ; Delay slots
264;
265;        /* Time slice interrupted thread.  */
266;        _tx_thread_time_slice();
267;
268        B           _tx_thread_time_slice               ; Call time-slice processing
269        MVKL        _tx_timer_ISR_return_2,B3           ; Build return address
270        MVKH        _tx_timer_ISR_return_2,B3           ;
271        NOP         3                                   ; Delay slots
272_tx_timer_ISR_return_2:
273;
274;    }
275;
276_tx_timer_not_ts_expiration:
277;
278;
279;    /* Call context restore.  */
280;    _tx_thread_context_restore();
281;
282        B           _tx_thread_context_restore          ; Jump to context restore - no return!
283        NOP         5                                   ; Delay slots
284;
285;    }
286;
287_tx_timer_nothing_expired:
288;
289        LDW         *+SP(20),A0                         ; Recover A0
290        LDW         *+SP(24),A1                         ; Recover A1
291        LDW         *+SP(28),A2                         ; Recover A2
292        LDW         *+SP(32),A3                         ; Recover A3
293        B           IRP                                 ; Return to point of interrupt
294||      LDW         *+SP(36),A4                         ; Recover A4
295        LDW         *+SP(96),B3                         ; Recover B3
296        ADDK.S2     288,SP                              ; Recover stack space
297        NOP         3                                   ; Delay slots
298;
299;}
300
301