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#ifdef TX_ENABLE_FIQ_SUPPORT 27DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled 28#else 29DISABLE_INTS = 0x80 @ IRQ interrupts disabled 30#endif 31@ 32 .global _tx_thread_system_state 33 .global _tx_thread_current_ptr 34 .global _tx_irq_processing_return 35 .global _tx_execution_isr_enter 36@ 37@ 38@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_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_context_save ARM9/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_context_save(VOID) 87@{ 88 .global _tx_thread_context_save 89 .type _tx_thread_context_save,function 90_tx_thread_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 STMDB sp!, {r0-r3} @ Save some working registers 100#ifdef TX_ENABLE_FIQ_SUPPORT 101 MRS r0, CPSR @ Pickup the CPSR 102 ORR r0, r0, #DISABLE_INTS @ Build disable interrupt CPSR 103 MSR CPSR_cxsf, r0 @ Disable interrupts 104#endif 105 LDR r3, =_tx_thread_system_state @ Pickup address of system state variable 106 LDR r2, [r3] @ Pickup system state 107 CMP r2, #0 @ Is this the first interrupt? 108 BEQ __tx_thread_not_nested_save @ Yes, not a nested context save 109@ 110@ /* Nested interrupt condition. */ 111@ 112 ADD r2, r2, #1 @ Increment the interrupt counter 113 STR r2, [r3] @ Store it back in the variable 114@ 115@ /* Save the rest of the scratch registers on the stack and return to the 116@ calling ISR. */ 117@ 118 MRS r0, SPSR @ Pickup saved SPSR 119 SUB lr, lr, #4 @ Adjust point of interrupt 120 STMDB sp!, {r0, r10, r12, lr} @ Store other registers 121@ 122@ /* Return to the ISR. */ 123@ 124 MOV r10, #0 @ Clear stack limit 125 126#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 127@ 128@ /* Call the ISR enter function to indicate an ISR is executing. */ 129@ 130 PUSH {lr} @ Save ISR lr 131 BL _tx_execution_isr_enter @ Call the ISR enter function 132 POP {lr} @ Recover ISR lr 133#endif 134 135 B __tx_irq_processing_return @ Continue IRQ processing 136@ 137__tx_thread_not_nested_save: 138@ } 139@ 140@ /* Otherwise, not nested, check to see if a thread was running. */ 141@ else if (_tx_thread_current_ptr) 142@ { 143@ 144 ADD r2, r2, #1 @ Increment the interrupt counter 145 STR r2, [r3] @ Store it back in the variable 146 LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr 147 LDR r0, [r1] @ Pickup current thread pointer 148 CMP r0, #0 @ Is it NULL? 149 BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in 150 @ scheduling loop - nothing needs saving! 151@ 152@ /* Save minimal context of interrupted thread. */ 153@ 154 MRS r2, SPSR @ Pickup saved SPSR 155 SUB lr, lr, #4 @ Adjust point of interrupt 156 STMDB sp!, {r2, r10, r12, lr} @ Store other registers 157@ 158@ /* Save the current stack pointer in the thread's control block. */ 159@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; 160@ 161@ /* Switch to the system stack. */ 162@ sp = _tx_thread_system_stack_ptr@ 163@ 164 MOV r10, #0 @ Clear stack limit 165 166#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 167@ 168@ /* Call the ISR enter function to indicate an ISR is executing. */ 169@ 170 PUSH {lr} @ Save ISR lr 171 BL _tx_execution_isr_enter @ Call the ISR enter function 172 POP {lr} @ Recover ISR lr 173#endif 174 175 B __tx_irq_processing_return @ Continue IRQ processing 176@ 177@ } 178@ else 179@ { 180@ 181__tx_thread_idle_system_save: 182@ 183@ /* Interrupt occurred in the scheduling loop. */ 184@ 185@ /* Not much to do here, just adjust the stack pointer, and return to IRQ 186@ processing. */ 187@ 188 MOV r10, #0 @ Clear stack limit 189 190#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 191@ 192@ /* Call the ISR enter function to indicate an ISR is executing. */ 193@ 194 PUSH {lr} @ Save ISR lr 195 BL _tx_execution_isr_enter @ Call the ISR enter function 196 POP {lr} @ Recover ISR lr 197#endif 198 199 ADD sp, sp, #16 @ Recover saved registers 200 B __tx_irq_processing_return @ Continue IRQ processing 201@ 202@ } 203@} 204 205 206 207