📄 hal_stub.c
字号:
//=============================================================================//// hal_stub.c//// Helper functions for stub, specific to eCos HAL////=============================================================================//####COPYRIGHTBEGIN####// // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // 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 Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s): jskov (based on powerpc/cogent hal_stub.c)// Contributors:jskov// Date: 1999-02-12// Purpose: Helper functions for stub, specific to eCos HAL// Description: Parts of the GDB stub requirements are provided by// the eCos HAL, rather than target and/or board specific// code. ////####DESCRIPTIONEND####////=============================================================================#include <pkgconf/hal.h>#ifdef CYGPKG_CYGMON#include <pkgconf/cygmon.h>#endif#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS#include <cyg/hal/hal_stub.h> // Our header#include <cyg/hal/hal_arch.h> // HAL_BREAKINST#include <cyg/hal/hal_cache.h> // HAL_xCACHE_x#include <cyg/hal/hal_intr.h> // interrupt disable/restore#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id#endif//-----------------------------------------------------------------------------// Extra eCos data.// Saved registers.HAL_SavedRegisters *_hal_registers;target_register_t registers[NUMREGS];target_register_t alt_registers[NUMREGS] ; // Thread or saved process statetarget_register_t * _registers = registers; // Pointer to current set of registers// Interrupt control.static volatile __PFI __interruptible_control;//-----------------------------------------------------------------------------// Register access// Return the currently-saved value corresponding to register REG of// the exception context.target_register_t get_register (regnames_t reg){ return _registers[reg];}// Store VALUE in the register corresponding to WHICH in the exception// context.void put_register (regnames_t which, target_register_t value){ _registers[which] = value;}//-----------------------------------------------------------------------------// Serial stuff#ifdef CYGPKG_CYGMONextern void ecos_bsp_console_putc(char);extern char ecos_bsp_console_getc(void);#endif// Write C to the current serial port.void putDebugChar (int c){#ifdef CYGPKG_CYGMON ecos_bsp_console_putc(c);#else HAL_STUB_PLATFORM_PUT_CHAR(c);#endif}// Read one character from the current serial port.int getDebugChar (void){#ifdef CYGPKG_CYGMON return ecos_bsp_console_getc();#else return HAL_STUB_PLATFORM_GET_CHAR();#endif}// Set the baud rate for the current serial port.void __set_baud_rate (int baud) {#ifdef CYGPKG_CYGMON // FIXME!#else HAL_STUB_PLATFORM_SET_BAUD_RATE(baud);#endif}//-----------------------------------------------------------------------------// GDB interrupt (BREAK) support.#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT#ifndef CYGPKG_HAL_ARM#if (HAL_BREAKINST_SIZE == 1)typedef cyg_uint8 t_inst;#elif (HAL_BREAKINST_SIZE == 2)typedef cyg_uint16 t_inst;#elif (HAL_BREAKINST_SIZE == 4)typedef cyg_uint32 t_inst;#else#error "Don't know how to handle that size"#endiftypedef struct{ t_inst *targetAddr; t_inst savedInstr;} instrBuffer;static instrBuffer break_buffer;volatile int cyg_hal_gdb_running_step = 0;void cyg_hal_gdb_place_break (target_register_t pc){ cyg_hal_gdb_interrupt( pc ); // Let's hope this becomes a drop-through:}void cyg_hal_gdb_interrupt (target_register_t pc){ // Clear flag that we Continued instead of Stepping cyg_hal_gdb_running_step = 0; // and override existing break? So that a ^C takes effect... if (NULL != break_buffer.targetAddr) cyg_hal_gdb_remove_break( (target_register_t)break_buffer.targetAddr ); if (NULL == break_buffer.targetAddr) { break_buffer.targetAddr = (t_inst*) pc; break_buffer.savedInstr = *(t_inst*)pc; *(t_inst*)pc = (t_inst)HAL_BREAKINST; __data_cache(CACHE_FLUSH); __instruction_cache(CACHE_FLUSH); }}int cyg_hal_gdb_remove_break (target_register_t pc){ if ( cyg_hal_gdb_running_step ) return 0; if ((t_inst*)pc == break_buffer.targetAddr) { *(t_inst*)pc = break_buffer.savedInstr; break_buffer.targetAddr = NULL; __data_cache(CACHE_FLUSH); __instruction_cache(CACHE_FLUSH); return 1; } return 0;}int cyg_hal_gdb_break_is_set (void){ if (NULL != break_buffer.targetAddr) { return 1; } return 0;}#endif // CYGPKG_HAL_ARM#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT// Use this function to disable serial interrupts whenever reply// characters are expected from GDB. The reason we want to control// whether the target can be interrupted or not is simply that GDB on// the host will be sending acknowledge characters/commands while the// stub is running - if serial interrupts were still active, the// characters would never reach the (polling) getDebugChar.static voidinterruptible(int state){ static int __interrupts_suspended = 0; if (__interruptible_control) { if (state) { __interrupts_suspended--; if (0 >= __interrupts_suspended) { __interrupts_suspended = 0; __interruptible_control(1); } } else { __interrupts_suspended++; if (1 == __interrupts_suspended) __interruptible_control(0); } }}//-----------------------------------------------------------------------------// eCos stub entry and exit magic.#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORTint cyg_hal_gdb_break;#endif// Called at stub *entry*static void handle_exception_cleanup( void ){ interruptible(0); // Expand the HAL_SavedRegisters structure into the GDB register // array format. HAL_GET_GDB_REGISTERS(®isters[0], _hal_registers); _registers = ®isters[0];#ifdef HAL_STUB_PLATFORM_STUBS_FIXUP // Some architectures may need to fix the PC in case of a partial // or fully executed trap instruction. GDB only takes correct action // when the PC is pointing to the breakpoint instruction it set. // // Most architectures would leave PC pointing at the trap // instruction itself though, and so do not need to do anything // special. HAL_STUB_PLATFORM_STUBS_FIXUP();#endif#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT // If we continued instead of stepping, when there was a break set // ie. we were stepping within a critical region, clear the break, and // that flag. If we stopped for some other reason, this has no effect. if ( cyg_hal_gdb_running_step ) { cyg_hal_gdb_running_step = 0; cyg_hal_gdb_remove_break(get_register (PC)); } // FIXME: (there may be a better way to do this) // If we hit a breakpoint set by the gdb interrupt stub, make it // seem like an interrupt rather than having hit a breakpoint. if (cyg_hal_gdb_remove_break(get_register (PC))) cyg_hal_gdb_break = 1; else cyg_hal_gdb_break = 0;#endif}// Called at stub *exit*static void handle_exception_init( void ){ // Compact register array again. HAL_SET_GDB_REGISTERS(_hal_registers, ®isters[0]); interruptible(1);}//-----------------------------------------------------------------------------// Initialization.// Signal handler.int cyg_hal_process_signal (int signal){ // We don't care about the signal (atm). return 0;}// Install the standard set of trap handlers for the stub.void __install_traps (void){ // Set signal handling vector so we can treat 'C<signum>' as 'c'. __process_signal_vec = &cyg_hal_process_signal; // Set exit vector to reset vector. This will allow automatic reset on
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -