📄 icontext.c
字号:
// (either minimal, or a saved PSR with traps disabled) // The saved register set is pretty minimal, so we have to grub // around in the stack to find out some truth... sptrap = (cyg_uint32 *)eCos_regset; // point to the IL save area for sptrap -= 24; // the trap handler, for PC, NPC trapli = (HAL_SavedWindow *)sptrap; // Get at those regs ctxli = (HAL_SavedWindow *)(trapli->i[6]); // (the frame pointer) // and get at the interruptee's regs // Pick up interruptee's registers from all over the stack: for ( reg = 0; reg < 8 ; reg++ ) { gdb[ G0 + reg ] = eCos_regset->g[reg]; gdb[ O0 + reg ] = trapli->i[reg]; gdb[ L0 + reg ] = ctxli->l[reg]; gdb[ I0 + reg ] = ctxli->i[reg]; } // Clear out G0 which is always 0 (but abused in eCos_regset) // and the FP regs which we do not have: gdb[ G0 ] = 0; for ( reg = F0; reg <= F31; reg++ ) gdb[ reg ] = 0; // In the save context _of the trap handler_ registers are as follows: // %l0 = psr (with this CWP/window-level in it) // %l1 = pc // %l2 = npc // %l3 = vector number (1-15 for interrupts) // %l4 = Y register preserved gdb[ Y ] = trapli->l[4]; scratch = trapli->l[0]; // the PSR in the trap handler scratch++; // back to interupted thread's window scratch &=~ 0x38; // clear ET and any CWP overflow gdb[ PSR ] = scratch; gdb[ WIM ] = 1 << ((__WINBITS & (1 + scratch))); // Read _a_ TBR value and ignore the current trap details: asm volatile ( "rd %%tbr, %0" : "=r"(scratch) : ); gdb[ TBR ] = (scratch &~ 0xfff); gdb[ PC ] = trapli->l[1]; gdb[ NPC ] = trapli->l[2]; gdb[ FPSR ] = 0; gdb[ CPSR ] = 0;#ifdef THREAD_DEBUG_SERIAL_VERBOSE newline(); swrites( "-----------------------------------------------------" ); newline(); swrites( "-------------- INTERRUPT STACK GET ------------------" ); newline(); swrites( "eCos regset at " ); swritex( eCos_regset ); newline(); swrites( " trapli " ); swritex( trapli ); newline(); swrites( " ctxli " ); swritex( ctxli ); newline(); x8( "global ", &(gdb[G0]) ); x8( " in ", &(gdb[I0]) ); x8( " local ", &(gdb[L0]) ); x8( " out ", &(gdb[O0]) ); swrites( "gdb PC = " ); swritex( gdb[ PC ] ); newline(); swrites( "gdb NPC = " ); swritex( gdb[ NPC ] ); newline(); swrites( "gdb PSR = " ); swritex( gdb[ PSR ] ); newline();#endif } else { // It's a synchronous context switch that led to this object. // Pick up interruptee's registers from the saved context: for ( reg = 0; reg < 8 ; reg++ ) {#ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM gdb[ G0 + reg ] = 0; gdb[ O0 + reg ] = 0;#else gdb[ G0 + reg ] = eCos_regset->g[reg]; gdb[ O0 + reg ] = eCos_regset->o[reg];#endif gdb[ L0 + reg ] = eCos_regset->li.l[reg]; gdb[ I0 + reg ] = eCos_regset->li.i[reg]; }#ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM // Set up the stack pointer by arithmetic and the return address gdb[ SP ] = ((cyg_uint32)(eCos_regset)); gdb[ O7 ] = eCos_regset->o[ 7 ];#else // Clear out G0 which is always 0 (but abused in eCos_regset) gdb[ G0 ] = 0;#endif // and clear the FP regs which we do not have: for ( reg = F0; reg <= F31; reg++ ) gdb[ reg ] = 0; gdb[ Y ] = 0; // it's not preserved. scratch = eCos_regset->g[ 0 ]; // the PSR in the saved context gdb[ PSR ] = scratch; // return it verbatim. gdb[ WIM ] = 1 << ((__WINBITS & (1 + scratch))); // Read _a_ TBR value and ignore the current trap details: asm volatile ( "rd %%tbr, %0" : "=r"(scratch) : ); gdb[ TBR ] = (scratch &~ 0xfff); gdb[ PC ] = eCos_regset->o[ 7 ]; // the return address gdb[ NPC ] = 4 + gdb[ PC ]; gdb[ FPSR ] = 0; gdb[ CPSR ] = 0;#ifdef THREAD_DEBUG_SERIAL_VERBOSE newline(); swrites( "-----------------------------------------------------" ); newline(); swrites( "-------------- SYNCHRONOUS SWITCH GET----------------" ); newline(); swrites( "eCos regset at " ); swritex( eCos_regset ); newline(); x8( "global ", &(gdb[G0]) ); x8( " in ", &(gdb[I0]) ); x8( " local ", &(gdb[L0]) ); x8( " out ", &(gdb[O0]) ); swrites( "gdb PC = " ); swritex( gdb[ PC ] ); newline(); swrites( "gdb NPC = " ); swritex( gdb[ NPC ] ); newline(); swrites( "gdb PSR = " ); swritex( gdb[ PSR ] ); newline();#endif }}// ---------------------------------------------------------------------------voidcyg_hal_sparc_set_gdb_regs( HAL_SavedRegisters *eCos_regset, void *gdb_regset ){ target_register_t *gdb = (target_register_t *)gdb_regset; int reg; cyg_uint32 scratch = 0; cyg_uint32 *sptrap; HAL_SavedWindow *trapli, *ctxli; // Guess where the eCos register set really is: if ( 0 == eCos_regset->g[0] || 0xc0 == (0xe0 & eCos_regset->g[0]) ) { // Then it's an interrupt stack saved state: // (either minimal, or a saved PSR with traps disabled) // The saved register set is pretty minimal, so we have to grub // around in the stack to find out some truth... sptrap = (cyg_uint32 *)eCos_regset; // point to the IL save area for sptrap -= 24; // the trap handler, for PC, NPC trapli = (HAL_SavedWindow *)sptrap; // Get at those regs ctxli = (HAL_SavedWindow *)(trapli->i[6]); // (the frame pointer) // and get at the interruptee's regs scratch = eCos_regset->g[0]; // Put back interruptee's registers all over the stack: for ( reg = 0; reg < 8 ; reg++ ) { eCos_regset->g[reg] = gdb[ G0 + reg ] ; trapli->i[reg] = gdb[ O0 + reg ] ; ctxli->l[reg] = gdb[ L0 + reg ] ; ctxli->i[reg] = gdb[ I0 + reg ] ; } // Put back the eCos G0 which is always 0 (but abused in eCos_regset) eCos_regset->g[0] = scratch; // In the save context _of the trap handler_ registers are as follows: // %l0 = psr (with this CWP/window-level in it) // %l1 = pc // %l2 = npc // %l3 = vector number (1-15 for interrupts) // %l4 = Y register preserved trapli->l[4] = gdb[ Y ]; // I am *not* interfering with the saved PSR, nor the TBR nor WIM. // put back return PC and NPC trapli->l[1] = gdb[ PC ] ; trapli->l[2] = gdb[ NPC ]; #ifdef THREAD_DEBUG_SERIAL_VERBOSE newline(); swrites( "-----------------------------------------------------" ); newline(); swrites( "-------------- INTERRUPT STACK SET ------------------" ); newline(); swrites( "eCos regset at " ); swritex( eCos_regset ); newline(); swrites( " trapli " ); swritex( trapli ); newline(); swrites( " ctxli " ); swritex( ctxli ); newline(); x8( "global ", &(gdb[G0]) ); x8( " in ", &(gdb[I0]) ); x8( " local ", &(gdb[L0]) ); x8( " out ", &(gdb[O0]) ); swrites( "gdb PC = " ); swritex( gdb[ PC ] ); newline(); swrites( "gdb NPC = " ); swritex( gdb[ NPC ] ); newline(); swrites( "gdb PSR = " ); swritex( gdb[ PSR ] ); newline();#endif } else { // It's a synchronous context switch that led to this object. // Pick up interruptee's registers from the saved context: scratch = eCos_regset->g[0]; for ( reg = 0; reg < 8 ; reg++ ) { eCos_regset->g[reg] = gdb[ G0 + reg ]; eCos_regset->o[reg] = gdb[ O0 + reg ]; eCos_regset->li.l[reg] = gdb[ L0 + reg ]; eCos_regset->li.i[reg] = gdb[ I0 + reg ]; } // Put back the eCos G0 which is always 0 (but abused in eCos_regset) eCos_regset->g[0] = scratch; // I am *not* interfering with the saved PSR, nor the TBR nor WIM. // The PC is in o7, altering it via GDB's PC is not on. // Setting the NPC in a voluntary context is meaningless.#ifdef THREAD_DEBUG_SERIAL_VERBOSE newline(); swrites( "-----------------------------------------------------" ); newline(); swrites( "-------------- SYNCHRONOUS SWITCH SET ---------------" ); newline(); swrites( "eCos regset at " ); swritex( eCos_regset ); newline(); x8( "global ", &(gdb[G0]) ); x8( " in ", &(gdb[I0]) ); x8( " local ", &(gdb[L0]) ); x8( " out ", &(gdb[O0]) ); swrites( "gdb PC = " ); swritex( gdb[ PC ] ); newline(); swrites( "gdb NPC = " ); swritex( gdb[ NPC ] ); newline(); swrites( "gdb PSR = " ); swritex( gdb[ PSR ] ); newline();#endif }}/*---------------------------------------------------------------------------*/// EOF icontext.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -