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; 23;#define TX_SOURCE_CODE 24; 25; 26;/* Include necessary system files. */ 27; 28;#include "tx_api.h" 29;#include "tx_thread.h" 30;#include "tx_timer.h" 31; 32; 33 .global __tx_thread_system_state 34 .global __tx_thread_current_ptr 35 .global __tx_thread_system_stack_ptr 36 .global __tx_thread_execute_ptr 37 .global __tx_timer_time_slice 38 .global __tx_thread_schedule 39 .global __tx_thread_preempt_disable 40 41 .text 42 43;/**************************************************************************/ 44;/* */ 45;/* FUNCTION RELEASE */ 46;/* */ 47;/* _tx_thread_context_restore RXv2/GNURX */ 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;/* 12-30-2020 William E. Lamie Initial Version 6.1.3 */ 81;/* 10-15-2021 William E. Lamie Modified comment(s), and */ 82;/* removed unnecessary stack */ 83;/* type placement, */ 84;/* resulting in version 6.1.9 */ 85;/* 01-31-2022 William E. Lamie Modified comment(s), */ 86;/* resulting in version 6.1.10 */ 87;/* 04-25-2022 William E. Lamie Modified comment(s), */ 88;/* resulting in version 6.1.11 */ 89;/* */ 90;/**************************************************************************/ 91;VOID _tx_thread_context_restore(VOID) 92;{ 93 .global __tx_thread_context_restore 94__tx_thread_context_restore: 95; 96; /* Lockout interrupts. */ 97 98 CLRPSW I ; Disable interrupts 99 100; /* Determine if interrupts are nested. */ 101; if (--_tx_thread_system_state) 102; { 103 104 MOV.L #__tx_thread_system_state, R1 105 MOV.L [R1], R2 106 SUB #1, R2 107 MOV.L R2,[R1] 108 BEQ __tx_thread_not_nested_restore 109 110; 111; /* Interrupts are nested. */ 112; 113; /* Recover the saved registers from the interrupt stack 114; and return to the point of interrupt. */ 115; 116__tx_thread_nested_restore: 117 POPC FPSW ; Restore FPU status 118 POPM R14-R15 ; Restore R14-R15 119 POPM R3-R5 ; Restore R3-R5 120 POPM R1-R2 ; Restore R1-R2 121 RTE ; Return to point of interrupt, restore PSW including IPL 122; } 123 124__tx_thread_not_nested_restore: 125; 126; /* Determine if a thread was interrupted and no preemption is required. */ 127; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) 128; || (_tx_thread_preempt_disable)) 129; { 130 131 MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address 132 MOV.L [R1], R2 133 CMP #0, R2 134 BEQ __tx_thread_idle_system_restore 135 136 MOV.L #__tx_thread_preempt_disable, R3 ; Pick up preempt disable flag 137 MOV.L [R3], R3 138 CMP #0, R3 139 BNE __tx_thread_no_preempt_restore ; If pre-empt disable flag set, we simply return to the original point of interrupt regardless 140 141 MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr) 142 CMP [R3], R2 143 BNE __tx_thread_preempt_restore ; Jump to pre-empt restoring 144; 145__tx_thread_no_preempt_restore: 146 SETPSW U ; User stack 147 POPC FPSW ; Restore FPU status 148 POPM R14-R15 ; Restore R14-R15 149 POPM R3-R5 ; Restore R3-R5 150 POPM R1-R2 ; Restore R1-R2 151 RTE ; Return to point of interrupt, restore PSW including IPL 152 153; } 154; else 155; { 156 157__tx_thread_preempt_restore: 158 159; /* Save the remaining time-slice and disable it. */ 160; if (_tx_timer_time_slice) 161; { 162 163 MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address 164 MOV.L [R3],R4 ; Pickup actual time-slice 165 CMP #0, R4 166 BEQ __tx_thread_dont_save_ts ; No time slice to save 167; 168; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; 169; _tx_timer_time_slice = 0; 170; 171 MOV.L R4,24[R2] ; Save thread's time slice 172 MOV.L #0,R4 ; Clear value 173 MOV.L R4,[R3] ; Disable global time slice flag 174; } 175__tx_thread_dont_save_ts: 176; 177; /* Now store the remaining registers! */ 178 179 SETPSW U ; User stack 180 PUSHM R6-R13 181 182 MVFACGU #0, A1, R4 ; Save accumulators. 183 MVFACHI #0, A1, R5 184 MVFACLO #0, A1, R6 185 PUSHM R4-R6 186 MVFACGU #0, A0, R4 187 MVFACHI #0, A0, R5 188 MVFACLO #0, A0, R6 189 PUSHM R4-R6 190 191; 192; /* Clear the current task pointer. */ 193; _tx_thread_current_ptr = TX_NULL; 194; R1 -> _tx_thread_current_ptr 195; R2 -> *_tx_thread_current_ptr 196 197 MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block 198 MOV.L #0,R2 ; Build NULL value 199 MOV.L R2,[R1] ; Set current thread to NULL 200 201; /* Return to the scheduler. */ 202; _tx_thread_schedule(); 203 204__tx_thread_idle_system_restore: 205 MVTC #0, PSW ; Reset interrupt priority level to 0 206 BRA __tx_thread_schedule ; Jump to scheduler 207; } 208; 209;} 210; 211 .end 212