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 .global __tx_thread_system_state 33 .global __tx_thread_current_ptr 34 .global __tx_thread_system_stack_ptr 35 36 .text 37;/**************************************************************************/ 38;/* */ 39;/* FUNCTION RELEASE */ 40;/* */ 41;/* _tx_thread_context_save RXv2/GNURX */ 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;/* 12-30-2020 William E. Lamie Initial Version 6.1.3 */ 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 .global __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 PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom) 118 JMP R1 ; Return address was preserved in R1 119 120; 121__tx_thread_not_nested_save: 122; } 123; 124; /* Otherwise, not nested, check to see if a thread was running. */ 125; else if (_tx_thread_current_ptr) 126; { 127; 128 ADD #1, R2 ; _tx_thread_system_state++ 129 MOV.L R2, [R1] 130 131 MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer 132 MOV.L [R2], R2 133 CMP #0,R2 ; Is it NULL? 134 BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore 135; 136; /* Move stack frame over to the current threads stack. */ 137; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */ 138; 139 MVFC USP, R1 ; Pick up user stack pointer 140 MOV.L 16[R0], R2 141 MOV.L R2, [-R1] ; Save PSW on thread stack 142 MOV.L 12[R0], R2 143 MOV.L R2, [-R1] ; Save PC on thread stack 144 MOV.L 8[R0], R2 145 MOV.L R2, [-R1] ; Save R2 on thread stack 146 MOV.L 4[R0], R2 147 MOV.L R2, [-R1] ; Save R1 on thread stack 148 MOV.L R5, [-R1] ; Save R5 on thread stack 149 MOV.L R4, [-R1] ; Save R4 on thread stack 150 MOV.L R3, [-R1] ; Save R3 on thread stack 151 MOV.L R15, [-R1] ; Save R15 on thread stack 152 MOV.L R14, [-R1] ; Save R14 on thread stack 153 MVFC FPSW, R3 154 MOV.L R3, [-R1] ; Save FPSW on thread stack 155 156 POP R2 ; Pick up return address from interrupt stack 157 ADD #16, R0, R0 ; Correct interrupt stack pointer back to the bottom 158 MVTC R1, USP ; Set user/thread stack pointer 159 JMP R2 ; Return to ISR 160 161; } 162; else 163; { 164; 165__tx_thread_idle_system_save: 166; 167; /* Interrupt occurred in the scheduling loop. */ 168; 169 POP R1 ; Pick up return address 170 ADD #16, R0, R0 ; Correct interrupt stack pointer back to the bottom (PC), don't care about saved registers 171 JMP R1 ; Return to caller 172; 173; } 174;} 175 .end 176