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