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;#include "tx_timer.h" 32; 33; 34#ifdef TX_ENABLE_FIQ_SUPPORT 35DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled 36#else 37DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled 38#endif 39 40 EXTERN _tx_thread_system_state 41 EXTERN _tx_thread_current_ptr 42 EXTERN _tx_execution_isr_enter 43; 44; 45;/**************************************************************************/ 46;/* */ 47;/* FUNCTION RELEASE */ 48;/* */ 49;/* _tx_thread_vectored_context_save ARM9/IAR */ 50;/* 6.1 */ 51;/* AUTHOR */ 52;/* */ 53;/* William E. Lamie, Microsoft Corporation */ 54;/* */ 55;/* DESCRIPTION */ 56;/* */ 57;/* This function saves the context of an executing thread in the */ 58;/* beginning of interrupt processing. The function also ensures that */ 59;/* the system stack is used upon return to the calling ISR. */ 60;/* */ 61;/* INPUT */ 62;/* */ 63;/* None */ 64;/* */ 65;/* OUTPUT */ 66;/* */ 67;/* None */ 68;/* */ 69;/* CALLS */ 70;/* */ 71;/* None */ 72;/* */ 73;/* CALLED BY */ 74;/* */ 75;/* ISRs */ 76;/* */ 77;/* RELEASE HISTORY */ 78;/* */ 79;/* DATE NAME DESCRIPTION */ 80;/* */ 81;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 82;/* */ 83;/**************************************************************************/ 84;VOID _tx_thread_vectored_context_save(VOID) 85;{ 86 RSEG .text:CODE:NOROOT(2) 87 PUBLIC _tx_thread_vectored_context_save 88 CODE32 89_tx_thread_vectored_context_save 90; 91; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked 92; out, we are in IRQ mode, the minimal context is already saved, and the 93; lr register contains the return ISR address. */ 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 var 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 occured 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_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 END 195 196