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; 22; 23;#define TX_SOURCE_CODE 24; 25; 26;/* Include necessary system files. */ 27; 28;#include "tx_api.h" 29;#include "tx_thread.h" 30; 31; 32 IF :DEF:TX_ENABLE_FIQ_SUPPORT 33DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled 34 ELSE 35DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled 36 ENDIF 37; 38; 39 IMPORT _tx_thread_system_state 40 IMPORT _tx_thread_current_ptr 41 IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY 42 IMPORT _tx_execution_isr_enter 43 ENDIF 44; 45; 46 AREA ||.text||, CODE, READONLY 47 PRESERVE8 48;/**************************************************************************/ 49;/* */ 50;/* FUNCTION RELEASE */ 51;/* */ 52;/* _tx_thread_vectored_context_save ARM11/AC5 */ 53;/* 6.1 */ 54;/* AUTHOR */ 55;/* */ 56;/* William E. Lamie, Microsoft Corporation */ 57;/* */ 58;/* DESCRIPTION */ 59;/* */ 60;/* This function saves the context of an executing thread in the */ 61;/* beginning of interrupt processing. The function also ensures that */ 62;/* the system stack is used upon return to the calling ISR. */ 63;/* */ 64;/* INPUT */ 65;/* */ 66;/* None */ 67;/* */ 68;/* OUTPUT */ 69;/* */ 70;/* None */ 71;/* */ 72;/* CALLS */ 73;/* */ 74;/* None */ 75;/* */ 76;/* CALLED BY */ 77;/* */ 78;/* ISRs */ 79;/* */ 80;/* RELEASE HISTORY */ 81;/* */ 82;/* DATE NAME DESCRIPTION */ 83;/* */ 84;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 85;/* */ 86;/**************************************************************************/ 87;VOID _tx_thread_vectored_context_save(VOID) 88;{ 89 EXPORT _tx_thread_vectored_context_save 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 IF :DEF: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 IF :DEF: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 IF {INTER} = {TRUE} 130 BX lr ; Return to caller 131 ELSE 132 MOV pc, lr ; Return to caller 133 ENDIF 134; 135__tx_thread_not_nested_save 136; } 137; 138; /* Otherwise, not nested, check to see if a thread was running. */ 139; else if (_tx_thread_current_ptr) 140; { 141; 142 ADD r2, r2, #1 ; Increment the interrupt counter 143 STR r2, [r3, #0] ; Store it back in the variable 144 LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr 145 LDR r0, [r1, #0] ; Pickup current thread pointer 146 CMP r0, #0 ; Is it NULL? 147 BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in 148 ; scheduling loop - nothing needs saving! 149; 150; /* Note: Minimal context of interrupted thread is already saved. */ 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 IF {INTER} = {TRUE} 170 BX lr ; Return to caller 171 ELSE 172 MOV pc, lr ; Return to caller 173 ENDIF 174; 175; } 176; else 177; { 178; 179__tx_thread_idle_system_save 180; 181; /* Interrupt occurred in the scheduling loop. */ 182; 183; /* Not much to do here, just adjust the stack pointer, and return to IRQ 184; processing. */ 185; 186 MOV r10, #0 ; Clear stack limit 187 188 IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY 189; 190; /* Call the ISR enter function to indicate an ISR is executing. */ 191; 192 PUSH {lr} ; Save ISR lr 193 BL _tx_execution_isr_enter ; Call the ISR enter function 194 POP {lr} ; Recover ISR lr 195 ENDIF 196 197 ADD sp, sp, #32 ; Recover saved registers 198 IF {INTER} = {TRUE} 199 BX lr ; Return to caller 200 ELSE 201 MOV pc, lr ; Return to caller 202 ENDIF 203; 204; } 205;} 206; 207 END 208 209