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 .global __tx_thread_system_state 23 .global __tx_thread_current_ptr 24 .global __tx_thread_system_stack_ptr 25 26 .text 27;/**************************************************************************/ 28;/* */ 29;/* FUNCTION RELEASE */ 30;/* */ 31;/* _tx_thread_context_save RXv1/GNURX */ 32;/* 6.1.11 */ 33;/* AUTHOR */ 34;/* */ 35;/* William E. Lamie, Microsoft Corporation */ 36;/* */ 37;/* DESCRIPTION */ 38;/* */ 39;/* This function saves the context of an executing thread in the */ 40;/* beginning of interrupt processing. The function also ensures that */ 41;/* the system stack is used upon return to the calling ISR. */ 42;/* */ 43;/* INPUT */ 44;/* */ 45;/* None */ 46;/* */ 47;/* OUTPUT */ 48;/* */ 49;/* None */ 50;/* */ 51;/* CALLS */ 52;/* */ 53;/* None */ 54;/* */ 55;/* CALLED BY */ 56;/* */ 57;/* ISRs */ 58;/* */ 59;/* RELEASE HISTORY */ 60;/* */ 61;/* DATE NAME DESCRIPTION */ 62;/* */ 63;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */ 64;/* 10-15-2021 William E. Lamie Modified comment(s), */ 65;/* resulting in version 6.1.9 */ 66;/* 01-31-2022 William E. Lamie Modified comment(s), */ 67;/* resulting in version 6.1.10 */ 68;/* 04-25-2022 William E. Lamie Modified comment(s), */ 69;/* resulting in version 6.1.11 */ 70;/* */ 71;/**************************************************************************/ 72;VOID _tx_thread_context_save(VOID) 73;{ 74 .global __tx_thread_context_save 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