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; 34 extern __tx_thread_system_state 35 extern __tx_thread_current_ptr 36 extern __tx_thread_preempt_disable 37 extern __tx_thread_execute_ptr 38 extern __tx_timer_time_slice 39 extern __tx_thread_schedule 40 41 section .text:CODE:ROOT 42 43;/**************************************************************************/ 44;/* */ 45;/* FUNCTION RELEASE */ 46;/* */ 47;/* _tx_thread_context_restore RXv3/IAR */ 48;/* 6.1.11 */ 49;/* AUTHOR */ 50;/* */ 51;/* William E. Lamie, Microsoft Corporation */ 52;/* */ 53;/* DESCRIPTION */ 54;/* */ 55;/* This function restores the interrupt context if it is processing a */ 56;/* nested interrupt. If not, it returns to the interrupt thread if no */ 57;/* preemption is necessary. Otherwise, if preemption is necessary or */ 58;/* if no thread was running, the function returns to the scheduler. */ 59;/* */ 60;/* INPUT */ 61;/* */ 62;/* None */ 63;/* */ 64;/* OUTPUT */ 65;/* */ 66;/* None */ 67;/* */ 68;/* CALLS */ 69;/* */ 70;/* _tx_thread_schedule Thread scheduling routine */ 71;/* */ 72;/* CALLED BY */ 73;/* */ 74;/* ISRs Interrupt Service Routines */ 75;/* */ 76;/* RELEASE HISTORY */ 77;/* */ 78;/* DATE NAME DESCRIPTION */ 79;/* */ 80;/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ 81;/* 10-15-2021 William E. Lamie Modified comment(s), and */ 82;/* added FPU support, */ 83;/* resulting in version 6.1.9 */ 84;/* 01-31-2022 William E. Lamie Modified comment(s), */ 85;/* resulting in version 6.1.10 */ 86;/* 04-25-2022 William E. Lamie Modified comment(s), */ 87;/* resulting in version 6.1.11 */ 88;/* */ 89;/**************************************************************************/ 90 public __tx_thread_context_restore 91 92__tx_thread_context_restore: 93; 94; /* Lockout interrupts. */ 95 96 CLRPSW I ; Disable interrupts 97 98; /* Determine if interrupts are nested. */ 99; if (--_tx_thread_system_state) 100; { 101 102 MOV.L #__tx_thread_system_state, R1 103 MOV.L [R1], R2 104 SUB #1, R2 105 MOV.L R2,[R1] 106 BEQ __tx_thread_not_nested_restore 107 108; 109; /* Interrupts are nested. */ 110; 111; /* Recover the saved registers from the interrupt stack 112; and return to the point of interrupt. */ 113; 114__tx_thread_nested_restore: 115 POPC FPSW ; Restore FPU status 116 POPM R14-R15 ; Restore R14-R15 117 POPM R3-R5 ; Restore R3-R5 118 POPM R1-R2 ; Restore R1-R2 119 RTE ; Return to point of interrupt, restore PSW including IPL 120; } 121 122__tx_thread_not_nested_restore: 123; 124; /* Determine if a thread was interrupted and no preemption is required. */ 125; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)) 126; || (_tx_thread_preempt_disable)) 127; { 128 129 MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address 130 MOV.L [R1], R2 131 CMP #0, R2 132 BEQ __tx_thread_idle_system_restore 133 134 MOV.L #__tx_thread_preempt_disable, R3 ; Pick up preempt disable flag 135 MOV.L [R3], R3 136 CMP #0, R3 137 BNE __tx_thread_no_preempt_restore ; If pre-empt disable flag set, we simply return to the original point of interrupt regardless 138 139 MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr) 140 CMP [R3], R2 141 BNE __tx_thread_preempt_restore ; Jump to pre-empt restoring 142; 143__tx_thread_no_preempt_restore: 144 SETPSW U ; User stack 145 POPC FPSW ; Restore FPU status 146 POPM R14-R15 ; Restore R14-R15 147 POPM R3-R5 ; Restore R3-R5 148 POPM R1-R2 ; Restore R1-R2 149 RTE ; Return to point of interrupt, restore PSW including IPL 150 151; } 152; else 153; { 154 155__tx_thread_preempt_restore: 156 157; /* Save the remaining time-slice and disable it. */ 158; if (_tx_timer_time_slice) 159; { 160 161 MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address 162 MOV.L [R3],R4 ; Pickup actual time-slice 163 CMP #0, R4 164 BEQ __tx_thread_dont_save_ts ; No time-slice to save 165; 166; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; 167; _tx_timer_time_slice = 0; 168; 169 MOV.L R4,24[R2] ; Save thread's time slice 170 MOV.L #0,R4 ; Clear value 171 MOV.L R4,[R3] ; Disable global time slice flag 172; } 173__tx_thread_dont_save_ts: 174; 175; /* Now store the remaining registers! */ 176 177 SETPSW U ; User stack 178 PUSHM R6-R13 179 180 MVFACGU #0, A1, R4 ; Save accumulators. 181 MVFACHI #0, A1, R5 182 MVFACLO #0, A1, R6 183 PUSHM R4-R6 184 MVFACGU #0, A0, R4 185 MVFACHI #0, A0, R5 186 MVFACLO #0, A0, R6 187 PUSHM R4-R6 188 189#if (__DPFPU == 1) 190 MOV.L 144[R2], R4 ; Get tx_thread_fpu_enable. 191 CMP #0, R4 192 BEQ __tx_thread_preempt_restore_fpu_skip 193 194 DPUSHM.D DR0-DR15 ; Save FPU register bank if tx_thread_fpu_enable is not 0. 195 DPUSHM.L DPSW-DECNT 196 197__tx_thread_preempt_restore_fpu_skip: 198#endif 199 200; 201; /* Clear the current task pointer. */ 202; _tx_thread_current_ptr = TX_NULL; 203; R1 -> _tx_thread_current_ptr 204; R2 -> *_tx_thread_current_ptr 205 206 MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block 207 MOV.L #0,R2 ; Build NULL value 208 MOV.L R2,[R1] ; Set current thread to NULL 209 210; /* Return to the scheduler. */ 211; _tx_thread_schedule(); 212 213__tx_thread_idle_system_restore: 214 MVTC #0, PSW ; Reset interrupt priority level to 0 215 BRA __tx_thread_schedule ; Jump to scheduler 216; } 217; 218;} 219; 220 END 221 222