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 extern __tx_thread_system_state 23 extern __tx_thread_current_ptr 24 25 section .text:CODE:ROOT 26;/**************************************************************************/ 27;/* */ 28;/* FUNCTION RELEASE */ 29;/* */ 30;/* _tx_thread_context_save RXv1/IAR */ 31;/* 6.1.11 */ 32;/* AUTHOR */ 33;/* */ 34;/* William E. Lamie, Microsoft Corporation */ 35;/* */ 36;/* DESCRIPTION */ 37;/* */ 38;/* This function saves the context of an executing thread in the */ 39;/* beginning of interrupt processing. The function also ensures that */ 40;/* the system stack is used upon return to the calling ISR. */ 41;/* */ 42;/* INPUT */ 43;/* */ 44;/* None */ 45;/* */ 46;/* OUTPUT */ 47;/* */ 48;/* None */ 49;/* */ 50;/* CALLS */ 51;/* */ 52;/* None */ 53;/* */ 54;/* CALLED BY */ 55;/* */ 56;/* ISRs */ 57;/* */ 58;/* RELEASE HISTORY */ 59;/* */ 60;/* DATE NAME DESCRIPTION */ 61;/* */ 62;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */ 63;/* 10-15-2021 William E. Lamie Modified comment(s), */ 64;/* resulting in version 6.1.9 */ 65;/* 01-31-2022 William E. Lamie Modified comment(s), */ 66;/* resulting in version 6.1.10 */ 67;/* 04-25-2022 William E. Lamie Modified comment(s), */ 68;/* resulting in version 6.1.11 */ 69;/* */ 70;/**************************************************************************/ 71;VOID _tx_thread_context_save(VOID) 72;{ 73 public __tx_thread_context_save 74 75__tx_thread_context_save: 76; 77; /* Upon entry to this routine, it is assumed that interrupts are locked 78; out and the (interrupt) stack frame looks like the following: 79; 80; (lower address) SP -> [return address of this call] 81; SP+4 -> Saved R1 82; SP+8 -> Saved R2 83; SP+12-> Interrupted PC 84; SP+16-> Interrupted PSW 85; 86; /* Check for a nested interrupt condition. */ 87; if (_tx_thread_system_state++) 88; { 89; 90 91 MOV.L #__tx_thread_system_state, R1 ; Pick up address of system state 92 MOV.L [R1], R2 ; Pick up system state 93 CMP #0, R2 ; 0 -> no nesting 94 BEQ __tx_thread_not_nested_save 95; 96; /* Nested interrupt condition. */ 97; 98 ADD #1, r2 ; _tx_thread_system_state++ 99 MOV.L r2, [r1] 100 101; 102; /* Save the rest of the scratch registers on the interrupt stack and return to the 103; calling ISR. */ 104 POP R1 ; Recuperate return address from stack 105 PUSHM R3-R5 106 PUSHM R14-R15 107 JMP R1 ; Return address was preserved in R1 108 109; 110__tx_thread_not_nested_save: 111; } 112; 113; /* Otherwise, not nested, check to see if a thread was running. */ 114; else if (_tx_thread_current_ptr) 115; { 116; 117 ADD #1, R2 ; _tx_thread_system_state++ 118 MOV.L R2, [R1] 119 120 MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer 121 MOV.L [R2], R2 122 CMP #0,R2 ; Is it NULL? 123 BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore 124; 125; /* Move stack frame over to the current threads stack. */ 126; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */ 127; 128 MVFC USP, R1 ; Pick up user stack pointer 129 MOV.L 16[R0], R2 130 MOV.L R2, [-R1] ; Save PSW on thread stack 131 MOV.L 12[R0], R2 132 MOV.L R2, [-R1] ; Save PC on thread stack 133 MOV.L 8[R0], R2 134 MOV.L R2, [-R1] ; Save R2 on thread stack 135 MOV.L 4[R0], R2 136 MOV.L R2, [-R1] ; Save R1 on thread stack 137 MOV.L R5, [-R1] ; Save R5 on thread stack 138 MOV.L R4, [-R1] ; Save R4 on thread stack 139 MOV.L R3, [-R1] ; Save R3 on thread stack 140 MOV.L R15, [-R1] ; Save R15 on thread stack 141 MOV.L R14, [-R1] ; Save R14 on thread stack 142 143 POP R2 ; Pick up return address from interrupt stack 144 ADD #16, R0, R0 ; Correct interrupt stack pointer back to the bottom 145 MVTC R1, USP ; Set user/thread stack pointer 146 JMP R2 ; Return to ISR 147 148; } 149; else 150; { 151; 152__tx_thread_idle_system_save: 153; 154; /* Interrupt occurred in the scheduling loop. */ 155; 156 POP R1 ; Pick up return address 157 ADD #16, R0, R0 ; Correct interrupt stack pointer back to the bottom (PC), don't care about saved registers 158 JMP R1 ; Return to caller 159; 160; } 161;} 162 END 163