📄 context.s
字号:
//=============================================================================
//
// context.S
//
// H8S context switch code
//
//=============================================================================
//###ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//###ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): Uwe Kindler
// Contributors: Uwe Kindler, yoshinori sato,
// Date: 2003-12-02
// Purpose: H8S context switch code
// Description: This file contains implementations of the thread context
// switch routines. It also contains the longjmp() and setjmp()
// routines.
//
//####DESCRIPTIONEND####
//
//=============================================================================
//=============================================================================
// DOXYGEN FILE HEADER
/// \file context.S
/// \brief H8S context switch code.
/// \author Uwe Kindler
/// \date 2003-12-02
///
/// This file contains implementations of the thread context
/// switch routines. It also contains the longjmp() and setjmp()
/// routines.
//=============================================================================
//=============================================================================
// INCLUDES
//=============================================================================
#include <pkgconf/hal.h>
#include <cyg/hal/arch.inc>
#include <cyg/hal/basetype.h>
//=============================================================================
// ASSEMBLER SETTINGS
//=============================================================================
.h8300s
//=============================================================================
// CONTEXT SWITCH FUNCTION
// DESCRIPTION:
// The state of the current thread is saved onto its stack, using the
// current value of SP and the address of the saved state is placed in
// er1 (*from). The value in er0 (*to) is then read and the state
// of the new thread is loaded from it. The current interrupt state
// is saved and restored as part of the thread context.
//
// PARAMETERS:
// hal_thread_switch_context(_to_, _from_);
// er0 - '_to_' A pointer to a location where the stack pointer of
// the current thread will be stored.
//
// er1 - '_from_' A pointer to a location from where the stack pointer
// of the next thread will be read.
//
// NOTES:
// 'hal_thread_switch_context' is a function and if we are here we
// already have a valid PC+CCR pushed onto stack. So we only have to
// push exr, er0-er6 and sp. After this operations the stack should look
// this way (saving of MACL and MACH is optional and depends on the
// configuration option CYGHWE_HAL_H8S_USE_MAC):
//
// [SP -->] [MACH 4]
// [MACL 4]
// -------------------------------------
// SP --> ER6 4 ER0 - ER6
// ER5 4
// ER4 4
// ER3 4
// ER2 4
// ER1 4
// ER0 4
// SP 4 Pre-Exception Stack pointer
// --------------------------------------------
// EXR 1 EXR register
// RSV 1 reserved
// --------------------------------------------
// CCR 1 CCR register
// PC 4 program counter
//=============================================================================
.global CYG_LABEL_DEFN(hal_thread_switch_context)
CYG_LABEL_DEFN(hal_thread_switch_context):
//
// CCR and PC are already pushed by the JSR instruction that
// brought us here. So we only have to store EXR and all general
// registers ER0 - ER7 and optional MACL and MACH
//
stc.w exr, @ - sp // push exr
subs #4, sp // reserve space for sp
stm er0 - er3, @ - sp // push er0-er3
stm er4 - er6, @ - sp // push er4-er6
hal_push_mac // push MAC if we configured to use it
mov.l sp, er2 // we are going to modify the sp value
add.l #SIZE_SAVED_STATE, er2 // pre exception stack pointer is current SP + size of saved state
mov.l er2, @(SAVED_STATE_SP, sp) // save pre exception sp on stack bevor er0 - this postion depends on wheter MAC is stored
mov.l sp, @er1 // move pointer to saved state into from
//
// Now load the destination thread by dropping through
// to hal_thread_load_context
//
//=============================================================================
// CONTEXT LOAD FUNCTION
// DESCRIPTION:
// Load thread context er1 = address of sp of next thread to execute
//
// NOTES:
// Note that this function is also the second half of
// hal_thread_switch_context and is simply dropped into from it.
//=============================================================================
.global CYG_LABEL_DEFN(hal_thread_load_context)
CYG_LABEL_DEFN(hal_thread_load_context):
mov.l @er0, sp // switch to stack of next thread to execute
//
// now restore the saved machine state from stack by the
// macro hal_cpu_load all. This macro is defined in arch.inc
// variant.inc or platform.inc
//
hal_cpu_load_all
rte // now SP points to EXR and we can return
//===========================================================================
// SETJMP AND LONGJMP SUPPORT
// DESCRIPTION:
// These functions provide support for the C setjmp() and longjmp()
// functions. Refer to the C library for further information.
// HAL longjmp(), setjmp() implementations. These implementations omit
// the usual movm [d2,d3,a2,a3],(sp). Which is the first instruction of
// all C compiled functions.
//
// NOTES:
// These definitions are repeated in hal_arch.h. If changes are required
// remember to update both sets.
//===========================================================================
#define CYGARC_JMP_BUF_SP 0
#define CYGARC_JMP_BUF_ER3 1
#define CYGARC_JMP_BUF_ER4 2
#define CYGARC_JMP_BUF_ER5 3
#define CYGARC_JMP_BUF_ER6 4
#define CYGARC_JMP_BUF_PC 5
#define CYGARC_JMP_BUF_SIZE 6
//===========================================================================
// SETJMP
// DESCRIPTION:
// Set a label for an non local jump.
//
// PARAMETERS:
// er0 - env Buffer for saving actual state
//
// NOTES:
// This just preserves the callee save registers namely a2,a3,d2,d3
// setjmp cannot use movm to do this as we need to keep the sp
// underneath all live data at all times.
//===========================================================================
.global CYG_LABEL_DEFN(hal_setjmp)
CYG_LABEL_DEFN(hal_setjmp):
mov.l er3, @(CYGARC_JMP_BUF_ER3*4, er0) // save er3
mov.l er4, @(CYGARC_JMP_BUF_ER4*4, er0) // save er4
mov.l er5, @(CYGARC_JMP_BUF_ER5*4, er0) // save er5
mov.l er6, @(CYGARC_JMP_BUF_ER6*4, er0) // save er6
mov.l @sp, er1 // get PC from stack
mov.l er1, @(CYGARC_JMP_BUF_PC*4, er0) // save PC
mov.l sp, er1
mov.l er1, @(CYGARC_JMP_BUF_SP*4, er0) // save SP
sub.l er0, er0 // return zero
rts
//===========================================================================
// LONGJMP
// DESCRIPTION:
// Jump to an non local label.
//
// PARAMETERS:
// er0 - env Buffer containg state to be restored
// er1 - val Value to be returned
//
// NOTES:
// Longjmp returns to caller of setjmp after restoring callee save
// registers
//===========================================================================
.global CYG_LABEL_DEFN(hal_longjmp)
CYG_LABEL_DEFN(hal_longjmp):
mov.l @(CYGARC_JMP_BUF_ER3*4, er0), er3 // restore er3
mov.l @(CYGARC_JMP_BUF_ER4*4, er0), er4 // restore er4
mov.l @(CYGARC_JMP_BUF_ER5*4, er0), er5 // restore er5
mov.l @(CYGARC_JMP_BUF_ER6*4, er0), er6 // restore er6
mov.l @(CYGARC_JMP_BUF_PC*4, er0), er2 // store PC value in er2
mov.l @(CYGARC_JMP_BUF_SP*4, er0), sp // restore SP
mov.l er2, @sp // retore PC on stack
mov.l er1, er0 // return val
rts
// -----------------------------------------------------------------------------
// end of context.S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -