⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 context.s

📁 ecos移植到R8H系列的源码。源码包来自http://www.cetoni.de/develop/develop_ecosh8s_en.html
💻 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 + -