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