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/ac5/src | |
| parent | 608f55f0d120886e0eddf7e39cf3c3b6f06bd08c (diff) | |
add ARM11v6.0.1_rel
Diffstat (limited to 'ports/arm11/ac5/src')
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_context_restore.s | 247 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_context_save.s | 207 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_fiq_context_restore.s | 259 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_fiq_context_save.s | 203 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s | 111 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s | 104 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_interrupt_control.s | 102 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_interrupt_disable.s | 98 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_interrupt_restore.s | 87 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_irq_nesting_end.s | 110 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_irq_nesting_start.s | 104 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_schedule.s | 172 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_stack_build.s | 156 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_system_return.s | 150 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_thread_vectored_context_save.s | 209 | ||||
| -rw-r--r-- | ports/arm11/ac5/src/tx_timer_interrupt.s | 258 |
16 files changed, 2577 insertions, 0 deletions
diff --git a/ports/arm11/ac5/src/tx_thread_context_restore.s b/ports/arm11/ac5/src/tx_thread_context_restore.s new file mode 100644 index 00000000..1d6cd60f --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_context_restore.s @@ -0,0 +1,247 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +IRQ_MODE EQU 0xD2 ; IRQ mode +SVC_MODE EQU 0xD3 ; SVC mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +THUMB_MASK EQU 0x20 ; Thumb bit mask +SVC_MODE_BITS EQU 0x13 ; SVC mode value +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_execute_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IMPORT _tx_thread_preempt_disable + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_exit + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_context_restore +_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 + + IF :DEF: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/ac5/src/tx_thread_context_save.s b/ports/arm11/ac5/src/tx_thread_context_save.s new file mode 100644 index 00000000..6ce74590 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_context_save.s @@ -0,0 +1,207 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF + + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT __tx_irq_processing_return + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_save ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_context_save +_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 + IF :DEF: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 + + IF :DEF: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 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, 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 + + IF :DEF: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 + + IF :DEF: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/ac5/src/tx_thread_fiq_context_restore.s b/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s new file mode 100644 index 00000000..a183032b --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s @@ -0,0 +1,259 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** 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 EQU 0xD3 ; SVC mode +FIQ_MODE EQU 0xD1 ; FIQ mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +THUMB_MASK EQU 0x20 ; Thumb bit mask +IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits +SVC_MODE_BITS EQU 0x13 ; SVC mode value +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_system_stack_ptr + IMPORT _tx_thread_execute_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IMPORT _tx_thread_preempt_disable + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_exit + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_restore ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_fiq_context_restore +_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 + + IF :DEF: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/ac5/src/tx_thread_fiq_context_save.s b/ports/arm11/ac5/src/tx_thread_fiq_context_save.s new file mode 100644 index 00000000..370e0946 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_context_save.s @@ -0,0 +1,203 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT __tx_fiq_processing_return + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_save ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_fiq_context_save +_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 + + IF :DEF: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 + + IF :DEF: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. */ +; + IF :DEF: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/ac5/src/tx_thread_fiq_nesting_end.s b/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s new file mode 100644 index 00000000..5d81879d --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s @@ -0,0 +1,111 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +FIQ_MODE_BITS EQU 0x11 ; FIQ mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_end ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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.s). */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_fiq_nesting_end +_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 + LDMIA sp!, {r1, lr} ; Pickup saved lr (and r1 throw-away for + ; 8-byte alignment logic) + 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 + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s b/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s new file mode 100644 index 00000000..32c1b258 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s @@ -0,0 +1,104 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +FIQ_DISABLE EQU 0x40 ; FIQ disable bit +MODE_MASK EQU 0x1F ; Mode mask +SYS_MODE_BITS EQU 0x1F ; System mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_start ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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.s). */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_fiq_nesting_start +_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 + STMDB sp!, {r1, lr} ; Push the system mode lr on the system mode stack + ; and push r1 just to keep 8-byte alignment + BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_control.s b/ports/arm11/ac5/src/tx_thread_interrupt_control.s new file mode 100644 index 00000000..f11c820e --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_interrupt_control.s @@ -0,0 +1,102 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +INT_MASK EQU 0xC0 ; Interrupt bit mask + ELSE +INT_MASK EQU 0x80 ; Interrupt bit mask + ENDIF +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_control ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_interrupt_control +_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 + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_disable.s b/ports/arm11/ac5/src/tx_thread_interrupt_disable.s new file mode 100644 index 00000000..a3145dab --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_interrupt_disable.s @@ -0,0 +1,98 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_disable ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_interrupt_disable +_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 + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_restore.s b/ports/arm11/ac5/src/tx_thread_interrupt_restore.s new file mode 100644 index 00000000..aad4e743 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_interrupt_restore.s @@ -0,0 +1,87 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_restore ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_restore(UINT old_posture) +;{ + EXPORT _tx_thread_interrupt_restore +_tx_thread_interrupt_restore +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r0 ; Setup new CPSR + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s b/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s new file mode 100644 index 00000000..415d6152 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s @@ -0,0 +1,110 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_end ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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.s). */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_irq_nesting_end +_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 + LDMIA sp!, {r1, lr} ; Pickup saved lr (and r1 throw-away for + ; 8-byte alignment logic) + 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 + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} + END + diff --git a/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s b/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s new file mode 100644 index 00000000..417235dd --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s @@ -0,0 +1,104 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +IRQ_DISABLE EQU 0x80 ; IRQ disable bit +MODE_MASK EQU 0x1F ; Mode mask +SYS_MODE_BITS EQU 0x1F ; System mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_start ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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.s). */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_irq_nesting_start +_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 + STMDB sp!, {r1, lr} ; Push the system mode lr on the system mode stack + ; and push r1 just to keep 8-byte alignment + BIC r0, r0, #IRQ_DISABLE ; Build enable IRQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_schedule.s b/ports/arm11/ac5/src/tx_thread_schedule.s new file mode 100644 index 00000000..0347394e --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_schedule.s @@ -0,0 +1,172 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +ENABLE_INTS EQU 0xC0 ; IRQ & FIQ Interrupts enabled mask + ELSE +ENABLE_INTS EQU 0x80 ; IRQ Interrupts enabled mask + ENDIF +; +; + IMPORT _tx_thread_execute_ptr + IMPORT _tx_thread_current_ptr + IMPORT _tx_timer_time_slice + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_thread_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_schedule +_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; +; + IF :DEF: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 + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_stack_build.s b/ports/arm11/ac5/src/tx_thread_stack_build.s new file mode 100644 index 00000000..d9b68fa9 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_stack_build.s @@ -0,0 +1,156 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +SVC_MODE EQU 0x13 ; SVC mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +CPSR_MASK EQU 0xDF ; Mask initial CPSR, IRQ & FIQ ints enabled + ELSE +CPSR_MASK EQU 0x9F ; Mask initial CPSR, IRQ ints enabled + ENDIF +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_stack_build ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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)) +;{ + EXPORT _tx_thread_stack_build +_tx_thread_stack_build +; +; +; /* Build a fake interrupt frame. The form of the fake interrupt stack +; on the ARM11 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 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 + 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 + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} + END + diff --git a/ports/arm11/ac5/src/tx_thread_system_return.s b/ports/arm11/ac5/src/tx_thread_system_return.s new file mode 100644 index 00000000..9bfd95d9 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_system_return.s @@ -0,0 +1,150 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF +; +; + IMPORT _tx_thread_current_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_thread_exit + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_system_return ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_system_return +_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 + + IF :DEF: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/ac5/src/tx_thread_vectored_context_save.s b/ports/arm11/ac5/src/tx_thread_vectored_context_save.s new file mode 100644 index 00000000..f318ff3d --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_vectored_context_save.s @@ -0,0 +1,209 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_vectored_context_save ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_thread_vectored_context_save +_tx_thread_vectored_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++) +; { +; + IF :DEF: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 + + IF :DEF: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 + + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +__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! +; +; /* 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_thread_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + + IF :DEF: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 + + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +; } +; 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 + + IF :DEF: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 + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +; } +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_timer_interrupt.s b/ports/arm11/ac5/src/tx_timer_interrupt.s new file mode 100644 index 00000000..158f6930 --- /dev/null +++ b/ports/arm11/ac5/src/tx_timer_interrupt.s @@ -0,0 +1,258 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** 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... +; + IMPORT _tx_timer_time_slice + IMPORT _tx_timer_system_clock + IMPORT _tx_timer_current_ptr + IMPORT _tx_timer_list_start + IMPORT _tx_timer_list_end + IMPORT _tx_timer_expired_time_slice + IMPORT _tx_timer_expired + IMPORT _tx_thread_time_slice + IMPORT _tx_timer_expiration_process +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* 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) +;{ + EXPORT _tx_timer_interrupt +_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 +; + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +;} + END + |
