275 lines
16 KiB
NASM
275 lines
16 KiB
NASM
;/**************************************************************************/
|
|
;/* */
|
|
;/* 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"
|
|
;
|
|
FP .set A15
|
|
DP .set B14
|
|
SP .set B15
|
|
;
|
|
.global _tx_thread_system_state
|
|
.global _tx_thread_current_ptr
|
|
.global _tx_thread_system_stack_ptr
|
|
;
|
|
;
|
|
.sect ".text"
|
|
;/**************************************************************************/
|
|
;/* */
|
|
;/* FUNCTION RELEASE */
|
|
;/* */
|
|
;/* _tx_thread_context_save C667x/TI */
|
|
;/* 6.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 */
|
|
;/* */
|
|
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
|
;/* */
|
|
;/**************************************************************************/
|
|
;VOID _tx_thread_context_save(VOID)
|
|
;{
|
|
.global _tx_thread_context_save
|
|
_tx_thread_context_save:
|
|
;
|
|
; /* Upon entry to this routine, it is assumed that all interrupts are locked
|
|
; out, an initial stack frame of 288 bytes has been allocated and registers
|
|
; A0, A1, A2, A3, A4, and B3 have been saved in the frame. Additionally,
|
|
; it is assumed that register B3 contains the ISR's return address. */
|
|
;
|
|
; /* Check for a nested interrupt condition. */
|
|
; if (_tx_thread_system_state++)
|
|
; {
|
|
;
|
|
MVKL _tx_thread_system_state,A0 ; Build address of system state
|
|
MVKH _tx_thread_system_state,A0 ;
|
|
LDW *A0,A1 ; Pickup current system state
|
|
STW A5,*+SP(40) ; Save A5
|
|
STW A6,*+SP(44) ; Save A6
|
|
STW A7,*+SP(48) ; Save A7
|
|
STW A8,*+SP(52) ; Save A8
|
|
[!A1] B _tx_thread_not_nested_save ; If 0, not a nested save condition
|
|
MVKL _tx_thread_current_ptr,A3 ; Build address of current thread ptr
|
|
MVKH _tx_thread_current_ptr,A3 ;
|
|
LDW *A3,A2 ; Pickup current thread pointer
|
|
ADD 1,A1,A1 ; Increment the system state (nested) counter
|
|
STW A1,*A0 ; Store system state
|
|
;
|
|
; /* Nested interrupt condition. Save remaining scratch registers, and control registers
|
|
; and return to calling ISR. */
|
|
;
|
|
STW A9,*+SP(56) ; Save A9
|
|
STW B0,*+SP(84) ; Save B0
|
|
STW B1,*+SP(88) ; Save B1
|
|
STW B2,*+SP(92) ; Save B2
|
|
; B3 is already saved!
|
|
STW B4,*+SP(100) ; Save B4
|
|
STW B5,*+SP(104) ; Save B5
|
|
STW B6,*+SP(108) ; Save B6
|
|
STW B7,*+SP(112) ; Save B7
|
|
STW B8,*+SP(116) ; Save B8
|
|
STW B9,*+SP(120) ; Save B9
|
|
MVC CSR,B0 ; Pickup CSR
|
|
B B3 ; Return to calling ISR
|
|
MVC IRP,B1 ; Pickup IRP
|
|
MVC AMR,B2 ; Pickup AMR
|
|
STW B0,*+SP(8) ; Save CSR
|
|
STW B1,*+SP(12) ; Save IRP
|
|
STW B2,*+SP(16) ; Save AMR
|
|
ZERO B0 ; Clear B0
|
|
MVC B0,AMR ; Clear AMR for linear addressing in ISR
|
|
STW A16,*+SP(140) ; Save A16
|
|
STW A17,*+SP(144) ; Save A17
|
|
STW A18,*+SP(148) ; Save A18
|
|
STW A19,*+SP(152) ; Save A19
|
|
STW A20,*+SP(156) ; Save A20
|
|
STW A21,*+SP(160) ; Save A21
|
|
STW A22,*+SP(164) ; Save A22
|
|
STW A23,*+SP(168) ; Save A23
|
|
STW A24,*+SP(172) ; Save A24
|
|
STW A25,*+SP(176) ; Save A25
|
|
STW A26,*+SP(180) ; Save A26
|
|
STW A27,*+SP(184) ; Save A27
|
|
STW A28,*+SP(188) ; Save A28
|
|
STW A29,*+SP(192) ; Save A29
|
|
STW A30,*+SP(196) ; Save A30
|
|
STW A31,*+SP(200) ; Save A31
|
|
STW B16,*+SP(204) ; Save B16
|
|
STW B17,*+SP(208) ; Save B17
|
|
STW B18,*+SP(212) ; Save B18
|
|
STW B19,*+SP(216) ; Save B19
|
|
STW B20,*+SP(220) ; Save B20
|
|
STW B21,*+SP(224) ; Save B21
|
|
STW B22,*+SP(228) ; Save B22
|
|
STW B23,*+SP(232) ; Save B23
|
|
STW B24,*+SP(236) ; Save B24
|
|
STW B25,*+SP(240) ; Save B25
|
|
STW B26,*+SP(244) ; Save B26
|
|
STW B27,*+SP(248) ; Save B27
|
|
STW B28,*+SP(252) ; Save B28
|
|
STW B29,*+SP(256) ; Save B29
|
|
STW B30,*+SP(260) ; Save B30
|
|
STW B31,*+SP(264) ; Save B31
|
|
MVC ILC,B0 ; Pickup ILC
|
|
MVC RILC,B1 ; Pickup RILC
|
|
MVC ITSR,B2 ; Pickup ITSR
|
|
STW B0,*+SP(268) ; Save ILC
|
|
STW B1,*+SP(272) ; Save RILC
|
|
STW B2,*+SP(276) ; Save ITSR
|
|
;
|
|
_tx_thread_not_nested_save:
|
|
; }
|
|
;
|
|
; /* Otherwise, not nested, check to see if a thread was running. */
|
|
; else if (_tx_thread_current_ptr)
|
|
; {
|
|
;
|
|
MVKL _tx_thread_system_stack_ptr,A0 ; Build address of system
|
|
MVKH _tx_thread_system_stack_ptr,A0 ; stack pointer
|
|
MV A2,A1 ; Transfer to A1 for B compare
|
|
[!A1] B _tx_thread_idle_system_save ; If Null, idle system save
|
|
STW A9,*+SP(56) ; Save A9
|
|
STW B0,*+SP(84) ; Save B0
|
|
STW B1,*+SP(88) ; Save B1
|
|
STW B2,*+SP(92) ; Save B2
|
|
NOP ; Delay slot
|
|
;
|
|
; /* At this point, a thread was interrupted and the remainder of its scratch and
|
|
; control registers must be saved. */
|
|
;
|
|
; B3 was already saved!
|
|
STW B4,*+SP(100) ; Save B4
|
|
STW B5,*+SP(104) ; Save B5
|
|
STW B6,*+SP(108) ; Save B6
|
|
STW B7,*+SP(112) ; Save B7
|
|
STW B8,*+SP(116) ; Save B8
|
|
STW B9,*+SP(120) ; Save B9
|
|
MVC CSR,B0 ; Pickup CSR
|
|
MVC IRP,B1 ; Pickup IRP
|
|
MVC AMR,B2 ; Pickup AMR
|
|
STW B0,*+SP(8) ; Save CSR
|
|
STW B1,*+SP(12) ; Save IRP
|
|
STW B2,*+SP(16) ; Save AMR
|
|
ZERO B0 ; Clear B0
|
|
MVC B0,AMR ; Clear AMR for linear addressing in ISR
|
|
STW A16,*+SP(140) ; Save A16
|
|
STW A17,*+SP(144) ; Save A17
|
|
STW A18,*+SP(148) ; Save A18
|
|
STW A19,*+SP(152) ; Save A19
|
|
STW A20,*+SP(156) ; Save A20
|
|
STW A21,*+SP(160) ; Save A21
|
|
STW A22,*+SP(164) ; Save A22
|
|
STW A23,*+SP(168) ; Save A23
|
|
STW A24,*+SP(172) ; Save A24
|
|
STW A25,*+SP(176) ; Save A25
|
|
STW A26,*+SP(180) ; Save A26
|
|
STW A27,*+SP(184) ; Save A27
|
|
STW A28,*+SP(188) ; Save A28
|
|
STW A29,*+SP(192) ; Save A29
|
|
STW A30,*+SP(196) ; Save A30
|
|
STW A31,*+SP(200) ; Save A31
|
|
STW B16,*+SP(204) ; Save B16
|
|
STW B17,*+SP(208) ; Save B17
|
|
STW B18,*+SP(212) ; Save B18
|
|
STW B19,*+SP(216) ; Save B19
|
|
STW B20,*+SP(220) ; Save B20
|
|
STW B21,*+SP(224) ; Save B21
|
|
STW B22,*+SP(228) ; Save B22
|
|
STW B23,*+SP(232) ; Save B23
|
|
STW B24,*+SP(236) ; Save B24
|
|
STW B25,*+SP(240) ; Save B25
|
|
STW B26,*+SP(244) ; Save B26
|
|
STW B27,*+SP(248) ; Save B27
|
|
STW B28,*+SP(252) ; Save B28
|
|
STW B29,*+SP(256) ; Save B29
|
|
STW B30,*+SP(260) ; Save B30
|
|
STW B31,*+SP(264) ; Save B31
|
|
MVC ILC,B0 ; Pickup ILC
|
|
MVC RILC,B1 ; Pickup RILC
|
|
MVC ITSR,B2 ; Pickup ITSR
|
|
STW B0,*+SP(268) ; Save ILC
|
|
STW B1,*+SP(272) ; Save RILC
|
|
STW B2,*+SP(276) ; Save ITSR
|
|
;
|
|
; /* 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;
|
|
;
|
|
STW SP,*+A1(8) ; Save stack pointer
|
|
B B3 ; Return to calling ISR
|
|
LDW *A0,SP ; Switch to system stack
|
|
NOP 4 ; Stack pointer is valid upon return!
|
|
;
|
|
; }
|
|
; 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 ISR
|
|
; processing. */
|
|
;
|
|
B B3 ; Return to ISR
|
|
ADDK.S2 288,SP ; Recover stack space
|
|
NOP 4 ; Delay slot
|
|
;
|
|
; }
|
|
;}
|
|
|