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; 23; 24;#define TX_SOURCE_CODE 25; 26; 27;/* Include necessary system files. */ 28; 29;#include "tx_api.h" 30;#include "tx_thread.h" 31; 32; 33 IMPORT _tx_thread_system_state 34 IMPORT _tx_thread_current_ptr 35 IMPORT __tx_fiq_processing_return 36 IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY 37 IMPORT _tx_execution_isr_enter 38 ENDIF 39; 40; 41 AREA ||.text||, CODE, READONLY 42 PRESERVE8 43;/**************************************************************************/ 44;/* */ 45;/* FUNCTION RELEASE */ 46;/* */ 47;/* _tx_thread_fiq_context_save ARM11/AC5 */ 48;/* 6.1 */ 49;/* AUTHOR */ 50;/* */ 51;/* William E. Lamie, Microsoft Corporation */ 52;/* */ 53;/* DESCRIPTION */ 54;/* */ 55;/* This function saves the context of an executing thread in the */ 56;/* beginning of interrupt processing. The function also ensures that */ 57;/* the system stack is used upon return to the calling ISR. */ 58;/* */ 59;/* INPUT */ 60;/* */ 61;/* None */ 62;/* */ 63;/* OUTPUT */ 64;/* */ 65;/* None */ 66;/* */ 67;/* CALLS */ 68;/* */ 69;/* None */ 70;/* */ 71;/* CALLED BY */ 72;/* */ 73;/* ISRs */ 74;/* */ 75;/* RELEASE HISTORY */ 76;/* */ 77;/* DATE NAME DESCRIPTION */ 78;/* */ 79;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 80;/* */ 81;/**************************************************************************/ 82; VOID _tx_thread_fiq_context_save(VOID) 83;{ 84 EXPORT _tx_thread_fiq_context_save 85_tx_thread_fiq_context_save 86; 87; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked 88; out, we are in IRQ mode, and all registers are intact. */ 89; 90; /* Check for a nested interrupt condition. */ 91; if (_tx_thread_system_state++) 92; { 93; 94 STMDB sp!, {r0-r3} ; Save some working registers 95 LDR r3, =_tx_thread_system_state ; Pickup address of system state var 96 LDR r2, [r3] ; Pickup system state 97 CMP r2, #0 ; Is this the first interrupt? 98 BEQ __tx_thread_fiq_not_nested_save ; Yes, not a nested context save 99; 100; /* Nested interrupt condition. */ 101; 102 ADD r2, r2, #1 ; Increment the interrupt counter 103 STR r2, [r3] ; Store it back in the variable 104; 105; /* Save the rest of the scratch registers on the stack and return to the 106; calling ISR. */ 107; 108 MRS r0, SPSR ; Pickup saved SPSR 109 SUB lr, lr, #4 ; Adjust point of interrupt 110 STMDB sp!, {r0, r10, r12, lr} ; Store other registers 111; 112; /* Return to the ISR. */ 113; 114 MOV r10, #0 ; Clear stack limit 115 116 IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY 117; 118; /* Call the ISR enter function to indicate an ISR is executing. */ 119; 120 PUSH {lr} ; Save ISR lr 121 BL _tx_execution_isr_enter ; Call the ISR enter function 122 POP {lr} ; Recover ISR lr 123 ENDIF 124 125 B __tx_fiq_processing_return ; Continue FIQ processing 126; 127__tx_thread_fiq_not_nested_save 128; } 129; 130; /* Otherwise, not nested, check to see if a thread was running. */ 131; else if (_tx_thread_current_ptr) 132; { 133; 134 ADD r2, r2, #1 ; Increment the interrupt counter 135 STR r2, [r3] ; Store it back in the variable 136 LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr 137 LDR r0, [r1] ; Pickup current thread pointer 138 CMP r0, #0 ; Is it NULL? 139 BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred in 140; ; scheduling loop - nothing needs saving! 141; 142; /* Save minimal context of interrupted thread. */ 143; 144 MRS r2, SPSR ; Pickup saved SPSR 145 SUB lr, lr, #4 ; Adjust point of interrupt 146 STMDB sp!, {r2, lr} ; Store other registers, Note that we don't 147; ; need to save sl and ip since FIQ has 148; ; copies of these registers. Nested 149; ; interrupt processing does need to save 150; ; these registers. 151; 152; /* Save the current stack pointer in the thread's control block. */ 153; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; 154; 155; /* Switch to the system stack. */ 156; sp = _tx_thread_system_stack_ptr; 157; 158 MOV r10, #0 ; Clear stack limit 159 160 IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY 161; 162; /* Call the ISR enter function to indicate an ISR is executing. */ 163; 164 PUSH {lr} ; Save ISR lr 165 BL _tx_execution_isr_enter ; Call the ISR enter function 166 POP {lr} ; Recover ISR lr 167 ENDIF 168 169 B __tx_fiq_processing_return ; Continue FIQ processing 170; 171; } 172; else 173; { 174; 175__tx_thread_fiq_idle_system_save 176; 177; /* Interrupt occurred in the scheduling loop. */ 178; 179 IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY 180; 181; /* Call the ISR enter function to indicate an ISR is executing. */ 182; 183 PUSH {lr} ; Save ISR lr 184 BL _tx_execution_isr_enter ; Call the ISR enter function 185 POP {lr} ; Recover ISR lr 186 ENDIF 187; 188; /* Not much to do here, save the current SPSR and LR for possible 189; use in IRQ interrupted in idle system conditions, and return to 190; FIQ interrupt processing. */ 191; 192 MRS r0, SPSR ; Pickup saved SPSR 193 SUB lr, lr, #4 ; Adjust point of interrupt 194 STMDB sp!, {r0, lr} ; Store other registers that will get used 195; ; or stripped off the stack in context 196; ; restore 197 B __tx_fiq_processing_return ; Continue FIQ processing 198; 199; } 200;} 201; 202 END 203 204