275 lines
15 KiB
ArmAsm
275 lines
15 KiB
ArmAsm
/**************************************************************************/
|
|
/* */
|
|
/* 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
|
|
|