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 .global _tx_thread_execute_ptr 40 .global _tx_timer_time_slice 41 .global _tx_thread_schedule 42 .global _tx_thread_preempt_disable 43; 44; 45 .sect ".text" 46;/**************************************************************************/ 47;/* */ 48;/* FUNCTION RELEASE */ 49;/* */ 50;/* _tx_thread_context_restore C667x/TI */ 51;/* 6.1 */ 52;/* AUTHOR */ 53;/* */ 54;/* William E. Lamie, Microsoft Corporation */ 55;/* */ 56;/* DESCRIPTION */ 57;/* */ 58;/* This function restores the interrupt context if it is processing a */ 59;/* nested interrupt. If not, it returns to the interrupt thread if no */ 60;/* preemption is necessary. Otherwise, if preemption is necessary or */ 61;/* if no thread was running, the function returns to the scheduler. */ 62;/* */ 63;/* INPUT */ 64;/* */ 65;/* None */ 66;/* */ 67;/* OUTPUT */ 68;/* */ 69;/* None */ 70;/* */ 71;/* CALLS */ 72;/* */ 73;/* _tx_thread_schedule Thread scheduling routine */ 74;/* */ 75;/* CALLED BY */ 76;/* */ 77;/* ISRs Interrupt Service Routines */ 78;/* */ 79;/* RELEASE HISTORY */ 80;/* */ 81;/* DATE NAME DESCRIPTION */ 82;/* */ 83;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 84;/* */ 85;/**************************************************************************/ 86;VOID _tx_thread_context_restore(VOID) 87;{ 88 .global _tx_thread_context_restore 89_tx_thread_context_restore: 90; 91; /* Lockout interrupts. */ 92; 93 MVC CSR,B0 ; Pickup CSR 94 AND -2,B0,B0 ; Build interrupt lockout value 95 MVC B0,CSR ; Lockout interrupts 96; 97; /* Determine if interrupts are nested. */ 98; if (--_tx_thread_system_state) 99; { 100; 101 MVKL _tx_thread_system_state,A0 ; Build address of system state 102 MVKH _tx_thread_system_state,A0 ; 103 LDW *A0,A1 ; Pickup system state variable 104 MVKL _tx_thread_current_ptr,A2 ; Build address of current thread ptr 105 NOP 3 ; Delay slots 106 SUB A1,1,A1 ; Decrement system state 107 [!A1] B _tx_thread_not_nested_restore ; If 0, not a nested restore 108 MVKH _tx_thread_current_ptr,A2 ; 109 LDW *A2,A3 ; Pickup current thread pointer 110 STW A1,*A0 ; Store system state 111 NOP 2 ; Delay slots 112; 113; /* Interrupts are nested. */ 114; 115; /* Just recover the saved registers and return to the point of 116; interrupt. */ 117; 118 LDW *+SP(8),B0 ; Recover saved CSR 119 LDW *+SP(12),B1 ; Recover saved IRP 120 LDW *+SP(16),B2 ; Recover saved AMR 121 LDW *+SP(20),A0 ; Recover A0 122 LDW *+SP(24),A1 ; Recover A1 123 LDW *+SP(28),A2 ; Recover A2 124 LDW *+SP(32),A3 ; Recover A3 125 LDW *+SP(36),A4 ; Recover A4 126 LDW *+SP(40),A5 ; Recover A5 127 LDW *+SP(44),A6 ; Recover A6 128 LDW *+SP(48),A7 ; Recover A7 129 LDW *+SP(52),A8 ; Recover A8 130 LDW *+SP(56),A9 ; Recover A9 131 MVC B0,CSR ; Setup CSR 132 MVC B1,IRP ; Setup IRP 133 MVC B2,AMR ; Setup AMR 134 LDW *+SP(268),B0 ; Recover saved ILC 135 LDW *+SP(272),B1 ; Recover saved RILC 136 LDW *+SP(276),B2 ; Recover saved ITSR 137 NOP 4 138 MVC B0,ILC ; Setup ILC 139 MVC B1,RILC ; Setup RILC 140 MVC B2,ITSR ; Setup ITSR 141 LDW *+SP(84),B0 ; Recover B0 142 LDW *+SP(88),B1 ; Recover B1 143 LDW *+SP(92),B2 ; Recover B2 144 LDW *+SP(100),B4 ; Recover B4 145 LDW *+SP(104),B5 ; Recover B5 146 LDW *+SP(108),B6 ; Recover B6 147 LDW *+SP(112),B7 ; Recover B7 148 LDW *+SP(116),B8 ; Recover B8 149 LDW *+SP(140),A16 ; Recover A16 150 LDW *+SP(144),A17 ; Recover A17 151 LDW *+SP(148),A18 ; Recover A18 152 LDW *+SP(152),A19 ; Recover A19 153 LDW *+SP(156),A20 ; Recover A20 154 LDW *+SP(160),A21 ; Recover A21 155 LDW *+SP(164),A22 ; Recover A22 156 LDW *+SP(168),A23 ; Recover A23 157 LDW *+SP(172),A24 ; Recover A24 158 LDW *+SP(176),A25 ; Recover A25 159 LDW *+SP(180),A26 ; Recover A26 160 LDW *+SP(184),A27 ; Recover A27 161 LDW *+SP(188),A28 ; Recover A28 162 LDW *+SP(192),A29 ; Recover A29 163 LDW *+SP(196),A30 ; Recover A30 164 LDW *+SP(200),A31 ; Recover A31 165 LDW *+SP(204),B16 ; Recover B16 166 LDW *+SP(208),B17 ; Recover B17 167 LDW *+SP(212),B18 ; Recover B18 168 LDW *+SP(216),B19 ; Recover B19 169 LDW *+SP(220),B20 ; Recover B20 170 LDW *+SP(224),B21 ; Recover B21 171 LDW *+SP(228),B22 ; Recover B22 172 LDW *+SP(232),B23 ; Recover B23 173 LDW *+SP(236),B24 ; Recover B24 174 LDW *+SP(240),B25 ; Recover B25 175 LDW *+SP(244),B26 ; Recover B26 176 LDW *+SP(248),B27 ; Recover B27 177 LDW *+SP(252),B28 ; Recover B28 178 LDW *+SP(256),B29 ; Recover B29 179 LDW *+SP(260),B30 ; Recover B30 180 LDW *+SP(264),B31 ; Recover B31 181 B IRP ; Return to point of interrupt 182|| LDW *+SP(120),B9 ; Recover B9 183 LDW *+SP(96),B3 ; Recover B3 184 ADDK.S2 288,SP ; Recover stack space 185 NOP 3 ; Delay slots 186; 187; } 188_tx_thread_not_nested_restore: 189; 190; /* Determine if a thread was interrupted and no preemption is required. */ 191; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)) 192; || (_tx_thread_preempt_disable)) 193; { 194; 195 NOP ; Delay 196 MV A3,A1 ; Move thread pointer into A1 197 [!A1] B _tx_thread_schedule ; If null, idle system restore 198 MVKL _tx_thread_preempt_disable,A0 ; Build preempt disable flag address 199 MVKH _tx_thread_preempt_disable,A0 ; 200 MVKL _tx_thread_execute_ptr,A4 ; Build execute thread pointer 201 MVKH _tx_thread_execute_ptr,A4 ; 202 LDW *A0,B1 ; Pickup preempt disable flag 203 204 LDW *A4,A6 ; Pickup next thread to execute 205 NOP 4 ; Delay slot 206 CMPEQ A6,A1,A7 ; Determine if threads are the same? 207 ADD A7,B1,B1 ; Add results together 208 [B1] B _tx_thread_no_preempt_restore ; If set, skip preeemption 209 LDW *+A1(8),A6 ; Recover thread's stack pointer 210 MVKL _tx_timer_time_slice,A5 ; Build time slice address 211 MVKH _tx_timer_time_slice,A5 ; 212 LDW *A5,B1 ; Pickup current time-slice 213 NOP ; Delay slot 214; 215; 216_tx_thread_preempt_restore: 217; 218; 219 MVKL 1,A0 ; Build the interrupt stack type 220 STW A0,*+A6(4) ; Save stack type 221; 222; /* Store the remaining registers on the thread's stack. */ 223; 224 STW A10,*+A6(60) ; Save A10 225 STW A11,*+A6(64) ; Save A11 226 STW A12,*+A6(68) ; Save A12 227 STW A13,*+A6(72) ; Save A13 228 STW A14,*+A6(76) ; Save A14 229 STW A15,*+A6(80) ; Save A15 (FP) 230 STW B10,*+A6(124) ; Save B10 231 ADDK 128,A6 ; Move stack pointer 232 STW B11,*+A6(0) ; Save B11 233 STW B12,*+A6(4) ; Save B12 234 STW B13,*+A6(8) ; Save B13 235; 236; /* Save the remaining time-slice and disable it. */ 237; if (_tx_timer_time_slice) 238; { 239; 240; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; 241; _tx_timer_time_slice = 0; 242; 243; } 244_tx_thread_dont_save_ts: 245; 246; 247; /* Clear the current task pointer. */ 248; _tx_thread_current_ptr = TX_NULL; 249; 250; /* Return to the scheduler. */ 251; _tx_thread_schedule(); 252; 253 B _tx_thread_schedule ; Return to scheduler 254 STW B1,*+A1(24) ; Store current time-slice 255 ZERO A3 ; Clear value 256 STW A3,*A2 ; Set current thread pointer to NULL 257 STW A3,*A5 ; Set time slice to 0 258 NOP ; Delay 259; 260; 261_tx_thread_no_preempt_restore: 262; 263; /* Restore interrupted thread. */ 264; 265; /* Pickup the saved stack pointer. */ 266; SP = _tx_thread_current_ptr -> tx_thread_stack_ptr; 267; 268; /* Recover the saved context and return to the point of interrupt. */ 269; 270 MV A6,SP ; Setup real stack pointer 271 LDW *+SP(8),B0 ; Recover saved CSR 272 LDW *+SP(12),B1 ; Recover saved IRP 273 LDW *+SP(16),B2 ; Recover saved AMR 274 LDW *+SP(20),A0 ; Recover A0 275 LDW *+SP(24),A1 ; Recover A1 276 LDW *+SP(28),A2 ; Recover A2 277 LDW *+SP(32),A3 ; Recover A3 278 LDW *+SP(36),A4 ; Recover A4 279 LDW *+SP(40),A5 ; Recover A5 280 LDW *+SP(44),A6 ; Recover A6 281 LDW *+SP(48),A7 ; Recover A7 282 LDW *+SP(52),A8 ; Recover A8 283 LDW *+SP(56),A9 ; Recover A9 284 MVC B0,CSR ; Setup CSR 285 MVC B1,IRP ; Setup IRP 286 MVC B2,AMR ; Setup AMR 287 LDW *+SP(268),B0 ; Recover saved ILC 288 LDW *+SP(272),B1 ; Recover saved RILC 289 LDW *+SP(276),B2 ; Recover saved ITSR 290 NOP 4 ; Delay 291 MVC B0,ILC ; Setup ILC 292 MVC B1,RILC ; Setup RILC 293 MVC B2,ITSR ; Setup ITSR 294 LDW *+SP(84),B0 ; Recover B0 295 LDW *+SP(88),B1 ; Recover B1 296 LDW *+SP(92),B2 ; Recover B2 297 LDW *+SP(100),B4 ; Recover B4 298 LDW *+SP(104),B5 ; Recover B5 299 LDW *+SP(108),B6 ; Recover B6 300 LDW *+SP(112),B7 ; Recover B7 301 LDW *+SP(116),B8 ; Recover B8 302 LDW *+SP(140),A16 ; Recover A16 303 LDW *+SP(144),A17 ; Recover A17 304 LDW *+SP(148),A18 ; Recover A18 305 LDW *+SP(152),A19 ; Recover A19 306 LDW *+SP(156),A20 ; Recover A20 307 LDW *+SP(160),A21 ; Recover A21 308 LDW *+SP(164),A22 ; Recover A22 309 LDW *+SP(168),A23 ; Recover A23 310 LDW *+SP(172),A24 ; Recover A24 311 LDW *+SP(176),A25 ; Recover A25 312 LDW *+SP(180),A26 ; Recover A26 313 LDW *+SP(184),A27 ; Recover A27 314 LDW *+SP(188),A28 ; Recover A28 315 LDW *+SP(192),A29 ; Recover A29 316 LDW *+SP(196),A30 ; Recover A30 317 LDW *+SP(200),A31 ; Recover A31 318 LDW *+SP(204),B16 ; Recover B16 319 LDW *+SP(208),B17 ; Recover B17 320 LDW *+SP(212),B18 ; Recover B18 321 LDW *+SP(216),B19 ; Recover B19 322 LDW *+SP(220),B20 ; Recover B20 323 LDW *+SP(224),B21 ; Recover B21 324 LDW *+SP(228),B22 ; Recover B22 325 LDW *+SP(232),B23 ; Recover B23 326 LDW *+SP(236),B24 ; Recover B24 327 LDW *+SP(240),B25 ; Recover B25 328 LDW *+SP(244),B26 ; Recover B26 329 LDW *+SP(248),B27 ; Recover B27 330 LDW *+SP(252),B28 ; Recover B28 331 LDW *+SP(256),B29 ; Recover B29 332 LDW *+SP(260),B30 ; Recover B30 333 LDW *+SP(264),B31 ; Recover B31 334 B IRP ; Return to point of interrupt 335|| LDW *+SP(120),B9 ; Recover B9 336 LDW *+SP(96),B3 ; Recover B3 337 ADDK.S2 288,SP ; Recover stack space 338 NOP 3 ; Delay slots 339; 340; } 341;} 342 343