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 24#define UserLocal $4,2 25#define C0_TCBind $2,2 26 27 .text 28 .set noreorder 29/**************************************************************************/ 30/* */ 31/* FUNCTION RELEASE */ 32/* */ 33/* _tx_timer_interrupt MIPS32_interAptiv/GNU */ 34/* 6.2.1 */ 35/* AUTHOR */ 36/* */ 37/* Scott Larson, Microsoft Corporation */ 38/* */ 39/* DESCRIPTION */ 40/* */ 41/* This function processes the hardware timer interrupt. This */ 42/* processing includes incrementing the system clock and checking for */ 43/* time slice and/or timer expiration. If either is found, the */ 44/* interrupt context save/restore functions are called along with the */ 45/* expiration functions. */ 46/* */ 47/* INPUT */ 48/* */ 49/* None */ 50/* */ 51/* OUTPUT */ 52/* */ 53/* None */ 54/* */ 55/* CALLS */ 56/* */ 57/* _tx_thread_smp_protect Get protection */ 58/* _tx_thread_smp_unprotect Release protection */ 59/* _tx_timer_expiration_process Timer expiration processing */ 60/* _tx_thread_time_slice Time slice interrupted thread */ 61/* */ 62/* CALLED BY */ 63/* */ 64/* interrupt vector */ 65/* */ 66/* RELEASE HISTORY */ 67/* */ 68/* DATE NAME DESCRIPTION */ 69/* */ 70/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ 71/* */ 72/**************************************************************************/ 73/* VOID _tx_timer_interrupt(VOID) 74{ */ 75 .globl _tx_timer_interrupt 76_tx_timer_interrupt: 77 78 /* Check VPE and throw away any timer interrupts for anything other than VPE 0. */ 79 80 mfc0 $8, UserLocal # Pickup VPE ID 81 beq $8, $0, _handle_timer_interrupt # If 0, VPE 0 should handle the interrupt 82 nop 83 jr $31 # Other VPE simply returns 84 nop 85_handle_timer_interrupt: 86 87 subu $29, $29, 16 # Allocate some storage on the stack 88 sw $31, 4($29) # Save ra 89 sw $16, 8($29) # Save preserved register s0 90 91 /* Get protection before the timer variables are updated. */ 92 /* _tx_thread_smp_protect(); */ 93 94 jal _tx_thread_smp_protect # Get VPE protection 95 nop # 96 addu $16, $2, 0 # Save return value 97 98 /* Increment timer interrupt active counter. */ 99 /* _tx_timer_interrupt_active++; */ 100 101 la $9, _tx_timer_interrupt_active # Build address of timer interrupt active count 102 lw $8, ($9) # Pickup timer interrupt active count 103 addu $8, $8, 1 # Increment timer interrupt active count 104 sw $8, ($9) # Store new timer interrupt active count 105 sync 106 107 /* Increment the system clock. */ 108 /* _tx_timer_system_clock++; */ 109 110 la $9, _tx_timer_system_clock # Pickup address of system clock 111 lw $8, ($9) # Pickup system clock 112 addu $8, $8, 1 # Increment system clock 113 sw $8, ($9) # Store new system clock 114 115 /* Test for timer expiration. */ 116 /* if (*_tx_timer_current_ptr) 117 { */ 118 119 la $13, _tx_timer_expired # Pickup address of timer expired flag 120 lw $10, ($13) # Pickup the timer expired flag 121 bne $10, $0, _tx_timer_done # If already expired, skip expiration processing 122 nop # 123 la $9, _tx_timer_current_ptr # Pickup address of current ptr 124 lw $8, ($9) # Pickup current pointer 125 la $13, _tx_timer_expired # Pickup address of timer expired flag 126 lw $10, ($8) # Pickup the current timer entry 127 ori $12, $0, 1 # Build TX_TRUE flag 128 beqz $10, _tx_timer_no_timer # If NULL, no timer has expired 129 nop # Delay slot 130 131 /* Set expiration flag. */ 132 /* _tx_timer_expired = TX_TRUE; */ 133 134 ori $15, $0, 2 # Set local expired flag 135 b _tx_timer_done # Finished timer processing 136 sw $12, ($13) # Set expired flag in memory 137 138 139 /* } 140 else 141 { */ 142_tx_timer_no_timer: 143 144 ori $15, $0, 0 # Set expired flag to false 145 146 /* No timer expired, increment the timer pointer. */ 147 /* _tx_timer_current_ptr++; */ 148 149 /* Check for wrap-around. */ 150 /* if (_tx_timer_current_ptr == _tx_timer_list_end) */ 151 152 la $12, _tx_timer_list_end # Pickup address of list end pointer 153 lw $11, ($12) # Pickup actual list end 154 addu $8, $8, 4 # Point to next timer entry 155 bne $8, $11, _tx_timer_skip_wrap # If not same, good pointer 156 sw $8, ($9) # Store new timer pointer 157 158 /* Wrap to beginning of list. */ 159 /* _tx_timer_current_ptr = _tx_timer_list_start; */ 160 161 la $12, _tx_timer_list_start # Pickup address of list start pointer 162 lw $10, ($12) # Pickup start of the list 163 sw $10, ($9) # Store new timer pointer 164 165 166_tx_timer_skip_wrap: 167 /* } */ 168 169_tx_timer_done: 170 171 /* Did a timer expire? */ 172 /* if (_tx_timer_expired) 173 { */ 174 175 beqz $15, _tx_timer_dont_activate # No, timer not expired 176 nop # Delay slot 177 178 /* Call the timer expiration processing. */ 179 /* _tx_timer_expiration_process(void); */ 180 181 la $9, _tx_timer_expiration_process # Build address of _tx_timer_expiratoin_process routine 182 jal $9 # Call _tx_timer_expiration_process 183 nop 184 lw $15, ($29) # Recover local expired flag 185 186 /* } */ 187_tx_timer_dont_activate: 188 189 190 /* Call time-slice processing. */ 191 /* _tx_thread_time_slice(); */ 192 193 la $9, _tx_thread_time_slice # Pickup address of time slice function 194 jal $9 # Call time slice 195 nop # Delay slot 196 197 /* Decrement timer interrupt active counter. */ 198 /* _tx_timer_interrupt_active--; */ 199 200 la $9, _tx_timer_interrupt_active # Build address of timer interrupt active count 201 lw $8, ($9) # Pickup timer interrupt active count 202 subu $8, $8, 1 # Decrement timer interrupt active count 203 sw $8, ($9) # Store new timer interrupt active count 204 sync 205 206 /* Release VPE protection. */ 207 /* _tx_thread_smp_unprotect(); */ 208 209 addu $4, $16, 0 # Setup input parameter 210 jal _tx_thread_smp_unprotect # Release protection 211 nop # 212 213 lw $31, 4($29) # Recover ra 214 lw $16, 8($29) # Recover s0 215 addu $29, $29, 16 # Recover stack space 216 j $31 # Return to caller 217 nop # Delay slot 218 219/* } */ 220