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