📄 icontext.c
字号:
/*=============================================================================//// icontext.c//// SPARClite HAL context init function////=============================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License. You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus. Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s): hmt// Contributors: hmt// Date: 1998-12-14// Purpose: HAL context initialization function// Description: Initialize a HAL context for SPARClite; this is in C and out// of line because there is too much of it for a simple macro.////####DESCRIPTIONEND####////===========================================================================*/#include <pkgconf/hal.h>#include <cyg/hal/hal_arch.h> // HAL header#include <cyg/infra/cyg_type.h>#include <cyg/hal/vectors.h> // SAVE_REGS_SIZE, __WINSIZE, .../*---------------------------------------------------------------------------*//* We lay out the stack in the manner that the PCS demands: * frame pointer -----> [top of stack] * Argument spill area (6 words) * Return Arg pointer * Initial saved register window (i[8], l[8]) * for use by program when it starts * [rest of] saved register object (various) * stack pointer -----> saved register window (i[8], l[8]) * to allow us to be interrupted. * * ie. frame pointer -> * struct HAL_FrameStructure * stack pointer -> struct HAL_SavedRegisters * * and when the context "resumes" sp is incremented by 40 * 4, the size of * a _struct HAL_SavedRegisters_ which points it at the extant but unused * _struct HAL_FrameStructure_ as the PCS requires. The frame pointer is * left pointing off the top of stack. * * * Thus the stack is the same if created from an already executing context: * * frame pointer -----> * [temporaries and locals] * [more arguments] * Argument spill area (6 words) * Return Arg pointer * [sp at entry]------> Previous saved register window (i[8], l[8]) * for use by program when it starts * [rest of] saved register object (various) * stack pointer -----> saved register window (i[8], l[8]) * to allow us to be interrupted. */CYG_ADDRESShal_thread_init_context( CYG_WORD sparg, CYG_WORD thread, CYG_WORD entry, CYG_WORD id ){ register CYG_WORD fp = sparg; register CYG_WORD sp = 0; register HAL_SavedRegisters *regs; register HAL_FrameStructure *frame; int i; if ( 0 == (id & 0xffff0000) ) id <<= 16; fp &= ~7; // round down to double alignment frame = (HAL_FrameStructure *)( fp - sizeof( HAL_FrameStructure ) ); regs = (HAL_SavedRegisters *)( ((CYG_WORD)frame) - sizeof(HAL_SavedRegisters) ); sp = (CYG_WORD)regs; for ( i = 0; i < 6; i++ ) { frame->spill_args[i] = id | 0xa0 | i; } frame->composite_return_ptr = 0; for ( i = 0; i < 8; i++ ) { frame->li.i[i] = id | ( 56 + i ); frame->li.l[i] = id | ( 48 + i ); regs ->li.i[i] = id | ( 24 + i ); regs ->li.l[i] = id | ( 16 + i ); regs ->o[i] = id | ( 8 + i ); regs ->g[i] = id | ( i ); } // first terminate the linked list on the stack in the initial // (already saved) register window: frame->li.i[6] = regs->li.i[6] = (cyg_uint32)fp; // frame pointer frame->li.i[7] = regs->li.i[7] = (cyg_uint32)0; // no ret addr here // and set up other saved regs as if called from just before // the entry point: regs->o[7] = (entry - 8); regs->o[6] = sp; // this is the argument that the entry point is called with regs->o[0] = thread; // this is the initial CWP; quite arbitrary really, the WIM is set up // accordingly in hal_thread_load_context(). regs->g[0] = 7; return (CYG_ADDRESS)sp;}// ---------------------------------------------------------------------------//#define THREAD_DEBUG_SERIAL_VERBOSE#ifdef THREAD_DEBUG_SERIAL_VERBOSE // NOT INCLUDED// This is unpleasant to try to debug, because these routines are called// WHEN THE PROGRAM IS NOT RUNNING from the CygMon's GDB stubs - so you// can't use any normal output: these little routines use the serial// line directly, so are best used when debugging via Ethernet, so you// just have a separate output stream to read. Nasty...#include <cyg/hal/hal_diag.h>#undef HAL_DIAG_WRITE_CHAR#define HAL_DIAG_WRITE_CHAR(_c_) CYG_MACRO_START \ SLEB_LED = (_c_); \ HAL_DIAG_WRITE_CHAR_DIRECT( _c_ ); \CYG_MACRO_ENDstatic void swritec( char c ){ HAL_DIAG_WRITE_CHAR( c );}static void swrites( char *s ){ char c; while ( 0 != (c = *s++) ) HAL_DIAG_WRITE_CHAR( c );}static void swritex( cyg_uint32 x ){ int i; swrites( "0x" ); for ( i = 28; i >= 0; i-= 4 ) { char c = "0123456789abcdef"[ 0xf & (x >> i) ]; HAL_DIAG_WRITE_CHAR( c ); }}#define newline() swrites( "\n\r" )static void x8( char *s, unsigned long *xp ){ int i; for ( i = 0; i < 8; i++ ) { swrites( s ); swritec( '0' + i ); swrites( " = " ); swritex( xp[i] ); if ( 3 == (i & 3) ) newline(); else swrites( " " ); }}#endif // THREAD_DEBUG_SERIAL_VERBOSE ... NOT INCLUDED// ---------------------------------------------------------------------------// Routines in icontext.c used here because they're quite large for// the SPARClite (note param order); these are used in talking to GDB.enum regnames {G0 = 0, G1, G2, G3, G4, G5, G6, G7, O0, O1, O2, O3, O4, O5, SP, O7, L0, L1, L2, L3, L4, L5, L6, L7, I0, I1, I2, I3, I4, I5, FP, I7, F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31, Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR};typedef unsigned long target_register_t;voidcyg_hal_sparc_get_gdb_regs( void *gdb_regset, HAL_SavedRegisters *eCos_regset ){ target_register_t *gdb = (target_register_t *)gdb_regset; int reg; cyg_uint32 scratch = 0; cyg_uint32 *sptrap; HAL_SavedWindow *trapli, *ctxli; if ( 0 == eCos_regset->g[0] || 0xc0 == (0xe0 & eCos_regset->g[0]) ) { // Then it's an interrupt stack saved state:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -