summaryrefslogtreecommitdiff
path: root/ports/risc-v64/gnu/src/tx_timer_interrupt.S
diff options
context:
space:
mode:
authorAkif Ejaz <[email protected]>2026-01-26 15:48:46 +0500
committerAkif Ejaz <[email protected]>2026-01-26 15:48:46 +0500
commit6c25effb405cc694578dec664a798fc8af3107e1 (patch)
tree36987ae1933ee659014c74942b318e2ca473c7e7 /ports/risc-v64/gnu/src/tx_timer_interrupt.S
parent12dac1d67d0dfe1c06f839ee285e190c759865a7 (diff)
improve port robustness, portability, and CSR handling
- removed tx_port.h dependency from .S files - replaced tx_timer_interrupt.c with tx_timer_interrupt.S - made some cleanups, formatting to better readability - removed macros (LOAD/STORE/REGBYTES) changed register nomenclature to use RISC-V ABI names (ra, sp, t0, etc.) - added readme_threadx.txt Signed-off-by: Akif Ejaz <[email protected]>
Diffstat (limited to 'ports/risc-v64/gnu/src/tx_timer_interrupt.S')
-rw-r--r--ports/risc-v64/gnu/src/tx_timer_interrupt.S210
1 files changed, 210 insertions, 0 deletions
diff --git a/ports/risc-v64/gnu/src/tx_timer_interrupt.S b/ports/risc-v64/gnu/src/tx_timer_interrupt.S
new file mode 100644
index 00000000..4b2acf61
--- /dev/null
+++ b/ports/risc-v64/gnu/src/tx_timer_interrupt.S
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * Copyright (c) 2024 Microsoft Corporation
+ *
+ * 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 */
+/* */
+/* Scott Larson, Microsoft Corporation */
+/* */
+/* 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 */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 03-08-2023 Scott Larson Initial Version 6.2.1 */
+/* */
+/**************************************************************************/
+/* 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 */
+ ld t1, 0(t0) /* Pickup system clock */
+ la t2, _tx_timer_time_slice /* Pickup address of time slice */
+ ld t3, 0(t2) /* Pickup time slice */
+ addi t1, t1, 1 /* Increment system clock */
+ sd 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--; */
+
+ sd 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
+
+/* } */