summaryrefslogtreecommitdiff
path: root/ports/risc-v64/gnu/src/tx_timer_interrupt.S
blob: 53e572f326e953a1ebe4b6792e2149a077268278 (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
/***************************************************************************
 * Copyright (c) 2026 10xEngineers
 *
 * 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                                                     */
/**                                                                       */
/**   Timer                                                               */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/

    .section .text
    .align 4
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _tx_timer_interrupt                                RISC-V64/GNU     */
/*                                                           6.2.1        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Akif Ejaz, 10xEngineers                                             */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function processes the hardware timer interrupt.  This         */
/*    processing includes incrementing the system clock and checking for  */
/*    time slice and/or timer expiration.  If either is found, the        */
/*    interrupt context save/restore functions are called along with the  */
/*    expiration functions.                                               */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _tx_timer_expiration_process          Timer expiration processing   */
/*    _tx_thread_time_slice                 Time slice interrupted thread */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    interrupt vector                                                    */
/*                                                                        */
/**************************************************************************/
/* VOID   _tx_timer_interrupt(VOID)
{  */
    .global  _tx_timer_interrupt
_tx_timer_interrupt:

    /* Increment the system clock.  */
    /* _tx_timer_system_clock++;  */

    la      t0, _tx_timer_system_clock                  // Pickup address of system clock
    lw      t1, 0(t0)                                   // Pickup system clock
    la      t2, _tx_timer_time_slice                    // Pickup address of time slice
    lw      t3, 0(t2)                                   // Pickup time slice
    addi    t1, t1, 1                                   // Increment system clock
    sw      t1, 0(t0)                                   // Store new system clock
    li      t6, 0                                       // Clear local expired flag

    /* Test for time-slice expiration.  */
    /* if (_tx_timer_time_slice)
    {  */

    beqz    t3, _tx_timer_no_time_slice                 // If 0, skip time slice processing
    addi    t3, t3, -1                                  // Decrement the time slice

       /* Decrement the time_slice.  */
       /* _tx_timer_time_slice--;  */

    sw      t3, 0(t2)                                   // Store new time slice

       /* Check for expiration.  */
       /* if (_tx_timer_time_slice == 0)  */

    bgtz    t3, _tx_timer_no_time_slice                 // If not 0, has not expired yet
    li      t1, 1                                       // Build expired flag

       /* Set the time-slice expired flag.  */
       /* _tx_timer_expired_time_slice =  TX_TRUE;  */

    la      t4, _tx_timer_expired_time_slice            // Get address of expired flag
    sw      t1, 0(t4)                                   // Set expired flag (UINT)
    ori     t6, t6, 1                                   // Set local expired flag

    /* }  */

_tx_timer_no_time_slice:

    /* Test for timer expiration.  */
    /* if (*_tx_timer_current_ptr)
    {  */

    la      t0, _tx_timer_current_ptr                   // Pickup address of current ptr
    ld      t1, 0(t0)                                   // Pickup current pointer (double word)
    ld      t3, 0(t1)                                   // Pickup the current timer entry (double word)
    la      t2, _tx_timer_expired                       // Pickup address of timer expired flag
    li      t4, 1                                       // Build TX_TRUE flag
    beqz    t3, _tx_timer_no_timer                      // If NULL, no timer has expired

        /* Set expiration flag.  */
        /* _tx_timer_expired =  TX_TRUE;  */

    ori     t6, t6, 2                                   // Set local expired flag
    sw      t4, 0(t2)                                   // Set expired flag in memory (UINT)
    j       _tx_timer_done                              // Finished timer processing


    /* }
    else
    {  */
_tx_timer_no_timer:

        /* No timer expired, increment the timer pointer.  */
        /* _tx_timer_current_ptr++;  */

        /* Check for wrap-around.  */
        /* if (_tx_timer_current_ptr == _tx_timer_list_end)  */

    la      t2, _tx_timer_list_end                      // Pickup address of list end pointer
    ld      t3, 0(t2)                                   // Pickup actual list end
    addi    t1, t1, 8                                   // Point to next timer entry
    sd      t1, 0(t0)                                   // Store new timer pointer
    bne     t1, t3, _tx_timer_skip_wrap                 // If not same, good pointer

            /* Wrap to beginning of list.  */
            /* _tx_timer_current_ptr =  _tx_timer_list_start;  */

    la      t2, _tx_timer_list_start                    // Pickup address of list start pointer
    ld      t4, 0(t2)                                   // Pickup start of the list
    sd      t4, 0(t0)                                   // Store new timer pointer


_tx_timer_skip_wrap:
    /* }  */

_tx_timer_done:


    /* See if anything has expired.  */
    /* if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
    {  */

    beqz    t6, _tx_timer_nothing_expired               // If nothing expired skip the rest
    addi    sp, sp, -16                                 // Allocate some storage on the stack
    sd      t6, 0(sp)                                   // Save local expired flag
    sd      ra, 8(sp)                                   // Save ra (8-byte aligned)

    /* Did a timer expire?  */
    /* if (_tx_timer_expired)
    {  */

    andi    t2, t6, 2                                   // Isolate the timer expired bit
    beqz    t2, _tx_timer_dont_activate                 // No, timer not expired

        /* Call the timer expiration processing.  */
        /* _tx_timer_expiration_process(void);  */

    call    _tx_timer_expiration_process                // Call _tx_timer_expiration_process
    ld      t6, 0(sp)                                   // Recover local expired flag

    /* }  */
_tx_timer_dont_activate:

    /* Did time slice expire?  */
    /* if (_tx_timer_expired_time_slice)
    {  */

    andi    t2, t6, 1                                   // Is the timer expired bit set?
    beqz    t2, _tx_timer_not_ts_expiration             // If not, skip time slice processing

        /* Time slice interrupted thread.  */
        /* _tx_thread_time_slice();  */

    call    _tx_thread_time_slice                       // Call time slice

     /* }  */

_tx_timer_not_ts_expiration:

    ld      ra, 8(sp)                                   // Recover ra
    addi    sp, sp, 16                                  // Recover stack space
    /* }  */

_tx_timer_nothing_expired:

    ret

/* }  */