updated to 6.0.1 and added additional processors/toolchains

This commit is contained in:
tameraw
2020-07-16 14:32:40 -07:00
parent f8e91d4762
commit 2c35570dc9
1285 changed files with 550383 additions and 50 deletions

View File

@@ -0,0 +1,107 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/** Initialize */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_initialize.h"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_initialize_fast_interrupt_setup ARC_HS/MetaWare */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function initializes register bank 1 for fast interrupt use. */
;/* The initialization includes setting the stack pointer to the value */
;/* supplied by the caller. */
;/* */
;/* INPUT */
;/* */
;/* stack_ptr Pointer to stack for bank 1 */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* None */
;/* */
;/* CALLED BY */
;/* */
;/* Application */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
;/* */
;/**************************************************************************/
;VOID _tx_initialize_fast_interrupt_setup(VOID *stack_ptr)
;{
.global _tx_initialize_fast_interrupt_setup
.type _tx_initialize_fast_interrupt_setup, @function
_tx_initialize_fast_interrupt_setup:
;
; /* Assume this routine is being called from initialization, with interrupts
; disabled and from register bank 0. Also assume that the stack pointer
; input is valid, i.e., there is no error checking on the validity of
; register_bank. */
;
sub sp, sp, 8 ; Build a small stack frame to hold the setup information
st gp, [sp, 0] ; Save gp in the frame
st r0, [sp, 4] ; Save sp in the frame
mov ilink, sp ; Move the stack frame into ilink
mov r1, 1 ; Select register bank 1
asl r2, r1, 16 ; Move the register bank bits over to proper location
lr r3, [status32] ; Pickup status32 register
or r3, r3, r2 ; Build new status32 register
kflag r3 ; Move to the hardware register bank
mov r0, ilink ; Place stack pointer in r0
ld sp, [r0, 4] ; Setup stack pointer for this hardware register bank
mov fp, 0 ; Setup fp
ld gp, [r0, 0] ; Setup gp
mov blink, 0 ; Setup blink
mov r0, 0 ; Clear r0
sub sp, sp, 8 ; Reserve space for saving ilink and status32.p0 on thread preemption
lr r3, [status32] ; Pickup status32 register
bclr r3, r3, 16 ; Build register bank 0 value
bclr r3, r3, 17 ;
bclr r3, r3, 18 ;
kflag r3 ; Move back to register bank 0
j_s.d [blink] ; Return to caller
add sp, sp, 8 ;
;}
.end

View File

@@ -0,0 +1,303 @@
;/**************************************************************************/
;/* */
;/* 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
;
.equ BTA, 0x412
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_fast_restore ARC_HS/MetaWare */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function restores the fast interrupt context, which can be a */
;/* nesting condition on a non-fast ISR, an idle system restore, a */
;/* restore of an interrupted thread, and a preemption of an interrupted*/
;/* thread. */
;/* */
;/* 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_fast_restore(VOID)
;{
.global _tx_thread_context_fast_restore
.type _tx_thread_context_fast_restore, @function
_tx_thread_context_fast_restore:
;
; /* Note: it is assumed that the stack pointer is in the same position now as
; it was after the last context fast save call. */
;
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR exit function to indicate an ISR is complete. */
;
bl.d _tx_execution_isr_exit ; Call the ISR exit function
sub sp, sp, 16 ; ..allocating some space on the stack
add sp, sp, 16 ; Recover the stack space
.endif
;
; /* Determine if interrupts are nested. */
; if (--_tx_thread_system_state)
; {
;
ld r0, [gp, _tx_thread_system_state@sda] ; Pickup system state contents
sub r0, r0, 1 ; Decrement the system state
st r0, [gp, _tx_thread_system_state@sda] ; Store the new system state
breq r0, 0, __tx_thread_not_nested_restore ; If zero, not a nested interrupt
;
; /* Interrupts are nested. */
;
; /* Just recover the saved registers and return to the point of
; interrupt. */
;
__tx_thread_nested_restore:
rtie ; Return from 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))
; {
;
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread pointer
ld r2, [gp, _tx_thread_preempt_disable@sda] ; Pickup preempt disable flag
sub.f 0, r0, 0 ; Set condition codes
beq.d __tx_thread_idle_system_restore ; If NULL, idle system was interrupted
lr r4, [AUX_IRQ_ACT] ; Pickup the interrupt active register
neg r5, r4 ; Negate
and r5, r4, r5 ; See if there are any other interrupts present
brne.d r4, r5, __tx_thread_no_preempt_restore ; If more interrupts, just return to the point of interrupt
ld r4, [gp, _tx_thread_execute_ptr@sda] ; Pickup next thread to execute
brne r2, 0, __tx_thread_no_preempt_restore ; If set, don't preempt executing thread
brne r0, r4, __tx_thread_preempt_restore ; Not equal, preempt executing thread
;
;
__tx_thread_no_preempt_restore:
;
; /* Restore interrupted thread or ISR. */
;
; /* Pickup the saved stack pointer. */
; sp = _tx_thread_current_ptr -> tx_thread_stack_ptr;
;
; /* Return to the point of interrupt. */
;
rtie ; Return from interrupt
;
; }
; else
; {
__tx_thread_preempt_restore:
;
lr r3, [status32_p0] ; Pickup the interrupted status32.p0 register
lsr r4, r3, 16 ; Move the register bank bits down
and r4, r4, 7 ; Isolate the register bank
breq r4, 0, __tx_software_interrupt_context ; If register bank 0, software interrupt context is present
st ilink, [sp, 0] ; Save ilink (point of interrupt)
st r3, [sp, 4] ; Save actual status32.p0
bclr r4, r3, 16 ; Build register bank 0 value
bclr r4, r4, 17 ;
bclr r4, r4, 18 ;
sr r4, [status32_p0] ; Setup status32.p0 to return to bank 0 when fast ISR is finishe
mov ilink, sp ; Pass the information back to the other register bank via ilink
bclr r3, r3, 31 ; Make sure interrupts are not enabled
kflag r3 ; Switch back to the interrupted thread's hardware register bank
sub sp, sp, 168 ; Allocate an hardware interrupt stack frame
st r0, [sp, 132] ; Temporarily save r0
mov r0, 3 ; Build hardware interrupt stack type
st r0, [sp, 0] ; Setup interrupt stack type
.ifndef TX_DISABLE_LP
lr r0, [LP_START] ; Pickup LP_START
st r0, [sp, 4] ; Save LP_START
lr r0, [LP_END] ; Pickup LP_END
st r0, [sp, 8] ; Save LP_END
st LP_COUNT, [sp, 12] ; Save LP_COUNT
.endif
lr r0, [BTA] ; Pickup BTA
st r0, [sp, 156] ; Save BTA
ld r0, [ilink, 0] ; Pickup the point of interrupt
st r0, [sp, 160] ; Setup the point of interrupt
st r0, [sp, 20] ; Save ilink
ld r0, [ilink, 4] ; Pickup the status32
st r0, [sp, 164] ; Setup the status32
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread pointer
st sp, [r0, 8] ; Save stack pointer in thread control block
ld r0, [sp, 132] ; Restore r0
lr ilink, [status32] ; Pickup status32 register
bset ilink, ilink, 16 ; Build register bank 1 value
bclr ilink, ilink, 17 ;
bclr ilink, ilink, 18 ;
kflag ilink ; Move back to register bank 0
b __tx_preempt_save_done ; Done, finished with preemption save
__tx_software_interrupt_context:
st ilink, [sp, 0] ; Save ilink (point of interrupt)
st r3, [sp, 4] ; Save status32
mov ilink, sp ; Pass the information back to the other register bank via ilink
bclr r3, r3, 31 ; Make sure interrupts are not enabled
kflag r3 ; Switch back to the interrupted thread's hardware register bank
sub sp, sp, 168 ; Allocate an hardware interrupt stack frame
st blink, [sp, 16] ; Save blink
st fp, [sp, 24] ; Save fp
st gp, [sp, 28] ; Save gp
st r25, [sp, 32] ; Save r25
st r24, [sp, 36] ; Save r24
st r23, [sp, 40] ; Save r23
st r22, [sp, 44] ; Save r22
st r21, [sp, 48] ; Save r21
st r20, [sp, 52] ; Save r20
st r19, [sp, 56] ; Save r19
st r18, [sp, 60] ; Save r18
st r17, [sp, 64] ; Save r17
st r16, [sp, 68] ; Save r16
st r15, [sp, 72] ; Save r15
st r14, [sp, 76] ; Save r14
st r13, [sp, 80] ; Save r13
st r12, [sp, 84] ; Save r12
st r11, [sp, 88] ; Save r11
st r10, [sp, 92] ; Save r10
st r9, [sp, 96] ; Save r9
st r8, [sp, 100] ; Save r8
st r7, [sp, 104] ; Save r7
st r6, [sp, 108] ; Save r6
st r5, [sp, 112] ; Save r5
st r4, [sp, 116] ; Save r6
st r3, [sp, 120] ; Save r3
st r2, [sp, 124] ; Save r2
st r1, [sp, 128] ; Save r1
st r0, [sp, 132] ; Save r0
st r30, [sp, 136] ; Save r30
.ifndef TX_DISABLE_LP
lr r10, [LP_START] ; Pickup LP_START
lr r9, [LP_END] ; Pickup LP_END
st LP_COUNT, [sp, 12] ; Save LP_COUNT
st r10, [sp, 4] ; Save LP_START
st r9, [sp, 8] ; Save LP_END
.endif
lr r0, [BTA] ; Pickup BTA
st r0, [sp, 156] ; Save BTA
mov r6, 1 ; Build interrupt stack type
st r6, [sp, 0] ; Setup interrupt stack type
ld r0, [ilink, 0] ; Pickup the point of interrupt
st r0, [sp, 160] ; Setup the point of interrupt
st r0, [sp, 20] ; Save ilink
ld r0, [ilink, 4] ; Pickup the status32
st r0, [sp, 164] ; Setup the status32
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread pointer
st sp, [r0, 8] ; Save stack pointer in thread control block
lr ilink, [status32] ; Pickup status32 register
bset ilink, ilink, 16 ; Build register bank 1 value
bclr ilink, ilink, 17 ;
bclr ilink, ilink, 18 ;
kflag ilink ; Move back to register bank 1
__tx_preempt_save_done:
;
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread ptr
;
; /* Save the remaining time-slice and disable it. */
; if (_tx_timer_time_slice)
; {
;
ld r2, [gp, _tx_timer_time_slice@sda] ; Pickup time-slice contents
mov r7, 0 ; Build clear/NULL value
breq r2, 0, __tx_thread_dont_save_ts ; No time-slice, don't need to save it
;
; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
; _tx_timer_time_slice = 0;
;
st r2, [r0, 24] ; If set, save remaining time-slice
st r7, [gp, _tx_timer_time_slice@sda] ; If set, clear time slice
;
; }
__tx_thread_dont_save_ts:
;
;
; /* Clear the current thread pointer. */
; _tx_thread_current_ptr = TX_NULL;
;
st r7, [gp, _tx_thread_current_ptr@sda] ; Set current thread ptr to NULL
mov ilink, _tx_thread_schedule ; Build address of scheduler
rtie ; Return from interrupt to scheduler
;
; }
;
; /* Return to the scheduler. */
; _tx_thread_schedule();
;
__tx_thread_idle_system_restore:
lr r4, [AUX_IRQ_ACT] ; Pickup the interrupt active register
neg r5, r4 ; Negate
and r5, r4, r5 ; See if there are any other interrupts present
sub.f 0, r4, r5 ; Set condition codes
bne __tx_thread_nested_restore ; If more interrupts, just return to the point of interrupt
mov ilink, _tx_thread_schedule ; Build address of scheduler
rtie ; Return from interrupt to scheduler
;
;}
.end

View File

@@ -0,0 +1,108 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_fast_save ARC_HS/MetaWare */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function saves the context of an executing thread in the */
;/* beginning of fast interrupt processing. The function assumes that */
;/* fast interrupts are enabled (priority 0) and multiple register */
;/* banks are available. In this case, register bank 1 is reserved by */
;/* hardware for fast interrupts. Additional assumptions include that */
;/* there will be no nested fast interrupts and the LP_START, LP_END, */
;/* and LP_COUNT registers are not used in the application's fast */
;/* interrupt 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_fast_save(VOID)
;{
.global _tx_thread_context_fast_save
.type _tx_thread_context_fast_save, @function
_tx_thread_context_fast_save:
;
; /* Increment nested interrupt count. */
; _tx_thread_system_state++;
;
ld r0, [gp, _tx_thread_system_state@sda] ; Pickup system state
add r0, r0, 1 ; Increment the nested interrupt count
st r0, [gp, _tx_thread_system_state@sda] ; Update system state
;
;
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
bl.d _tx_execution_isr_enter ; Call the ISR enter function
nop ; Delay slot
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
;
j [blink] ; Return to the ISR
;
;}
.end

View File

@@ -0,0 +1,322 @@
;/**************************************************************************/
;/* */
;/* 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
;
.equ BTA, 0x412
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_restore ARC_HS/MetaWare */
;/* 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)
;{
.global _tx_thread_context_restore
.type _tx_thread_context_restore, @function
_tx_thread_context_restore:
;
; /* Note: it is assumed that the stack pointer is in the same position now as
; it was after the last context save call. */
;
; /* Lockout interrupts. */
;
clri ; Disable interrupts
nop ; Delay for interrupts to really be disabled
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR exit function to indicate an ISR is complete. */
;
bl.d _tx_execution_isr_exit ; Call the ISR exit function
sub sp, sp, 16 ; ..allocating some space on the stack
add sp, sp, 16 ; Recover the stack space
.endif
;
; /* Determine if interrupts are nested. */
; if (--_tx_thread_system_state)
; {
;
ld r0, [gp, _tx_thread_system_state@sda] ; Pickup system state contents
sub r0, r0, 1 ; Decrement the system state
st r0, [gp, _tx_thread_system_state@sda] ; Store the new system state
breq r0, 0, __tx_thread_not_nested_restore ; If zero, not a nested interrupt
;
; /* Interrupts are nested. */
;
; /* Just recover the saved registers and return to the point of
; interrupt. */
;
__tx_thread_nested_restore:
.ifndef TX_DISABLE_LP
ld r0, [sp, 4] ; Recover LP_START
sr r0, [LP_START] ; Restore LP_START
ld r1, [sp, 8] ; Recover LP_END
sr r1, [LP_END] ; Restore LP_END
ld r2, [sp, 12] ; Recover LP_COUNT
mov LP_COUNT, r2
.endif
ld r2, [sp, 156] ; Pickup BTA
sr r2, [BTA] ; Recover BTA
.ifdef TX_ENABLE_ACC
ld r58, [sp, 140] ; Recover r58
ld r59, [sp, 144] ; Recover r59
.endif
ld blink, [sp, 16] ; Recover blink
ld r12, [sp, 84] ; Recover r12
ld r11, [sp, 88] ; Recover r11
ld r10, [sp, 92] ; Recover r10
ld r9, [sp, 96] ; Recover r9
ld r8, [sp, 100] ; Recover r8
ld r7, [sp, 104] ; Recover r7
ld r6, [sp, 108] ; Recover r6
ld r5, [sp, 112] ; Recover r5
ld r4, [sp, 116] ; Recover r4
ld r3, [sp, 120] ; Recover r3
ld r2, [sp, 124] ; Recover r2
ld r1, [sp, 128] ; Recover r1
ld r0, [sp, 132] ; Recover r0
add sp, sp, 160 ; Recover interrupt stack frame
rtie ; Return from 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))
; {
;
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread pointer
ld r2, [gp, _tx_thread_preempt_disable@sda] ; Pickup preempt disable flag
sub.f 0, r0, 0 ; Set condition codes
beq.d __tx_thread_idle_system_restore ; If NULL, idle system was interrupted
lr r4, [AUX_IRQ_ACT] ; Pickup the interrupt active register
neg r5, r4 ; Negate
and r5, r4, r5 ; See if there are any other interrupts present
brne.d r4, r5, __tx_thread_no_preempt_restore ; If more interrupts, just return to the point of interrupt
ld r4, [gp, _tx_thread_execute_ptr@sda] ; Pickup next thread to execute
brne r2, 0, __tx_thread_no_preempt_restore ; If set, don't preempt executing thread
brne r0, r4, __tx_thread_preempt_restore ; Not equal, preempt executing thread
;
;
__tx_thread_no_preempt_restore:
;
; /* Restore interrupted thread or ISR. */
;
; /* Pickup the saved stack pointer. */
; sp = _tx_thread_current_ptr -> tx_thread_stack_ptr;
;
; /* Recover the saved context and return to the point of interrupt. */
;
ld sp, [r0, 8] ; Switch back to thread's stack
.ifndef TX_DISABLE_LP
ld r0, [sp, 4] ; Recover LP_START
sr r0, [LP_START] ; Restore LP_START
ld r1, [sp, 8] ; Recover LP_END
sr r1, [LP_END] ; Restore LP_END
ld r2, [sp, 12] ; Recover LP_COUNT
mov LP_COUNT, r2
.endif
ld r2, [sp, 156] ; Pickup BTA
sr r2, [BTA] ; Recover BTA
.ifdef TX_ENABLE_ACC
ld r58, [sp, 140] ; Recover r58
ld r59, [sp, 144] ; Recover r59
.endif
ld blink, [sp, 16] ; Recover blink
ld r12, [sp, 84] ; Recover r12
ld r11, [sp, 88] ; Recover r11
ld r10, [sp, 92] ; Recover r10
ld r9, [sp, 96] ; Recover r9
ld r8, [sp, 100] ; Recover r8
ld r7, [sp, 104] ; Recover r7
ld r6, [sp, 108] ; Recover r6
ld r5, [sp, 112] ; Recover r5
ld r4, [sp, 116] ; Recover r4
ld r3, [sp, 120] ; Recover r3
ld r2, [sp, 124] ; Recover r2
ld r1, [sp, 128] ; Recover r1
ld r0, [sp, 132] ; Recover r0
add sp, sp, 160 ; Recover interrupt stack frame
rtie ; Return from interrupt
;
; }
; else
; {
__tx_thread_preempt_restore:
;
ld r7, [r0, 8] ; Pickup stack pointer
lr r3, [status32] ; Pickup the status32 register
lsr r4, r3, 16 ; Move the register bank bits down
and r4, r4, 7 ; Isolate the register bank
breq r4, 0, __tx_software_interrupt_context ; If register bank 0, software interrupt context is present
mov sp, r7 ; Setup sp in this register bank
mov r6, 3 ; Build hardware interrupt stack type
st r6, [sp, 0] ; Setup interrupt stack type
ld blink, [sp, 16] ; Recover blink
ld r12, [sp, 84] ; Recover r12
ld r11, [sp, 88] ; Recover r11
ld r10, [sp, 92] ; Recover r10
ld r9, [sp, 96] ; Recover r9
ld r8, [sp, 100] ; Recover r8
ld r7, [sp, 104] ; Recover r7
ld r6, [sp, 108] ; Recover r6
ld r5, [sp, 112] ; Recover r5
ld r4, [sp, 116] ; Recover r4
ld r3, [sp, 120] ; Recover r3
ld r2, [sp, 124] ; Recover r2
ld r1, [sp, 128] ; Recover r1
ld r0, [sp, 132] ; Recover r0
lr ilink, [status32] ; Pickup status32 register
bclr ilink, ilink, 16 ; Build register bank 0 value
bclr ilink, ilink, 17 ;
bclr ilink, ilink, 18 ;
kflag ilink ; Move back to register bank 0
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread ptr
b __tx_preempt_save_done ; Done, finished with preemption save
nop
__tx_software_interrupt_context:
mov r6, 1 ; Build interrupt stack type
st r6, [r7, 0] ; Setup interrupt stack type
st fp, [r7, 24] ; Save fp
st gp, [r7, 28] ; Save gp
st r25, [r7, 32] ; Save r25
st r24, [r7, 36] ; Save r24
st r23, [r7, 40] ; Save r23
st r22, [r7, 44] ; Save r22
st r21, [r7, 48] ; Save r21
st r20, [r7, 52] ; Save r20
st r19, [r7, 56] ; Save r19
st r18, [r7, 60] ; Save r18
st r17, [r7, 64] ; Save r17
st r16, [r7, 68] ; Save r16
st r15, [r7, 72] ; Save r15
st r14, [r7, 76] ; Save r14
st r13, [r7, 80] ; Save r13
st r30, [r7, 136] ; Save r30
__tx_preempt_save_done:
;
; /* Save the remaining time-slice and disable it. */
; if (_tx_timer_time_slice)
; {
;
ld r2, [gp, _tx_timer_time_slice@sda] ; Pickup time-slice contents
mov r7, 0 ; Build clear/NULL value
breq r2, 0, __tx_thread_dont_save_ts ; No time-slice, don't need to save it
;
; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
; _tx_timer_time_slice = 0;
;
st r2, [r0, 24] ; If set, save remaining time-slice
st r7, [gp, _tx_timer_time_slice@sda] ; If set, clear time slice
;
; }
__tx_thread_dont_save_ts:
;
;
; /* Clear the current thread pointer. */
; _tx_thread_current_ptr = TX_NULL;
;
st r7, [gp, _tx_thread_current_ptr@sda] ; Set current thread ptr to NULL
sub sp, sp, 8 ; Allocate a small stack frame on the system stack
lr r0, [STATUS32] ; Pickup STATUS32
st r0, [sp, 4] ; Place on stack
mov r0, _tx_thread_schedule ; Build address of scheduler
st r0, [sp, 0] ; Write over the point of interrupt
rtie ; Return from interrupt to scheduler
;
; }
;
; /* Return to the scheduler. */
; _tx_thread_schedule();
;
__tx_thread_idle_system_restore:
lr r4, [AUX_IRQ_ACT] ; Pickup the interrupt active register
neg r5, r4 ; Negate
and r5, r4, r5 ; See if there are any other interrupts present
sub.f 0, r4, r5 ; Set condition codes
bne __tx_thread_nested_restore ; If more interrupts, just return to the point of interrupt
lr r0, [STATUS32] ; Pickup STATUS32
st r0, [sp, 4] ; Place on stack
mov r0, _tx_thread_schedule ; Build address of scheduler
st r0, [sp, 0] ; Write over the point of interrupt
rtie ; Return from interrupt to scheduler
;
;}
.end

View File

@@ -0,0 +1,242 @@
;/**************************************************************************/
;/* */
;/* 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
;
.equ BTA, 0x412
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_save ARC_HS/MetaWare */
;/* 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)
;{
.global _tx_thread_context_save
.type _tx_thread_context_save, @function
_tx_thread_context_save:
;
; /* Upon entry to this routine, it is assumed that an interrupt stack frame
; has already been allocated, and the interrupted blink register is already saved. */
;
clri ; Disable interrupts
st r1, [sp, 128] ; Save r1
st r0, [sp, 132] ; Save r0
;
; /* Check for a nested interrupt condition. */
; if (_tx_thread_system_state++)
; {
;
ld r0, [gp, _tx_thread_system_state@sda] ; Pickup system state
st r3, [sp, 120] ; Save r3
st r2, [sp, 124] ; Save r2
breq r0, 0, __tx_thread_not_nested_save ; If 0, we are not in a nested
; condition
;
; /* Nested interrupt condition. */
;
add r0, r0, 1 ; Increment the nested interrupt count
st r0, [gp, _tx_thread_system_state@sda] ; Update system state
;
; /* Save the rest of the scratch registers on the stack and return to the
; calling ISR. */
;
__tx_thread_nested_save: ; Label is for special nested interrupt case from idle system save below
st r12, [sp, 84] ; Save r12
st r11, [sp, 88] ; Save r11
st r10, [sp, 92] ; Save r10
st r9, [sp, 96] ; Save r9
st r8, [sp, 100] ; Save r8
st r7, [sp, 104] ; Save r7
st r6, [sp, 108] ; Save r6
st r5, [sp, 112] ; Save r5
st r4, [sp, 116] ; Save r6
lr r10, [LP_START] ; Pickup LP_START
lr r9, [LP_END] ; Pickup LP_END
st LP_COUNT, [sp, 12] ; Save LP_COUNT
st r10, [sp, 4] ; Save LP_START
st r9, [sp, 8] ; Save LP_END
.ifdef TX_ENABLE_ACC
st r58, [sp, 140] ; Save r58
st r59, [sp, 144] ; Save r59
.endif
lr r0, [BTA] ; Pickup BTA
st r0, [sp, 156] ; Save BTA
;
; /* Return to the ISR. */
;
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
bl.d _tx_execution_isr_enter ; Call the ISR enter function
nop ; Delay slot
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
;
j.d [blink] ; Return to Level 1 ISR
st ilink, [sp, 20] ; Save ilink
;
__tx_thread_not_nested_save:
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
add r0, r0, 1 ; Increment the nested interrupt count
st r0, [gp, _tx_thread_system_state@sda] ; Update system state
ld r1, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread pointer
st r12, [sp, 84] ; Save r12
st r11, [sp, 88] ; Save r11
breq r1, 0, __tx_thread_idle_system_save ; If no thread is running, idle system was
; interrupted.
;
; /* Save minimal context of interrupted thread. */
;
st r10, [sp, 92] ; Save r10
st r9, [sp, 96] ; Save r9
st r8, [sp, 100] ; Save r8
st r7, [sp, 104] ; Save r7
st r6, [sp, 108] ; Save r6
st r5, [sp, 112] ; Save r5
st r4, [sp, 116] ; Save r4
lr r10, [LP_START] ; Pickup LP_START
lr r9, [LP_END] ; Pickup LP_END
st LP_COUNT, [sp, 12] ; Save LP_COUNT
st r10, [sp, 4] ; Save LP_START
st r9, [sp, 8] ; Save LP_END
st ilink, [sp, 20] ; Save ilink
.ifdef TX_ENABLE_ACC
st r58, [sp, 140] ; Save r58
st r59, [sp, 144] ; Save r59
.endif
lr r0, [BTA] ; Pickup BTA
st r0, [sp, 156] ; Save BTA
;
; /* Save the current stack pointer in the thread's control block. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
st sp, [r1, 8] ; Save thread's stack pointer
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
bl.d _tx_execution_isr_enter ; Call the ISR enter function
nop ; Delay slot
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
j_s.d [blink] ; Return to calling ISR
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
;
; }
; else
; {
;
__tx_thread_idle_system_save:
;
; /* Interrupt occurred in the scheduling loop. */
;
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
bl.d _tx_execution_isr_enter ; Call the ISR enter function
nop ; Delay slot
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
;
; /* See if we have a special nesting condition. This happens when the higher priority
; interrupt occurs before the nested interrupt logic is valid. */
;
lr r0, [AUX_IRQ_ACT] ; Pickup the interrupt active register
neg r1, r0 ; Negate
and r1, r0, r1 ; See if there are any other interrupts present
brne r0, r1, __tx_thread_nested_save ; If more interrupts, go into the nested interrupt save logic
;
; /* Not much to do here, just adjust the stack pointer, and return to
; ISR processing. */
;
j_s.d [blink] ; Return to ISR
add sp, sp, 160 ; Recover stack space
;
; }
;}
.end

View File

@@ -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"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_control ARC_HS/MetaWare */
;/* 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)
;{
.global _tx_thread_interrupt_control
.type _tx_thread_interrupt_control, @function
_tx_thread_interrupt_control:
;
; /* Pickup current interrupt lockout posture. */
;
clri r1 ; Get current interrupt state
;
; /* Apply the new interrupt posture. */
;
seti r0 ; Set desired interrupt state
j_s.d [blink] ; Return to caller with delay slot
mov r0, r1 ; Return previous mask value. Return value is TX_INT_DISABLE or TX_INT_ENABLE.
;
;}
.end

View File

@@ -0,0 +1,113 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_register_bank_assign ARC_HS/MetaWare */
;/* 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 */
;/* register_bank Register bank number */
;/* (1 through max-1) */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* None */
;/* */
;/* CALLED BY */
;/* */
;/* Application */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_register_bank_assign(VOID *thread_ptr, UINT register_bank)
;{
.global _tx_thread_register_bank_assign
.type _tx_thread_register_bank_assign, @function
_tx_thread_register_bank_assign:
;
; /* Assume this routine is being called from initialization, with interrupts
; disabled and from register bank 0. Also assume that the thread pointer and
; register bank input is valid, i.e., there is no error checking on the validity of
; the thread pointer or the register_bank.
;
; It is worth noting that if fast interrupts are being used, register bank 1
; is reserved for the fast interrupt processing, so thread register bank assignments
; should begin at bank 2. */
;
mov ilink, r0 ; Move the thread control block into ilink
asl r2, r1, 16 ; Move the register bank bits over to proper location
lr r3, [status32] ; Pickup status32 register
or r3, r3, r2 ; Build new status32 register
ld r4, [r0, 8] ; Pickup stack pointer for the thread
ld r5, [r4, 164] ; Pickup initial status32 from stack area
or r5, r5, r2 ; Modify initial status32 with register bank number
st r5, [r4, 164] ; Store initial status32 in stack area
kflag r3 ; Move to the hardware register bank
mov r0, ilink ; Place thread control block in r0
ld sp, [r0, 8] ; Setup stack pointer for this hardware register bank
ld fp, [sp, 24] ; Setup fp
ld gp, [sp, 28] ; Setup gp
ld blink, [sp, 16] ; Setup blink
ld ilink, [sp, 20] ; Setup ilink
lr r3, [status32] ; Pickup status32 register
bclr r3, r3, 16 ; Build register bank 0 value
bclr r3, r3, 17 ;
bclr r3, r3, 18 ;
kflag r3 ; Move back to register bank 0
mov r5, 3 ; Build type for hardware interrupt context
j_s.d [blink] ; Return to caller
st r5, [r4, 0] ; Set stack frame type
;}
.end

View File

@@ -0,0 +1,265 @@
;/**************************************************************************/
;/* */
;/* 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
;
;
.equ BTA, 0x412
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_schedule ARC_HS/MetaWare */
;/* 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)
;{
.global _tx_thread_schedule
.type _tx_thread_schedule, @function
_tx_thread_schedule:
;
; /* Switch to system stack. */
;
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
;
; /* Enable interrupts. */
;
mov r0, 0x1F ; Build enable interrupt value
seti r0 ; Enable interrupts
;
; /* Wait for a thread to execute. */
; do
; {
;
__tx_thread_schedule_loop:
;
ld r0, [gp, _tx_thread_execute_ptr@sda] ; Pickup next thread to execute
breq r0, 0, __tx_thread_schedule_loop ; If NULL, keep looking
;
; }
; while(_tx_thread_execute_ptr == TX_NULL);
;
; /* Yes! We have a thread to execute. Lockout interrupts and
; transfer control to it. */
;
clri ; Lockout interrupts
nop ; Delay for interrupts to really be disabled
;
; /* Setup the current thread pointer. */
; _tx_thread_current_ptr = _tx_thread_execute_ptr;
;
st r0, [gp, _tx_thread_current_ptr@sda] ; Setup current thread pointer
;
; /* Increment the run count for this thread. */
; _tx_thread_current_ptr -> tx_thread_run_count++;
;
ld r3, [r0, 4] ; Pickup run counter
ld r4, [r0, 24] ; Pickup time-slice for this thread
add r3, r3, 1 ; Increment run counter
st r3, [r0, 4] ; Store the new run counter
;
; /* Setup time-slice, if present. */
; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
;
st r4, [gp, _tx_timer_time_slice@sda] ; Setup time-slice
;
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the thread entry function to indicate the thread is executing. */
;
bl.d _tx_execution_thread_enter ; Call the thread execution enter function
sub sp, sp, 16 ; ..allocating some space on the stack
add sp, sp, 16 ; Recover the stack space
.endif
;
; /* Switch to the thread's stack. */
; sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
;
ld sp, [r0, 8] ; Switch to thread's stack
ld r1, [sp, 0] ; Pickup stack type
brlt r1, 2, __tx_restore_non_hw_context ; If less than 2, restore a software context
breq r1, 3, __tx_hw_interrupt_restore ; If interrupt restore, restore interrupted hardware context
ld r2, [sp, 4] ; Pickup status32
kflag r2 ; Enter the proper register bank
ld r3, [sp, 8] ; Pickup the saved interrupt posture
add sp, sp, 12 ; Recover small stack frame
j_s.d [blink] ; Return to thread and restore flags
seti r3 ; Recover STATUS32
__tx_hw_interrupt_restore:
mov r0, 0x2 ; Pretend level 1 interrupt is returning
sr r0, [AUX_IRQ_ACT] ;
.ifndef TX_DISABLE_LP
ld r0, [sp, 4] ; Recover LP_START
sr r0, [LP_START] ; Restore LP_START
ld r1, [sp, 8] ; Recover LP_END
sr r1, [LP_END] ; Restore LP_END
ld r2, [sp, 12] ; Recover LP_COUNT
mov LP_COUNT, r2
.endif
.ifdef TX_ENABLE_ACC
ld r58, [sp, 140] ; Recover r58
ld r59, [sp, 144] ; Recover r59
.endif
ld r0, [sp, 156] ; Pickup saved BTA
sr r0, [BTA] ; Recover BTA
ld ilink, [sp, 20] ; Recover ilink
ld r0, [sp, 164] ; Pickup the interrupted status32
bclr r0, r0, 31 ; Make sure interrupts are not enabled
kflag r0 ; Switch to the proper register bank
add sp, sp, 160 ; Recover the interrupt stack frame
rtie ; Return to point of interrupt
__tx_restore_non_hw_context:
;
; /* Determine if an interrupt frame or a synchronous task suspension frame
; is present. */
;
ld r1, [sp, 0] ; Pickup the stack type
brne r1, 0, __tx_thread_schedule_int_ret ; Compare to solicited stack type. If not, thread was interrupted
ld blink, [sp, 4] ; Recover blink
ld fp, [sp, 8] ; Recover fp
ld gp, [sp, 12] ; Recover gp
ld r25, [sp, 16] ; Recover r25
ld r24, [sp, 20] ; Recover r24
ld r23, [sp, 24] ; Recover r23
ld r22, [sp, 28] ; Recover r22
ld r21, [sp, 32] ; Recover r21
ld r20, [sp, 36] ; Recover r20
ld r19, [sp, 40] ; Recover r19
ld r18, [sp, 44] ; Recover r18
ld r17, [sp, 48] ; Recover r17
ld r16, [sp, 52] ; Recover r16
ld r15, [sp, 56] ; Recover r15
ld r14, [sp, 60] ; Recover r14
ld r13, [sp, 64] ; Recover r13
ld r1, [sp, 68] ; Pickup status32
ld r30, [sp, 72] ; Recover r30
add sp, sp, 76 ; Recover solicited stack frame
j_s.d [blink] ; Return to thread and restore flags
seti r1 ; Recover STATUS32
;
__tx_thread_schedule_int_ret:
;
mov r0, 0x2 ; Pretend level 1 interrupt is returning
sr r0, [AUX_IRQ_ACT] ;
.ifndef TX_DISABLE_LP
ld r0, [sp, 4] ; Recover LP_START
sr r0, [LP_START] ; Restore LP_START
ld r1, [sp, 8] ; Recover LP_END
sr r1, [LP_END] ; Restore LP_END
ld r2, [sp, 12] ; Recover LP_COUNT
mov LP_COUNT, r2
.endif
ld r0, [sp, 156] ; Pickup saved BTA
sr r0, [BTA] ; Recover BTA
ld blink, [sp, 16] ; Recover blink
ld ilink, [sp, 20] ; Recover ilink
ld fp, [sp, 24] ; Recover fp
ld gp, [sp, 28] ; Recover gp
ld r25, [sp, 32] ; Recover r25
ld r24, [sp, 36] ; Recover r24
ld r23, [sp, 40] ; Recover r23
ld r22, [sp, 44] ; Recover r22
ld r21, [sp, 48] ; Recover r21
ld r20, [sp, 52] ; Recover r20
ld r19, [sp, 56] ; Recover r19
ld r18, [sp, 60] ; Recover r18
ld r17, [sp, 64] ; Recover r17
ld r16, [sp, 68] ; Recover r16
ld r15, [sp, 72] ; Recover r15
ld r14, [sp, 76] ; Recover r14
ld r13, [sp, 80] ; Recover r13
ld r12, [sp, 84] ; Recover r12
ld r11, [sp, 88] ; Recover r11
ld r10, [sp, 92] ; Recover r10
ld r9, [sp, 96] ; Recover r9
ld r8, [sp, 100] ; Recover r8
ld r7, [sp, 104] ; Recover r7
ld r6, [sp, 108] ; Recover r6
ld r5, [sp, 112] ; Recover r5
ld r4, [sp, 116] ; Recover r4
ld r3, [sp, 120] ; Recover r3
ld r2, [sp, 124] ; Recover r2
ld r1, [sp, 128] ; Recover r1
ld r0, [sp, 132] ; Recover r0
ld r30, [sp, 136] ; Recover r30
.ifdef TX_ENABLE_ACC
ld r58, [sp, 140] ; Recover r58
ld r59, [sp, 144] ; Recover r59
.endif
add sp, sp, 160 ; Recover interrupt stack frame
rtie ; Return to point of interrupt
;
;}
;
.end

View File

@@ -0,0 +1,205 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
.equ LONG_ALIGN_MASK, 0xFFFFFFFC
.equ INT_ENABLE_BITS, 0x8000001E
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_stack_build ARC_HS/MetaWare */
;/* 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))
;{
.global _tx_thread_stack_build
.type _tx_thread_stack_build, @function
_tx_thread_stack_build:
;
;
; /* Build a fake interrupt frame. The form of the fake interrupt stack
; on the ARC HS should look like the following after it is built.
; Note that the extension registers are always assigned space here.
;
; Stack Top: 1 Interrupt stack frame type
; LP_START Initial loop start
; LP_END Initial loop end
; LP_COUNT Initial loop count
; blink Initial blink value
; ilink Initial ilink (point of interrupt)
; fp (r27) Initial fp (0)
; gp Initial gp
; r25 Initial r25
; r24 Initial r24
; r23 Initial r23
; r22 Initial r22
; r21 Initial r21
; r20 Initial r20
; r19 Initial r19
; r18 Initial r18
; r17 Initial r17
; r16 Initial r16
; r15 Initial r15
; r14 Initial r14
; r13 Initial r13
; r12 Initial r12
; r11 Initial r11
; r10 Initial r10
; r9 Initial r9
; r8 Initial r8
; r7 Initial r7
; r6 Initial r6
; r5 Initial r5
; r4 Initial r4
; r3 Initial r3
; r2 Initial r2
; r1 Initial r1
; r0 Initial r0
; r30 Initial r30
; r58 Initial r58
; r59 Initial r59
; 0 Reserved
; 0 Reserved
; 0 Initial BTA
; 0 Point of Interrupt (thread entry point)
; 0 Initial STATUS32
; 0 Backtrace
; 0 Backtrace
; 0 Backtrace
; 0 Backtrace
;
; *: these registers will only be saved and restored if flag -Xxmac_d16 is passed to hcac
;
; Stack Bottom: (higher memory address) */
;
ld r3, [r0, 16] ; Pickup end of stack area
and r3, r3, LONG_ALIGN_MASK ; Ensure long-word alignment
sub r3, r3, 196 ; Allocate an interrupt stack frame (ARC HS)
;
; /* Actually build the stack frame. */
;
st 1, [r3, 0] ; Store interrupt stack type on the
; top of the stack
mov r5, 0 ; Build initial clear value
st r5, [r3, 4] ; Store initial LP_START
st r5, [r3, 8] ; Store initial LP_END
st r5, [r3, 12] ; Store initial LP_COUNT
st r5, [r3, 16] ; Store initial blink
st r1, [r3, 20] ; Store initial ilink
st r5, [r3, 24] ; Store initial fp (0 for backtrace)
st gp, [r3, 28] ; Store current gp
st r5, [r3, 32] ; Store initial r25
st r5, [r3, 36] ; Store initial r24
st r5, [r3, 40] ; Store initial r23
st r5, [r3, 44] ; Store initial r22
st r5, [r3, 48] ; Store initial r21
st r5, [r3, 52] ; Store initial r20
st r5, [r3, 56] ; Store initial r19
st r5, [r3, 60] ; Store initial r18
st r5, [r3, 64] ; Store initial r17
st r5, [r3, 68] ; Store initial r16
st r5, [r3, 72] ; Store initial r15
st r5, [r3, 76] ; Store initial r14
st r5, [r3, 80] ; Store initial r13
st r5, [r3, 84] ; Store initial r12
st r5, [r3, 88] ; Store initial r11
st r5, [r3, 92] ; Store initial r10
st r5, [r3, 96] ; Store initial r9
st r5, [r3, 100] ; Store initial r8
st r5, [r3, 104] ; Store initial r7
st r5, [r3, 108] ; Store initial r6
st r5, [r3, 112] ; Store initial r5
st r5, [r3, 116] ; Store initial r4
st r5, [r3, 120] ; Store initial r3
st r5, [r3, 124] ; Store initial r2
st r5, [r3, 128] ; Store initial r1
st r5, [r3, 132] ; Store initial r0
st r5, [r3, 136] ; Store initial r30
st r5, [r3, 140] ; Store initial r58
st r5, [r3, 144] ; Store initial r59
st r5, [r3, 148] ; Reserved
st r5, [r3, 152] ; Reserved
st r5, [r3, 156] ; Store initial BTA
st r1, [r3, 160] ; Store initial point of entry
lr r6, [status32] ; Pickup STATUS32
or r6, r6, INT_ENABLE_BITS ; Make sure interrupts are enabled
st r6, [r3, 164] ; Store initial STATUS32
st r5, [r3, 168] ; Backtrace 0
st r5, [r3, 172] ; Backtrace 0
st r5, [r3, 176] ; Backtrace 0
st r5, [r3, 180] ; Backtrace 0
;
; /* Setup stack pointer. */
; thread_ptr -> tx_thread_stack_ptr = r3;
;
j_s.d [blink] ; Return to caller
st r3, [r0, 8] ; Save stack pointer in thread's
; control block
;}
.end

View File

@@ -0,0 +1,169 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_system_return ARC_HS/MetaWare */
;/* 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)
;{
.global _tx_thread_system_return
.type _tx_thread_system_return, @function
_tx_thread_system_return:
;
; /* Save minimal context on the stack. */
;
; /* Lockout interrupts. */
;
clri r2 ; Disable interrupts
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread ptr
lr r3, [status32] ; Pickup the status32 register
lsr r4, r3, 16 ; Move the register bank bits down
and r4, r4, 7 ; Isolate the register bank
breq r4, 0, __tx_software_context ; If register bank 0, software context is present
sub sp, sp, 12 ; Build small stack frame
mov r4, 2 ; Build solicited hardward stack frame type
st r4, [sp, 0] ; Set stack frame type
st r3, [sp, 4] ; Save status32
st r2, [sp, 8] ; Save interrupt posture
st sp, [r0, 8] ; Save thread's stack pointer
bclr r3, r3, 16 ; Build register bank 0 value
bclr r3, r3, 17 ;
bclr r3, r3, 18 ;
kflag r3 ; Move back to register bank 0
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread ptr
b.d __tx_save_done
mov r3, 0 ; Build clear value
__tx_software_context:
sub sp, sp, 76 ; Allocate a solicited stack frame
mov r3, 0 ; Build a solicited stack type
st r3, [sp, 0] ; Store stack type on the top
st blink, [sp, 4] ; Save return address and flags
st fp, [sp, 8] ; Save fp
st r26, [sp, 12] ; Save r26
st r25, [sp, 16] ; Save r25
st r24, [sp, 20] ; Save r24
st r23, [sp, 24] ; Save r23
st r22, [sp, 28] ; Save r22
st r21, [sp, 32] ; Save r21
st r20, [sp, 36] ; Save r20
st r19, [sp, 40] ; Save r19
st r18, [sp, 44] ; Save r18
st r17, [sp, 48] ; Save r17
st r16, [sp, 52] ; Save r16
st r15, [sp, 56] ; Save r15
st r14, [sp, 60] ; Save r14
st r13, [sp, 64] ; Save r13
st r2, [sp, 68] ; Save status32
st r30, [sp, 72] ; Save r30
st sp, [r0, 8] ; Save thread's stack pointer
__tx_save_done:
;
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the thread exit function to indicate the thread is no longer executing. */
;
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
bl.d _tx_execution_thread_exit ; Call the thread exit function
sub sp, sp, 16 ; ..allocating some space on the stack
add sp, sp, 16 ; Recover the stack space
ld r0, [gp, _tx_thread_current_ptr@sda] ; Pickup current thread ptr
mov r3, 0 ; Build clear value
.endif
;
; /* Save current stack and switch to system stack. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
; sp = _tx_thread_system_stack_ptr;
;
; /* Determine if the time-slice is active. */
; if (_tx_timer_time_slice)
; {
;
ld r5, [gp, _tx_timer_time_slice@sda] ; Pickup current time-slice
breq r5, 0, __tx_thread_dont_save_ts ; If not, skip save processing
;
; /* 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;
;
st r3, [gp, _tx_timer_time_slice@sda] ; Clear time-slice variable
st r5, [r0, 24] ; Save current time-slice
;
; }
__tx_thread_dont_save_ts:
;
; /* Clear the current thread pointer. */
; _tx_thread_current_ptr = TX_NULL;
;
b.d _tx_thread_schedule ; Return to scheduler..
st r3, [gp, _tx_thread_current_ptr@sda] ; ..clearing current thread pointer
;
;}
.end

View File

@@ -0,0 +1,238 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_timer_interrupt ARC_HS/MetaWare */
;/* 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 Process timer expiration */
;/* _tx_thread_time_slice Time slice interrupted thread */
;/* _tx_thread_context_save Save interrupt context */
;/* _tx_thread_context_restore Restore interrupt context */
;/* */
;/* 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)
;{
.global _tx_timer_interrupt
.type _tx_timer_interrupt, @function
_tx_timer_interrupt:
;
; /* Upon entry to this routine, it is assumed the interrupt stack frame has
; already been allocated and registers r0, r1, and r2 have already been saved
; at offsets 0, 4, and 8 respectively. */
;
; /* Increment the system clock. */
; _tx_timer_system_clock++;
;
clri ; Lockout interrupts
ld r0, [gp,_tx_timer_system_clock@sda] ; Pickup current system clock
ld r2, [gp, _tx_timer_time_slice@sda] ; Pickup current time-slice
add r0, r0, 1 ; Increment the system clock
st r0, [gp,_tx_timer_system_clock@sda] ; Store system clock back in memory
; /* Test for time-slice expiration. */
; if (_tx_timer_time_slice)
; {
;
mov r1, 0 ; Clear expiration flag
breq r2, 0, __tx_timer_no_time_slice ; If zero, no time-slice is active
;
; /* Decrement the time_slice. */
; _tx_timer_time_slice--;
;
sub r2, r2, 1 ; Decrement time-slice
st r2, [gp, _tx_timer_time_slice@sda] ; Store new time-slice value
;
; /* Check for expiration. */
; if (__tx_timer_time_slice == 0)
;
brne r2, 0, __tx_timer_no_time_slice ; If non-zero, skip over expiration
;
; /* Set the time-slice expired flag. */
; _tx_timer_expired_time_slice = TX_TRUE;
;
mov r1, 1 ; Set register flag
st r1, [gp, _tx_timer_expired_time_slice@sda] ; Set the time-slice expired flag
;
; }
;
__tx_timer_no_time_slice:
;
; /* Test for timer expiration. */
; if (*_tx_timer_current_ptr)
; {
;
ld r0, [gp, _tx_timer_current_ptr@sda] ; Pickup current timer pointer
ld r2, [r0, 0] ; Pickup examine actual list entry
breq r2, 0, __tx_timer_no_timer ;
; If NULL, no timer has expired, just move to the next entry
;
; /* Set expiration flag. */
; _tx_timer_expired = TX_TRUE;
;
mov r1, 1 ; Build expiration value
b.d __tx_timer_done ; Skip moving the timer pointer
st r1, [gp, _tx_timer_expired@sda] ; Set the expired value
;
; }
; else
; {
__tx_timer_no_timer:
;
; /* No timer expired, increment the timer pointer. */
; _tx_timer_current_ptr++;
;
ld r2, [gp, _tx_timer_list_end@sda] ; Pickup end of list
add r0, r0, 4 ; Move to next timer entry
;
; /* Check for wrap-around. */
; if (_tx_timer_current_ptr == _tx_timer_list_end)
;
st r0, [gp, _tx_timer_current_ptr@sda] ; Store the current timer
brne r0, r2, __tx_timer_skip_wrap ; If not equal, don't wrap the list
;
; /* Wrap to beginning of list. */
; _tx_timer_current_ptr = _tx_timer_list_start;
;
ld r2, [gp, _tx_timer_list_start@sda] ; Pickup start of timer list
st r2, [gp, _tx_timer_current_ptr@sda] ; Set current timer to the start
;
__tx_timer_skip_wrap:
;
; }
;
__tx_timer_done:
;
;
; /* See if anything has expired. */
; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
; {
;
breq r1, 0, __tx_timer_nothing_expired ; If 0, nothing has expired
;
__tx_something_expired:
;
ld r0, [sp, 0] ; Recover r0
ld r1, [sp, 4] ; Recover r1
ld r2, [sp, 8] ; Recover r2
st blink, [sp, 16] ; Save blink
bl _tx_thread_context_save ; Save interrupted context
;
; /* Did a timer expire? */
; if (_tx_timer_expired)
; {
;
ld r2, [gp, _tx_timer_expired@sda] ; Pickup timer expired flag
ld r4, [gp, _tx_thread_preempt_disable@sda] ; Pickup preempt disable
breq r2, 0, __tx_timer_dont_activate ; If not set, skip expiration processing
;
; /* Process the timer expiration. */
; /* _tx_timer_expiration_process(); */
bl.d _tx_timer_expiration_process ; Call the timer expiration handling routine
sub sp, sp, 16 ; ..allocating some space on the stack
add sp, sp, 16 ; Recover the stack space
;
; }
__tx_timer_dont_activate:
;
; /* Did time slice expire? */
; if (_tx_timer_expired_time_slice)
; {
;
ld r2, [gp, _tx_timer_expired_time_slice@sda] ; Pickup expired time-slice flag
breq r2, 0, __tx_timer_not_ts_expiration ; If not set, skip time-slice
;
; /* Time slice interrupted thread. */
; /* _tx_thread_time_slice(); */
bl.d _tx_thread_time_slice ; Call time-slice processing
sub sp, sp, 16 ; ..allocating some stack space
add sp, sp, 16 ; Recover stack space
;
; }
;
__tx_timer_not_ts_expiration:
;
st 0, [gp, _tx_timer_expired_time_slice@sda]
b _tx_thread_context_restore ; Go restore interrupt context..
; ..clearing time-slice expired flag
; Note that we don't return from
; this function.
;
; }
;
__tx_timer_nothing_expired:
;
ld r0, [sp, 0] ; Recover r0
ld r1, [sp, 4] ; Recover r1
ld r2, [sp, 8] ; Recover r2
add sp, sp, 160 ; Recover interrupt stack frame
rtie ; Return to point of interrupt
;
;}
.end