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