1@/**************************************************************************/ 2@/* */ 3@/* Copyright (c) Microsoft Corporation. All rights reserved. */ 4@/* */ 5@/* This software is licensed under the Microsoft Software License */ 6@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8@/* and in the root directory of this software. */ 9@/* */ 10@/**************************************************************************/ 11@ 12@ 13@/**************************************************************************/ 14@/**************************************************************************/ 15@/** */ 16@/** ThreadX Component */ 17@/** */ 18@/** Thread */ 19@/** */ 20@/**************************************************************************/ 21@/**************************************************************************/ 22#ifdef TX_INCLUDE_USER_DEFINE_FILE 23#include "tx_user.h" 24#endif 25 26 .global _tx_thread_system_state 27 .global _tx_thread_current_ptr 28 .global __tx_fiq_processing_return 29 .global _tx_execution_isr_enter 30@ 31@ 32@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save 33@ since it will never be called 16-bit mode. */ 34@ 35 .arm 36 .text 37 .align 2 38@/**************************************************************************/ 39@/* */ 40@/* FUNCTION RELEASE */ 41@/* */ 42@/* _tx_thread_fiq_context_save ARM9/GNU */ 43@/* 6.2.1 */ 44@/* AUTHOR */ 45@/* */ 46@/* William E. Lamie, Microsoft Corporation */ 47@/* */ 48@/* DESCRIPTION */ 49@/* */ 50@/* This function saves the context of an executing thread in the */ 51@/* beginning of interrupt processing. The function also ensures that */ 52@/* the system stack is used upon return to the calling ISR. */ 53@/* */ 54@/* INPUT */ 55@/* */ 56@/* None */ 57@/* */ 58@/* OUTPUT */ 59@/* */ 60@/* None */ 61@/* */ 62@/* CALLS */ 63@/* */ 64@/* None */ 65@/* */ 66@/* CALLED BY */ 67@/* */ 68@/* ISRs */ 69@/* */ 70@/* RELEASE HISTORY */ 71@/* */ 72@/* DATE NAME DESCRIPTION */ 73@/* */ 74@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 75@/* 03-08-2023 Cindy Deng Modified comment(s), added */ 76@/* #include tx_user.h, */ 77@/* resulting in version 6.2.1 */ 78@/* */ 79@/**************************************************************************/ 80@ VOID _tx_thread_fiq_context_save(VOID) 81@{ 82 .global _tx_thread_fiq_context_save 83 .type _tx_thread_fiq_context_save,function 84_tx_thread_fiq_context_save: 85@ 86@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked 87@ out, we are in IRQ mode, and all registers are intact. */ 88@ 89@ /* Check for a nested interrupt condition. */ 90@ if (_tx_thread_system_state++) 91@ { 92@ 93 STMDB sp!, {r0-r3} @ Save some working registers 94 LDR r3, =_tx_thread_system_state @ Pickup address of system state variable 95 LDR r2, [r3] @ Pickup system state 96 CMP r2, #0 @ Is this the first interrupt? 97 BEQ __tx_thread_fiq_not_nested_save @ Yes, not a nested context save 98@ 99@ /* Nested interrupt condition. */ 100@ 101 ADD r2, r2, #1 @ Increment the interrupt counter 102 STR r2, [r3] @ Store it back in the variable 103@ 104@ /* Save the rest of the scratch registers on the stack and return to the 105@ calling ISR. */ 106@ 107 MRS r0, SPSR @ Pickup saved SPSR 108 SUB lr, lr, #4 @ Adjust point of interrupt 109 STMDB sp!, {r0, r10, r12, lr} @ Store other registers 110@ 111@ /* Return to the ISR. */ 112@ 113 MOV r10, #0 @ Clear stack limit 114 115#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 116@ 117@ /* Call the ISR enter function to indicate an ISR is executing. */ 118@ 119 PUSH {lr} @ Save ISR lr 120 BL _tx_execution_isr_enter @ Call the ISR enter function 121 POP {lr} @ Recover ISR lr 122#endif 123 124 B __tx_fiq_processing_return @ Continue FIQ processing 125@ 126__tx_thread_fiq_not_nested_save: 127@ } 128@ 129@ /* Otherwise, not nested, check to see if a thread was running. */ 130@ else if (_tx_thread_current_ptr) 131@ { 132@ 133 ADD r2, r2, #1 @ Increment the interrupt counter 134 STR r2, [r3] @ Store it back in the variable 135 LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr 136 LDR r0, [r1] @ Pickup current thread pointer 137 CMP r0, #0 @ Is it NULL? 138 BEQ __tx_thread_fiq_idle_system_save @ If so, interrupt occurred in 139@ @ scheduling loop - nothing needs saving! 140@ 141@ /* Save minimal context of interrupted thread. */ 142@ 143 MRS r2, SPSR @ Pickup saved SPSR 144 SUB lr, lr, #4 @ Adjust point of interrupt 145 STMDB sp!, {r2, lr} @ Store other registers, Note that we don't 146@ @ need to save sl and ip since FIQ has 147@ @ copies of these registers. Nested 148@ @ interrupt processing does need to save 149@ @ these registers. 150@ 151@ /* Save the current stack pointer in the thread's control block. */ 152@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; 153@ 154@ /* Switch to the system stack. */ 155@ sp = _tx_thread_system_stack_ptr; 156@ 157 MOV r10, #0 @ Clear stack limit 158 159#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 160@ 161@ /* Call the ISR enter function to indicate an ISR is executing. */ 162@ 163 PUSH {lr} @ Save ISR lr 164 BL _tx_execution_isr_enter @ Call the ISR enter function 165 POP {lr} @ Recover ISR lr 166#endif 167 168 B __tx_fiq_processing_return @ Continue FIQ processing 169@ 170@ } 171@ else 172@ { 173@ 174__tx_thread_fiq_idle_system_save: 175@ 176@ /* Interrupt occurred in the scheduling loop. */ 177@ 178#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 179@ 180@ /* Call the ISR enter function to indicate an ISR is executing. */ 181@ 182 PUSH {lr} @ Save ISR lr 183 BL _tx_execution_isr_enter @ Call the ISR enter function 184 POP {lr} @ Recover ISR lr 185#endif 186@ 187@ /* Not much to do here, save the current SPSR and LR for possible 188@ use in IRQ interrupted in idle system conditions, and return to 189@ FIQ interrupt processing. */ 190@ 191 MRS r0, SPSR @ Pickup saved SPSR 192 SUB lr, lr, #4 @ Adjust point of interrupt 193 STMDB sp!, {r0, lr} @ Store other registers that will get used 194@ @ or stripped off the stack in context 195@ @ restore 196 B __tx_fiq_processing_return @ Continue FIQ processing 197@ 198@ } 199@} 200 201