summaryrefslogtreecommitdiff
path: root/ports/arm11/iar/src/tx_thread_context_save.s
diff options
context:
space:
mode:
Diffstat (limited to 'ports/arm11/iar/src/tx_thread_context_save.s')
-rw-r--r--ports/arm11/iar/src/tx_thread_context_save.s222
1 files changed, 222 insertions, 0 deletions
diff --git a/ports/arm11/iar/src/tx_thread_context_save.s b/ports/arm11/iar/src/tx_thread_context_save.s
new file mode 100644
index 00000000..71d7347e
--- /dev/null
+++ b/ports/arm11/iar/src/tx_thread_context_save.s
@@ -0,0 +1,222 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) 1996-2018 by Express Logic Inc. */
+;/* */
+;/* This software is copyrighted by and is the sole property of Express */
+;/* Logic, Inc. All rights, title, ownership, or other interests */
+;/* in the software remain the property of Express Logic, Inc. This */
+;/* software may only be used in accordance with the corresponding */
+;/* license agreement. Any unauthorized use, duplication, transmission, */
+;/* distribution, or disclosure of this software is expressly forbidden. */
+;/* */
+;/* This Copyright notice may not be removed or modified without prior */
+;/* written consent of Express Logic, Inc. */
+;/* */
+;/* Express Logic, Inc. reserves the right to modify this software */
+;/* without notice. */
+;/* */
+;/* Express Logic, Inc. [email protected] */
+;/* 11423 West Bernardo Court http://www.expresslogic.com */
+;/* San Diego, CA 92127 */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled
+#else
+DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled
+#endif
+
+
+ EXTERN _tx_thread_system_state
+ EXTERN _tx_thread_current_ptr
+ EXTERN __tx_irq_processing_return
+ EXTERN _tx_execution_isr_enter
+;
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save ARM11/IAR */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Express Logic, Inc. */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ RSEG .text:CODE:NOROOT(2)
+ PUBLIC _tx_thread_context_save
+ CODE32
+_tx_thread_context_save
+;
+; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+; out, we are in IRQ mode, and all registers are intact. */
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+ STMDB sp!, {r0-r3} ; Save some working registers
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ MRS r0, CPSR ; Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR
+ MSR CPSR_cxsf, r0 ; Disable interrupts
+#endif
+ LDR r3, =_tx_thread_system_state ; Pickup address of system state var
+ LDR r2, [r3, #0] ; Pickup system state
+ CMP r2, #0 ; Is this the first interrupt?
+ BEQ __tx_thread_not_nested_save ; Yes, not a nested context save
+;
+; /* Nested interrupt condition. */
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3, #0] ; Store it back in the variable
+;
+; /* Save the rest of the scratch registers on the stack and return to the
+; calling ISR. */
+;
+ MRS r0, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r0, r10, r12, lr} ; Store other registers
+;
+; /* Return to the ISR. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+#endif
+
+ B __tx_irq_processing_return ; Continue IRQ processing
+;
+__tx_thread_not_nested_save
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3, #0] ; Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1, #0] ; Pickup current thread pointer
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; If so, interrupt occured in
+ ; scheduling loop - nothing needs saving!
+;
+; /* Save minimal context of interrupted thread. */
+;
+ MRS r2, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r2, r10, r12, lr} ; Store other registers
+;
+; /* Save the current stack pointer in the thread's control block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+;
+; /* Switch to the system stack. */
+; sp = _tx_thread_system_stack_ptr;
+;
+ MOV r10, #0 ; Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+#endif
+
+ B __tx_irq_processing_return ; Continue IRQ processing
+;
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+; /* Not much to do here, just adjust the stack pointer, and return to IRQ
+; processing. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+#endif
+
+ ADD sp, sp, #16 ; Recover saved registers
+ B __tx_irq_processing_return ; Continue IRQ processing
+;
+; }
+;}
+;
+
+;
+;
+ END
+