diff options
| author | Scott Larson <[email protected]> | 2020-08-07 17:47:29 -0700 |
|---|---|---|
| committer | Scott Larson <[email protected]> | 2020-08-07 17:47:29 -0700 |
| commit | 6a018a4cfda937c0d8cbdee761187c5c5843e115 (patch) | |
| tree | cc9990878ab97ac171a192fe1c2922e752feee99 /ports/arm11/iar/src | |
| parent | 608f55f0d120886e0eddf7e39cf3c3b6f06bd08c (diff) | |
add ARM11v6.0.1_rel
Diffstat (limited to 'ports/arm11/iar/src')
17 files changed, 3571 insertions, 0 deletions
diff --git a/ports/arm11/iar/src/tx_iar.c b/ports/arm11/iar/src/tx_iar.c new file mode 100644 index 00000000..95592d4b --- /dev/null +++ b/ports/arm11/iar/src/tx_iar.c @@ -0,0 +1,816 @@ +/**************************************************************************/ +/* */ +/* 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 www.expresslogic.com */ +/* San Diego, CA 92127 */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** IAR Multithreaded Library Support */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define TX_SOURCE_CODE + + +/* Define IAR library for tools prior to version 8. */ + +#if (__VER__ < 8000000) + + +/* IAR version 7 and below. */ + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_initialize.h" +#include "tx_thread.h" +#include "tx_mutex.h" + + +/* This implementation requires that the following macros are defined in the + tx_port.h file and <yvals.h> is included with the following code segments: + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include <yvals.h> +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + + This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the + application. + + Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected. +*/ + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#include <yvals.h> + + +#if _MULTI_THREAD + +TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK]; +UINT __tx_iar_system_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_system_lock_no_mutexes; +UINT __tx_iar_system_lock_internal_errors; +UINT __tx_iar_system_lock_isr_caller; + + +/* Define the TLS access function for the IAR library. */ + +void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp) +{ + +char _DLIB_TLS_MEMORY *p = 0; + + /* Is there a current thread? */ + if (_tx_thread_current_ptr) + p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer; + else + p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD"); + p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp); + return (void _DLIB_TLS_MEMORY *) p; +} + + +/* Define mutexes for IAR library. */ + +void __iar_system_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_LOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_system_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_system_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_system_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_system_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_system_Mtxlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } +} + +void __iar_system_Mtxunlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } +} + + +#if _DLIB_FILE_DESCRIPTOR + +TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK]; +UINT __tx_iar_file_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_file_lock_no_mutexes; +UINT __tx_iar_file_lock_internal_errors; +UINT __tx_iar_file_lock_isr_caller; + + +void __iar_file_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_FLOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_file_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_file_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_file_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_file_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_file_Mtxlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} + +void __iar_file_Mtxunlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} +#endif /* _DLIB_FILE_DESCRIPTOR */ + +#endif /* _MULTI_THREAD */ + +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ + +#else /* IAR version 8 and above. */ + + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_initialize.h" +#include "tx_thread.h" +#include "tx_mutex.h" + +/* This implementation requires that the following macros are defined in the + tx_port.h file and <yvals.h> is included with the following code segments: + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include <yvals.h> +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + + This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the + application. + + Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected. +*/ + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#include <DLib_threads.h> + + +void * __aeabi_read_tp(); + +void* _tx_iar_create_per_thread_tls_area(); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); + +#pragma section="__iar_tls$$DATA" + +/* Define the TLS access function for the IAR library. */ +void * __aeabi_read_tp(void) +{ + void *p = 0; + TX_THREAD *thread_ptr = _tx_thread_current_ptr; + if (thread_ptr) + { + p = thread_ptr->tx_thread_iar_tls_pointer; + } + else + { + p = __section_begin("__iar_tls$$DATA"); + } + return p; +} + +/* Define the TLS creation and destruction to use malloc/free. */ + +void* _tx_iar_create_per_thread_tls_area() +{ + UINT tls_size = __iar_tls_size(); + + /* Get memory for TLS. */ + void *p = malloc(tls_size); + + /* Initialize TLS-area and run constructors for objects in TLS */ + __iar_tls_init(p); + return p; +} + +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr) +{ + /* Destroy objects living in TLS */ + __call_thread_dtors(); + free(tls_ptr); +} + +#ifndef _MAX_LOCK +#define _MAX_LOCK 4 +#endif + +static TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK]; +static UINT __tx_iar_system_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_system_lock_no_mutexes; +UINT __tx_iar_system_lock_internal_errors; +UINT __tx_iar_system_lock_isr_caller; + + +/* Define mutexes for IAR library. */ + +void __iar_system_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_LOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_system_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_system_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_system_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_system_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_system_Mtxlock(__iar_Rmtx *m) +{ + if (*m) + { + UINT status; + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } + } +} + +void __iar_system_Mtxunlock(__iar_Rmtx *m) +{ + if (*m) + { + UINT status; + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } + } +} + + +#if _DLIB_FILE_DESCRIPTOR + +#include <stdio.h> /* Added to get access to FOPEN_MAX */ +#ifndef _MAX_FLOCK +#define _MAX_FLOCK FOPEN_MAX /* Define _MAX_FLOCK as the maximum number of open files */ +#endif + + +TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK]; +UINT __tx_iar_file_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_file_lock_no_mutexes; +UINT __tx_iar_file_lock_internal_errors; +UINT __tx_iar_file_lock_isr_caller; + + +void __iar_file_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_FLOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_file_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_file_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_file_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_file_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_file_Mtxlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} + +void __iar_file_Mtxunlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} +#endif /* _DLIB_FILE_DESCRIPTOR */ + +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ + +#endif /* IAR version 8 and above. */ diff --git a/ports/arm11/iar/src/tx_thread_context_restore.s b/ports/arm11/iar/src/tx_thread_context_restore.s new file mode 100644 index 00000000..a66ecdc5 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_context_restore.s @@ -0,0 +1,258 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +SVC_MODE DEFINE 0xD3 ; SVC mode +IRQ_MODE DEFINE 0xD2 ; IRQ mode +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; Disable IRQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +THUMB_MASK DEFINE 0x20 ; Thumb bit mask +SVC_MODE_BITS DEFINE 0x13 ; SVC mode value + +; + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN _tx_thread_execute_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_thread_schedule + EXTERN _tx_thread_preempt_disable + EXTERN _tx_execution_isr_exit +; +; + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the interrupt context if it is processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_restore(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_context_restore + CODE32 +_tx_thread_context_restore +; +; /* Lockout interrupts. */ +; + MRS r3, CPSR ; Pickup current CPSR + ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value + MSR CPSR_cxsf, r0 ; Lockout interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR exit function to indicate an ISR is complete. */ +; + BL _tx_execution_isr_exit ; Call the ISR exit function +#endif +; +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { +; + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + SUB r2, r2, #1 ; Decrement the counter + STR r2, [r3, #0] ; Store the counter + CMP r2, #0 ; Was this the first interrupt? + BEQ __tx_thread_not_nested_restore ; If so, not a nested restore +; +; /* Interrupts are nested. */ +; +; /* Just recover the saved registers and return to the point of +; interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +__tx_thread_not_nested_restore +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { +; + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup actual current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_restore ; Yes, idle system was interrupted +; + LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address + LDR r2, [r3, #0] ; Pickup actual preempt disable flag + CMP r2, #0 ; Is it set? + BNE __tx_thread_no_preempt_restore ; Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr + LDR r2, [r3, #0] ; Pickup actual execute thread pointer + CMP r0, r2 ; Is the same thread highest priority? + BNE __tx_thread_preempt_restore ; No, preemption needs to happen +; +; +__tx_thread_no_preempt_restore +; +; /* Restore interrupted thread or ISR. */ +; +; /* Pickup the saved stack pointer. */ +; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +; +; /* Recover the saved context and return to the point of interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +; else +; { +__tx_thread_preempt_restore +; + LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers + MOV r1, lr ; Save lr (point of interrupt) + MOV r2, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r2 ; Enter SVC mode + STR r1, [sp, #-4]! ; Save point of interrupt + STMDB sp!, {r4-r12, lr} ; Save upper half of registers + MOV r4, r3 ; Save SPSR in r4 + MOV r2, #IRQ_MODE ; Build IRQ mode CPSR + MSR CPSR_c, r2 ; Enter IRQ mode + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOV r5, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r5 ; Enter SVC mode + STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack + MOV r3, #1 ; Build interrupt stack type + STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + STR sp, [r0, #8] ; Save stack pointer in thread control + ; block + BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 ; Lockout interrupts +; +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r2, [r3, #0] ; Pickup time-slice + CMP r2, #0 ; Is it active? + BEQ __tx_thread_dont_save_ts ; No, don't save it +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r2, [r0, #24] ; Save thread's time-slice + MOV r2, #0 ; Clear value + STR r2, [r3, #0] ; Disable global time-slice flag +; +; } +__tx_thread_dont_save_ts +; +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV r0, #0 ; NULL value + STR r0, [r1, #0] ; Clear current thread pointer +; +; /* Return to the scheduler. */ +; _tx_thread_schedule(); +; + B _tx_thread_schedule ; Return to scheduler +; } +; +__tx_thread_idle_system_restore +; +; /* Just return back to the scheduler! */ +; + MRS r3, CPSR ; Pickup current CPSR + BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 ; Lockout interrupts + B _tx_thread_schedule ; Return to scheduler +;} +; +; + END + 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 + diff --git a/ports/arm11/iar/src/tx_thread_fiq_context_restore.s b/ports/arm11/iar/src/tx_thread_fiq_context_restore.s new file mode 100644 index 00000000..a8f9f0bd --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_context_restore.s @@ -0,0 +1,269 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +SVC_MODE DEFINE 0xD3 ; SVC mode +FIQ_MODE DEFINE 0xD1 ; FIQ mode +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +THUMB_MASK DEFINE 0x20 ; Thumb bit mask +IRQ_MODE_BITS DEFINE 0x12 ; IRQ mode bits +SVC_MODE_BITS DEFINE 0x13 ; SVC mode value + +; + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN _tx_thread_execute_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_thread_schedule + EXTERN _tx_thread_preempt_disable + EXTERN _tx_execution_isr_exit +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_restore ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the fiq interrupt context when processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* FIQ ISR Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_context_restore(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_context_restore + CODE32 +_tx_thread_fiq_context_restore +; +; /* Lockout interrupts. */ +; + MRS r3, CPSR ; Pickup current CPSR + ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value + MSR CPSR_cxsf, r0 ; Lockout interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR exit function to indicate an ISR is complete. */ +; + BL _tx_execution_isr_exit ; Call the ISR exit function +#endif +; +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { +; + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3] ; Pickup system state + SUB r2, r2, #1 ; Decrement the counter + STR r2, [r3] ; Store the counter + CMP r2, #0 ; Was this the first interrupt? + BEQ __tx_thread_fiq_not_nested_restore ; If so, not a nested restore +; +; /* Interrupts are nested. */ +; +; /* Just recover the saved registers and return to the point of +; interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +__tx_thread_fiq_not_nested_restore +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { +; + LDR r1, [sp] ; Pickup the saved SPSR + MOV r2, #MODE_MASK ; Build mask to isolate the interrupted mode + AND r1, r1, r2 ; Isolate mode bits + CMP r1, #IRQ_MODE_BITS ; Was an interrupt taken in IRQ mode before we + ; got to context save? */ + BEQ __tx_thread_fiq_no_preempt_restore ; Yes, just go back to point of interrupt + + + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup actual current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_fiq_idle_system_restore ; Yes, idle system was interrupted + + LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address + LDR r2, [r3] ; Pickup actual preempt disable flag + CMP r2, #0 ; Is it set? + BNE __tx_thread_fiq_no_preempt_restore ; Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr + LDR r2, [r3] ; Pickup actual execute thread pointer + CMP r0, r2 ; Is the same thread highest priority? + BNE __tx_thread_fiq_preempt_restore ; No, preemption needs to happen + + +__tx_thread_fiq_no_preempt_restore +; +; /* Restore interrupted thread or ISR. */ +; +; /* Pickup the saved stack pointer. */ +; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +; +; /* Recover the saved context and return to the point of interrupt. */ +; + LDMIA sp!, {r0, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +; else +; { +__tx_thread_fiq_preempt_restore +; + LDMIA sp!, {r3, lr} ; Recover temporarily saved registers + MOV r1, lr ; Save lr (point of interrupt) + MOV r2, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r2 ; Enter SVC mode + STR r1, [sp, #-4]! ; Save point of interrupt + STMDB sp!, {r4-r12, lr} ; Save upper half of registers + MOV r4, r3 ; Save SPSR in r4 + MOV r2, #FIQ_MODE ; Build FIQ mode CPSR + MSR CPSR_cxsf, r2 ; Re-enter FIQ mode + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOV r5, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r5 ; Enter SVC mode + STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack + MOV r3, #1 ; Build interrupt stack type + STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup current thread pointer + STR sp, [r0, #8] ; Save stack pointer in thread control + ; block */ + BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 ; Lockout interrupts +; +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r2, [r3] ; Pickup time-slice + CMP r2, #0 ; Is it active? + BEQ __tx_thread_fiq_dont_save_ts ; No, don't save it +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r2, [r0, #24] ; Save thread's time-slice + MOV r2, #0 ; Clear value + STR r2, [r3] ; Disable global time-slice flag +; +; } +__tx_thread_fiq_dont_save_ts +; +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV r0, #0 ; NULL value + STR r0, [r1] ; Clear current thread pointer +; +; /* Return to the scheduler. */ +; _tx_thread_schedule(); +; + B _tx_thread_schedule ; Return to scheduler +; } +; +__tx_thread_fiq_idle_system_restore +; +; /* Just return back to the scheduler! */ +; + ADD sp, sp, #24 ; Recover FIQ stack space + MRS r3, CPSR ; Pickup current CPSR + BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 ; Lockout interrupts + B _tx_thread_schedule ; Return to scheduler +; +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_context_save.s b/ports/arm11/iar/src/tx_thread_fiq_context_save.s new file mode 100644 index 00000000..7745f756 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_context_save.s @@ -0,0 +1,215 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN __tx_fiq_processing_return + EXTERN _tx_execution_isr_enter +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_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_fiq_context_save(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_context_save + CODE32 +_tx_thread_fiq_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 + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_fiq_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3] ; 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_fiq_processing_return ; Continue FIQ processing +; +__tx_thread_fiq_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] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred 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, lr} ; Store other registers, Note that we don't +; ; need to save sl and ip since FIQ has +; ; copies of these registers. Nested +; ; interrupt processing does need to save +; ; these 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_fiq_processing_return ; Continue FIQ processing +; +; } +; else +; { +; +__tx_thread_fiq_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; +#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 +; +; /* Not much to do here, save the current SPSR and LR for possible +; use in IRQ interrupted in idle system conditions, and return to +; FIQ interrupt processing. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, lr} ; Store other registers that will get used +; ; or stripped off the stack in context +; ; restore + B __tx_fiq_processing_return ; Continue FIQ processing +; +; } +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_nesting_end.s b/ports/arm11/iar/src/tx_thread_fiq_nesting_end.s new file mode 100644 index 00000000..008b3b40 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_nesting_end.s @@ -0,0 +1,121 @@ +;/**************************************************************************/ +;/* */ +;/* 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 ; Disable IRQ & FIQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +FIQ_MODE_BITS DEFINE 0x11 ; FIQ mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_end ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from FIQ mode after */ +;/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */ +;/* processing from system mode back to FIQ mode prior to the ISR */ +;/* calling _tx_thread_fiq_context_restore. Note that this function */ +;/* assumes the system stack pointer is in the same position after */ +;/* nesting start function was called. */ +;/* */ +;/* This function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with FIQ interrupts disabled. */ +;/* */ +;/* 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_fiq_nesting_end(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_nesting_end + CODE32 +_tx_thread_fiq_nesting_end + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value + MSR CPSR_cxsf, r0 ; Disable interrupts + LDR lr, [sp] ; Pickup saved lr + ADD sp, sp, #4 ; Adjust stack pointer + BIC r0, r0, #MODE_MASK ; Clear mode bits + ORR r0, r0, #FIQ_MODE_BITS ; Build IRQ mode CPSR + MSR CPSR_cxsf, r0 ; Re-enter IRQ mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_nesting_start.s b/ports/arm11/iar/src/tx_thread_fiq_nesting_start.s new file mode 100644 index 00000000..f4411d08 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_nesting_start.s @@ -0,0 +1,114 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +FIQ_DISABLE DEFINE 0x40 ; FIQ disable bit +MODE_MASK DEFINE 0x1F ; Mode mask +SYS_MODE_BITS DEFINE 0x1F ; System mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_start ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from FIQ mode after */ +;/* _tx_thread_fiq_context_save has been called and switches the FIQ */ +;/* processing to the system mode so nested FIQ interrupt processing */ +;/* is possible (system mode has its own "lr" register). Note that */ +;/* this function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with FIQ interrupts enabled. */ +;/* */ +;/* 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_fiq_nesting_start(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_nesting_start + CODE32 +_tx_thread_fiq_nesting_start + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + BIC r0, r0, #MODE_MASK ; Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + STR lr, [sp, #-4]! ; Push the system mode lr on the system mode stack + BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_interrupt_control.s b/ports/arm11/iar/src/tx_thread_interrupt_control.s new file mode 100644 index 00000000..f80e31d8 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_interrupt_control.s @@ -0,0 +1,115 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +INT_MASK DEFINE 0xC0 ; Interrupt bit mask +#else +INT_MASK DEFINE 0x80 ; Interrupt bit mask +#endif +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_control ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for changing the interrupt lockout */ +;/* posture of the system. */ +;/* */ +;/* INPUT */ +;/* */ +;/* new_posture New interrupt lockout posture */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_control(UINT new_posture) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_interrupt_control + CODE32 +_tx_thread_interrupt_control +; +; /* Pickup current interrupt lockout posture. */ +; + MRS r3, CPSR ; Pickup current CPSR + BIC r1, r3, #INT_MASK ; Clear interrupt lockout bits + ORR r1, r1, r0 ; Or-in new interrupt lockout bits +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r1 ; Setup new CPSR + AND r0, r3, #INT_MASK ; Return previous interrupt mask +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +; +;} +; +; + END diff --git a/ports/arm11/iar/src/tx_thread_interrupt_disable.s b/ports/arm11/iar/src/tx_thread_interrupt_disable.s new file mode 100644 index 00000000..e3029ecb --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_interrupt_disable.s @@ -0,0 +1,113 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled +#else +DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled +#endif +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_disable ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for disabling interrupts */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_disable(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_interrupt_disable + CODE32 +_tx_thread_interrupt_disable??rA +_tx_thread_interrupt_disable +; +; /* Pickup current interrupt lockout posture. */ +; + MRS r0, CPSR ; Pickup current CPSR +; +; /* Mask interrupts. */ +; + ORR r1, r0, #DISABLE_INTS ; Mask interrupts + MSR CPSR_cxsf, r1 ; Setup new CPSR +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} +; +; + END diff --git a/ports/arm11/iar/src/tx_thread_interrupt_restore.s b/ports/arm11/iar/src/tx_thread_interrupt_restore.s new file mode 100644 index 00000000..0c0fdef0 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_interrupt_restore.s @@ -0,0 +1,99 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_restore ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for restoring interrupts to the state */ +;/* returned by a previous _tx_thread_interrupt_disable call. */ +;/* */ +;/* INPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;void _tx_thread_interrupt_restore(UINT old_posture) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_interrupt_restore + CODE32 +_tx_thread_interrupt_restore +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r0 ; Setup new CPSR +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} +; + END diff --git a/ports/arm11/iar/src/tx_thread_irq_nesting_end.s b/ports/arm11/iar/src/tx_thread_irq_nesting_end.s new file mode 100644 index 00000000..50da22c4 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_irq_nesting_end.s @@ -0,0 +1,122 @@ +;/**************************************************************************/ +;/* */ +;/* 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 ; Disable IRQ & FIQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +IRQ_MODE_BITS DEFINE 0x12 ; IRQ mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_end ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from IRQ mode after */ +;/* _tx_thread_irq_nesting_start has been called and switches the IRQ */ +;/* processing from system mode back to IRQ mode prior to the ISR */ +;/* calling _tx_thread_context_restore. Note that this function */ +;/* assumes the system stack pointer is in the same position after */ +;/* nesting start function was called. */ +;/* */ +;/* This function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with IRQ interrupts disabled. */ +;/* */ +;/* 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_irq_nesting_end(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_irq_nesting_end + CODE32 +_tx_thread_irq_nesting_end + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value + MSR CPSR_cxsf, r0 ; Disable interrupts + LDR lr, [sp] ; Pickup saved lr + ADD sp, sp, #4 ; Adjust stack pointer + BIC r0, r0, #MODE_MASK ; Clear mode bits + ORR r0, r0, #IRQ_MODE_BITS ; Build IRQ mode CPSR + MSR CPSR_cxsf, r0 ; Re-enter IRQ mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_irq_nesting_start.s b/ports/arm11/iar/src/tx_thread_irq_nesting_start.s new file mode 100644 index 00000000..eb1977cc --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_irq_nesting_start.s @@ -0,0 +1,114 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +IRQ_DISABLE DEFINE 0x80 ; IRQ disable bit +MODE_MASK DEFINE 0x1F ; Mode mask +SYS_MODE_BITS DEFINE 0x1F ; System mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_start ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from IRQ mode after */ +;/* _tx_thread_context_save has been called and switches the IRQ */ +;/* processing to the system mode so nested IRQ interrupt processing */ +;/* is possible (system mode has its own "lr" register). Note that */ +;/* this function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with IRQ interrupts enabled. */ +;/* */ +;/* 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_irq_nesting_start(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_irq_nesting_start + CODE32 +_tx_thread_irq_nesting_start + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + BIC r0, r0, #MODE_MASK ; Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + STR lr, [sp, #-4]! ; Push the system mode lr on the system mode stack + BIC r0, r0, #IRQ_DISABLE ; Build enable IRQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_schedule.s b/ports/arm11/iar/src/tx_thread_schedule.s new file mode 100644 index 00000000..db2d2591 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_schedule.s @@ -0,0 +1,183 @@ +;/**************************************************************************/ +;/* */ +;/* 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 +ENABLE_INTS DEFINE 0xC0 ; IRQ & FIQ Interrupts enabled mask +#else +ENABLE_INTS DEFINE 0x80 ; IRQ Interrupts enabled mask +#endif +; +; + EXTERN _tx_thread_execute_ptr + EXTERN _tx_thread_current_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_execution_thread_enter +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function waits for a thread control block pointer to appear in */ +;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ +;/* in the variable, the corresponding thread is resumed. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_initialize_kernel_enter ThreadX entry function */ +;/* _tx_thread_system_return Return to system from thread */ +;/* _tx_thread_context_restore Restore thread's context */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_schedule(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_schedule + CODE32 +_tx_thread_schedule??rA +_tx_thread_schedule +; +; /* Enable interrupts. */ +; + MRS r2, CPSR ; Pickup CPSR + BIC r0, r2, #ENABLE_INTS ; Clear the disable bit(s) + MSR CPSR_cxsf, r0 ; Enable interrupts +; +; /* Wait for a thread to execute. */ +; do +; { + LDR r1, =_tx_thread_execute_ptr ; Address of thread execute ptr +; +__tx_thread_schedule_loop +; + LDR r0, [r1, #0] ; Pickup next thread to execute + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_schedule_loop ; If so, keep looking for a thread +; +; } +; while(_tx_thread_execute_ptr == TX_NULL); +; +; /* Yes! We have a thread to execute. Lockout interrupts and +; transfer control to it. */ +; + MSR CPSR_cxsf, r2 ; Disable interrupts +; +; /* Setup the current thread pointer. */ +; _tx_thread_current_ptr = _tx_thread_execute_ptr; +; + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread + STR r0, [r1, #0] ; Setup current thread pointer +; +; /* Increment the run count for this thread. */ +; _tx_thread_current_ptr -> tx_thread_run_count++; +; + LDR r2, [r0, #4] ; Pickup run counter + LDR r3, [r0, #24] ; Pickup time-slice for this thread + ADD r2, r2, #1 ; Increment thread run-counter + STR r2, [r0, #4] ; Store the new run counter +; +; /* Setup time-slice, if present. */ +; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +; + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + ; variable + LDR sp, [r0, #8] ; Switch stack pointers + STR r3, [r2, #0] ; Setup time-slice +; +; /* Switch to the thread's stack. */ +; sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; +; +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the thread entry function to indicate the thread is executing. */ +; + BL _tx_execution_thread_enter ; Call the thread execution enter function +#endif +; +; /* Determine if an interrupt frame or a synchronous task suspension frame +; is present. */ +; + LDMIA sp!, {r0, r1} ; Pickup the stack type and saved CPSR + CMP r0, #0 ; Check for synchronous context switch + MSRNE SPSR_cxsf, r1 ; Setup SPSR for return + LDMNEIA sp!, {r0-r12, lr, pc}^ ; Return to point of thread interrupt + LDMIA sp!, {r4-r11, lr} ; Return to thread synchronously + MSR CPSR_cxsf, r1 ; Recover CPSR +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +; +;} +; + END + diff --git a/ports/arm11/iar/src/tx_thread_stack_build.s b/ports/arm11/iar/src/tx_thread_stack_build.s new file mode 100644 index 00000000..61b3f8a1 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_stack_build.s @@ -0,0 +1,170 @@ +;/**************************************************************************/ +;/* */ +;/* 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" +; +; +SVC_MODE DEFINE 0x13 ; SVC mode +#ifdef TX_ENABLE_FIQ_SUPPORT +CPSR_MASK DEFINE 0xDF ; Mask initial CPSR, IRQ & FIQ ints enabled +#else +CPSR_MASK DEFINE 0x9F ; Mask initial CPSR, IRQ ints enabled +#endif +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_stack_build ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function builds a stack frame on the supplied thread's stack. */ +;/* The stack frame results in a fake interrupt return to the supplied */ +;/* function pointer. */ +;/* */ +;/* INPUT */ +;/* */ +;/* thread_ptr Pointer to thread control blk */ +;/* function_ptr Pointer to return function */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_thread_create Create thread service */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_stack_build + + CODE32 +_tx_thread_stack_build +; +; +; /* Build a fake interrupt frame. The form of the fake interrupt stack +; on the ARM9 should look like the following after it is built: +; +; Stack Top: 1 Interrupt stack frame type +; CPSR Initial value for CPSR +; a1 (r0) Initial value for a1 +; a2 (r1) Initial value for a2 +; a3 (r2) Initial value for a3 +; a4 (r3) Initial value for a4 +; v1 (r4) Initial value for v1 +; v2 (r5) Initial value for v2 +; v3 (r6) Initial value for v3 +; v4 (r7) Initial value for v4 +; v5 (r8) Initial value for v5 +; sb (r9) Initial value for sb +; sl (r10) Initial value for sl +; fp (r11) Initial value for fp +; ip (r12) Initial value for ip +; lr (r14) Initial value for lr +; pc (r15) Initial value for pc +; 0 For stack backtracing +; +; Stack Bottom: (higher memory address) */ +; + LDR r2, [r0, #16] ; Pickup end of stack area + BIC r2, r2, #7 ; Ensure long-word alignment + SUB r2, r2, #76 ; Allocate space for the stack frame +; +; /* Actually build the stack frame. */ +; + MOV r3, #1 ; Build interrupt stack type + STR r3, [r2, #0] ; Store stack type + MOV r3, #0 ; Build initial register value + STR r3, [r2, #8] ; Store initial r0 + STR r3, [r2, #12] ; Store initial r1 + STR r3, [r2, #16] ; Store initial r2 + STR r3, [r2, #20] ; Store initial r3 + STR r3, [r2, #24] ; Store initial r4 + STR r3, [r2, #28] ; Store initial r5 + STR r3, [r2, #32] ; Store initial r6 + STR r3, [r2, #36] ; Store initial r7 + STR r3, [r2, #40] ; Store initial r8 + STR r3, [r2, #44] ; Store initial r9 + LDR r3, [r0, #12] ; Pickup stack starting address + STR r3, [r2, #48] ; Store initial r10 (sl) + MOV r3, #0 ; Build initial register value + STR r3, [r2, #52] ; Store initial r11 + STR r3, [r2, #56] ; Store initial r12 + STR r3, [r2, #60] ; Store initial lr + STR r1, [r2, #64] ; Store initial pc + STR r3, [r2, #68] ; 0 for back-trace + MRS r1, CPSR ; Pickup CPSR + BIC r1, r1, #CPSR_MASK ; Mask mode bits of CPSR + ORR r3, r1, #SVC_MODE ; Build CPSR, SVC mode, interrupts enabled + STR r3, [r2, #4] ; Store initial CPSR +; +; /* Setup stack pointer. */ +; thread_ptr -> tx_thread_stack_ptr = r2; +; + STR r2, [r0, #8] ; Save stack pointer in thread's + ; control block +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} + END + diff --git a/ports/arm11/iar/src/tx_thread_system_return.s b/ports/arm11/iar/src/tx_thread_system_return.s new file mode 100644 index 00000000..0c6198af --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_system_return.s @@ -0,0 +1,161 @@ +;/**************************************************************************/ +;/* */ +;/* 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_current_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_thread_schedule + EXTERN _tx_execution_thread_exit +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_system_return ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is target processor specific. It is used to transfer */ +;/* control from a thread back to the ThreadX system. Only a */ +;/* minimal context is saved since the compiler assumes temp registers */ +;/* are going to get slicked by a function call anyway. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling loop */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ThreadX components */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_system_return(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_system_return + CODE32 +_tx_thread_system_return??rA +_tx_thread_system_return +; +; /* Save minimal context on the stack. */ +; + MOV r0, #0 ; Build a solicited stack type + MRS r1, CPSR ; Pickup the CPSR + STMDB sp!, {r0-r1, r4-r11, lr} ; Save minimal context +; +; /* Lockout interrupts. */ +; + ORR r2, r1, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r2 ; Disable interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the thread exit function to indicate the thread is no longer executing. */ +; + BL _tx_execution_thread_exit ; Call the thread exit function +#endif + + LDR r3, =_tx_thread_current_ptr ; Pickup address of current ptr + LDR r0, [r3, #0] ; Pickup current thread pointer + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + LDR r1, [r2, #0] ; Pickup current time slice +; +; /* Save current stack and switch to system stack. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; sp = _tx_thread_system_stack_ptr; +; + STR sp, [r0, #8] ; Save thread stack pointer +; +; /* Determine if the time-slice is active. */ +; if (_tx_timer_time_slice) +; { +; + MOV r4, #0 ; Build clear value + CMP r1, #0 ; Is a time-slice active? + BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice +; +; /* Save time-slice for the thread and clear the current time-slice. */ +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r4, [r2, #0] ; Clear time-slice + STR r1, [r0, #24] ; Save current time-slice +; +; } +__tx_thread_dont_save_ts +; +; /* Clear the current thread pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + STR r4, [r3, #0] ; Clear current thread pointer + B _tx_thread_schedule ; Jump to scheduler! +; +;} + END + diff --git a/ports/arm11/iar/src/tx_thread_vectored_context_save.s b/ports/arm11/iar/src/tx_thread_vectored_context_save.s new file mode 100644 index 00000000..6bf9209c --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_vectored_context_save.s @@ -0,0 +1,207 @@ +;/**************************************************************************/ +;/* */ +;/* 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_execution_isr_enter +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_vectored_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_vectored_context_save(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_vectored_context_save + CODE32 +_tx_thread_vectored_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, the minimal context is already saved, and the +; lr register contains the return ISR address. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; +#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 +; +; /* Note: Minimal context of interrupted thread is already saved. */ +; +; /* 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 + + MOV pc, lr ; Return to caller +; +__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! +; +; /* Note: Minimal context of interrupted thread is already saved. */ +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_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 + + MOV pc, lr ; Return to caller +; +; } +; 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, #32 ; Recover saved registers + MOV pc, lr ; Return to caller +; +; } +;} + END + diff --git a/ports/arm11/iar/src/tx_timer_interrupt.s b/ports/arm11/iar/src/tx_timer_interrupt.s new file mode 100644 index 00000000..7bb4f09f --- /dev/null +++ b/ports/arm11/iar/src/tx_timer_interrupt.s @@ -0,0 +1,272 @@ +;/**************************************************************************/ +;/* */ +;/* 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 */ +;/** */ +;/** Timer */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_timer.h" +;#include "tx_thread.h" +; +; +;Define Assembly language external references... +; + EXTERN _tx_timer_time_slice + EXTERN _tx_timer_system_clock + EXTERN _tx_timer_current_ptr + EXTERN _tx_timer_list_start + EXTERN _tx_timer_list_end + EXTERN _tx_timer_expired_time_slice + EXTERN _tx_timer_expired + EXTERN _tx_thread_time_slice + EXTERN _tx_timer_expiration_process +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function processes the hardware timer interrupt. This */ +;/* processing includes incrementing the system clock and checking for */ +;/* time slice and/or timer expiration. If either is found, the */ +;/* interrupt context save/restore functions are called along with the */ +;/* expiration functions. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_timer_expiration_process Timer expiration processing */ +;/* _tx_thread_time_slice Time-slice interrupted thread */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* interrupt vector */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_timer_interrupt(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_timer_interrupt + CODE32 +_tx_timer_interrupt +; +; /* Upon entry to this routine, it is assumed that context save has already +; been called, and therefore the compiler scratch registers are available +; for use. */ +; +; /* Increment the system clock. */ +; _tx_timer_system_clock++; +; + LDR r1, =_tx_timer_system_clock ; Pickup address of system clock + LDR r0, [r1, #0] ; Pickup system clock + ADD r0, r0, #1 ; Increment system clock + STR r0, [r1, #0] ; Store new system clock +; +; /* Test for time-slice expiration. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup address of time-slice + LDR r2, [r3, #0] ; Pickup time-slice + CMP r2, #0 ; Is it non-active? + BEQ __tx_timer_no_time_slice ; Yes, skip time-slice processing +; +; /* Decrement the time_slice. */ +; _tx_timer_time_slice--; +; + SUB r2, r2, #1 ; Decrement the time-slice + STR r2, [r3, #0] ; Store new time-slice value +; +; /* Check for expiration. */ +; if (__tx_timer_time_slice == 0) +; + CMP r2, #0 ; Has it expired? + BNE __tx_timer_no_time_slice ; No, skip expiration processing +; +; /* Set the time-slice expired flag. */ +; _tx_timer_expired_time_slice = TX_TRUE; +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup address of expired flag + MOV r0, #1 ; Build expired value + STR r0, [r3, #0] ; Set time-slice expiration flag +; +; } +; +__tx_timer_no_time_slice +; +; /* Test for timer expiration. */ +; if (*_tx_timer_current_ptr) +; { +; + LDR r1, =_tx_timer_current_ptr ; Pickup current timer pointer addr + LDR r0, [r1, #0] ; Pickup current timer + LDR r2, [r0, #0] ; Pickup timer list entry + CMP r2, #0 ; Is there anything in the list? + BEQ __tx_timer_no_timer ; No, just increment the timer +; +; /* Set expiration flag. */ +; _tx_timer_expired = TX_TRUE; +; + LDR r3, =_tx_timer_expired ; Pickup expiration flag address + MOV r2, #1 ; Build expired value + STR r2, [r3, #0] ; Set expired flag + B __tx_timer_done ; Finished timer processing +; +; } +; else +; { +__tx_timer_no_timer +; +; /* No timer expired, increment the timer pointer. */ +; _tx_timer_current_ptr++; +; + ADD r0, r0, #4 ; Move to next timer +; +; /* Check for wrap-around. */ +; if (_tx_timer_current_ptr == _tx_timer_list_end) +; + LDR r3, =_tx_timer_list_end ; Pickup addr of timer list end + LDR r2, [r3, #0] ; Pickup list end + CMP r0, r2 ; Are we at list end? + BNE __tx_timer_skip_wrap ; No, skip wrap-around logic +; +; /* Wrap to beginning of list. */ +; _tx_timer_current_ptr = _tx_timer_list_start; +; + LDR r3, =_tx_timer_list_start ; Pickup addr of timer list start + LDR r0, [r3, #0] ; Set current pointer to list start +; +__tx_timer_skip_wrap +; + STR r0, [r1, #0] ; Store new current timer pointer +; } +; +__tx_timer_done +; +; +; /* See if anything has expired. */ +; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +; { +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of expired flag + LDR r2, [r3, #0] ; Pickup time-slice expired flag + CMP r2, #0 ; Did a time-slice expire? + BNE __tx_something_expired ; If non-zero, time-slice expired + LDR r1, =_tx_timer_expired ; Pickup addr of other expired flag + LDR r0, [r1, #0] ; Pickup timer expired flag + CMP r0, #0 ; Did a timer expire? + BEQ __tx_timer_nothing_expired ; No, nothing expired +; +__tx_something_expired +; +; + STMDB sp!, {r0, lr} ; Save the lr register on the stack + ; and save r0 just to keep 8-byte alignment +; +; /* Did a timer expire? */ +; if (_tx_timer_expired) +; { +; + LDR r1, =_tx_timer_expired ; Pickup addr of expired flag + LDR r0, [r1, #0] ; Pickup timer expired flag + CMP r0, #0 ; Check for timer expiration + BEQ __tx_timer_dont_activate ; If not set, skip timer activation +; +; /* Process timer expiration. */ +; _tx_timer_expiration_process(); +; + BL _tx_timer_expiration_process ; Call the timer expiration handling routine +; +; } +__tx_timer_dont_activate +; +; /* Did time slice expire? */ +; if (_tx_timer_expired_time_slice) +; { +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of time-slice expired + LDR r2, [r3, #0] ; Pickup the actual flag + CMP r2, #0 ; See if the flag is set + BEQ __tx_timer_not_ts_expiration ; No, skip time-slice processing +; +; /* Time slice interrupted thread. */ +; _tx_thread_time_slice(); + + BL _tx_thread_time_slice ; Call time-slice processing +; +; } +; +__tx_timer_not_ts_expiration +; +; + LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for + ; the 8-byte stack alignment +; +; } +; +__tx_timer_nothing_expired +; +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +; +;} + END + |
