Release 6.2.1 on 08 Mar 2023. Expand to see details.
cee19603d Include tx_user.h conditionally. e40e08007 Update owners d69641273 Update release date and version 394aee52f Add tx_user.h to GNU port assembly files 5cca2ddd0 RISC-V 64 bit port for Microchip e0f2c373c Link Winmm.lib that required by the high-resolution timer. 6af472a68 Update Win32 port with high resolution timer. aea7b556a Add DMB ISH barrier inst in ARMv8-A SMP scheduler 19091a262 Add .section .preamble to m3 m4 m7 module ports ced60e1b7 Add missing parenthesis in ports assembly file 309dc77ca Modules Cortex-A7 IAR new port c752a4063 Modules Cortex-A7 GNU new port dc224b90f Fix race condition in tx_thread_wait_abort and update regression test 6e261f5b7 create threadx cmsis-pack
This commit is contained in:
284
ports/risc-v64/gnu/src/tx_thread_context_save.S
Normal file
284
ports/risc-v64/gnu/src/tx_thread_context_save.S
Normal file
@@ -0,0 +1,284 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "tx_port.h"
|
||||
|
||||
.section .text
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_save RISC-V64/GNU */
|
||||
/* 6.2.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 03-08-2023 Scott Larson Initial Version 6.2.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_save(VOID)
|
||||
{ */
|
||||
.global _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. */
|
||||
|
||||
STORE x5, 19*REGBYTES(sp) // First store t0 and t1
|
||||
STORE x6, 18*REGBYTES(sp)
|
||||
|
||||
la x5, _tx_thread_system_state // Pickup address of system state
|
||||
LOAD 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
|
||||
STORE 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. */
|
||||
|
||||
STORE x7, 17*REGBYTES(sp) // Store t2
|
||||
STORE x8, 12*REGBYTES(sp) // Store s0
|
||||
STORE x10, 27*REGBYTES(sp) // Store a0
|
||||
STORE x11, 26*REGBYTES(sp) // Store a1
|
||||
STORE x12, 25*REGBYTES(sp) // Store a2
|
||||
STORE x13, 24*REGBYTES(sp) // Store a3
|
||||
STORE x14, 23*REGBYTES(sp) // Store a4
|
||||
STORE x15, 22*REGBYTES(sp) // Store a5
|
||||
STORE x16, 21*REGBYTES(sp) // Store a6
|
||||
STORE x17, 20*REGBYTES(sp) // Store a7
|
||||
STORE x28, 16*REGBYTES(sp) // Store t3
|
||||
STORE x29, 15*REGBYTES(sp) // Store t4
|
||||
STORE x30, 14*REGBYTES(sp) // Store t5
|
||||
STORE x31, 13*REGBYTES(sp) // Store t6
|
||||
csrr t0, mepc // Load exception program counter
|
||||
STORE t0, 30*REGBYTES(sp) // Save it on the stack
|
||||
|
||||
/* Save floating point scratch registers. */
|
||||
#if defined(__riscv_float_abi_single)
|
||||
fsw f0, 31*REGBYTES(sp) // Store ft0
|
||||
fsw f1, 32*REGBYTES(sp) // Store ft1
|
||||
fsw f2, 33*REGBYTES(sp) // Store ft2
|
||||
fsw f3, 34*REGBYTES(sp) // Store ft3
|
||||
fsw f4, 35*REGBYTES(sp) // Store ft4
|
||||
fsw f5, 36*REGBYTES(sp) // Store ft5
|
||||
fsw f6, 37*REGBYTES(sp) // Store ft6
|
||||
fsw f7, 38*REGBYTES(sp) // Store ft7
|
||||
fsw f10,41*REGBYTES(sp) // Store fa0
|
||||
fsw f11,42*REGBYTES(sp) // Store fa1
|
||||
fsw f12,43*REGBYTES(sp) // Store fa2
|
||||
fsw f13,44*REGBYTES(sp) // Store fa3
|
||||
fsw f14,45*REGBYTES(sp) // Store fa4
|
||||
fsw f15,46*REGBYTES(sp) // Store fa5
|
||||
fsw f16,47*REGBYTES(sp) // Store fa6
|
||||
fsw f17,48*REGBYTES(sp) // Store fa7
|
||||
fsw f28,59*REGBYTES(sp) // Store ft8
|
||||
fsw f29,60*REGBYTES(sp) // Store ft9
|
||||
fsw f30,61*REGBYTES(sp) // Store ft10
|
||||
fsw f31,62*REGBYTES(sp) // Store ft11
|
||||
csrr t0, fcsr
|
||||
STORE t0, 63*REGBYTES(sp) // Store fcsr
|
||||
#elif defined(__riscv_float_abi_double)
|
||||
fsd f0, 31*REGBYTES(sp) // Store ft0
|
||||
fsd f1, 32*REGBYTES(sp) // Store ft1
|
||||
fsd f2, 33*REGBYTES(sp) // Store ft2
|
||||
fsd f3, 34*REGBYTES(sp) // Store ft3
|
||||
fsd f4, 35*REGBYTES(sp) // Store ft4
|
||||
fsd f5, 36*REGBYTES(sp) // Store ft5
|
||||
fsd f6, 37*REGBYTES(sp) // Store ft6
|
||||
fsd f7, 38*REGBYTES(sp) // Store ft7
|
||||
fsd f10,41*REGBYTES(sp) // Store fa0
|
||||
fsd f11,42*REGBYTES(sp) // Store fa1
|
||||
fsd f12,43*REGBYTES(sp) // Store fa2
|
||||
fsd f13,44*REGBYTES(sp) // Store fa3
|
||||
fsd f14,45*REGBYTES(sp) // Store fa4
|
||||
fsd f15,46*REGBYTES(sp) // Store fa5
|
||||
fsd f16,47*REGBYTES(sp) // Store fa6
|
||||
fsd f17,48*REGBYTES(sp) // Store fa7
|
||||
fsd f28,59*REGBYTES(sp) // Store ft8
|
||||
fsd f29,60*REGBYTES(sp) // Store ft9
|
||||
fsd f30,61*REGBYTES(sp) // Store ft10
|
||||
fsd f31,62*REGBYTES(sp) // Store ft11
|
||||
csrr t0, fcsr
|
||||
STORE t0, 63*REGBYTES(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
|
||||
STORE x6, 0(x5) // Store the interrupt counter
|
||||
|
||||
/* Not nested: Find the user thread that was running and load our SP */
|
||||
|
||||
LOAD 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. */
|
||||
|
||||
STORE x7, 17*REGBYTES(sp) // Store t2
|
||||
STORE x8, 12*REGBYTES(sp) // Store s0
|
||||
STORE x10, 27*REGBYTES(sp) // Store a0
|
||||
STORE x11, 26*REGBYTES(sp) // Store a1
|
||||
STORE x12, 25*REGBYTES(sp) // Store a2
|
||||
STORE x13, 24*REGBYTES(sp) // Store a3
|
||||
STORE x14, 23*REGBYTES(sp) // Store a4
|
||||
STORE x15, 22*REGBYTES(sp) // Store a5
|
||||
STORE x16, 21*REGBYTES(sp) // Store a6
|
||||
STORE x17, 20*REGBYTES(sp) // Store a7
|
||||
STORE x28, 16*REGBYTES(sp) // Store t3
|
||||
STORE x29, 15*REGBYTES(sp) // Store t4
|
||||
STORE x30, 14*REGBYTES(sp) // Store t5
|
||||
STORE x31, 13*REGBYTES(sp) // Store t6
|
||||
|
||||
csrr t0, mepc // Load exception program counter
|
||||
STORE t0, 30*REGBYTES(sp) // Save it on the stack
|
||||
|
||||
/* Save floating point scratch registers. */
|
||||
#if defined(__riscv_float_abi_single)
|
||||
fsw f0, 31*REGBYTES(sp) // Store ft0
|
||||
fsw f1, 32*REGBYTES(sp) // Store ft1
|
||||
fsw f2, 33*REGBYTES(sp) // Store ft2
|
||||
fsw f3, 34*REGBYTES(sp) // Store ft3
|
||||
fsw f4, 35*REGBYTES(sp) // Store ft4
|
||||
fsw f5, 36*REGBYTES(sp) // Store ft5
|
||||
fsw f6, 37*REGBYTES(sp) // Store ft6
|
||||
fsw f7, 38*REGBYTES(sp) // Store ft7
|
||||
fsw f10,41*REGBYTES(sp) // Store fa0
|
||||
fsw f11,42*REGBYTES(sp) // Store fa1
|
||||
fsw f12,43*REGBYTES(sp) // Store fa2
|
||||
fsw f13,44*REGBYTES(sp) // Store fa3
|
||||
fsw f14,45*REGBYTES(sp) // Store fa4
|
||||
fsw f15,46*REGBYTES(sp) // Store fa5
|
||||
fsw f16,47*REGBYTES(sp) // Store fa6
|
||||
fsw f17,48*REGBYTES(sp) // Store fa7
|
||||
fsw f28,59*REGBYTES(sp) // Store ft8
|
||||
fsw f29,60*REGBYTES(sp) // Store ft9
|
||||
fsw f30,61*REGBYTES(sp) // Store ft10
|
||||
fsw f31,62*REGBYTES(sp) // Store ft11
|
||||
csrr t0, fcsr
|
||||
STORE t0, 63*REGBYTES(sp) // Store fcsr
|
||||
#elif defined(__riscv_float_abi_double)
|
||||
fsd f0, 31*REGBYTES(sp) // Store ft0
|
||||
fsd f1, 32*REGBYTES(sp) // Store ft1
|
||||
fsd f2, 33*REGBYTES(sp) // Store ft2
|
||||
fsd f3, 34*REGBYTES(sp) // Store ft3
|
||||
fsd f4, 35*REGBYTES(sp) // Store ft4
|
||||
fsd f5, 36*REGBYTES(sp) // Store ft5
|
||||
fsd f6, 37*REGBYTES(sp) // Store ft6
|
||||
fsd f7, 38*REGBYTES(sp) // Store ft7
|
||||
fsd f10,41*REGBYTES(sp) // Store fa0
|
||||
fsd f11,42*REGBYTES(sp) // Store fa1
|
||||
fsd f12,43*REGBYTES(sp) // Store fa2
|
||||
fsd f13,44*REGBYTES(sp) // Store fa3
|
||||
fsd f14,45*REGBYTES(sp) // Store fa4
|
||||
fsd f15,46*REGBYTES(sp) // Store fa5
|
||||
fsd f16,47*REGBYTES(sp) // Store fa6
|
||||
fsd f17,48*REGBYTES(sp) // Store fa7
|
||||
fsd f28,59*REGBYTES(sp) // Store ft8
|
||||
fsd f29,60*REGBYTES(sp) // Store ft9
|
||||
fsd f30,61*REGBYTES(sp) // Store ft10
|
||||
fsd f31,62*REGBYTES(sp) // Store ft11
|
||||
csrr t0, fcsr
|
||||
STORE t0, 63*REGBYTES(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; */
|
||||
|
||||
LOAD t1, _tx_thread_current_ptr // Pickup current thread pointer
|
||||
STORE sp, 2*REGBYTES(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
|
||||
|
||||
|
||||
LOAD 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 defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
|
||||
addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled
|
||||
#else
|
||||
addi sp, sp, 32*REGBYTES // Recover the reserved stack space
|
||||
#endif
|
||||
ret // Return to calling ISR
|
||||
Reference in New Issue
Block a user