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;/** ThreadX Component */ 16;/** */ 17;/** Thread */ 18;/** */ 19;/**************************************************************************/ 20;/**************************************************************************/ 21#ifdef TX_INCLUDE_USER_DEFINE_FILE 22#include "tx_user.h" 23#endif 24 25 .equ BTA, 0x412 26 27;/**************************************************************************/ 28;/* */ 29;/* FUNCTION RELEASE */ 30;/* */ 31;/* _tx_thread_context_save ARC_HS/MetaWare */ 32;/* 6.2.1 */ 33;/* AUTHOR */ 34;/* */ 35;/* William E. Lamie, Microsoft Corporation */ 36;/* */ 37;/* DESCRIPTION */ 38;/* */ 39;/* This function saves the context of an executing thread in the */ 40;/* beginning of interrupt processing. The function also ensures that */ 41;/* the system stack is used upon return to the calling ISR. */ 42;/* */ 43;/* INPUT */ 44;/* */ 45;/* None */ 46;/* */ 47;/* OUTPUT */ 48;/* */ 49;/* None */ 50;/* */ 51;/* CALLS */ 52;/* */ 53;/* None */ 54;/* */ 55;/* CALLED BY */ 56;/* */ 57;/* ISRs */ 58;/* */ 59;/* RELEASE HISTORY */ 60;/* */ 61;/* DATE NAME DESCRIPTION */ 62;/* */ 63;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 64;/* 10-15-2021 Andres Mlinar Modified comment(s), and */ 65;/* r25/r30 are caller saved, */ 66;/* resulting in version 6.1.9 */ 67;/* 03-08-2023 Cindy Deng Modified comment(s), added */ 68;/* #include tx_user.h, */ 69;/* resulting in version 6.2.1 */ 70;/* */ 71;/**************************************************************************/ 72;VOID _tx_thread_context_save(VOID) 73;{ 74 .global _tx_thread_context_save 75 .type _tx_thread_context_save, @function 76_tx_thread_context_save: 77; 78; /* Upon entry to this routine, it is assumed that an interrupt stack frame 79; has already been allocated, and the interrupted blink register is already saved. */ 80; 81 clri ; Disable interrupts 82 st r1, [sp, 128] ; Save r1 83 st r0, [sp, 132] ; Save r0 84; 85; /* Check for a nested interrupt condition. */ 86; if (_tx_thread_system_state++) 87; { 88; 89 ld r0, [gp, _tx_thread_system_state@sda] ; Pickup system state 90 st r3, [sp, 120] ; Save r3 91 st r2, [sp, 124] ; Save r2 92 breq r0, 0, __tx_thread_not_nested_save ; If 0, we are not in a nested 93 ; condition 94; 95; /* Nested interrupt condition. */ 96; 97 add r0, r0, 1 ; Increment the nested interrupt count 98 st r0, [gp, _tx_thread_system_state@sda] ; Update system state 99; 100; /* Save the rest of the scratch registers on the stack and return to the 101; calling ISR. */ 102; 103__tx_thread_nested_save: ; Label is for special nested interrupt case from idle system save below 104 st r30, [sp, 136] ; Save r30 105 st r25, [sp, 32] ; Save r25 106 st r12, [sp, 84] ; Save r12 107 st r11, [sp, 88] ; Save r11 108 st r10, [sp, 92] ; Save r10 109 st r9, [sp, 96] ; Save r9 110 st r8, [sp, 100] ; Save r8 111 st r7, [sp, 104] ; Save r7 112 st r6, [sp, 108] ; Save r6 113 st r5, [sp, 112] ; Save r5 114 st r4, [sp, 116] ; Save r4 115 lr r10, [LP_START] ; Pickup LP_START 116 lr r9, [LP_END] ; Pickup LP_END 117 st LP_COUNT, [sp, 12] ; Save LP_COUNT 118 st r10, [sp, 4] ; Save LP_START 119 st r9, [sp, 8] ; Save LP_END 120 .ifdef TX_ENABLE_ACC 121 st r58, [sp, 140] ; Save r58 122 st r59, [sp, 144] ; Save r59 123 .endif 124 lr r0, [BTA] ; Pickup BTA 125 st r0, [sp, 156] ; Save BTA 126 127; 128; /* Return to the ISR. */ 129; 130 .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 131; 132; /* Call the ISR enter function to indicate an ISR is executing. */ 133; 134 sub sp, sp, 32 ; Allocating some space on the stack 135 st blink, [sp, 16] ; Save blink 136 bl.d _tx_execution_isr_enter ; Call the ISR enter function 137 nop ; Delay slot 138 ld blink, [sp, 16] ; Recover blink 139 add sp, sp, 32 ; Recover the stack space 140 .endif 141; 142 143 j.d [blink] ; Return to Level 1 ISR 144 st ilink, [sp, 20] ; Save ilink 145; 146__tx_thread_not_nested_save: 147; } 148; 149; /* Otherwise, not nested, check to see if a thread was running. */ 150; else if (_tx_thread_current_ptr) 151; { 152; 153 add r0, r0, 1 ; Increment the nested interrupt count 154 st r0, [gp, _tx_thread_system_state@sda] ; Update system state 155 ld r1, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread pointer 156 st r30, [sp, 136] ; Save r30 157 st r25, [sp, 32] ; Save r25 158 st r12, [sp, 84] ; Save r12 159 st r11, [sp, 88] ; Save r11 160 breq r1, 0, __tx_thread_idle_system_save ; If no thread is running, idle system was 161 ; interrupted. 162; 163; /* Save minimal context of interrupted thread. */ 164; 165 st r10, [sp, 92] ; Save r10 166 st r9, [sp, 96] ; Save r9 167 st r8, [sp, 100] ; Save r8 168 st r7, [sp, 104] ; Save r7 169 st r6, [sp, 108] ; Save r6 170 st r5, [sp, 112] ; Save r5 171 st r4, [sp, 116] ; Save r4 172 lr r10, [LP_START] ; Pickup LP_START 173 lr r9, [LP_END] ; Pickup LP_END 174 st LP_COUNT, [sp, 12] ; Save LP_COUNT 175 st r10, [sp, 4] ; Save LP_START 176 st r9, [sp, 8] ; Save LP_END 177 st ilink, [sp, 20] ; Save ilink 178 .ifdef TX_ENABLE_ACC 179 st r58, [sp, 140] ; Save r58 180 st r59, [sp, 144] ; Save r59 181 .endif 182 lr r0, [BTA] ; Pickup BTA 183 st r0, [sp, 156] ; Save BTA 184; 185; /* Save the current stack pointer in the thread's control block. */ 186; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; 187; 188 st sp, [r1, 8] ; Save thread's stack pointer 189 190 .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 191; 192; /* Call the ISR enter function to indicate an ISR is executing. */ 193; 194 sub sp, sp, 32 ; Allocating some space on the stack 195 st blink, [sp, 16] ; Save blink 196 bl.d _tx_execution_isr_enter ; Call the ISR enter function 197 nop ; Delay slot 198 ld blink, [sp, 16] ; Recover blink 199 add sp, sp, 32 ; Recover the stack space 200 .endif 201 202; 203; /* Switch to the system stack. */ 204; sp = _tx_thread_system_stack_ptr; 205; 206 j_s.d [blink] ; Return to calling ISR 207 ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack 208; 209; } 210; else 211; { 212; 213__tx_thread_idle_system_save: 214; 215; /* Interrupt occurred in the scheduling loop. */ 216; 217 .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 218; 219; /* Call the ISR enter function to indicate an ISR is executing. */ 220; 221 sub sp, sp, 32 ; Allocating some space on the stack 222 st blink, [sp, 16] ; Save blink 223 bl.d _tx_execution_isr_enter ; Call the ISR enter function 224 nop ; Delay slot 225 ld blink, [sp, 16] ; Recover blink 226 add sp, sp, 32 ; Recover the stack space 227 .endif 228; 229; /* See if we have a special nesting condition. This happens when the higher priority 230; interrupt occurs before the nested interrupt logic is valid. */ 231; 232 lr r0, [AUX_IRQ_ACT] ; Pickup the interrupt active register 233 neg r1, r0 ; Negate 234 and r1, r0, r1 ; See if there are any other interrupts present 235 brne r0, r1, __tx_thread_nested_save ; If more interrupts, go into the nested interrupt save logic 236; 237; /* Not much to do here, just adjust the stack pointer, and return to 238; ISR processing. */ 239; 240 j_s.d [blink] ; Return to ISR 241 add sp, sp, 160 ; Recover stack space 242; 243; } 244;} 245 .end 246