1;/**************************************************************************/ 2;/* */ 3;/* Copyright (c) Microsoft Corporation. All rights reserved. */ 4;/* */ 5;/* This software is licensed under the Microsoft Software License */ 6;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8;/* and in the root directory of this software. */ 9;/* */ 10;/**************************************************************************/ 11; 12; 13;/**************************************************************************/ 14;/**************************************************************************/ 15;/** */ 16;/** ThreadX Component */ 17;/** */ 18;/** Thread */ 19;/** */ 20;/**************************************************************************/ 21;/**************************************************************************/ 22; 23; 24;#define TX_SOURCE_CODE 25; 26; 27;/* Include necessary system files. */ 28; 29;#include "tx_api.h" 30;#include "tx_thread.h" 31;#include "tx_timer.h" 32; 33 .global __tx_thread_system_state 34 .global __tx_thread_current_ptr 35 .global __tx_thread_system_stack_ptr 36 37 .text 38;/**************************************************************************/ 39;/* */ 40;/* FUNCTION RELEASE */ 41;/* */ 42;/* _tx_thread_context_save RXv3/GNURX */ 43;/* 6.1.11 */ 44;/* AUTHOR */ 45;/* */ 46;/* William E. Lamie, Microsoft Corporation */ 47;/* */ 48;/* DESCRIPTION */ 49;/* */ 50;/* This function saves the context of an executing thread in the */ 51;/* beginning of interrupt processing. The function also ensures that */ 52;/* the system stack is used upon return to the calling ISR. */ 53;/* */ 54;/* INPUT */ 55;/* */ 56;/* None */ 57;/* */ 58;/* OUTPUT */ 59;/* */ 60;/* None */ 61;/* */ 62;/* CALLS */ 63;/* */ 64;/* None */ 65;/* */ 66;/* CALLED BY */ 67;/* */ 68;/* ISRs */ 69;/* */ 70;/* RELEASE HISTORY */ 71;/* */ 72;/* DATE NAME DESCRIPTION */ 73;/* */ 74;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ 75;/* 10-15-2021 William E. Lamie Modified comment(s), */ 76;/* resulting in version 6.1.9 */ 77;/* 01-31-2022 William E. Lamie Modified comment(s), */ 78;/* resulting in version 6.1.10 */ 79;/* 04-25-2022 William E. Lamie Modified comment(s), */ 80;/* resulting in version 6.1.11 */ 81;/* */ 82;/**************************************************************************/ 83;VOID _tx_thread_context_save(VOID) 84;{ 85 .global __tx_thread_context_save 86__tx_thread_context_save: 87; 88; /* Upon entry to this routine, it is assumed that interrupts are locked 89; out and the (interrupt) stack frame looks like the following: 90; 91; (lower address) SP -> [return address of this call] 92; SP+4 -> Saved R1 93; SP+8 -> Saved R2 94; SP+12-> Interrupted PC 95; SP+16-> Interrupted PSW 96; 97; /* Check for a nested interrupt condition. */ 98; if (_tx_thread_system_state++) 99; { 100; 101 102 MOV.L #__tx_thread_system_state, R1 ; Pick up address of system state 103 MOV.L [R1], R2 ; Pick up system state 104 CMP #0, R2 ; 0 -> no nesting 105 BEQ __tx_thread_not_nested_save 106; 107; /* Nested interrupt condition. */ 108; 109 ADD #1, r2 ; _tx_thread_system_state++ 110 MOV.L r2, [r1] 111 112; 113; /* Save the rest of the scratch registers on the interrupt stack and return to the 114; calling ISR. */ 115 POP R1 ; recuperate return address from stack 116 PUSHM R3-R5 117 PUSHM R14-R15 118 PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom) 119 JMP R1 ; Return address was preserved in R1 120 121; 122__tx_thread_not_nested_save: 123; } 124; 125; /* Otherwise, not nested, check to see if a thread was running. */ 126; else if (_tx_thread_current_ptr) 127; { 128; 129 ADD #1, R2 ; _tx_thread_system_state++ 130 MOV.L R2, [R1] 131 132 MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer 133 MOV.L [R2], R2 134 CMP #0,R2 ; Is it NULL? 135 BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore 136; 137; /* Move stack frame over to the current threads stack. */ 138; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */ 139; 140 MVFC USP, R1 ; Pick up user stack pointer 141 MOV.L 16[R0], R2 142 MOV.L R2, [-R1] ; Save PSW on thread stack 143 MOV.L 12[R0], R2 144 MOV.L R2, [-R1] ; Save PC on thread stack 145 MOV.L 8[R0], R2 146 MOV.L R2, [-R1] ; Save R2 on thread stack 147 MOV.L 4[R0], R2 148 MOV.L R2, [-R1] ; Save R1 on thread stack 149 MOV.L R5, [-R1] ; Save R5 on thread stack 150 MOV.L R4, [-R1] ; Save R4 on thread stack 151 MOV.L R3, [-R1] ; Save R3 on thread stack 152 MOV.L R15, [-R1] ; Save R15 on thread stack 153 MOV.L R14, [-R1] ; Save R14 on thread stack 154 MVFC FPSW, R3 155 MOV.L R3, [-R1] ; Save FPSW on thread stack 156 157 POP R2 ; Pick up return address from interrupt stack 158 ADD #16, R0, R0 ; Correct interrupt stack pointer back to the bottom 159 MVTC R1, USP ; Set user/thread stack pointer 160 JMP R2 ; Return to ISR 161 162; } 163; else 164; { 165; 166__tx_thread_idle_system_save: 167; 168; /* Interrupt occurred in the scheduling loop. */ 169; 170 POP R1 ; Pick up return address 171 ADD #16, R0, R0 ; Correct interrupt stack pointer back to the bottom (PC), don't care about saved registers 172 JMP R1 ; Return to caller 173; 174; } 175;} 176 .end 177 178 179 180