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