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 extern __tx_thread_system_state 34 extern __tx_thread_current_ptr 35 36 section .text:CODE:ROOT 37;/**************************************************************************/ 38;/* */ 39;/* FUNCTION RELEASE */ 40;/* */ 41;/* _tx_thread_context_save RXv3/IAR */ 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;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ 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 public __tx_thread_context_save 85 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