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@/** Thread */ 18@/** */ 19@/**************************************************************************/ 20@/**************************************************************************/ 21#ifdef TX_INCLUDE_USER_DEFINE_FILE 22#include "tx_user.h" 23#endif 24 25#ifdef TX_ENABLE_FIQ_SUPPORT 26DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled 27#else 28DISABLE_INTS = 0x80 @ IRQ interrupts disabled 29#endif 30@ 31@ 32 .global _tx_thread_system_state 33 .global _tx_thread_current_ptr 34 .global _tx_execution_isr_enter 35@ 36@ 37@ 38@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save 39@ since it will never be called 16-bit mode. */ 40@ 41 .arm 42 .text 43 .align 2 44@/**************************************************************************/ 45@/* */ 46@/* FUNCTION RELEASE */ 47@/* */ 48@/* _tx_thread_vectored_context_save ARM11/GNU */ 49@/* 6.2.1 */ 50@/* AUTHOR */ 51@/* */ 52@/* William E. Lamie, Microsoft Corporation */ 53@/* */ 54@/* DESCRIPTION */ 55@/* */ 56@/* This function saves the context of an executing thread in the */ 57@/* beginning of interrupt processing. The function also ensures that */ 58@/* the system stack is used upon return to the calling ISR. */ 59@/* */ 60@/* INPUT */ 61@/* */ 62@/* None */ 63@/* */ 64@/* OUTPUT */ 65@/* */ 66@/* None */ 67@/* */ 68@/* CALLS */ 69@/* */ 70@/* None */ 71@/* */ 72@/* CALLED BY */ 73@/* */ 74@/* ISRs */ 75@/* */ 76@/* RELEASE HISTORY */ 77@/* */ 78@/* DATE NAME DESCRIPTION */ 79@/* */ 80@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 81@/* 03-08-2023 Cindy Deng Modified comment(s), added */ 82@/* #include tx_user.h, */ 83@/* resulting in version 6.2.1 */ 84@/* */ 85@/**************************************************************************/ 86@VOID _tx_thread_vectored_context_save(VOID) 87@{ 88 .global _tx_thread_vectored_context_save 89 .type _tx_thread_vectored_context_save,function 90_tx_thread_vectored_context_save: 91@ 92@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked 93@ out, we are in IRQ mode, and all registers are intact. */ 94@ 95@ /* Check for a nested interrupt condition. */ 96@ if (_tx_thread_system_state++) 97@ { 98@ 99#ifdef TX_ENABLE_FIQ_SUPPORT 100 MRS r0, CPSR @ Pickup the CPSR 101 ORR r0, r0, #DISABLE_INTS @ Build disable interrupt CPSR 102 MSR CPSR_cxsf, r0 @ Disable interrupts 103#endif 104 LDR r3, =_tx_thread_system_state @ Pickup address of system state variable 105 LDR r2, [r3, #0] @ Pickup system state 106 CMP r2, #0 @ Is this the first interrupt? 107 BEQ __tx_thread_not_nested_save @ Yes, not a nested context save 108@ 109@ /* Nested interrupt condition. */ 110@ 111 ADD r2, r2, #1 @ Increment the interrupt counter 112 STR r2, [r3, #0] @ Store it back in the variable 113@ 114@ /* Note: Minimal context of interrupted thread is already saved. */ 115@ 116@ /* Return to the ISR. */ 117@ 118 MOV r10, #0 @ Clear stack limit 119 120#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 121@ 122@ /* Call the ISR enter function to indicate an ISR is executing. */ 123@ 124 PUSH {lr} @ Save ISR lr 125 BL _tx_execution_isr_enter @ Call the ISR enter function 126 POP {lr} @ Recover ISR lr 127#endif 128 129 MOV pc, lr @ Return to caller 130@ 131__tx_thread_not_nested_save: 132@ } 133@ 134@ /* Otherwise, not nested, check to see if a thread was running. */ 135@ else if (_tx_thread_current_ptr) 136@ { 137@ 138 ADD r2, r2, #1 @ Increment the interrupt counter 139 STR r2, [r3, #0] @ Store it back in the variable 140 LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr 141 LDR r0, [r1, #0] @ Pickup current thread pointer 142 CMP r0, #0 @ Is it NULL? 143 BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in 144 @ scheduling loop - nothing needs saving! 145@ 146@ /* Note: Minimal context of interrupted thread is already saved. */ 147@ 148@ /* Save the current stack pointer in the thread's control block. */ 149@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; 150@ 151@ /* Switch to the system stack. */ 152@ sp = _tx_thread_system_stack_ptr; 153@ 154 MOV r10, #0 @ Clear stack limit 155 156#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 157@ 158@ /* Call the ISR enter function to indicate an ISR is executing. */ 159@ 160 PUSH {lr} @ Save ISR lr 161 BL _tx_execution_isr_enter @ Call the ISR enter function 162 POP {lr} @ Recover ISR lr 163#endif 164 165 MOV pc, lr @ Return to caller 166@ 167@ } 168@ else 169@ { 170@ 171__tx_thread_idle_system_save: 172@ 173@ /* Interrupt occurred in the scheduling loop. */ 174@ 175@ /* Not much to do here, just adjust the stack pointer, and return to IRQ 176@ processing. */ 177@ 178 MOV r10, #0 @ Clear stack limit 179 180#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 181@ 182@ /* Call the ISR enter function to indicate an ISR is executing. */ 183@ 184 PUSH {lr} @ Save ISR lr 185 BL _tx_execution_isr_enter @ Call the ISR enter function 186 POP {lr} @ Recover ISR lr 187#endif 188 189 ADD sp, sp, #32 @ Recover saved registers 190 MOV pc, lr @ Return to caller 191@ 192@ } 193@} 194 195