1/*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12/**************************************************************************/ 13/**************************************************************************/ 14/** */ 15/** ThreadX Component */ 16/** */ 17/** Timer */ 18/** */ 19/**************************************************************************/ 20/**************************************************************************/ 21#ifdef TX_INCLUDE_USER_DEFINE_FILE 22#include "tx_user.h" 23#endif 24 25 .text 26 .align 3 27/**************************************************************************/ 28/* */ 29/* FUNCTION RELEASE */ 30/* */ 31/* _tx_timer_interrupt ARMv8-A */ 32/* 6.3.0 */ 33/* AUTHOR */ 34/* */ 35/* William E. Lamie, Microsoft Corporation */ 36/* */ 37/* DESCRIPTION */ 38/* */ 39/* This function processes the hardware timer interrupt. This */ 40/* processing includes incrementing the system clock and checking for */ 41/* time slice and/or timer expiration. If either is found, the */ 42/* interrupt context save/restore functions are called along with the */ 43/* expiration functions. */ 44/* */ 45/* INPUT */ 46/* */ 47/* None */ 48/* */ 49/* OUTPUT */ 50/* */ 51/* None */ 52/* */ 53/* CALLS */ 54/* */ 55/* _tx_timer_expiration_process Timer expiration processing */ 56/* _tx_thread_time_slice Time slice interrupted thread */ 57/* */ 58/* CALLED BY */ 59/* */ 60/* interrupt vector */ 61/* */ 62/* RELEASE HISTORY */ 63/* */ 64/* DATE NAME DESCRIPTION */ 65/* */ 66/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 67/* 10-31-2023 Tiejun Zhou Modified comment(s), added */ 68/* #include tx_user.h, */ 69/* resulting in version 6.3.0 */ 70/* */ 71/**************************************************************************/ 72// VOID _tx_timer_interrupt(VOID) 73// { 74 .global _tx_timer_interrupt 75 .type _tx_timer_interrupt, @function 76_tx_timer_interrupt: 77 78 /* Upon entry to this routine, it is assumed that context save has already 79 been called, and therefore the compiler scratch registers are available 80 for use. */ 81 82 /* Increment the system clock. */ 83 // _tx_timer_system_clock++; 84 85 LDR x1, =_tx_timer_system_clock // Pickup address of system clock 86 LDR w0, [x1, #0] // Pickup system clock 87 ADD w0, w0, #1 // Increment system clock 88 STR w0, [x1, #0] // Store new system clock 89 90 /* Test for time-slice expiration. */ 91 /* if (_tx_timer_time_slice) 92 { */ 93 94 LDR x3, =_tx_timer_time_slice // Pickup address of time-slice 95 LDR w2, [x3, #0] // Pickup time-slice 96 CMP w2, #0 // Is it non-active? 97 BEQ __tx_timer_no_time_slice // Yes, skip time-slice processing 98 99 /* Decrement the time_slice. */ 100 /* _tx_timer_time_slice--; */ 101 102 SUB w2, w2, #1 // Decrement the time-slice 103 STR w2, [x3, #0] // Store new time-slice value 104 105 /* Check for expiration. */ 106 /* if (__tx_timer_time_slice == 0) */ 107 108 CMP w2, #0 // Has it expired? 109 BNE __tx_timer_no_time_slice // No, skip expiration processing 110 111 /* Set the time-slice expired flag. */ 112 /* _tx_timer_expired_time_slice = TX_TRUE; */ 113 114 LDR x3, =_tx_timer_expired_time_slice // Pickup address of expired flag 115 MOV w0, #1 // Build expired value 116 STR w0, [x3, #0] // Set time-slice expiration flag 117 118 /* } */ 119 120__tx_timer_no_time_slice: 121 122 /* Test for timer expiration. */ 123 // if (*_tx_timer_current_ptr) 124 // { 125 126 LDR x1, =_tx_timer_current_ptr // Pickup current timer pointer addr 127 LDR x0, [x1, #0] // Pickup current timer 128 LDR x2, [x0, #0] // Pickup timer list entry 129 CMP x2, #0 // Is there anything in the list? 130 BEQ __tx_timer_no_timer // No, just increment the timer 131 132 /* Set expiration flag. */ 133 // _tx_timer_expired = TX_TRUE; 134 135 LDR x3, =_tx_timer_expired // Pickup expiration flag address 136 MOV w2, #1 // Build expired value 137 STR w2, [x3, #0] // Set expired flag 138 B __tx_timer_done // Finished timer processing 139 140 // } 141 // else 142 // { 143__tx_timer_no_timer: 144 145 /* No timer expired, increment the timer pointer. */ 146 // _tx_timer_current_ptr++; 147 148 ADD x0, x0, #8 // Move to next timer 149 150 /* Check for wrap-around. */ 151 // if (_tx_timer_current_ptr == _tx_timer_list_end) 152 153 LDR x3, =_tx_timer_list_end // Pickup addr of timer list end 154 LDR x2, [x3, #0] // Pickup list end 155 CMP x0, x2 // Are we at list end? 156 BNE __tx_timer_skip_wrap // No, skip wrap-around logic 157 158 /* Wrap to beginning of list. */ 159 // _tx_timer_current_ptr = _tx_timer_list_start; 160 161 LDR x3, =_tx_timer_list_start // Pickup addr of timer list start 162 LDR x0, [x3, #0] // Set current pointer to list start 163 164__tx_timer_skip_wrap: 165 166 STR x0, [x1, #0] // Store new current timer pointer 167 // } 168 169__tx_timer_done: 170 171 172 /* See if anything has expired. */ 173 // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) 174 //{ 175 176 LDR x3, =_tx_timer_expired_time_slice // Pickup addr of expired flag 177 LDR w2, [x3, #0] // Pickup time-slice expired flag 178 CMP w2, #0 // Did a time-slice expire? 179 BNE __tx_something_expired // If non-zero, time-slice expired 180 LDR x1, =_tx_timer_expired // Pickup addr of other expired flag 181 LDR w0, [x1, #0] // Pickup timer expired flag 182 CMP w0, #0 // Did a timer expire? 183 BEQ __tx_timer_nothing_expired // No, nothing expired 184 185__tx_something_expired: 186 187 188 STP x29, x30, [sp, #-16]! // Save x29 (frame pointer), x30 (link register) 189 190 /* Did a timer expire? */ 191 // if (_tx_timer_expired) 192 // { 193 194 LDR x1, =_tx_timer_expired // Pickup addr of expired flag 195 LDR w0, [x1, #0] // Pickup timer expired flag 196 CMP w0, #0 // Check for timer expiration 197 BEQ __tx_timer_dont_activate // If not set, skip timer activation 198 199 /* Process timer expiration. */ 200 // _tx_timer_expiration_process(); 201 202 BL _tx_timer_expiration_process // Call the timer expiration handling routine 203 204 // } 205__tx_timer_dont_activate: 206 207 /* Did time slice expire? */ 208 // if (_tx_timer_expired_time_slice) 209 // { 210 211 LDR x3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired 212 LDR w2, [x3, #0] // Pickup the actual flag 213 CMP w2, #0 // See if the flag is set 214 BEQ __tx_timer_not_ts_expiration // No, skip time-slice processing 215 216 /* Time slice interrupted thread. */ 217 // _tx_thread_time_slice(); 218 219 BL _tx_thread_time_slice // Call time-slice processing 220 221 // }/ 222 223__tx_timer_not_ts_expiration: 224 225 LDP x29, x30, [sp], #16 // Recover x29, x30 226 // } 227 228__tx_timer_nothing_expired: 229 230 RET // Return to caller 231 232// } 233