6.1 minor release
This commit is contained in:
130
ports/risc-v32/iar/src/tx_initialize_low_level.s
Normal file
130
ports/risc-v32/iar/src/tx_initialize_low_level.s
Normal file
@@ -0,0 +1,130 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Initialize */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h" */
|
||||
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
EXTERN _tx_initialize_unused_memory
|
||||
EXTERN _tx_thread_context_save
|
||||
EXTERN _tx_thread_context_restore
|
||||
EXTERN _tx_timer_interrupt
|
||||
|
||||
RSEG FREE_MEM:DATA
|
||||
PUBLIC __tx_free_memory_start
|
||||
__tx_free_memory_start:
|
||||
DS32 4
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_low_level RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for any low-level processor */
|
||||
/* initialization, including setting up interrupt vectors, setting */
|
||||
/* up a periodic timer interrupt source, saving the system stack */
|
||||
/* pointer for use in ISR processing later, and finding the first */
|
||||
/* available RAM memory address for tx_application_define. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_initialize_low_level(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_initialize_low_level
|
||||
_tx_initialize_low_level:
|
||||
sw sp, _tx_thread_system_stack_ptr, t0 ; Save system stack pointer
|
||||
|
||||
la t0, __tx_free_memory_start ; Pickup first free address
|
||||
sw t0, _tx_initialize_unused_memory, t1 ; Save unused memory address
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/* Define the actual timer interrupt/exception handler. */
|
||||
|
||||
PUBLIC _tx_timer_interrupt_handler
|
||||
PUBLIC __minterrupt_000007
|
||||
EXTWEAK __require_minterrupt_vector_table
|
||||
_tx_timer_interrupt_handler:
|
||||
__minterrupt_000007:
|
||||
REQUIRE __require_minterrupt_vector_table
|
||||
|
||||
|
||||
/* Before calling _tx_thread_context_save, we have to allocate an interrupt
|
||||
stack frame and save the current value of x1 (ra). */
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, -260 ; Allocate space for all registers - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -128 ; Allocate space for all registers - without floating point enabled
|
||||
#endif
|
||||
sw x1, 0x70(sp) ; Store RA
|
||||
call _tx_thread_context_save ; Call ThreadX context save
|
||||
|
||||
/* Call the ThreadX timer routine. */
|
||||
call _tx_timer_interrupt ; Call timer interrupt handler
|
||||
|
||||
/* Timer interrupt processing is done, jump to ThreadX context restore. */
|
||||
j _tx_thread_context_restore ; Jump to ThreadX context restore function. Note: this does not return!
|
||||
|
||||
|
||||
END
|
||||
|
||||
344
ports/risc-v32/iar/src/tx_thread_context_restore.s
Normal file
344
ports/risc-v32/iar/src/tx_thread_context_restore.s
Normal file
@@ -0,0 +1,344 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h" */
|
||||
|
||||
EXTERN _tx_thread_execute_ptr
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_thread_preempt_disable
|
||||
EXTERN _tx_thread_schedule
|
||||
EXTERN _tx_thread_system_state
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_isr_exit
|
||||
#endif
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_restore RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function restores the interrupt context if it is processing a */
|
||||
/* nested interrupt. If not, it returns to the interrupt thread if no */
|
||||
/* preemption is necessary. Otherwise, if preemption is necessary or */
|
||||
/* if no thread was running, the function returns to the scheduler. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_schedule Thread scheduling routine */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ISRs Interrupt Service Routines */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_restore(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_context_restore
|
||||
_tx_thread_context_restore:
|
||||
|
||||
/* Lockout interrupts. */
|
||||
|
||||
csrci mstatus, 0x08 ; Disable interrupts
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
call _tx_execution_isr_exit ; Call the ISR execution exit function
|
||||
#endif
|
||||
|
||||
/* Determine if interrupts are nested. */
|
||||
/* if (--_tx_thread_system_state)
|
||||
{ */
|
||||
|
||||
la t0, _tx_thread_system_state ; Pickup addr of nested interrupt count
|
||||
lw t1, 0(t0) ; Pickup nested interrupt count
|
||||
addi t1, t1, -1 ; Decrement the nested interrupt counter
|
||||
sw t1, 0(t0) ; Store new nested count
|
||||
beqz t1, _tx_thread_not_nested_restore ; If 0, not nested restore
|
||||
|
||||
/* Interrupts are nested. */
|
||||
|
||||
/* Just recover the saved registers and return to the point of
|
||||
interrupt. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Recover floating point registers. */
|
||||
|
||||
flw f0, 0x7C(sp) ; Recover ft0
|
||||
flw f1, 0x80(sp) ; Recover ft1
|
||||
flw f2, 0x84(sp) ; Recover ft2
|
||||
flw f3, 0x88(sp) ; Recover ft3
|
||||
flw f4, 0x8C(sp) ; Recover ft4
|
||||
flw f5, 0x90(sp) ; Recover ft5
|
||||
flw f6, 0x94(sp) ; Recover ft6
|
||||
flw f7, 0x98(sp) ; Recover ft7
|
||||
flw f10,0xA4(sp) ; Recover fa0
|
||||
flw f11,0xA8(sp) ; Recover fa1
|
||||
flw f12,0xAC(sp) ; Recover fa2
|
||||
flw f13,0xB0(sp) ; Recover fa3
|
||||
flw f14,0xB4(sp) ; Recover fa4
|
||||
flw f15,0xB8(sp) ; Recover fa5
|
||||
flw f16,0xBC(sp) ; Recover fa6
|
||||
flw f17,0xC0(sp) ; Recover fa7
|
||||
flw f28,0xEC(sp) ; Recover ft8
|
||||
flw f29,0xF0(sp) ; Recover ft9
|
||||
flw f30,0xF4(sp) ; Recover ft10
|
||||
flw f31,0xF8(sp) ; Recover ft11
|
||||
lw t0, 0xFC(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover standard registers. */
|
||||
|
||||
/* Restore registers,
|
||||
Skip global pointer because that does not change
|
||||
Also skip the saved registers since they have been restored by any function we called.
|
||||
Except s0 since we use it ourselves. */
|
||||
|
||||
lw t0, 0x78(sp) ; Recover mepc
|
||||
csrw mepc, t0 ; Setup mepc
|
||||
li t0, 0x1880 ; Prepare MPIP
|
||||
csrw mstatus, t0 ; Enable MPIP
|
||||
|
||||
lw x1, 0x70(sp) ; Recover RA
|
||||
lw x5, 0x4C(sp) ; Recover t0
|
||||
lw x6, 0x48(sp) ; Recover t1
|
||||
lw x7, 0x44(sp) ; Recover t2
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x10, 0x6C(sp) ; Recover a0
|
||||
lw x11, 0x68(sp) ; Recover a1
|
||||
lw x12, 0x64(sp) ; Recover a2
|
||||
lw x13, 0x60(sp) ; Recover a3
|
||||
lw x14, 0x5C(sp) ; Recover a4
|
||||
lw x15, 0x58(sp) ; Recover a5
|
||||
lw x16, 0x54(sp) ; Recover a6
|
||||
lw x17, 0x50(sp) ; Recover a7
|
||||
lw x28, 0x40(sp) ; Recover t3
|
||||
lw x29, 0x3C(sp) ; Recover t4
|
||||
lw x30, 0x38(sp) ; Recover t5
|
||||
lw x31, 0x34(sp) ; Recover t6
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover stack frame - without floating point enabled
|
||||
#endif
|
||||
mret ; Return to point of interrupt
|
||||
|
||||
/* } */
|
||||
_tx_thread_not_nested_restore:
|
||||
/* Determine if a thread was interrupted and no preemption is required. */
|
||||
/* else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|
||||
|| (_tx_thread_preempt_disable))
|
||||
{ */
|
||||
|
||||
lw t1, _tx_thread_current_ptr ; Pickup current thread pointer
|
||||
beqz t1, _tx_thread_idle_system_restore ; If NULL, idle system restore
|
||||
|
||||
lw t2, _tx_thread_preempt_disable ; Pickup preempt disable flag
|
||||
bgtz t2, _tx_thread_no_preempt_restore ; If set, restore interrupted thread
|
||||
|
||||
lw t2, _tx_thread_execute_ptr ; Pickup thread execute pointer
|
||||
bne t1, t2, _tx_thread_preempt_restore ; If higher-priority thread is ready, preempt
|
||||
|
||||
|
||||
_tx_thread_no_preempt_restore:
|
||||
/* Restore interrupted thread or ISR. */
|
||||
|
||||
/* Pickup the saved stack pointer. */
|
||||
/* SP = _tx_thread_current_ptr -> tx_thread_stack_ptr; */
|
||||
|
||||
lw sp, 8(t1) ; Switch back to thread's stack
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Recover floating point registers. */
|
||||
|
||||
flw f0, 0x7C(sp) ; Recover ft0
|
||||
flw f1, 0x80(sp) ; Recover ft1
|
||||
flw f2, 0x84(sp) ; Recover ft2
|
||||
flw f3, 0x88(sp) ; Recover ft3
|
||||
flw f4, 0x8C(sp) ; Recover ft4
|
||||
flw f5, 0x90(sp) ; Recover ft5
|
||||
flw f6, 0x94(sp) ; Recover ft6
|
||||
flw f7, 0x98(sp) ; Recover ft7
|
||||
flw f10,0xA4(sp) ; Recover fa0
|
||||
flw f11,0xA8(sp) ; Recover fa1
|
||||
flw f12,0xAC(sp) ; Recover fa2
|
||||
flw f13,0xB0(sp) ; Recover fa3
|
||||
flw f14,0xB4(sp) ; Recover fa4
|
||||
flw f15,0xB8(sp) ; Recover fa5
|
||||
flw f16,0xBC(sp) ; Recover fa6
|
||||
flw f17,0xC0(sp) ; Recover fa7
|
||||
flw f28,0xEC(sp) ; Recover ft8
|
||||
flw f29,0xF0(sp) ; Recover ft9
|
||||
flw f30,0xF4(sp) ; Recover ft10
|
||||
flw f31,0xF8(sp) ; Recover ft11
|
||||
lw t0, 0xFC(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover the saved context and return to the point of interrupt. */
|
||||
|
||||
/* Recover standard registers. */
|
||||
/* Restore registers,
|
||||
Skip global pointer because that does not change */
|
||||
|
||||
lw t0, 0x78(sp) ; Recover mepc
|
||||
csrw mepc, t0 ; Setup mepc
|
||||
li t0, 0x1880 ; Prepare MPIP
|
||||
csrw mstatus, t0 ; Enable MPIP
|
||||
|
||||
lw x1, 0x70(sp) ; Recover RA
|
||||
lw x5, 0x4C(sp) ; Recover t0
|
||||
lw x6, 0x48(sp) ; Recover t1
|
||||
lw x7, 0x44(sp) ; Recover t2
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x10, 0x6C(sp) ; Recover a0
|
||||
lw x11, 0x68(sp) ; Recover a1
|
||||
lw x12, 0x64(sp) ; Recover a2
|
||||
lw x13, 0x60(sp) ; Recover a3
|
||||
lw x14, 0x5C(sp) ; Recover a4
|
||||
lw x15, 0x58(sp) ; Recover a5
|
||||
lw x16, 0x54(sp) ; Recover a6
|
||||
lw x17, 0x50(sp) ; Recover a7
|
||||
lw x28, 0x40(sp) ; Recover t3
|
||||
lw x29, 0x3C(sp) ; Recover t4
|
||||
lw x30, 0x38(sp) ; Recover t5
|
||||
lw x31, 0x34(sp) ; Recover t6
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover stack frame - without floating point enabled
|
||||
#endif
|
||||
mret ; Return to point of interrupt
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
_tx_thread_preempt_restore:
|
||||
/* Instead of directly activating the thread again, ensure we save the
|
||||
entire stack frame by saving the remaining registers. */
|
||||
|
||||
lw t0, 8(t1) ; Pickup thread's stack pointer
|
||||
ori t3, x0, 1 ; Build interrupt stack type
|
||||
sw t3, 0(t0) ; Store stack type
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Store floating point preserved registers. */
|
||||
|
||||
fsw f8, 0x9C(t0) ; Store fs0
|
||||
fsw f9, 0xA0(t0) ; Store fs1
|
||||
fsw f18, 0xC4(t0) ; Store fs2
|
||||
fsw f19, 0xC8(t0) ; Store fs3
|
||||
fsw f20, 0xCC(t0) ; Store fs4
|
||||
fsw f21, 0xD0(t0) ; Store fs5
|
||||
fsw f22, 0xD4(t0) ; Store fs6
|
||||
fsw f23, 0xD8(t0) ; Store fs7
|
||||
fsw f24, 0xDC(t0) ; Store fs8
|
||||
fsw f25, 0xE0(t0) ; Store fs9
|
||||
fsw f26, 0xE4(t0) ; Store fs10
|
||||
fsw f27, 0xE8(t0) ; Store fs11
|
||||
#endif
|
||||
|
||||
/* Store standard preserved registers. */
|
||||
|
||||
sw x9, 0x2C(t0) ; Store s1
|
||||
sw x18, 0x28(t0) ; Store s2
|
||||
sw x19, 0x24(t0) ; Store s3
|
||||
sw x20, 0x20(t0) ; Store s4
|
||||
sw x21, 0x1C(t0) ; Store s5
|
||||
sw x22, 0x18(t0) ; Store s6
|
||||
sw x23, 0x14(t0) ; Store s7
|
||||
sw x24, 0x10(t0) ; Store s8
|
||||
sw x25, 0x0C(t0) ; Store s9
|
||||
sw x26, 0x08(t0) ; Store s10
|
||||
sw x27, 0x04(t0) ; Store s11
|
||||
; Note: s0 is already stored!
|
||||
|
||||
/* Save the remaining time-slice and disable it. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
la t0, _tx_timer_time_slice ; Pickup time slice variable address
|
||||
lw t2, 0(t0) ; Pickup time slice
|
||||
beqz t2, _tx_thread_dont_save_ts ; If 0, skip time slice processing
|
||||
|
||||
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice
|
||||
_tx_timer_time_slice = 0; */
|
||||
|
||||
sw t2, 24(t1) ; Save current time slice
|
||||
sw x0, 0(t0) ; Clear global time slice
|
||||
|
||||
|
||||
/* } */
|
||||
_tx_thread_dont_save_ts:
|
||||
/* Clear the current task pointer. */
|
||||
/* _tx_thread_current_ptr = TX_NULL; */
|
||||
|
||||
/* Return to the scheduler. */
|
||||
/* _tx_thread_schedule(); */
|
||||
|
||||
sw x0, _tx_thread_current_ptr, t0 ; Clear current thread pointer*/
|
||||
/* } */
|
||||
|
||||
_tx_thread_idle_system_restore:
|
||||
/* Just return back to the scheduler! */
|
||||
j _tx_thread_schedule ; Return to scheduler
|
||||
|
||||
/* } */
|
||||
END
|
||||
263
ports/risc-v32/iar/src/tx_thread_context_save.s
Normal file
263
ports/risc-v32/iar/src/tx_thread_context_save.s
Normal file
@@ -0,0 +1,263 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h" */
|
||||
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_thread_system_state
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_isr_enter
|
||||
#endif
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_save RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function saves the context of an executing thread in the */
|
||||
/* beginning of interrupt processing. The function also ensures that */
|
||||
/* the system stack is used upon return to the calling ISR. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ISRs */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_save(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_context_save
|
||||
_tx_thread_context_save:
|
||||
|
||||
/* Upon entry to this routine, it is assumed that interrupts are locked
|
||||
out and the interrupt stack fame has been allocated and x1 (ra) has
|
||||
been saved on the stack. */
|
||||
|
||||
sw x5, 0x4C(sp) ; First store t0 and t1
|
||||
sw x6, 0x48(sp)
|
||||
|
||||
la x5, _tx_thread_system_state ; Pickup address of system state
|
||||
lw x6, 0(x5) ; Pickup system state
|
||||
|
||||
/* Check for a nested interrupt condition. */
|
||||
/* if (_tx_thread_system_state++)
|
||||
{ */
|
||||
beqz x6, _tx_thread_not_nested_save ; If 0, first interrupt condition
|
||||
addi x6, x6, 1 ; Increment the interrupt counter
|
||||
sw x6, 0(x5) ; Store the interrupt counter
|
||||
|
||||
/* Nested interrupt condition.
|
||||
Save the reset of the scratch registers on the stack and return to the
|
||||
calling ISR. */
|
||||
|
||||
sw x7, 0x44(sp) ; Store t2
|
||||
sw x8, 0x30(sp) ; Store s0
|
||||
sw x10, 0x6C(sp) ; Store a0
|
||||
sw x11, 0x68(sp) ; Store a1
|
||||
sw x12, 0x64(sp) ; Store a2
|
||||
sw x13, 0x60(sp) ; Store a3
|
||||
sw x14, 0x5C(sp) ; Store a4
|
||||
sw x15, 0x58(sp) ; Store a5
|
||||
sw x16, 0x54(sp) ; Store a6
|
||||
sw x17, 0x50(sp) ; Store a7
|
||||
sw x28, 0x40(sp) ; Store t3
|
||||
sw x29, 0x3C(sp) ; Store t4
|
||||
sw x30, 0x38(sp) ; Store t5
|
||||
sw x31, 0x34(sp) ; Store t6
|
||||
csrr t0, mepc ; Load exception program counter
|
||||
sw t0, 0x78(sp) ; Save it on the stack
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Save floating point scratch registers. */
|
||||
|
||||
fsw f0, 0x7C(sp) ; Store ft0
|
||||
fsw f1, 0x80(sp) ; Store ft1
|
||||
fsw f2, 0x84(sp) ; Store ft2
|
||||
fsw f3, 0x88(sp) ; Store ft3
|
||||
fsw f4, 0x8C(sp) ; Store ft4
|
||||
fsw f5, 0x90(sp) ; Store ft5
|
||||
fsw f6, 0x94(sp) ; Store ft6
|
||||
fsw f7, 0x98(sp) ; Store ft7
|
||||
fsw f10,0xA4(sp) ; Store fa0
|
||||
fsw f11,0xA8(sp) ; Store fa1
|
||||
fsw f12,0xAC(sp) ; Store fa2
|
||||
fsw f13,0xB0(sp) ; Store fa3
|
||||
fsw f14,0xB4(sp) ; Store fa4
|
||||
fsw f15,0xB8(sp) ; Store fa5
|
||||
fsw f16,0xBC(sp) ; Store fa6
|
||||
fsw f17,0xC0(sp) ; Store fa7
|
||||
fsw f28,0xEC(sp) ; Store ft8
|
||||
fsw f29,0xF0(sp) ; Store ft9
|
||||
fsw f30,0xF4(sp) ; Store ft10
|
||||
fsw f31,0xF8(sp) ; Store ft11
|
||||
csrr t0, fcsr
|
||||
sw t0, 0xFC(sp) ; Store fcsr
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
call _tx_execution_isr_enter ; Call the ISR execution enter function
|
||||
#endif
|
||||
|
||||
ret ; Return to calling ISR
|
||||
|
||||
_tx_thread_not_nested_save:
|
||||
/* } */
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
/* else if (_tx_thread_current_ptr)
|
||||
{ */
|
||||
addi x6, x6, 1 ; Increment the interrupt counter
|
||||
sw x6, 0(x5) ; Store the interrupt counter
|
||||
|
||||
/* Not nested: Find the user thread that was running and load our SP */
|
||||
|
||||
lw x5, _tx_thread_current_ptr ; Pickup current thread pointer
|
||||
beqz x5, _tx_thread_idle_system_save ; If NULL, idle system was interrupted
|
||||
|
||||
/* Save the standard scratch registers. */
|
||||
|
||||
sw x7, 0x44(sp) ; Store t2
|
||||
sw x8, 0x30(sp) ; Store s0
|
||||
sw x10, 0x6C(sp) ; Store a0
|
||||
sw x11, 0x68(sp) ; Store a1
|
||||
sw x12, 0x64(sp) ; Store a2
|
||||
sw x13, 0x60(sp) ; Store a3
|
||||
sw x14, 0x5C(sp) ; Store a4
|
||||
sw x15, 0x58(sp) ; Store a5
|
||||
sw x16, 0x54(sp) ; Store a6
|
||||
sw x17, 0x50(sp) ; Store a7
|
||||
sw x28, 0x40(sp) ; Store t3
|
||||
sw x29, 0x3C(sp) ; Store t4
|
||||
sw x30, 0x38(sp) ; Store t5
|
||||
sw x31, 0x34(sp) ; Store t6
|
||||
|
||||
csrr t0, mepc ; Load exception program counter
|
||||
sw t0, 0x78(sp) ; Save it on the stack
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Save floating point scratch registers. */
|
||||
|
||||
fsw f0, 0x7C(sp) ; Store ft0
|
||||
fsw f1, 0x80(sp) ; Store ft1
|
||||
fsw f2, 0x84(sp) ; Store ft2
|
||||
fsw f3, 0x88(sp) ; Store ft3
|
||||
fsw f4, 0x8C(sp) ; Store ft4
|
||||
fsw f5, 0x90(sp) ; Store ft5
|
||||
fsw f6, 0x94(sp) ; Store ft6
|
||||
fsw f7, 0x98(sp) ; Store ft7
|
||||
fsw f10,0xA4(sp) ; Store fa0
|
||||
fsw f11,0xA8(sp) ; Store fa1
|
||||
fsw f12,0xAC(sp) ; Store fa2
|
||||
fsw f13,0xB0(sp) ; Store fa3
|
||||
fsw f14,0xB4(sp) ; Store fa4
|
||||
fsw f15,0xB8(sp) ; Store fa5
|
||||
fsw f16,0xBC(sp) ; Store fa6
|
||||
fsw f17,0xC0(sp) ; Store fa7
|
||||
fsw f28,0xEC(sp) ; Store ft8
|
||||
fsw f29,0xF0(sp) ; Store ft9
|
||||
fsw f30,0xF4(sp) ; Store ft10
|
||||
fsw f31,0xF8(sp) ; Store ft11
|
||||
csrr t0, fcsr
|
||||
sw t0, 0xFC(sp) ; Store fcsr
|
||||
#endif
|
||||
|
||||
/* Save the current stack pointer in the thread's control block. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
|
||||
|
||||
/* Switch to the system stack. */
|
||||
/* sp = _tx_thread_system_stack_ptr; */
|
||||
|
||||
lw t1, _tx_thread_current_ptr ; Pickup current thread pointer
|
||||
sw sp, 8(t1) ; Save stack pointer*/
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
/* _tx_execution_isr_enter is called with thread stack pointer */
|
||||
call _tx_execution_isr_enter ; Call the ISR execution enter function
|
||||
#endif
|
||||
|
||||
|
||||
lw sp, _tx_thread_system_stack_ptr ; Switch to system stack
|
||||
ret ; Return to calling ISR
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
|
||||
_tx_thread_idle_system_save:
|
||||
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
call _tx_execution_isr_enter ; Call the ISR execution enter function
|
||||
#endif
|
||||
|
||||
/* Interrupt occurred in the scheduling loop. */
|
||||
|
||||
/* }
|
||||
} */
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover the reserved stack space
|
||||
#endif
|
||||
ret ; Return to calling ISR
|
||||
|
||||
END
|
||||
|
||||
94
ports/risc-v32/iar/src/tx_thread_interrupt_control.s
Normal file
94
ports/risc-v32/iar/src/tx_thread_interrupt_control.s
Normal file
@@ -0,0 +1,94 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_thread.h" */
|
||||
|
||||
RETURN_MASK DEFINE 0x0000000F
|
||||
SET_SR_MASK DEFINE 0xFFFFFFF0
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_control RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for changing the interrupt lockout */
|
||||
/* posture of the system. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* new_posture New interrupt lockout posture */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* old_posture Old interrupt lockout posture */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* UINT _tx_thread_interrupt_control(UINT new_posture)
|
||||
{ */
|
||||
PUBLIC _tx_thread_interrupt_control
|
||||
_tx_thread_interrupt_control:
|
||||
/* Pickup current interrupt lockout posture. */
|
||||
|
||||
csrr t0, mstatus
|
||||
mv t1, t0 ; Save original mstatus for return
|
||||
|
||||
/* Apply the new interrupt posture. */
|
||||
|
||||
li t2, SET_SR_MASK ; Build set SR mask
|
||||
and t0, t0, t2 ; Isolate interrupt lockout bits
|
||||
or t0, t0, a0 ; Put new lockout bits in
|
||||
csrw mstatus, t0
|
||||
andi a0, t1, RETURN_MASK ; Return original mstatus.
|
||||
ret
|
||||
/* } */
|
||||
END
|
||||
|
||||
274
ports/risc-v32/iar/src/tx_thread_schedule.s
Normal file
274
ports/risc-v32/iar/src/tx_thread_schedule.s
Normal file
@@ -0,0 +1,274 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h" */
|
||||
|
||||
|
||||
EXTERN _tx_thread_execute_ptr
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_thread_enter
|
||||
#endif
|
||||
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_schedule RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function waits for a thread control block pointer to appear in */
|
||||
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
|
||||
/* in the variable, the corresponding thread is resumed. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
/* _tx_thread_system_return Return to system from thread */
|
||||
/* _tx_thread_context_restore Restore thread's context */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_schedule(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_schedule
|
||||
_tx_thread_schedule:
|
||||
|
||||
/* Enable interrupts. */
|
||||
csrsi mstatus, 0x08 ; Enable interrupts
|
||||
|
||||
/* Wait for a thread to execute. */
|
||||
/* do
|
||||
{ */
|
||||
|
||||
la t0, _tx_thread_execute_ptr ; Pickup address of execute ptr
|
||||
_tx_thread_schedule_loop:
|
||||
lw t1, 0(t0) ; Pickup next thread to execute
|
||||
beqz t1, _tx_thread_schedule_loop ; If NULL, wait for thread to execute
|
||||
|
||||
/* }
|
||||
while(_tx_thread_execute_ptr == TX_NULL); */
|
||||
|
||||
/* Yes! We have a thread to execute. Lockout interrupts and
|
||||
transfer control to it. */
|
||||
csrci mstatus, 0x08 ; Lockout interrupts
|
||||
|
||||
/* Setup the current thread pointer. */
|
||||
/* _tx_thread_current_ptr = _tx_thread_execute_ptr; */
|
||||
|
||||
la t0, _tx_thread_current_ptr ; Pickup current thread pointer address
|
||||
sw t1, 0(t0) ; Set current thread pointer
|
||||
|
||||
/* Increment the run count for this thread. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_run_count++; */
|
||||
|
||||
lw t2, 4(t1) ; Pickup run count
|
||||
lw t3, 24(t1) ; Pickup time slice value
|
||||
addi t2, t2, 1 ; Increment run count
|
||||
sw t2, 4(t1) ; Store new run count
|
||||
|
||||
/* Setup time-slice, if present. */
|
||||
/* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */
|
||||
|
||||
la t2, _tx_timer_time_slice ; Pickup time-slice variable address
|
||||
|
||||
/* Switch to the thread's stack. */
|
||||
/* SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */
|
||||
|
||||
lw sp, 8(t1) ; Switch to thread's stack
|
||||
sw t3, 0(t2) ; Store new time-slice*/
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
call _tx_execution_thread_enter ; Call the thread execution enter function
|
||||
#endif
|
||||
|
||||
/* Determine if an interrupt frame or a synchronous task suspension frame
|
||||
is present. */
|
||||
|
||||
lw t2, 0(sp) ; Pickup stack type
|
||||
beqz t2, _tx_thread_synch_return ; If 0, solicited thread return
|
||||
|
||||
/* Determine if floating point registers need to be recovered. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
flw f0, 0x7C(sp) ; Recover ft0
|
||||
flw f1, 0x80(sp) ; Recover ft1
|
||||
flw f2, 0x84(sp) ; Recover ft2
|
||||
flw f3, 0x88(sp) ; Recover ft3
|
||||
flw f4, 0x8C(sp) ; Recover ft4
|
||||
flw f5, 0x90(sp) ; Recover ft5
|
||||
flw f6, 0x94(sp) ; Recover ft6
|
||||
flw f7, 0x98(sp) ; Recover ft7
|
||||
flw f8, 0x9C(sp) ; Recover fs0
|
||||
flw f9, 0xA0(sp) ; Recover fs1
|
||||
flw f10,0xA4(sp) ; Recover fa0
|
||||
flw f11,0xA8(sp) ; Recover fa1
|
||||
flw f12,0xAC(sp) ; Recover fa2
|
||||
flw f13,0xB0(sp) ; Recover fa3
|
||||
flw f14,0xB4(sp) ; Recover fa4
|
||||
flw f15,0xB8(sp) ; Recover fa5
|
||||
flw f16,0xBC(sp) ; Recover fa6
|
||||
flw f17,0xC0(sp) ; Recover fa7
|
||||
flw f18,0xC4(sp) ; Recover fs2
|
||||
flw f19,0xC8(sp) ; Recover fs3
|
||||
flw f20,0xCC(sp) ; Recover fs4
|
||||
flw f21,0xD0(sp) ; Recover fs5
|
||||
flw f22,0xD4(sp) ; Recover fs6
|
||||
flw f23,0xD8(sp) ; Recover fs7
|
||||
flw f24,0xDC(sp) ; Recover fs8
|
||||
flw f25,0xE0(sp) ; Recover fs9
|
||||
flw f26,0xE4(sp) ; Recover fs10
|
||||
flw f27,0xE8(sp) ; Recover fs11
|
||||
flw f28,0xEC(sp) ; Recover ft8
|
||||
flw f29,0xF0(sp) ; Recover ft9
|
||||
flw f30,0xF4(sp) ; Recover ft10
|
||||
flw f31,0xF8(sp) ; Recover ft11
|
||||
lw t0, 0xFC(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover standard registers. */
|
||||
|
||||
lw t0, 0x78(sp) ; Recover mepc
|
||||
csrw mepc, t0 ; Store mepc
|
||||
li t0, 0x1880 ; Prepare MPIP
|
||||
csrw mstatus, t0 ; Enable MPIP
|
||||
|
||||
lw x1, 0x70(sp) ; Recover RA
|
||||
lw x5, 0x4C(sp) ; Recover t0
|
||||
lw x6, 0x48(sp) ; Recover t1
|
||||
lw x7, 0x44(sp) ; Recover t2
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x9, 0x2C(sp) ; Recover s1
|
||||
lw x10, 0x6C(sp) ; Recover a0
|
||||
lw x11, 0x68(sp) ; Recover a1
|
||||
lw x12, 0x64(sp) ; Recover a2
|
||||
lw x13, 0x60(sp) ; Recover a3
|
||||
lw x14, 0x5C(sp) ; Recover a4
|
||||
lw x15, 0x58(sp) ; Recover a5
|
||||
lw x16, 0x54(sp) ; Recover a6
|
||||
lw x17, 0x50(sp) ; Recover a7
|
||||
lw x18, 0x28(sp) ; Recover s2
|
||||
lw x19, 0x24(sp) ; Recover s3
|
||||
lw x20, 0x20(sp) ; Recover s4
|
||||
lw x21, 0x1C(sp) ; Recover s5
|
||||
lw x22, 0x18(sp) ; Recover s6
|
||||
lw x23, 0x14(sp) ; Recover s7
|
||||
lw x24, 0x10(sp) ; Recover s8
|
||||
lw x25, 0x0C(sp) ; Recover s9
|
||||
lw x26, 0x08(sp) ; Recover s10
|
||||
lw x27, 0x04(sp) ; Recover s11
|
||||
lw x28, 0x40(sp) ; Recover t3
|
||||
lw x29, 0x3C(sp) ; Recover t4
|
||||
lw x30, 0x38(sp) ; Recover t5
|
||||
lw x31, 0x34(sp) ; Recover t6
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 260 ; Recover stack frame - with floating point registers
|
||||
#else
|
||||
addi sp, sp, 128 ; Recover stack frame - without floating point registers
|
||||
#endif
|
||||
mret ; Return to point of interrupt
|
||||
|
||||
_tx_thread_synch_return:
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
flw f8, 0x3C(sp) ; Recover fs0
|
||||
flw f9, 0x40(sp) ; Recover fs1
|
||||
flw f18,0x44(sp) ; Recover fs2
|
||||
flw f19,0x48(sp) ; Recover fs3
|
||||
flw f20,0x4C(sp) ; Recover fs4
|
||||
flw f21,0x50(sp) ; Recover fs5
|
||||
flw f22,0x54(sp) ; Recover fs6
|
||||
flw f23,0x58(sp) ; Recover fs7
|
||||
flw f24,0x5C(sp) ; Recover fs8
|
||||
flw f25,0x60(sp) ; Recover fs9
|
||||
flw f26,0x64(sp) ; Recover fs10
|
||||
flw f27,0x68(sp) ; Recover fs11
|
||||
lw t0, 0x6C(sp) ; Recover fcsr
|
||||
csrw fcsr, t0 ;
|
||||
#endif
|
||||
|
||||
/* Recover standard preserved registers. */
|
||||
/* Recover standard registers. */
|
||||
|
||||
lw x1, 0x34(sp) ; Recover RA
|
||||
lw x8, 0x30(sp) ; Recover s0
|
||||
lw x9, 0x2C(sp) ; Recover s1
|
||||
lw x18, 0x28(sp) ; Recover s2
|
||||
lw x19, 0x24(sp) ; Recover s3
|
||||
lw x20, 0x20(sp) ; Recover s4
|
||||
lw x21, 0x1C(sp) ; Recover s5
|
||||
lw x22, 0x18(sp) ; Recover s6
|
||||
lw x23, 0x14(sp) ; Recover s7
|
||||
lw x24, 0x10(sp) ; Recover s8
|
||||
lw x25, 0x0C(sp) ; Recover s9
|
||||
lw x26, 0x08(sp) ; Recover s10
|
||||
lw x27, 0x04(sp) ; Recover s11
|
||||
lw t0, 0x38(sp) ; Recover mstatus
|
||||
csrw mstatus, t0 ; Store mstatus, enables interrupt
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, 116 ; Recover stack frame
|
||||
#else
|
||||
addi sp, sp, 64 ; Recover stack frame
|
||||
#endif
|
||||
ret ; Return to thread
|
||||
|
||||
/* } */
|
||||
END
|
||||
|
||||
240
ports/risc-v32/iar/src/tx_thread_stack_build.s
Normal file
240
ports/risc-v32/iar/src/tx_thread_stack_build.s
Normal file
@@ -0,0 +1,240 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_thread.h" */
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_stack_build RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function builds a stack frame on the supplied thread's stack. */
|
||||
/* The stack frame results in a fake interrupt return to the supplied */
|
||||
/* function pointer. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to thread control blk */
|
||||
/* function_ptr Pointer to return function */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_create Create thread service */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
|
||||
{ */
|
||||
PUBLIC _tx_thread_stack_build
|
||||
_tx_thread_stack_build:
|
||||
|
||||
|
||||
/* Build a fake interrupt frame. The form of the fake interrupt stack
|
||||
on the RISC-V RV32 should look like the following after it is built:
|
||||
|
||||
Stack Top: 1 (00) Interrupt stack frame type
|
||||
x27 (04) Initial s11
|
||||
x26 (08) Initial s10
|
||||
x25 (12) Initial s9
|
||||
x24 (16) Initial s8
|
||||
x23 (20) Initial s7
|
||||
x22 (24) Initial s6
|
||||
x21 (28) Initial s5
|
||||
x20 (32) Initial s4
|
||||
x19 (36) Initial s3
|
||||
x18 (40) Initial s2
|
||||
x9 (44) Initial s1
|
||||
x8 (48) Initial s0
|
||||
x31 (52) Initial t6
|
||||
x30 (56) Initial t5
|
||||
x29 (60) Initial t4
|
||||
x28 (64) Initial t3
|
||||
x7 (68) Initial t2
|
||||
x6 (72) Initial t1
|
||||
x5 (76) Initial t0
|
||||
x17 (80) Initial a7
|
||||
x16 (84) Initial a6
|
||||
x15 (88) Initial a5
|
||||
x14 (92) Initial a4
|
||||
x13 (96) Initial a3
|
||||
x12 (100) Initial a2
|
||||
x11 (104) Initial a1
|
||||
x10 (108) Initial a0
|
||||
x1 (112) Initial ra
|
||||
mepc (120) Initial mepc
|
||||
If floating point support:
|
||||
f0 (124) Inital ft0
|
||||
f1 (128) Inital ft1
|
||||
f2 (132) Inital ft2
|
||||
f3 (136) Inital ft3
|
||||
f4 (140) Inital ft4
|
||||
f5 (144) Inital ft5
|
||||
f6 (148) Inital ft6
|
||||
f7 (152) Inital ft7
|
||||
f8 (156) Inital fs0
|
||||
f9 (160) Inital fs1
|
||||
f10 (164) Inital fa0
|
||||
f11 (168) Inital fa1
|
||||
f12 (172) Inital fa2
|
||||
f13 (176) Inital fa3
|
||||
f14 (180) Inital fa4
|
||||
f15 (184) Inital fa5
|
||||
f16 (188) Inital fa6
|
||||
f17 (192) Inital fa7
|
||||
f18 (196) Inital fs2
|
||||
f19 (200) Inital fs3
|
||||
f20 (204) Inital fs4
|
||||
f21 (208) Inital fs5
|
||||
f22 (212) Inital fs6
|
||||
f23 (216) Inital fs7
|
||||
f24 (220) Inital fs8
|
||||
f25 (224) Inital fs9
|
||||
f26 (228) Inital fs10
|
||||
f27 (232) Inital fs11
|
||||
f28 (236) Inital ft8
|
||||
f29 (240) Inital ft9
|
||||
f30 (244) Inital ft10
|
||||
f31 (248) Inital ft11
|
||||
fscr (252) Inital fscr
|
||||
|
||||
Stack Bottom: (higher memory address) */
|
||||
|
||||
lw t0, 16(a0) ; Pickup end of stack area
|
||||
li t1, ~15 ; Build 16-byte alignment mask
|
||||
and t0, t0, t1 ; Make sure 16-byte alignment
|
||||
|
||||
/* Actually build the stack frame. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi t0, t0, -260
|
||||
#else
|
||||
addi t0, t0, -128 ; Allocate space for the stack frame
|
||||
#endif
|
||||
li t1, 1 ; Build stack type
|
||||
sw t1, 0(t0) ; Place stack type on the top
|
||||
sw x0, 4(t0) ; Initial s11
|
||||
sw x0, 8(t0) ; Initial s10
|
||||
sw x0, 12(t0) ; Initial s9
|
||||
sw x0, 16(t0) ; Initial s8
|
||||
sw x0, 20(t0) ; Initial s7
|
||||
sw x0, 24(t0) ; Initial s6
|
||||
sw x0, 28(t0) ; Initial s5
|
||||
sw x0, 32(t0) ; Initial s4
|
||||
sw x0, 36(t0) ; Initial s3
|
||||
sw x0, 40(t0) ; Initial s2
|
||||
sw x0, 44(t0) ; Initial s1
|
||||
sw x0, 48(t0) ; Initial s0
|
||||
sw x0, 52(t0) ; Initial t6
|
||||
sw x0, 56(t0) ; Initial t5
|
||||
sw x0, 60(t0) ; Initial t4
|
||||
sw x0, 64(t0) ; Initial t3
|
||||
sw x0, 68(t0) ; Initial t2
|
||||
sw x0, 72(t0) ; Initial t1
|
||||
sw x0, 76(t0) ; Initial t0
|
||||
sw x0, 80(t0) ; Initial a7
|
||||
sw x0, 84(t0) ; Initial a6
|
||||
sw x0, 88(t0) ; Initial a5
|
||||
sw x0, 92(t0) ; Initial a4
|
||||
sw x0, 96(t0) ; Initial a3
|
||||
sw x0, 100(t0) ; Initial a2
|
||||
sw x0, 104(t0) ; Initial a1
|
||||
sw x0, 108(t0) ; Initial a0
|
||||
sw x0, 112(t0) ; Initial ra
|
||||
sw a1, 120(t0) ; Initial mepc
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
sw x0, 124(t0) ; Inital ft0
|
||||
sw x0, 128(t0) ; Inital ft1
|
||||
sw x0, 132(t0) ; Inital ft2
|
||||
sw x0, 136(t0) ; Inital ft3
|
||||
sw x0, 140(t0) ; Inital ft4
|
||||
sw x0, 144(t0) ; Inital ft5
|
||||
sw x0, 148(t0) ; Inital ft6
|
||||
sw x0, 152(t0) ; Inital ft7
|
||||
sw x0, 156(t0) ; Inital fs0
|
||||
sw x0, 160(t0) ; Inital fs1
|
||||
sw x0, 164(t0) ; Inital fa0
|
||||
sw x0, 168(t0) ; Inital fa1
|
||||
sw x0, 172(t0) ; Inital fa2
|
||||
sw x0, 176(t0) ; Inital fa3
|
||||
sw x0, 180(t0) ; Inital fa4
|
||||
sw x0, 184(t0) ; Inital fa5
|
||||
sw x0, 188(t0) ; Inital fa6
|
||||
sw x0, 192(t0) ; Inital fa7
|
||||
sw x0, 196(t0) ; Inital fs2
|
||||
sw x0, 200(t0) ; Inital fs3
|
||||
sw x0, 204(t0) ; Inital fs4
|
||||
sw x0, 208(t0) ; Inital fs5
|
||||
sw x0, 212(t0) ; Inital fs6
|
||||
sw x0, 216(t0) ; Inital fs7
|
||||
sw x0, 220(t0) ; Inital fs8
|
||||
sw x0, 224(t0) ; Inital fs9
|
||||
sw x0, 228(t0) ; Inital fs10
|
||||
sw x0, 232(t0) ; Inital fs11
|
||||
sw x0, 236(t0) ; Inital ft8
|
||||
sw x0, 240(t0) ; Inital ft9
|
||||
sw x0, 244(t0) ; Inital ft10
|
||||
sw x0, 248(t0) ; Inital ft11
|
||||
csrr a1, fcsr ; Read fcsr and use it for initial value for each thread
|
||||
sw a1, 252(t0) ; Initial fscr
|
||||
sw x0, 256(t0) ; Reserved word (0)
|
||||
#else
|
||||
sw x0, 124(t0) ; Reserved word (0)
|
||||
#endif
|
||||
|
||||
/* Setup stack pointer. */
|
||||
/* thread_ptr -> tx_thread_stack_ptr = t0; */
|
||||
|
||||
sw t0, 8(a0) ; Save stack pointer in thread's
|
||||
ret ; control block and return
|
||||
/* } */
|
||||
END
|
||||
|
||||
184
ports/risc-v32/iar/src/tx_thread_system_return.s
Normal file
184
ports/risc-v32/iar/src/tx_thread_system_return.s
Normal file
@@ -0,0 +1,184 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h" */
|
||||
|
||||
EXTERN _tx_thread_execute_ptr
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_thread_system_stack_ptr
|
||||
EXTERN _tx_thread_schedule
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
EXTERN _tx_execution_thread_exit
|
||||
#endif
|
||||
|
||||
SECTION `.text`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_system_return RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is target processor specific. It is used to transfer */
|
||||
/* control from a thread back to the system. Only a minimal context */
|
||||
/* is saved since the compiler assumes temp registers are going to get */
|
||||
/* slicked by a function call anyway. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_schedule Thread scheduling loop */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ThreadX components */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_system_return(VOID)
|
||||
{ */
|
||||
PUBLIC _tx_thread_system_return
|
||||
_tx_thread_system_return:
|
||||
|
||||
/* Save minimal context on the stack. */
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
addi sp, sp, -116 ; Allocate space on the stack - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, -64 ; Allocate space on the stack - without floating point enabled
|
||||
#endif
|
||||
|
||||
#if __iar_riscv_base_isa == rv32e
|
||||
|
||||
/* Store floating point preserved registers. */
|
||||
|
||||
fsw f8, 0x3C(sp) ; Store fs0
|
||||
fsw f9, 0x40(sp) ; Store fs1
|
||||
fsw f18, 0x44(sp) ; Store fs2
|
||||
fsw f19, 0x48(sp) ; Store fs3
|
||||
fsw f20, 0x4C(sp) ; Store fs4
|
||||
fsw f21, 0x50(sp) ; Store fs5
|
||||
fsw f22, 0x54(sp) ; Store fs6
|
||||
fsw f23, 0x58(sp) ; Store fs7
|
||||
fsw f24, 0x5C(sp) ; Store fs8
|
||||
fsw f25, 0x60(sp) ; Store fs9
|
||||
fsw f26, 0x64(sp) ; Store fs10
|
||||
fsw f27, 0x68(sp) ; Store fs11
|
||||
csrr t0, fcsr
|
||||
sw t0, 0x6C(sp) ; Store fcsr
|
||||
#endif
|
||||
|
||||
|
||||
sw x0, 0(sp) ; Solicited stack type
|
||||
sw x1, 0x34(sp) ; Save RA
|
||||
sw x8, 0x30(sp) ; Save s0
|
||||
sw x9, 0x2C(sp) ; Save s1
|
||||
sw x18, 0x28(sp) ; Save s2
|
||||
sw x19, 0x24(sp) ; Save s3
|
||||
sw x20, 0x20(sp) ; Save s4
|
||||
sw x21, 0x1C(sp) ; Save s5
|
||||
sw x22, 0x18(sp) ; Save s6
|
||||
sw x23, 0x14(sp) ; Save s7
|
||||
sw x24, 0x10(sp) ; Save s8
|
||||
sw x25, 0x0C(sp) ; Save s9
|
||||
sw x26, 0x08(sp) ; Save s10
|
||||
sw x27, 0x04(sp) ; Save s11
|
||||
csrr t0, mstatus ; Pickup mstatus
|
||||
sw t0, 0x38(sp) ; Save mstatus
|
||||
|
||||
|
||||
/* Lockout interrupts. - will be enabled in _tx_thread_schedule */
|
||||
|
||||
csrci mstatus, 0xF
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
call _tx_execution_thread_exit ; Call the thread execution exit function
|
||||
#endif
|
||||
|
||||
la t0, _tx_thread_current_ptr ; Pickup address of pointer
|
||||
lw t1, 0(t0) ; Pickup current thread pointer
|
||||
la t2,_tx_thread_system_stack_ptr ; Pickup stack pointer address
|
||||
|
||||
/* Save current stack and switch to system stack. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
|
||||
SP = _tx_thread_system_stack_ptr; */
|
||||
|
||||
sw sp, 8(t1) ; Save stack pointer
|
||||
lw sp, 0(t2) ; Switch to system stack
|
||||
|
||||
/* Determine if the time-slice is active. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
la t4, _tx_timer_time_slice ; Pickup time slice variable addr
|
||||
lw t3, 0(t4) ; Pickup time slice value
|
||||
la t2, _tx_thread_schedule ; Pickup address of scheduling loop
|
||||
beqz t3, _tx_thread_dont_save_ts ; If no time-slice, don't save it
|
||||
|
||||
/* Save time-slice for the thread and clear the current time-slice. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
_tx_timer_time_slice = 0; */
|
||||
|
||||
sw t3, 24(t1) ; Save current time-slice for thread
|
||||
sw x0, 0(t4) ; Clear time-slice variable
|
||||
|
||||
/* } */
|
||||
_tx_thread_dont_save_ts:
|
||||
|
||||
/* Clear the current thread pointer. */
|
||||
/* _tx_thread_current_ptr = TX_NULL; */
|
||||
|
||||
sw x0, 0(t0) ; Clear current thread pointer
|
||||
jr t2 ; Return to thread scheduler
|
||||
|
||||
/* } */
|
||||
|
||||
END
|
||||
|
||||
234
ports/risc-v32/iar/src/tx_timer_interrupt.s
Normal file
234
ports/risc-v32/iar/src/tx_timer_interrupt.s
Normal file
@@ -0,0 +1,234 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Timer */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h"
|
||||
#include "tx_timer.h"
|
||||
#include "tx_thread.h" */
|
||||
|
||||
EXTERN _tx_timer_system_clock
|
||||
EXTERN _tx_timer_time_slice
|
||||
EXTERN _tx_timer_expired_time_slice
|
||||
EXTERN _tx_timer_current_ptr
|
||||
EXTERN _tx_timer_expired
|
||||
EXTERN _tx_timer_list_end
|
||||
EXTERN _tx_timer_list_start
|
||||
EXTERN _tx_timer_expiration_process
|
||||
EXTERN _tx_thread_time_slice
|
||||
|
||||
|
||||
SECTION `.mtext`:CODE:REORDER:NOROOT(2)
|
||||
CODE
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_timer_interrupt RISC-V32/IAR */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* Tom van Leeuwen, Technolution B.V. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_timer_interrupt(VOID)
|
||||
{ */
|
||||
PUBLIC _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
|
||||
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
|
||||
lw t1, 0(t0) ; Pickup current pointer
|
||||
lw t3, 0(t1) ; Pickup the current timer entry
|
||||
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
|
||||
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
|
||||
lw t3, 0(t2) ; Pickup actual list end
|
||||
addi t1, t1, 4 ; Point to next timer entry
|
||||
sw 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
|
||||
lw t4, 0(t2) ; Pickup start of the list
|
||||
sw 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
|
||||
and t2, t6, 2 ; Isolate the timer expired bit
|
||||
addi sp, sp, -16 ; Allocate some storage on the stack
|
||||
sw t6, 0(sp) ; Save local expired flag
|
||||
sw ra, 4(sp) ; Save ra
|
||||
|
||||
/* Did a timer expire? */
|
||||
/* if (_tx_timer_expired)
|
||||
{ */
|
||||
|
||||
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
|
||||
lw t6, 0(sp) ; Recover local expired flag
|
||||
|
||||
/* } */
|
||||
_tx_timer_dont_activate:
|
||||
|
||||
/* Did time slice expire? */
|
||||
/* if (_tx_timer_expired_time_slice)
|
||||
{ */
|
||||
|
||||
and 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:
|
||||
|
||||
lw ra, 4(sp) ; Recover ra
|
||||
addi sp, sp, 16 ; Recover stack space
|
||||
/* } */
|
||||
|
||||
_tx_timer_nothing_expired:
|
||||
|
||||
ret
|
||||
|
||||
/* } */
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user