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; 32FP .set A15 33DP .set B14 34SP .set B15 35; 36 .global _tx_thread_system_state 37 .global _tx_thread_current_ptr 38 .global _tx_thread_system_stack_ptr 39; 40; 41 .sect ".text" 42;/**************************************************************************/ 43;/* */ 44;/* FUNCTION RELEASE */ 45;/* */ 46;/* _tx_thread_context_save C667x/TI */ 47;/* 6.1 */ 48;/* AUTHOR */ 49;/* */ 50;/* William E. Lamie, Microsoft Corporation */ 51;/* */ 52;/* DESCRIPTION */ 53;/* */ 54;/* This function saves the context of an executing thread in the */ 55;/* beginning of interrupt processing. The function also ensures that */ 56;/* the system stack is used upon return to the calling ISR. */ 57;/* */ 58;/* INPUT */ 59;/* */ 60;/* None */ 61;/* */ 62;/* OUTPUT */ 63;/* */ 64;/* None */ 65;/* */ 66;/* CALLS */ 67;/* */ 68;/* None */ 69;/* */ 70;/* CALLED BY */ 71;/* */ 72;/* ISRs */ 73;/* */ 74;/* RELEASE HISTORY */ 75;/* */ 76;/* DATE NAME DESCRIPTION */ 77;/* */ 78;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 79;/* */ 80;/**************************************************************************/ 81;VOID _tx_thread_context_save(VOID) 82;{ 83 .global _tx_thread_context_save 84_tx_thread_context_save: 85; 86; /* Upon entry to this routine, it is assumed that all interrupts are locked 87; out, an initial stack frame of 288 bytes has been allocated and registers 88; A0, A1, A2, A3, A4, and B3 have been saved in the frame. Additionally, 89; it is assumed that register B3 contains the ISR's return address. */ 90; 91; /* Check for a nested interrupt condition. */ 92; if (_tx_thread_system_state++) 93; { 94; 95 MVKL _tx_thread_system_state,A0 ; Build address of system state 96 MVKH _tx_thread_system_state,A0 ; 97 LDW *A0,A1 ; Pickup current system state 98 STW A5,*+SP(40) ; Save A5 99 STW A6,*+SP(44) ; Save A6 100 STW A7,*+SP(48) ; Save A7 101 STW A8,*+SP(52) ; Save A8 102 [!A1] B _tx_thread_not_nested_save ; If 0, not a nested save condition 103 MVKL _tx_thread_current_ptr,A3 ; Build address of current thread ptr 104 MVKH _tx_thread_current_ptr,A3 ; 105 LDW *A3,A2 ; Pickup current thread pointer 106 ADD 1,A1,A1 ; Increment the system state (nested) counter 107 STW A1,*A0 ; Store system state 108; 109; /* Nested interrupt condition. Save remaining scratch registers, and control registers 110; and return to calling ISR. */ 111; 112 STW A9,*+SP(56) ; Save A9 113 STW B0,*+SP(84) ; Save B0 114 STW B1,*+SP(88) ; Save B1 115 STW B2,*+SP(92) ; Save B2 116 ; B3 is already saved! 117 STW B4,*+SP(100) ; Save B4 118 STW B5,*+SP(104) ; Save B5 119 STW B6,*+SP(108) ; Save B6 120 STW B7,*+SP(112) ; Save B7 121 STW B8,*+SP(116) ; Save B8 122 STW B9,*+SP(120) ; Save B9 123 MVC CSR,B0 ; Pickup CSR 124 B B3 ; Return to calling ISR 125 MVC IRP,B1 ; Pickup IRP 126 MVC AMR,B2 ; Pickup AMR 127 STW B0,*+SP(8) ; Save CSR 128 STW B1,*+SP(12) ; Save IRP 129 STW B2,*+SP(16) ; Save AMR 130 ZERO B0 ; Clear B0 131 MVC B0,AMR ; Clear AMR for linear addressing in ISR 132 STW A16,*+SP(140) ; Save A16 133 STW A17,*+SP(144) ; Save A17 134 STW A18,*+SP(148) ; Save A18 135 STW A19,*+SP(152) ; Save A19 136 STW A20,*+SP(156) ; Save A20 137 STW A21,*+SP(160) ; Save A21 138 STW A22,*+SP(164) ; Save A22 139 STW A23,*+SP(168) ; Save A23 140 STW A24,*+SP(172) ; Save A24 141 STW A25,*+SP(176) ; Save A25 142 STW A26,*+SP(180) ; Save A26 143 STW A27,*+SP(184) ; Save A27 144 STW A28,*+SP(188) ; Save A28 145 STW A29,*+SP(192) ; Save A29 146 STW A30,*+SP(196) ; Save A30 147 STW A31,*+SP(200) ; Save A31 148 STW B16,*+SP(204) ; Save B16 149 STW B17,*+SP(208) ; Save B17 150 STW B18,*+SP(212) ; Save B18 151 STW B19,*+SP(216) ; Save B19 152 STW B20,*+SP(220) ; Save B20 153 STW B21,*+SP(224) ; Save B21 154 STW B22,*+SP(228) ; Save B22 155 STW B23,*+SP(232) ; Save B23 156 STW B24,*+SP(236) ; Save B24 157 STW B25,*+SP(240) ; Save B25 158 STW B26,*+SP(244) ; Save B26 159 STW B27,*+SP(248) ; Save B27 160 STW B28,*+SP(252) ; Save B28 161 STW B29,*+SP(256) ; Save B29 162 STW B30,*+SP(260) ; Save B30 163 STW B31,*+SP(264) ; Save B31 164 MVC ILC,B0 ; Pickup ILC 165 MVC RILC,B1 ; Pickup RILC 166 MVC ITSR,B2 ; Pickup ITSR 167 STW B0,*+SP(268) ; Save ILC 168 STW B1,*+SP(272) ; Save RILC 169 STW B2,*+SP(276) ; Save ITSR 170; 171_tx_thread_not_nested_save: 172; } 173; 174; /* Otherwise, not nested, check to see if a thread was running. */ 175; else if (_tx_thread_current_ptr) 176; { 177; 178 MVKL _tx_thread_system_stack_ptr,A0 ; Build address of system 179 MVKH _tx_thread_system_stack_ptr,A0 ; stack pointer 180 MV A2,A1 ; Transfer to A1 for B compare 181 [!A1] B _tx_thread_idle_system_save ; If Null, idle system save 182 STW A9,*+SP(56) ; Save A9 183 STW B0,*+SP(84) ; Save B0 184 STW B1,*+SP(88) ; Save B1 185 STW B2,*+SP(92) ; Save B2 186 NOP ; Delay slot 187; 188; /* At this point, a thread was interrupted and the remainder of its scratch and 189; control registers must be saved. */ 190; 191 ; B3 was already saved! 192 STW B4,*+SP(100) ; Save B4 193 STW B5,*+SP(104) ; Save B5 194 STW B6,*+SP(108) ; Save B6 195 STW B7,*+SP(112) ; Save B7 196 STW B8,*+SP(116) ; Save B8 197 STW B9,*+SP(120) ; Save B9 198 MVC CSR,B0 ; Pickup CSR 199 MVC IRP,B1 ; Pickup IRP 200 MVC AMR,B2 ; Pickup AMR 201 STW B0,*+SP(8) ; Save CSR 202 STW B1,*+SP(12) ; Save IRP 203 STW B2,*+SP(16) ; Save AMR 204 ZERO B0 ; Clear B0 205 MVC B0,AMR ; Clear AMR for linear addressing in ISR 206 STW A16,*+SP(140) ; Save A16 207 STW A17,*+SP(144) ; Save A17 208 STW A18,*+SP(148) ; Save A18 209 STW A19,*+SP(152) ; Save A19 210 STW A20,*+SP(156) ; Save A20 211 STW A21,*+SP(160) ; Save A21 212 STW A22,*+SP(164) ; Save A22 213 STW A23,*+SP(168) ; Save A23 214 STW A24,*+SP(172) ; Save A24 215 STW A25,*+SP(176) ; Save A25 216 STW A26,*+SP(180) ; Save A26 217 STW A27,*+SP(184) ; Save A27 218 STW A28,*+SP(188) ; Save A28 219 STW A29,*+SP(192) ; Save A29 220 STW A30,*+SP(196) ; Save A30 221 STW A31,*+SP(200) ; Save A31 222 STW B16,*+SP(204) ; Save B16 223 STW B17,*+SP(208) ; Save B17 224 STW B18,*+SP(212) ; Save B18 225 STW B19,*+SP(216) ; Save B19 226 STW B20,*+SP(220) ; Save B20 227 STW B21,*+SP(224) ; Save B21 228 STW B22,*+SP(228) ; Save B22 229 STW B23,*+SP(232) ; Save B23 230 STW B24,*+SP(236) ; Save B24 231 STW B25,*+SP(240) ; Save B25 232 STW B26,*+SP(244) ; Save B26 233 STW B27,*+SP(248) ; Save B27 234 STW B28,*+SP(252) ; Save B28 235 STW B29,*+SP(256) ; Save B29 236 STW B30,*+SP(260) ; Save B30 237 STW B31,*+SP(264) ; Save B31 238 MVC ILC,B0 ; Pickup ILC 239 MVC RILC,B1 ; Pickup RILC 240 MVC ITSR,B2 ; Pickup ITSR 241 STW B0,*+SP(268) ; Save ILC 242 STW B1,*+SP(272) ; Save RILC 243 STW B2,*+SP(276) ; Save ITSR 244; 245; /* Save the current stack pointer in the thread's control block. */ 246; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP; 247; 248; /* Switch to the system stack. */ 249; SP = _tx_thread_system_stack_ptr; 250; 251 STW SP,*+A1(8) ; Save stack pointer 252 B B3 ; Return to calling ISR 253 LDW *A0,SP ; Switch to system stack 254 NOP 4 ; Stack pointer is valid upon return! 255; 256; } 257; else 258; { 259; 260_tx_thread_idle_system_save: 261; 262; /* Interrupt occurred in the scheduling loop. */ 263; 264; /* Not much to do here, just adjust the stack pointer, and return to ISR 265; processing. */ 266; 267 B B3 ; Return to ISR 268 ADDK.S2 288,SP ; Recover stack space 269 NOP 4 ; Delay slot 270; 271; } 272;} 273 274