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