From bc8bed494d3a37eea022c1385008bdab991f3370 Mon Sep 17 00:00:00 2001 From: yajunxiaMS <120770040+yajunxiaMS@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:35:31 +0800 Subject: [PATCH] =?UTF-8?q?Added=20thumb=20mode=20support=20under=20IAR=20?= =?UTF-8?q?for=20module=20manager=20on=20Cortex-A7=20pl=E2=80=A6=20(#289)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added thumb mode support under IAR for module manager on Cortex-A7 platform. * update code for comments. --- .../src/txm_module_manager_thread_create.c | 10 +- .../gnu/example_build/txm_module_preamble.s | 12 +- .../cortex_a7/gnu/inc/txm_module_port.h | 2 +- .../src/tx_thread_context_save.s | 4 +- .../src/tx_thread_stack_build.s | 2 + .../iar/example_build/sample_threadx_module.c | 5 - .../example_build/sample_threadx_module.ewp | 12 +- .../sample_threadx_module_manager.ewd | 8 +- .../sample_threadx_module_manager.ewp | 12 +- .../cortex_a7/iar/example_build/tx.ewp | 4 +- .../example_build/tx_initialize_low_level.s | 9 +- .../cortex_a7/iar/example_build/txm.ewp | 18 +- .../iar/example_build/txm_module_preamble.s | 10 +- ports_module/cortex_a7/iar/inc/tx_port.h | 60 +-- .../cortex_a7/iar/inc/txm_module_port.h | 17 +- .../src/tx_thread_context_restore.s | 264 ++++------ .../src/tx_thread_context_save.s | 128 ++--- .../src/tx_thread_fiq_context_restore.s | 51 +- .../src/tx_thread_fiq_context_save.s | 9 +- .../src/tx_thread_fiq_nesting_end.s | 13 +- .../src/tx_thread_fiq_nesting_start.s | 10 +- .../src/tx_thread_interrupt_control.s | 48 +- .../src/tx_thread_interrupt_disable.s | 11 +- .../src/tx_thread_interrupt_restore.s | 39 +- .../src/tx_thread_irq_nesting_end.s | 9 +- .../src/tx_thread_irq_nesting_start.s | 9 +- .../module_manager/src/tx_thread_schedule.s | 456 +++++++++++------- .../src/tx_thread_stack_build.s | 96 ++-- .../src/tx_thread_system_return.s | 112 ++--- .../src/tx_thread_vectored_context_save.s | 9 +- .../module_manager/src/tx_timer_interrupt.s | 13 +- .../txm_module_manager_thread_stack_build.s | 19 +- .../src/txm_module_manager_user_mode_entry.s | 22 +- 33 files changed, 809 insertions(+), 694 deletions(-) diff --git a/common_modules/module_manager/src/txm_module_manager_thread_create.c b/common_modules/module_manager/src/txm_module_manager_thread_create.c index 2f50cfd7..0ff76936 100644 --- a/common_modules/module_manager/src/txm_module_manager_thread_create.c +++ b/common_modules/module_manager/src/txm_module_manager_thread_create.c @@ -94,9 +94,11 @@ /* 03-08-2023 Scott Larson Check module stack for */ /* overlap, */ /* resulting in version 6.2.1 */ -/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* xx-xx-xxxx Xiuwen Cai, Yajun xia Modified comment(s), */ /* added option for random */ /* number stack filling, */ +/* fixed the kernel stack */ +/* allocation issue, */ /* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -327,9 +329,8 @@ ULONG i; /* Initialize thread control block to all zeros. */ TX_MEMSET(thread_ptr, 0, sizeof(TX_THREAD)); -#if TXM_MODULE_MEMORY_PROTECTION - /* If this is a memory protected module, allocate a kernel stack. */ - if((module_instance -> txm_module_instance_property_flags) & TXM_MODULE_MEMORY_PROTECTION) + /* If the thread runs on user mode, allocate the kernel stack for syscall. */ + if((module_instance -> txm_module_instance_property_flags) & TXM_MODULE_USER_MODE) { ULONG status; @@ -354,6 +355,7 @@ ULONG i; thread_ptr -> tx_thread_module_kernel_stack_size = TXM_MODULE_KERNEL_STACK_SIZE; } +#if TXM_MODULE_MEMORY_PROTECTION /* Place the stack parameters into the thread's control block. */ thread_ptr -> tx_thread_module_stack_start = stack_start; thread_ptr -> tx_thread_module_stack_size = stack_size; diff --git a/ports_module/cortex_a7/gnu/example_build/txm_module_preamble.s b/ports_module/cortex_a7/gnu/example_build/txm_module_preamble.s index 663c448f..7678628b 100644 --- a/ports_module/cortex_a7/gnu/example_build/txm_module_preamble.s +++ b/ports_module/cortex_a7/gnu/example_build/txm_module_preamble.s @@ -14,14 +14,18 @@ __txm_module_preamble: .dc.l 0x1 // Module Minor Version .dc.l 32 // Module Preamble Size in 32-bit words .dc.l 0x12345678 // Module ID (application defined) - .dc.l 0x01000001 // Module Properties where: + .dc.l 0x02000001 // Module Properties where: // Bits 31-24: Compiler ID // 0 -> IAR // 1 -> RVDS // 2 -> GNU - // Bits 23-1: Reserved - // Bit 0: 0 -> Privileged mode execution (no MMU protection) - // 1 -> User mode execution (MMU protection) + // Bits 23-3: Reserved + // Bit 2: 0 -> Disable shared/external memory access + // 1 -> Enable shared/external memory access + // Bit 1: 0 -> No MPU protection + // 1 -> MPU protection (must have user mode selected - bit 0 set) + // Bit 0: 0 -> Privileged mode execution + // 1 -> User mode execution .dc.l _txm_module_thread_shell_entry // Module Shell Entry Point .dc.l demo_module_start // Module Start Thread Entry Point .dc.l 0 // Module Stop Thread Entry Point diff --git a/ports_module/cortex_a7/gnu/inc/txm_module_port.h b/ports_module/cortex_a7/gnu/inc/txm_module_port.h index d509303d..ec94b86e 100644 --- a/ports_module/cortex_a7/gnu/inc/txm_module_port.h +++ b/ports_module/cortex_a7/gnu/inc/txm_module_port.h @@ -410,7 +410,7 @@ UINT _txm_module_manager_inside_data_check(ULONG pointer); #define TXM_MODULE_MANAGER_VERSION_ID \ CHAR _txm_module_manager_version_id[] = \ - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A7/MMU/GNU Version 6.2.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A7/MMU/GNU Version 6.x *"; #endif diff --git a/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_context_save.s b/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_context_save.s index 65c3ac39..effcc99c 100644 --- a/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_context_save.s +++ b/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_context_save.s @@ -30,7 +30,9 @@ .global _tx_thread_system_state .global _tx_thread_current_ptr .global __tx_irq_processing_return - +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + .global _tx_execution_isr_enter +#endif /* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save since it will never be called 16-bit mode. */ diff --git a/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_stack_build.s b/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_stack_build.s index ad8abad3..d868cfdb 100644 --- a/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_stack_build.s +++ b/ports_module/cortex_a7/gnu/module_manager/src/tx_thread_stack_build.s @@ -38,6 +38,8 @@ CPSR_MASK = 0xFF // Mask initial CPSR, T, IRQ & F CPSR_MASK = 0xBF // Mask initial CPSR, T, IRQ interrupts enabled #endif + .global _tx_thread_schedule + .text .align 2 /**************************************************************************/ diff --git a/ports_module/cortex_a7/iar/example_build/sample_threadx_module.c b/ports_module/cortex_a7/iar/example_build/sample_threadx_module.c index d81c0c6d..0cad4a70 100644 --- a/ports_module/cortex_a7/iar/example_build/sample_threadx_module.c +++ b/ports_module/cortex_a7/iar/example_build/sample_threadx_module.c @@ -232,11 +232,6 @@ void thread_0_entry(ULONG thread_input) UINT status; - /* Test external/shared memory. */ - *(ULONG *) 0x90000000 = 0xdeadbeef; - *(ULONG *) 0x90000FFC = 0xfeed0add; - *(ULONG *) 0x90001000 = 0xfedcba01; - /* This thread simply sits in while-forever-sleep loop. */ while(1) { diff --git a/ports_module/cortex_a7/iar/example_build/sample_threadx_module.ewp b/ports_module/cortex_a7/iar/example_build/sample_threadx_module.ewp index 6141e05c..cc1ed0c4 100644 --- a/ports_module/cortex_a7/iar/example_build/sample_threadx_module.ewp +++ b/ports_module/cortex_a7/iar/example_build/sample_threadx_module.ewp @@ -125,21 +125,21 @@ diff --git a/ports_module/cortex_a7/iar/example_build/tx_initialize_low_level.s b/ports_module/cortex_a7/iar/example_build/tx_initialize_low_level.s index f592c1ed..8b4695ec 100644 --- a/ports_module/cortex_a7/iar/example_build/tx_initialize_low_level.s +++ b/ports_module/cortex_a7/iar/example_build/tx_initialize_low_level.s @@ -81,7 +81,7 @@ __tx_free_memory_start ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_initialize_low_level Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -115,6 +115,9 @@ __tx_free_memory_start ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_initialize_low_level(VOID) @@ -152,11 +155,7 @@ _tx_initialize_low_level ; ; /* Done, return to caller. */ ; -#ifdef TX_THUMB - BX lr ; Return to caller -#else MOV pc, lr ; Return to caller -#endif ;} ; ;/* Define shells for each of the interrupt vectors. */ diff --git a/ports_module/cortex_a7/iar/example_build/txm.ewp b/ports_module/cortex_a7/iar/example_build/txm.ewp index 5eef0927..b8b34b1f 100644 --- a/ports_module/cortex_a7/iar/example_build/txm.ewp +++ b/ports_module/cortex_a7/iar/example_build/txm.ewp @@ -82,7 +82,7 @@ diff --git a/ports_module/cortex_a7/iar/example_build/txm_module_preamble.s b/ports_module/cortex_a7/iar/example_build/txm_module_preamble.s index 31ccca5b..343d2a6b 100644 --- a/ports_module/cortex_a7/iar/example_build/txm_module_preamble.s +++ b/ports_module/cortex_a7/iar/example_build/txm_module_preamble.s @@ -32,9 +32,13 @@ __txm_module_preamble: ; 0 -> IAR ; 1 -> RVDS ; 2 -> GNU - ; Bits 23-1: Reserved - ; Bit 0: 0 -> Privileged mode execution (no MPU protection) - ; 1 -> User mode execution (MPU protection) + ; Bits 23-3: Reserved + ; Bit 2: 0 -> Disable shared/external memory access + ; 1 -> Enable shared/external memory access + ; Bit 1: 0 -> No MPU protection + ; 1 -> MPU protection (must have user mode selected - bit 0 set) + ; Bit 0: 0 -> Privileged mode execution + ; 1 -> User mode execution DC32 _txm_module_thread_shell_entry - . - 0 ; Module Shell Entry Point DC32 demo_module_start - . - 0 ; Module Start Thread Entry Point DC32 0 ; Module Stop Thread Entry Point diff --git a/ports_module/cortex_a7/iar/inc/tx_port.h b/ports_module/cortex_a7/iar/inc/tx_port.h index 3780666b..8110088b 100644 --- a/ports_module/cortex_a7/iar/inc/tx_port.h +++ b/ports_module/cortex_a7/iar/inc/tx_port.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-A7/IAR */ -/* 6.1.6 */ +/* 6.x */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,9 @@ /* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ /* macro definition, */ /* resulting in version 6.1.6 */ +/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* Added thumb mode support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -315,22 +318,13 @@ void __iar_Initlocks(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Determine if the ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ +/* Redefine the macro for calculating the lowest bit set. */ #ifndef TX_DISABLE_INLINE - -#if __CORE__ > __ARM4TM__ - -#if __CPU_MODE__ == 2 - #define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ b = (UINT) __CLZ(m); \ b = 31 - b; #endif -#endif -#endif /* Define ThreadX interrupt lockout and restore macros for protection on @@ -358,35 +352,41 @@ void _tx_thread_interrupt_restore(UINT old_posture); #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); #else -#if __CPU_MODE__ == 2 - -#if (__VER__ < 8002000) -__intrinsic unsigned long __get_CPSR(); -__intrinsic void __set_CPSR( unsigned long ); -#endif - - -#if (__VER__ < 8002000) +#if (__VER__ < 8002000) && (__CPU_MODE__ == 2) #define TX_INTERRUPT_SAVE_AREA ULONG interrupt_save; #else #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #endif -#define TX_DISABLE interrupt_save = __get_CPSR(); \ - __set_CPSR(interrupt_save | TX_INT_DISABLE); -#define TX_RESTORE __set_CPSR(interrupt_save); +#ifdef TX_ENABLE_FIQ_SUPPORT + +#define TX_DISABLE \ + { \ + asm volatile (" MRS %0,CPSR": "=r" (interrupt_save)); \ + asm volatile (" CPSID if"); \ + } +#define TX_RESTORE \ + { \ + if ((interrupt_save & 0x40) == 0) \ + asm volatile (" CPSIE f"); \ + if ((interrupt_save & 0x80) == 0) \ + asm volatile (" CPSIE i"); \ + } #else -UINT _tx_thread_interrupt_disable(void); -void _tx_thread_interrupt_restore(UINT old_posture); +#define TX_DISABLE \ + { \ + asm volatile (" MRS %0,CPSR": "=r" (interrupt_save)); \ + asm volatile (" CPSID i"); \ + } +#define TX_RESTORE \ + { \ + if ((interrupt_save & 0x80) == 0) \ + asm volatile (" CPSIE i"); \ + } - -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; - -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); #endif #endif diff --git a/ports_module/cortex_a7/iar/inc/txm_module_port.h b/ports_module/cortex_a7/iar/inc/txm_module_port.h index 1b31c6f7..2cebb878 100644 --- a/ports_module/cortex_a7/iar/inc/txm_module_port.h +++ b/ports_module/cortex_a7/iar/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-A7/MMU/IAR */ -/* 6.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -41,6 +41,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +/* Added thumb mode support, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -117,7 +120,7 @@ The following extensions must also be defined in tx_port.h: /* Define the properties for this particular module port. */ #ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED -#define TXM_MODULE_MEMORY_PROTECTION 0x00000001 +#define TXM_MODULE_MEMORY_PROTECTION 0x00000002 #else #define TXM_MODULE_MEMORY_PROTECTION 0x00000000 #endif @@ -126,7 +129,7 @@ The following extensions must also be defined in tx_port.h: /* Define the supported options for this module. */ -#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_MEMORY_PROTECTION) +#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_USER_MODE | TXM_MODULE_MEMORY_PROTECTION) #define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0 @@ -360,8 +363,8 @@ typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT /* Define the macro to populate the thread control block with module port-specific information. */ #define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \ - thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \ - thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \ + thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \ + thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \ if (thread_ptr -> tx_thread_module_user_mode) \ { \ thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \ @@ -369,7 +372,7 @@ typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT else \ { \ thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \ - } +} /* Define the macro to populate the module control block with module port-specific information. @@ -418,7 +421,7 @@ UINT _txm_module_manager_inside_data_check(ULONG pointer); #define TXM_MODULE_MANAGER_VERSION_ID \ CHAR _txm_module_manager_version_id[] = \ - "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A7/MMU/iar Version 6.2.1 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A7/MMU/iar Version 6.x *"; #endif diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_restore.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_restore.s index a332a862..7a053ae0 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_restore.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_restore.s @@ -26,13 +26,6 @@ IRQ_MODE EQU 0x12 ; IRQ mode SVC_MODE EQU 0x13 ; SVC mode SYS_MODE EQU 0x1F ; SYS mode -THUMB_MASK EQU 0x20 ; Thumb bit mask - -#ifdef TX_ENABLE_FIQ_SUPPORT -DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts -#else -DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts -#endif ; ; EXTERN _tx_thread_system_state @@ -41,7 +34,7 @@ DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts EXTERN _tx_timer_time_slice EXTERN _tx_thread_schedule EXTERN _tx_thread_preempt_disable -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) EXTERN _tx_execution_isr_exit #endif ; @@ -52,7 +45,7 @@ DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_context_restore Cortex-A7/MMU/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* Scott Larson, Microsoft Corporation */ @@ -85,168 +78,119 @@ DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_context_restore(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_context_restore - ARM -_tx_thread_context_restore -; -; /* Lockout interrupts. */ -; -#ifdef TX_ENABLE_FIQ_SUPPORT - CPSID if ; Disable IRQ and FIQ interrupts +#if defined(THUMB_MODE) + THUMB #else - CPSID i ; Disable IRQ interrupts + ARM +#endif +_tx_thread_context_restore + +#ifdef TX_ENABLE_FIQ_SUPPORT + CPSID if ; Disable IRQ and FIQ +#else + CPSID i ; Disable IRQ #endif -#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 +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) +; /* 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; -; + +; /* Check if interrupts are nested. */ + LDR r1, =_tx_thread_system_state ; Load address of system state variable + LDR r0, [r1] ; Load the counter + SUBS r0, r0, #1 ; Decrement the counter + STR r0, [r1] ; Store the counter + BNE restore_and_return_from_irq ; If the counter is not 0, this is a nested restore, just return + +; /* Check if a thread was interrupted and no preemption is required. */ + LDR r1, =_tx_thread_current_ptr ; Load address of current thread ptr + LDR r0, [r1] ; Load actual current thread pointer + CMP r0, #0 ; Is it NULL ? + BEQ restore_and_return_from_irq ; If the current thread pointer is NULL, idle system was interrupted, just return + +; /* Check if the current thread can be preempted. */ + LDR r3, =_tx_thread_preempt_disable ; Load preempt disable address + LDR r2, [r3] ; Load actual preempt disable flag + CMP r2, #0 ; Is it set ? + BNE restore_and_return_from_irq ; If the preempt disable flag is set, do not preempt, just return + +; /* Check if the next thread is different of the current thread. */ + LDR r3, =_tx_thread_execute_ptr ; Load address of execute thread ptr + LDR r2, [r3] ; Load actual execute thread pointer + CMP r0, r2 ; Is the next thread the same as the current thread ? + BEQ restore_and_return_from_irq ; If this is the same thread, do not preempt, just return + +; /* Clear the current task pointer. */ + MOV r3, #0 ; NULL value + STR r3, [r1] ; Clear current thread pointer + + POP {r2, r10, r12, lr} ; Recover temporarily saved registers + +; /* Save registers of the current thread on its stack */ +; /* Save integer registers. */ + MOV r1, lr ; Save lr (point of interrupt) + CPS #SYS_MODE ; Enter SYS mode + STR r1, [sp, #-4]! ; Save point of interrupt + PUSH {r4-r12, lr} ; Save upper half of registers + CPS #IRQ_MODE ; Enter IRQ mode + POP {r4-r7} ; Recover r0-r3 + CPS #SYS_MODE ; Enter SYS mode + PUSH {r4-r7} ; Save r0-r3 on thread's stack +#ifdef TX_ENABLE_VFP_SUPPORT +; /* Save VFP registers. */ + LDR r1, [r0, #144] ; Pickup the VFP enabled flag + CMP r1, #0 ; Is the VFP enabled? + BEQ skip_vfp_save ; No, skip VFP IRQ save + VMRS r1, FPSCR ; Pickup the FPSCR + STR r1, [sp, #-4]! ; Save FPSCR + VSTMDB sp!, {D16-D31} ; Save D16-D31 + VSTMDB sp!, {D0-D15} ; Save D0-D15 +skip_vfp_save: +#endif +; /* Save CPSR and stack type. */ + MOV r1, #1 ; Build interrupt stack type + PUSH {r1, r2} ; Save interrupt stack type and SPSR + STR sp, [r0, #8] ; Save stack pointer in thread control block + +; /* Save the remaining time-slice and disable it. */ + LDR r2, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r1, [r2] ; Pickup time-slice + CMP r1, #0 ; Is it active? + BEQ dont_save_ts ; No, don't save it + STR r1, [r0, #24] ; Save thread's time-slice + STR r3, [r2] ; Disable global time-slice flag +dont_save_ts: + + B _tx_thread_schedule ; Go to the scheduler + +; /* Return to point of interrupt */ +restore_and_return_from_irq: ; /* 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) - CPS #SYS_MODE ; Enter SYS mode - STR r1, [sp, #-4]! ; Save point of interrupt on thread's stack - STMDB sp!, {r4-r12, lr} ; Save upper half of registers on thread's stack - MOV r4, r3 ; Save SPSR in r4 - CPS #IRQ_MODE ; Enter IRQ mode - LDMIA sp!, {r0-r3} ; Recover r0-r3 - CPS #SYS_MODE ; Enter SYS mode - STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack - - LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr - LDR r0, [r1, #0] ; Pickup current thread pointer - -#ifdef __ARMVFP__ - LDR r2, [r0, #144] ; Pickup the VFP enabled flag - CMP r2, #0 ; Is the VFP enabled? - BEQ _tx_skip_irq_vfp_save ; No, skip VFP IRQ save - VMRS r2, FPSCR ; Pickup the FPSCR - STR r2, [sp, #-4]! ; Save FPSCR - VSTMDB sp!, {D16-D31} ; Save D16-D31 - VSTMDB sp!, {D0-D15} ; Save D0-D15 -_tx_skip_irq_vfp_save + POP {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + POP {r0-r3} ; Recover r0-r3 +#if defined(THUMB_MODE) && defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else + MOVS pc, lr ; Return to point of interrupt #endif - - MOV r3, #1 ; Build interrupt stack type - STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR - STR sp, [r0, #8] ; Save stack pointer in thread control - ; block -; -; /* 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(); -; - CPS #IRQ_MODE ; Enter IRQ mode - MRS r1, SPSR ; Get SPSR - ORR r1, r1, #SYS_MODE ; Change to SYS Mode - BIC r1, r1, #THUMB_MASK ; Clear thumb bit - MSR SPSR_cxsf, r1 ; Put SYS Mode in SPSR - LDR lr, =_tx_thread_schedule ; Load scheduler address - MOVS pc, lr ; Return to scheduler -; } -; -__tx_thread_idle_system_restore -; -; /* Just return back to the scheduler! */ -; - LDR lr, =_tx_thread_schedule ; Load scheduler address - MOVS pc, lr ; Return to scheduler ;} ; - END - + END \ No newline at end of file diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_save.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_save.s index 8daa4306..506872db 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_save.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_context_save.s @@ -23,9 +23,8 @@ ; EXTERN _tx_thread_system_state - EXTERN _tx_thread_current_ptr EXTERN __tx_irq_processing_return -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) EXTERN _tx_execution_isr_enter #endif ; @@ -36,7 +35,7 @@ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_context_save Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -68,124 +67,51 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_context_save(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_context_save +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _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 - CPSID if ; Disable FIQ 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 + CPSID if ; Disable FIQ interrupts #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 occurred in - ; scheduling loop - nothing needs saving! -; + PUSH {r0-r3} ; Save some working registers + ; /* 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 + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + PUSH {r0, r10, r12, lr} ; Store other registers -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; + LDR r1, =_tx_thread_system_state ; Pickup address of system state variable + LDR r0, [r1] ; Pickup system state + ADD r0, #1 ; Increment the interrupt counter + STR r0, [r1] ; Store it back in the variable + + MOV r10, #0 ; Clear stack limit + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) ; /* 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 + 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 -; -; } + B __tx_irq_processing_return ; Continue IRQ processing ;} ; END diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_restore.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_restore.s index 96844809..d21c044d 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_restore.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_restore.s @@ -42,7 +42,7 @@ IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_fiq_context_restore Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -75,13 +75,20 @@ IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_fiq_context_restore(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_fiq_context_restore +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_fiq_context_restore ; ; /* Lockout interrupts. */ @@ -111,10 +118,21 @@ _tx_thread_fiq_context_restore ; /* Just recover the saved registers and return to the point of ; interrupt. */ ; - LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + POP {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs MSR SPSR_cxsf, r0 ; Put SPSR back - LDMIA sp!, {r0-r3} ; Recover r0-r3 + POP {r0-r3} ; Recover r0-r3 +#if defined(THUMB_MODE) && defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else MOVS pc, lr ; Return to point of interrupt +#endif ; ; } __tx_thread_fiq_not_nested_restore @@ -154,31 +172,42 @@ __tx_thread_fiq_no_preempt_restore ; /* 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. */ +; /* Recover the saved context and return to the point of interrupt. */ ; - LDMIA sp!, {r0, lr} ; Recover SPSR, POI, and scratch regs + POP {r0, lr} ; Recover SPSR, POI, and scratch regs MSR SPSR_cxsf, r0 ; Put SPSR back - LDMIA sp!, {r0-r3} ; Recover r0-r3 + POP {r0-r3} ; Recover r0-r3 +#if defined(THUMB_MODE) && defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else MOVS pc, lr ; Return to point of interrupt +#endif ; ; } ; else ; { __tx_thread_fiq_preempt_restore ; - LDMIA sp!, {r3, lr} ; Recover temporarily saved registers + POP {r3, 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 + PUSH {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_c, r2 ; Re-enter FIQ mode - LDMIA sp!, {r0-r3} ; Recover r0-r3 + POP {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 + PUSH {r0-r3} ; Save r0-r3 on thread's stack LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr LDR r0, [r1] ; Pickup current thread pointer @@ -195,7 +224,7 @@ _tx_skip_fiq_vfp_save #endif MOV r3, #1 ; Build interrupt stack type - STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + PUSH {r3, r4} ; Save interrupt stack type and SPSR STR sp, [r0, #8] ; Save stack pointer in thread control ; block ; diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_save.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_save.s index 4f0b6cf7..7c0b56e1 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_save.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_context_save.s @@ -32,7 +32,7 @@ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_fiq_context_save Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -64,13 +64,20 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ; VOID _tx_thread_fiq_context_save(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_fiq_context_save +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_fiq_context_save ; ; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_end.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_end.s index 7f4cd145..56dab99e 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_end.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_end.s @@ -33,7 +33,7 @@ FIQ_MODE_BITS EQU 0x11 ; FIQ mode bits ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_fiq_nesting_end Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -73,13 +73,20 @@ FIQ_MODE_BITS EQU 0x11 ; FIQ mode bits ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_fiq_nesting_end(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_fiq_nesting_end +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_fiq_nesting_end MOV r3,lr ; Save ISR return address MRS r0, CPSR ; Pickup the CPSR @@ -90,11 +97,7 @@ _tx_thread_fiq_nesting_end BIC r0, r0, #MODE_MASK ; Clear mode bits ORR r0, r0, #FIQ_MODE_BITS ; Build IRQ mode CPSR MSR CPSR_c, r0 ; Re-enter IRQ mode -#ifdef INTER BX r3 ; Return to caller -#else - MOV pc, r3 ; Return to caller -#endif ;} ; END diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_start.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_start.s index 7b8beef2..2b416b05 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_start.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_fiq_nesting_start.s @@ -29,7 +29,7 @@ SYS_MODE_BITS EQU 0x1F ; System mode bits ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_fiq_nesting_start Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -66,13 +66,15 @@ SYS_MODE_BITS EQU 0x1F ; System mode bits ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_fiq_nesting_start(VOID) ;{ RSEG .text:CODE:NOROOT(2) EXPORT _tx_thread_fiq_nesting_start - ARM _tx_thread_fiq_nesting_start MOV r3,lr ; Save ISR return address MRS r0, CPSR ; Pickup the CPSR @@ -83,11 +85,7 @@ _tx_thread_fiq_nesting_start ; and push r1 just to keep 8-byte alignment BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR MSR CPSR_c, r0 ; Enter system mode -#ifdef INTER BX r3 ; Return to caller -#else - MOV pc, r3 ; Return to caller -#endif ;} ; END diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_control.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_control.s index f237cc35..14fda0ae 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_control.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_control.s @@ -21,10 +21,10 @@ ;/**************************************************************************/ ; -#ifdef TX_ENABLE_FIQ_SUPPORT INT_MASK EQU 0xC0 ; Interrupt bit mask -#else -INT_MASK EQU 0x80 ; Interrupt bit mask +IRQ_MASK EQU 0x80 ; Interrupt bit mask +#ifdef TX_ENABLE_FIQ_SUPPORT +FIQ_MASK EQU 0x40 ; Interrupt bit mask #endif ; ; @@ -34,7 +34,7 @@ INT_MASK EQU 0x80 ; Interrupt bit mask ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_interrupt_control Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -65,26 +65,42 @@ INT_MASK EQU 0x80 ; Interrupt bit mask ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;UINT _tx_thread_interrupt_control(UINT new_posture) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_interrupt_control +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _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 - BX lr ; Return to caller + MRS r1, CPSR ; Pickup current CPSR + +#ifdef TX_ENABLE_FIQ_SUPPORT + CPSID if ; Disable IRQ and FIQ +#else + CPSID i ; Disable IRQ +#endif + + TST r0, #IRQ_MASK + BNE no_irq + CPSIE i +no_irq: +#ifdef TX_ENABLE_FIQ_SUPPORT + TST r0, #FIQ_MASK + BNE no_fiq + CPSIE f +no_fiq: +#endif + + AND r0, r1, #INT_MASK + BX lr ; ;} ; diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_disable.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_disable.s index 360764e0..234fe450 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_disable.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_disable.s @@ -21,15 +21,13 @@ ;/**************************************************************************/ -DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled - ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_interrupt_disable Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -59,13 +57,20 @@ DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;UINT _tx_thread_interrupt_disable(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_interrupt_disable +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_interrupt_disable ; ; /* Pickup current interrupt lockout posture. */ diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_restore.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_restore.s index bbd940e3..92ecb10c 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_restore.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_interrupt_restore.s @@ -20,14 +20,18 @@ ;/**************************************************************************/ ;/**************************************************************************/ - +INT_MASK EQU 0xC0 ; Interrupt bit mask +IRQ_MASK EQU 0x80 ; Interrupt bit mask +#ifdef TX_ENABLE_FIQ_SUPPORT +FIQ_MASK EQU 0x40 ; Interrupt bit mask +#endif ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_interrupt_restore Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -58,23 +62,36 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;void _tx_thread_interrupt_restore(UINT old_posture) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_interrupt_restore - ARM -_tx_thread_interrupt_restore -; -; /* Apply the new interrupt posture. */ -; - MSR CPSR_cxsf, r0 ; Setup new CPSR -#ifdef TX_THUMB - BX lr ; Return to caller +#ifdef THUMB_MODE + THUMB #else - MOV pc, lr ; Return to caller + ARM #endif +_tx_thread_interrupt_restore + +; /* Apply the new interrupt posture. */ + + TST r0, #IRQ_MASK + BNE no_irq + CPSIE i +no_irq: +#ifdef TX_ENABLE_FIQ_SUPPORT + TST r0, #FIQ_MASK + BNE no_fiq + CPSIE f +no_fiq: +#endif + + BX lr ; Return to caller ;} ; END diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_end.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_end.s index fcfd3796..09a2c710 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_end.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_end.s @@ -38,7 +38,7 @@ IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_irq_nesting_end Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -78,13 +78,20 @@ IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_irq_nesting_end(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_irq_nesting_end +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_irq_nesting_end MOV r3,lr ; Save ISR return address MRS r0, CPSR ; Pickup the CPSR diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_start.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_start.s index 471fa268..a7461cc6 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_start.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_irq_nesting_start.s @@ -32,7 +32,7 @@ SYS_MODE_BITS EQU 0x1F ; System mode bits ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_irq_nesting_start Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -69,13 +69,20 @@ SYS_MODE_BITS EQU 0x1F ; System mode bits ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_irq_nesting_start(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_irq_nesting_start +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_irq_nesting_start MOV r3, lr ; Save ISR return address MRS r0, CPSR ; Pickup the CPSR diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_schedule.s index 0e9eeb7c..9fae3e1d 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_schedule.s @@ -24,7 +24,7 @@ EXTERN _tx_thread_execute_ptr EXTERN _tx_thread_current_ptr EXTERN _tx_timer_time_slice -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) EXTERN _tx_execution_thread_enter #endif @@ -33,10 +33,10 @@ USR_MODE EQU 0x10 ; USR mode SVC_MODE EQU 0x13 ; SVC mode SYS_MODE EQU 0x1F ; SYS mode +INT_MASK EQU 0xC0 ; Interrupt bit mask +IRQ_MASK EQU 0x80 ; Interrupt bit mask #ifdef TX_ENABLE_FIQ_SUPPORT -ENABLE_INTS EQU 0xC0 ; IRQ & FIQ Interrupts enabled mask -#else -ENABLE_INTS EQU 0x80 ; IRQ Interrupts enabled mask +FIQ_MASK EQU 0x40 ; Interrupt bit mask #endif MODE_MASK EQU 0x1F ; Mode mask @@ -53,7 +53,7 @@ THUMB_MASK EQU 0x20 ; Thumb bit mask ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_schedule Cortex-A7/MMU/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* Scott Larson, Microsoft Corporation */ @@ -87,13 +87,20 @@ THUMB_MASK EQU 0x20 ; Thumb bit mask ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_schedule(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_schedule +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_schedule ; Enter the scheduler. @@ -112,38 +119,38 @@ _tx_scheduler_fault__ RSEG .text:CODE:NOROOT(2) PUBLIC SWI_Handler +#ifdef THUMB_MODE + THUMB +#else ARM +#endif SWI_Handler - STMFD sp!, {r0-r3, r12, lr} ; Store the registers - MOV r1, sp ; Set pointer to parameters - MRS r0, spsr ; Get spsr - STMFD sp!, {r0, r3} ; Store spsr onto stack and another - ; register to maintain 8-byte-aligned stack - TST r0, #THUMB_MASK ; Occurred in Thumb state? - LDRNEH r0, [lr,#-2] ; Yes: Load halfword and... - BICNE r0, r0, #0xFF00 ; ...extract comment field - LDREQ r0, [lr,#-4] ; No: Load word and... - BICEQ r0, r0, #0xFF000000 ; ...extract comment field + PUSH {r0-r3, r12, lr} ; Store the registers - ; r0 now contains SVC number - ; r1 now contains pointer to stacked registers + MRS r0, spsr ; Get spsr + TST r0, #THUMB_MASK ; Occurred in Thumb state? + ITTEE NE + LDRHNE r1, [lr,#-2] ; Yes: Load halfword and... + BICNE r1, r1, #0xFF00 ; ...extract comment field + LDREQ r1, [lr,#-4] ; No: Load word and... + BICEQ r1, r1, #0xFF000000 ; ...extract comment field + + ; r1 now contains SVC number - ; ; The service call is handled here - ; - - CMP r0, #0 ; Is it a schedule request? + + CMP r1, #0 ; Is it a schedule request? BEQ _tx_handler_svc_schedule ; Yes, go there - CMP r0, #1 ; Is it a system mode enter request? + CMP r1, #1 ; Is it a system mode enter request? BEQ _tx_handler_svc_super_enter ; Yes, go there - CMP r0, #2 ; Is it a system mode exit request? + CMP r1, #2 ; Is it a system mode exit request? BEQ _tx_handler_svc_super_exit ; Yes, go there - + LDR r2, =0x123456 - CMP r0, r2 ; Is it an ARM request? + CMP r1, r2 ; Is it an ARM request? BEQ _tx_handler_svc_arm ; Yes, go there ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -152,7 +159,7 @@ SWI_Handler ; Unrecognized service call PUBWEAK _tx_handler_svc_unrecognized _tx_handler_svc_unrecognized - + BKPT 0x0000 _tx_handler_svc_unrecognized_loop ; We should never get here B _tx_handler_svc_unrecognized_loop @@ -163,72 +170,103 @@ _tx_handler_svc_unrecognized_loop ; We should never get here ; supervisor mode to service a kernel call. _tx_handler_svc_super_enter ; Make sure that we have been called from the system mode enter location (security) - LDR r2, =_txm_system_mode_enter ; Load the address of the known call point - SUB r1, lr, #4 ; Calculate the address of the actual call - CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry? - BNE _tx_handler_svc_unrecognized ; Return to where we came + LDR r2, =_txm_system_mode_enter ; Load the address of the known call point + BIC r2, #1 ; Clear bit 0 of the symbol address (it is 1 in Thumb mode, 0 in ARM mode) + MOV r1, lr ; Get return address + TST r0, #THUMB_MASK ; Check if we come from Thumb mode or ARM mode + ITE NE + SUBNE r1, #2 ; Calculate the address of the actual call (thumb mode) + SUBEQ r1, #4 ; Calculate the address of the actual call (ARM mode) + CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry? + BNE _tx_handler_svc_unrecognized ; Return to where we came ; Clear the user mode flag in the thread structure - LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address - LDR r2, [r1] ; Load current thread location from the pointer (pointer indirection) - MOV r1, #0 ; Load the new user mode flag value (user mode flag clear -> not user mode -> system) - STR r1, [r2, #0x9C] ; Clear the current user mode selection for thread - + LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address + LDR r2, [r1] ; Load current thread location from the pointer (pointer indirection) + MOV r1, #0 ; Load the new user mode flag value (user mode flag clear -> not user mode -> system) + STR r1, [r2, #0x9C] ; Clear tx_thread_module_current_user_mode for thread + ; Now we enter the system mode and return - LDMFD sp!, {r0, r3} ; Get spsr from the stack - BIC r0, r0, #MODE_MASK ; clear mode field - ORR r0, r0, #SYS_MODE ; system mode code - MSR SPSR_cxsf, r0 ; Restore the spsr - - LDR r1, [r2, #0xA8] ; Load the module kernel stack pointer - CPS #SYS_MODE ; Switch to SYS mode - MOV r3, sp ; Grab thread stack pointer - MOV sp, r1 ; Set SP to kernel stack pointer - CPS #SVC_MODE ; Switch back to SVC mode - STR r3, [r2, #0xB0] ; Save thread stack pointer -#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE - LDR r3, [r2, #0xAC] ; Load the module kernel stack size - STR r3, [r2, #20] ; Set stack size - LDRD r0, r1, [r2, #0xA4] ; Load the module kernel stack start and end - STRD r0, r1, [r2, #0x0C] ; Set stack start and end + BIC r0, r0, #MODE_MASK ; clear mode field + ORR r0, r0, #SYS_MODE ; system mode code + MSR SPSR_cxsf, r0 ; Restore the spsr + + LDR r1, [r2, #0xA8] ; Load the module kernel stack pointer + CPS #SYS_MODE ; Switch to SYS mode + MOV r3, sp ; Grab thread stack pointer + MOV sp, r1 ; Set SP to kernel stack pointer + CPS #SVC_MODE ; Switch back to SVC mode + STR r3, [r2, #0xB0] ; Save thread stack pointer +#ifdef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE + ; do nothing +#else + LDR r3, [r2, #0xAC] ; Load the module kernel stack size + STR r3, [r2, #20] ; Set stack size + LDRD r0, r1, [r2, #0xA4] ; Load the module kernel stack start and end + STRD r0, r1, [r2, #0x0C] ; Set stack start and end #endif - LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return - + + ; Restore the registers and return +#if defined(THUMB_MODE) + POP {r0-r3, r12, lr} +#if defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else + SUBS pc, lr, #0 +#endif +#else + LDMFD sp!, {r0-r3, r12, pc}^ +#endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SVC 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; At this point we have an SVC 2, which means we are exiting ; supervisor mode after servicing a kernel call. -_tx_handler_svc_super_exit +_tx_handler_svc_super_exit: ; Make sure that we have been called from the system mode exit location (security) - LDR r2, =_txm_system_mode_exit ; Load the address of the known call point - SUB r1, lr, #4 ; Calculate the address of the actual call - CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry? - BNE _tx_handler_svc_unrecognized ; Return to where we came + LDR r2, =_txm_system_mode_exit ; Load the address of the known call point + BIC r2, #1 ; Clear bit 0 of the symbol address (it is 1 in Thumb mode, 0 in ARM mode) + MOV r1, lr ; Get return address + TST r0, #THUMB_MASK ; Check if we come from Thumb mode or ARM mode + ITE NE + SUBNE r1, #2 ; Calculate the address of the actual call (thumb mode) + SUBEQ r1, #4 ; Calculate the address of the actual call (ARM mode) + CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry? + BNE _tx_handler_svc_unrecognized ; Return to where we came ; Set the user mode flag into the thread structure - LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address - LDR r2, [r1] ; Load the current thread location from the pointer (pointer indirection) - MOV r1, #1 ; Load the new user mode flag value (user mode enabled -> not system anymore) - STR r1, [r2, #0x9C] ; Clear the current user mode selection for thread + LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address + LDR r2, [r1] ; Load the current thread location from the pointer (pointer indirection) + MOV r1, #1 ; Load the new user mode flag value (user mode enabled -> not system anymore) + STR r1, [r2, #0x9C] ; Set tx_thread_module_current_user_mode for thread ; Now we enter user mode (exit the system mode) and return - LDMFD sp!, {r0, r3} ; Get spsr from the stack - BIC r0, r0, #MODE_MASK ; clear mode field - ORR r0, r0, #USR_MODE ; user mode code - MSR SPSR_cxsf, r0 ; Restore the spsr + BIC r0, r0, #MODE_MASK ; clear mode field + ORR r0, r0, #USR_MODE ; user mode code + MSR SPSR_cxsf, r0 ; Restore the spsr - LDR r1, [r2, #0xB0] ; Load the module thread stack pointer - CPS #SYS_MODE ; Switch to SYS mode - MOV sp, r1 ; Set SP back to thread stack pointer - CPS #SVC_MODE ; Switch back to SVC mode -#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE - LDR r3, [r2, #0xBC] ; Load the module thread stack size - STR r3, [r2, #20] ; Set stack size - LDRD r0, r1, [r2, #0xB4] ; Load the module thread stack start and end - STRD r0, r1, [r2, #0x0C] ; Set stack start and end + LDR r1, [r2, #0xB0] ; Load the module thread stack pointer + CPS #SYS_MODE ; Switch to SYS mode + MOV r3, sp ; Grab kernel stack pointer + MOV sp, r1 ; Set SP back to thread stack pointer + CPS #SVC_MODE ; Switch back to SVC mode +#ifdef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE + ; do nothing +#else + LDR r3, [r2, #0xBC] ; Load the module thread stack size + STR r3, [r2, #20] ; Set stack size + LDRD r0, r1, [r2, #0xB4] ; Load the module thread stack start and end + STRD r0, r1, [r2, #0x0C] ; Set stack start and end #endif - LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ARM Semihosting @@ -237,20 +275,34 @@ _tx_handler_svc_arm ; *** TODO: handle semihosting requests or ARM angel requests *** - ; just return - LDMFD sp!, {r0, r3} ; Get spsr from the stack - MSR SPSR_cxsf, r0 ; Restore the spsr - LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return - + ; Restore the registers and return +#if defined(THUMB_MODE) + POP {r0-r3, r12, lr} +#if defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else + SUBS pc, lr, #0 +#endif + +#else + LDMFD sp!, {r0-r3, r12, pc}^ +#endif + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SVC 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; At this point we have an SVC 0: enter the scheduler. _tx_handler_svc_schedule - LDMFD sp!, {r0, r3} ; Get spsr from stack - MSR SPSR_cxsf, r0 ; Restore spsr - LDMFD sp!, {r0-r3, r12, lr} ; Restore the registers + POP {r0-r3, r12, lr} ; Restore the registers + ; This code waits for a thread control block pointer to appear in ; the _tx_thread_execute_ptr variable. Once a thread pointer appears @@ -258,66 +310,71 @@ _tx_handler_svc_schedule ; ; /* Enable interrupts. */ ; - CPSIE i ; Enable IRQ interrupts - +#ifdef TX_ENABLE_FIQ_SUPPORT + CPSIE if ; Enable IRQ and FIQ interrupts +#else + CPSIE i ; Enable IRQ interrupts +#endif ; ; /* Wait for a thread to execute. */ ; do ; { - LDR r1, =_tx_thread_execute_ptr ; Address of thread execute ptr + 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. */ -; - CPSID i ; 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 - STR r3, [r2, #0] ; Setup time-slice -; -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -; -; /* Call the thread entry function to indicate the thread is executing. */ -; - MOV r5, r0 ; Save r0 - BL _tx_execution_thread_enter ; Call the thread execution enter function - MOV r0, r5 ; Restore r0 + LDR r0, [r1] ; 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. +#ifdef TX_ENABLE_FIQ_SUPPORT + CPSID if ; Disable IRQ and FIQ interrupts +#else + CPSID i ; Disable IRQ interrupts +#endif + +; /* 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] ; 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 + STR r3, [r2, #0] ; Setup time-slice + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + +; /* Call the thread entry function to indicate the thread is executing. */ + + MOV r5, r0 ; Save r0 + BL _tx_execution_thread_enter ; Call the thread execution enter function + MOV r0, r5 ; Restore r0 #endif ; Determine if an interrupt frame or a synchronous task suspension frame is present. - CPS #SYS_MODE ; Enter SYS mode - LDR sp, [r0, #8] ; Switch to thread stack pointer - LDMIA sp!, {r4, r5} ; Pickup the stack type and saved CPSR - CPS #SVC_MODE ; Enter SVC mode + CPS #SYS_MODE ; Enter SYS mode + LDR sp, [r0, #8] ; Switch to thread stack pointer + POP {r4, r5} ; Pickup the stack type and saved CPSR + CPS #SVC_MODE ; Enter SVC mode - ; ************************************************************************** + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/ ; Set up MMU for module. LDR r2, [r0, #0x94] ; Pickup the module pointer CMP r2, #0 ; Valid module pointer? + IT NE LDRNE r2, [r2, #0x64] ; Load ASID ; Otherwise, ASID 0 & master table will be loaded. ; Is ASID already loaded? @@ -329,28 +386,27 @@ __tx_thread_schedule_loop DSB ISB ; Load new ASID and TTBR - LDR r1, =_txm_ttbr1_page_table ; Load master TTBR - ORR r1, r1, #0x48 ; OR it with #TTBR0_ATTRIBUTES + LDR r1, =_txm_ttbr1_page_table ; Load master TTBR + ORR r1, r1, #0x9 ; OR it with #TTBR0_ATTRIBUTES MCR p15, 0, r1, c2, c0, 0 ; Change TTBR to master ISB DSB MCR p15, 0, r2, c13, c0, 1 ; Change ASID to new value ISB ; Change TTBR to new value - MOV r3, #14 - ADD r1, r1, r2, LSL r3 + ADD r1, r1, r2, LSL #14 ; r1 = _txm_ttbr1_page_table + (asid << 14) MCR p15, 0, r1, c2, c0, 0 ; Change TTBR to new value - + ; refresh TLB MOV r2, #0 DSB - MCR p15, 0, r2, c8, c7, 0 ; Invalidate entire unified TLB - MCR p15, 0, r2, c7, c5, 0 ; Invalidate all instruction caches to PoU - MCR p15, 0, r2, c7, c5, 6 ; Invalidate branch predictor + MCR p15, 0, r2, c8, c7, 0 ; Invalidate entire unified TLB + MCR p15, 0, r2, c7, c5, 0 ; Invalidate all instruction caches to PoU + MCR p15, 0, r2, c7, c5, 6 ; Invalidate branch predictor DSB ISB - - ;test address translation + + ; test address translation ;mcr p15, 0, r0, c7, c8, 0 _tx_skip_mmu_update @@ -358,13 +414,13 @@ _tx_skip_mmu_update CMP r4, #0 ; Check for synchronous context switch BEQ _tx_solicited_return - + MSR SPSR_cxsf, r5 ; Setup SPSR for return LDR r1, [r0, #8] ; Get thread SP LDR lr, [r1, #0x40] ; Get thread PC CPS #SYS_MODE ; Enter SYS mode - -#ifdef __ARMVFP__ + +#ifdef TX_ENABLE_VFP_SUPPORT LDR r2, [r0, #144] ; Pickup the VFP enabled flag CMP r2, #0 ; Is the VFP enabled? BEQ _tx_skip_interrupt_vfp_restore ; No, skip VFP interrupt restore @@ -377,11 +433,23 @@ _tx_skip_mmu_update CPS #SYS_MODE ; Enter SYS mode _tx_skip_interrupt_vfp_restore #endif - - LDMIA sp!, {r0-r12, lr} ; Restore registers - ADD sp, sp, #4 ; Fix stack pointer + + POP {r0-r12, lr} ; Restore registers + ADD sp, #4 ; Fix stack pointer (skip PC saved on stack) CPS #SVC_MODE ; Enter SVC mode + +#if defined(THUMB_MODE) && defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else SUBS pc, lr, #0 ; Return to point of thread interrupt +#endif _tx_solicited_return MOV r2, r5 ; Move CPSR to scratch register @@ -398,11 +466,23 @@ _tx_solicited_return _tx_skip_solicited_vfp_restore #endif - LDMIA sp!, {r4-r11, lr} ; Restore registers - MOV r1, lr ; Copy lr to r1 to preserve across mode change - CPS #SVC_MODE ; Enter SVC mode - MSR SPSR_cxsf, r2 ; Recover CPSR - SUBS pc, r1, #0 ; Return to thread synchronously + POP {r4-r11, lr} ; Restore registers + MOV r1, lr ; Copy lr to r1 to preserve across mode change + CPS #SVC_MODE ; Enter SVC mode + MSR SPSR_cxsf, r2 ; Recover CPSR + MOV lr, r1 ; Deprecated return via r1, so copy r1 to lr and return via lr +#if defined(THUMB_MODE) && defined(IAR_SIMULATOR) + +; /* The reason for adding this segment is that IAR's simulator +; may not handle PC-relative instructions correctly in thumb mode.*/ + STR lr, [sp, #-8] + MRS lr, SPSR + STR lr, [sp, #-4] + SUB lr, sp, #8 + RFE lr +#else + SUBS pc, lr, #0 ; Return to thread synchronously +#endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End SWI_Handler @@ -410,44 +490,58 @@ _tx_skip_solicited_vfp_restore #ifdef __ARMVFP__ PUBLIC tx_thread_vfp_enable - ARM -tx_thread_vfp_enable??rA -tx_thread_vfp_enable - MRS r2, CPSR ; Pickup the CPSR -#ifdef TX_ENABLE_FIQ_SUPPORT - CPSID if ; Disable IRQ and FIQ interrupts +#ifdef THUMB_MODE + THUMB #else - CPSID i ; Disable IRQ interrupts + ARM #endif - LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup current thread pointer +tx_thread_vfp_enable + MRS r0, CPSR ; Pickup current CPSR +#ifdef TX_ENABLE_FIQ_SUPPORT + CPSID if ; Disable IRQ and FIQ +#else + CPSID i ; Disable IRQ +#endif + LDR r2, =_tx_thread_current_ptr ; Build current thread pointer address + LDR r1, [r2] ; Pickup current thread pointer CMP r1, #0 ; Check for NULL thread pointer - BEQ __tx_no_thread_to_enable ; If NULL, skip VFP enable - MOV r0, #1 ; Build enable value - STR r0, [r1, #144] ; Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD) -__tx_no_thread_to_enable - MSR CPSR_cxsf, r2 ; Recover CPSR - BX LR ; Return to caller + BEQ restore_ints ; If NULL, skip VFP enable + MOV r2, #1 ; Build enable value + STR r2, [r1, #144] ; Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD) + B restore_ints PUBLIC tx_thread_vfp_disable - ARM -tx_thread_vfp_disable - MRS r2, CPSR ; Pickup the CPSR -#ifdef TX_ENABLE_FIQ_SUPPORT - CPSID if ; Disable IRQ and FIQ interrupts +#ifdef THUMB_MODE + THUMB #else - CPSID i ; Disable IRQ interrupts + ARM #endif - LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address - LDR r1, [r0] ; Pickup current thread pointer +tx_thread_vfp_disable + MRS r0, CPSR ; Pickup current CPSR +#ifdef TX_ENABLE_FIQ_SUPPORT + CPSID if ; Disable IRQ and FIQ +#else + CPSID i ; Disable IRQ +#endif + LDR r2, =_tx_thread_current_ptr ; Build current thread pointer address + LDR r1, [r2] ; Pickup current thread pointer CMP r1, #0 ; Check for NULL thread pointer - BEQ __tx_no_thread_to_disable ; If NULL, skip VFP disable - MOV r0, #0 ; Build disable value - STR r0, [r1, #144] ; Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD) -__tx_no_thread_to_disable - MSR CPSR_cxsf, r2 ; Recover CPSR - BX LR ; Return to caller + BEQ restore_ints ; If NULL, skip VFP disable + MOV r2, #0 ; Build disable value + STR r2, [r1, #144] ; Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD) + +restore_ints: + TST r0, #IRQ_MASK + BNE no_irq + CPSIE i +no_irq: +#ifdef TX_ENABLE_FIQ_SUPPORT + TST r0, #FIQ_MASK + BNE no_fiq + CPSIE f +no_fiq: #endif + BX lr END diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_stack_build.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_stack_build.s index dcde4147..92ed468d 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_stack_build.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_stack_build.s @@ -30,13 +30,14 @@ CPSR_MASK EQU 0x9F ; Mask initial CPSR, IRQ ints en THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR + EXTERN _tx_thread_schedule ;/**************************************************************************/ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_stack_build Cortex-A7/MMU/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* Scott Larson, Microsoft Corporation */ @@ -69,13 +70,20 @@ THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_stack_build +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_stack_build ; ; @@ -103,49 +111,51 @@ _tx_thread_stack_build ; ; Stack Bottom: (higher memory address) */ ; - LDR r2, [r0, #16] ; Pickup end of stack area - BIC r2, r2, #7 ; Ensure 8-byte 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 + LDR r2, [r0, #16] ; Pickup end of stack area + BIC r2, r2, #7 ; Ensure 8-byte alignment + SUB r2, r2, #76 ; Allocate space for the stack frame - MRS r3, CPSR ; Pickup CPSR - BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR - ORR r3, r3, #SYS_MODE ; Build CPSR, SYS mode, interrupts enabled - BIC r3, r3, #THUMB_MASK ; Clear Thumb bit by default - AND r1, r1, #1 ; Determine if the entry function is in Thumb mode - CMP r1, #1 ; Is the Thumb bit set? - ORREQ r3, r3, #THUMB_MASK ; Yes, set the Thumb bit - 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 - BX lr ; Return to caller +; /* Actually build the stack frame. */ + + MOV r3, #1 ; Build interrupt stack type + STR r3, [r2, #0] ; Store stack type + + MRS r3, CPSR ; Pickup CPSR + BIC r3, #CPSR_MASK ; Mask mode bits of CPSR + ORR r3, #SYS_MODE ; Build CPSR, SYS mode, interrupts enabled + TST r1, #1 ; Check if the initial PC is a Thumb function + IT NE + ORRNE r3, #THUMB_MASK ; If the initial PC is a thumb function, CPSR must reflect this + STR r3, [r2, #4] ; Store initial CPSR + + 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 + STR r3, [r2, #52] ; Store initial r11 + STR r3, [r2, #56] ; Store initial r12 + STR r3, [r2, #68] ; 0 for back-trace + + LDR r3, [r0, #12] ; Pickup stack starting address + STR r3, [r2, #48] ; Store initial r10 (sl) + + LDR r3,=_tx_thread_schedule ; Pickup address of _tx_thread_schedule for GDB backtrace + STR r3, [r2, #60] ; Store initial r14 (lr) + + STR r1, [r2, #64] ; Store initial pc + +; /* Setup stack pointer. */ + + STR r2, [r0, #8] ; Save stack pointer in thread's + ; control block + BX lr ; Return to caller ;} diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_system_return.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_system_return.s index b52a15b1..98ec7a77 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_system_return.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_system_return.s @@ -23,7 +23,7 @@ EXTERN _tx_thread_current_ptr EXTERN _tx_timer_time_slice EXTERN _tx_thread_schedule -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) EXTERN _tx_execution_thread_exit #endif @@ -32,7 +32,7 @@ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_system_return Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -65,73 +65,78 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_system_return(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_system_return +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_system_return -; /* Save minimal context on the stack. */ +; /* Save minimal context on the stack. */ ; - STMDB sp!, {r4-r11, lr} ; Save minimal context - LDR r5, =_tx_thread_current_ptr ; Pickup address of current ptr - LDR r6, [r5, #0] ; Pickup current thread pointer + PUSH {r4-r11, lr} ; Save minimal context -#ifdef __ARMVFP__ - LDR r0, [r6, #144] ; Pickup the VFP enabled flag - CMP r0, #0 ; Is the VFP enabled? - BEQ _tx_skip_solicited_vfp_save ; No, skip VFP solicited save - VMRS r4, FPSCR ; Pickup the FPSCR - STR r4, [sp, #-4]! ; Save FPSCR - VSTMDB sp!, {D16-D31} ; Save D16-D31 - VSTMDB sp!, {D8-D15} ; Save D8-D15 -_tx_skip_solicited_vfp_save + LDR r4, =_tx_thread_current_ptr ; Pickup address of current ptr + LDR r5, [r4] ; Pickup current thread pointer + +#ifdef TX_ENABLE_VFP_SUPPORT + LDR r1, [r5, #144] ; Pickup the VFP enabled flag + CMP r1, #0 ; Is the VFP enabled? + BEQ _tx_skip_solicited_vfp_save ; No, skip VFP solicited save + VMRS r1, FPSCR ; Pickup the FPSCR + STR r1, [sp, #-4]! ; Save FPSCR + VSTMDB sp!, {D16-D31} ; Save D16-D31 + VSTMDB sp!, {D8-D15} ; Save D8-D15 +_tx_skip_solicited_vfp_save: #endif - MOV r0, #0 ; Build a solicited stack type - MRS r1, CPSR ; Pickup the CPSR - STMDB sp!, {r0-r1} ; Save type and CPSR -; -; /* Lockout interrupts. */ -; + MOV r0, #0 ; Build a solicited stack type + MRS r1, CPSR ; Pickup the CPSR, T bit is always cleared by hardware + TST lr, #1 ; Check if calling function is in Thumb mode + IT NE + ORRNE r1, #0x20 ; Set the T bit so that the correct mode is set on return + PUSH {r0-r1} ; Save type and CPSR + #ifdef TX_ENABLE_FIQ_SUPPORT - CPSID if ; Disable IRQ and FIQ interrupts + CPSID if ; Disable IRQ and FIQ #else - CPSID i ; Disable IRQ interrupts + CPSID i ; Disable IRQ #endif -#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 +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + +; /* 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 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, [r6, #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 the current remaining 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, [r6, #24] ; Store current time-slice + MOV r3, r4 ; Pickup address of current ptr + MOV r0, r5 ; Pickup current thread pointer + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + LDR r1, [r2] ; Pickup current time slice + +; /* Save current stack and switch to system stack. */ + + STR sp, [r0, #8] ; Save thread stack pointer + +; /* Determine if the time-slice is active. */ + + 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. */ + + STR r4, [r2] ; Clear time-slice + STR r1, [r0, #24] ; Save current time-slice ; ; } __tx_thread_dont_save_ts @@ -139,9 +144,8 @@ __tx_thread_dont_save_ts ; /* Clear the current thread pointer. */ ; _tx_thread_current_ptr = TX_NULL; ; - STR r4, [r5, #0] ; Clear current thread pointer - - B _tx_thread_schedule ; Jump to scheduler! + STR r4, [r3] ; Clear current thread pointer + B _tx_thread_schedule ; Jump to scheduler! ; ;} END diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_vectored_context_save.s b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_vectored_context_save.s index 202ab5d4..157eda49 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_thread_vectored_context_save.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_thread_vectored_context_save.s @@ -31,7 +31,7 @@ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_thread_vectored_context_save Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -63,13 +63,20 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_thread_vectored_context_save(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_thread_vectored_context_save +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_thread_vectored_context_save ; ; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked diff --git a/ports_module/cortex_a7/iar/module_manager/src/tx_timer_interrupt.s b/ports_module/cortex_a7/iar/module_manager/src/tx_timer_interrupt.s index 29e1c9be..b79fdac4 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/tx_timer_interrupt.s +++ b/ports_module/cortex_a7/iar/module_manager/src/tx_timer_interrupt.s @@ -39,7 +39,7 @@ ;/* FUNCTION RELEASE */ ;/* */ ;/* _tx_timer_interrupt Cortex-A7/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* William E. Lamie, Microsoft Corporation */ @@ -74,13 +74,20 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _tx_timer_interrupt(VOID) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _tx_timer_interrupt +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _tx_timer_interrupt ; ; /* Upon entry to this routine, it is assumed that context save has already @@ -193,7 +200,7 @@ __tx_timer_done __tx_something_expired ; ; - STMDB sp!, {r0, lr} ; Save the lr register on the stack + PUSH {r0, lr} ; Save the lr register on the stack ; and save r0 just to keep 8-byte alignment ; ; /* Did a timer expire? */ @@ -231,7 +238,7 @@ __tx_timer_dont_activate ; __tx_timer_not_ts_expiration ; - LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for + POP {r0, lr} ; Recover lr register (r0 is just there for ; the 8-byte stack alignment ; ; } diff --git a/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_thread_stack_build.s b/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_thread_stack_build.s index 46ff4ec7..c1c37db9 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_thread_stack_build.s +++ b/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_thread_stack_build.s @@ -35,7 +35,7 @@ CPSR_MASK EQU 0x9F ; Mask initial CPSR, IRQ ints en ;/* FUNCTION RELEASE */ ;/* */ ;/* _txm_module_manager_thread_stack_build Cortex-A7/MMU/IAR */ -;/* 6.1 */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* Scott Larson, Microsoft Corporation */ @@ -68,13 +68,20 @@ CPSR_MASK EQU 0x9F ; Mask initial CPSR, IRQ ints en ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ ;VOID _txm_module_manager_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(TX_THREAD *, TXM_MODULE_INSTANCE *)) ;{ RSEG .text:CODE:NOROOT(2) PUBLIC _txm_module_manager_thread_stack_build +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _txm_module_manager_thread_stack_build ; ; @@ -132,13 +139,15 @@ _txm_module_manager_thread_stack_build STR r1, [r2, #64] ; Store initial pc STR r3, [r2, #68] ; 0 for back-trace MRS r3, CPSR ; Pickup CPSR - BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR + BIC r3, #CPSR_MASK ; Mask mode bits of CPSR TST r1, #1 ; Test if THUMB bit set in initial PC - ORRNE r3, r3, #THUMB_MASK ; Set T bit if set + IT NE + ORRNE r3, #THUMB_MASK ; Set T bit if set LDR r1, [r0, #156] ; Load tx_thread_module_current_user_mode TST r1, #1 ; Test if the flag is set - ORREQ r3, r3, #SYS_MODE ; Flag not set: Build CPSR, SYS mode, IRQ enabled - ORRNE r3, r3, #USR_MODE ; Flag set: Build CPSR, USR mode, IRQ enabled + ITE EQ + ORREQ r3, #SYS_MODE ; Flag not set: Build CPSR, SYS mode, IRQ enabled + ORRNE r3, #USR_MODE ; Flag set: Build CPSR, USR mode, IRQ enabled STR r3, [r2, #4] ; Store initial CPSR ; ; /* Setup stack pointer. */ diff --git a/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_user_mode_entry.s b/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_user_mode_entry.s index 501c79bb..6f45aad6 100644 --- a/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_user_mode_entry.s +++ b/ports_module/cortex_a7/iar/module_manager/src/txm_module_manager_user_mode_entry.s @@ -20,7 +20,6 @@ ;/**************************************************************************/ ;/**************************************************************************/ ; - EXTERN _tx_thread_current_ptr EXTERN _txm_module_manager_kernel_dispatch @@ -28,8 +27,8 @@ ;/* */ ;/* FUNCTION RELEASE */ ;/* */ -;/* tx Cortex-A7/MMU/IAR */ -;/* 6.1 */ +;/* tx Cortex-A7/MMU/IAR */ +;/* 6.x */ ;/* AUTHOR */ ;/* */ ;/* Scott Larson, Microsoft Corporation */ @@ -60,18 +59,29 @@ ;/* DATE NAME DESCRIPTION */ ;/* */ ;/* 09-30-2020 Scott Larson Initial Version 6.1 */ +;/* xx-xx-xxxx Yajun Xia Modified comment(s), */ +;/* Added thumb mode support, */ +;/* resulting in version 6.x */ ;/* */ ;/**************************************************************************/ RSEG .text:CODE:NOROOT(2) PUBLIC _txm_module_manager_user_mode_entry +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _txm_module_manager_user_mode_entry PUBLIC _txm_system_mode_enter +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _txm_system_mode_enter SVC 1 ; Get out of user mode -_txm_module_priv + ; At this point, we are in system mode. ; Save LR (and r3 for 8 byte aligned stack) and call the kernel dispatch function. PUSH {r3, lr} @@ -79,7 +89,11 @@ _txm_module_priv POP {r3, lr} PUBLIC _txm_system_mode_exit +#ifdef THUMB_MODE + THUMB +#else ARM +#endif _txm_system_mode_exit ; Trap to restore user mode while inside of ThreadX SVC 2