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

📄 hal_stub.c

📁 移植到WLIT项目的redboot源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================================////      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, 2001 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   jskov (based on powerpc/cogent hal_stub.c)// Contributors:jskov, dmoseley// 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#include <cyg/hal/hal_if.h>             // ROM calling interface#include <cyg/hal/hal_misc.h>           // Helper functions#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT#include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id#endif#ifdef USE_LONG_NAMES_FOR_ENUM_REGNAMES#ifndef PC#define PC REG_PC#endif#ifndef SP#define SP REG_SP#endif#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 registerstarget_register_t orig_registers[NUMREGS];  // Registers to get back to original state#if defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT)static int  _hw_stop_reason;   // Reason we were stopped by hw.// strings indexed by hw stop reasons defined in hal_stub.hstatic const char * const _hw_stop_str[] = {    "",    "hbreak",    "watch",    "rwatch",    "awatch"};static void *_watch_data_addr; // The data address if stopped by watchpoint#endif// Register validity checking#ifdef CYGHWR_REGISTER_VALIDITY_CHECKINGint registers_valid[NUMREGS];int *_registers_valid = registers_valid;#endif#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away// Interrupt control.static volatile __PFI __interruptible_control;#endif//-----------------------------------------------------------------------------// 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];}#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING// Return the validity of register REG.intget_register_valid (regnames_t reg){    return _registers_valid[reg];}#endif// 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 CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();    CYGACC_COMM_IF_PUTC(*__debug_procs, c);#elif defined(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 CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();    return CYGACC_COMM_IF_GETC(*__debug_procs);#elif defined(CYGPKG_CYGMON)    return ecos_bsp_console_getc();#else    return HAL_STUB_PLATFORM_GET_CHAR();#endif}// Flush output channelvoidhal_flush_output(void){#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();    CYGACC_COMM_IF_CONTROL(*__debug_procs, __COMMCTL_FLUSH_OUTPUT);#endif}// Set the baud rate for the current serial port.void __set_baud_rate (int baud) {#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();    CYGACC_COMM_IF_CONTROL(*__debug_procs, __COMMCTL_SETBAUD, baud);#elif defined(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){    CYGARC_HAL_SAVE_GP();    // 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);    }    CYGARC_HAL_RESTORE_GP();}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 (state) {        __interrupts_suspended--;        if (0 >= __interrupts_suspended) {            __interrupts_suspended = 0;#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away            {                hal_virtual_comm_table_t* __chan;                __chan = CYGACC_CALL_IF_DEBUG_PROCS();                CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_ENABLE);            }#else                            if (__interruptible_control)                __interruptible_control(1);#endif        }    } else {        __interrupts_suspended++;        if (1 == __interrupts_suspended)#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away            {                hal_virtual_comm_table_t* __chan;                __chan = CYGACC_CALL_IF_DEBUG_PROCS();                CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);            }#else                            if (__interruptible_control)                __interruptible_control(0);#endif    }}#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT//-----------------------------------------------------------------------------// GDB O-packetizer function.// This gets called via the virtual vector debug comms entry and// handles O-packetization. The debug comms entries are used for the// actual device IO.static cyg_uint8cyg_hal_gdb_diag_getc(void* __ch_data){    cyg_uint8 __ch;    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();    CYGARC_HAL_SAVE_GP();    __ch = CYGACC_COMM_IF_GETC(*__chan);    CYGARC_HAL_RESTORE_GP();    return __ch;}static voidcyg_hal_gdb_diag_putc(void* __ch_data, cyg_uint8 c){    static char line[100];    static int pos = 0;    CYGARC_HAL_SAVE_GP();    // No need to send CRs    if( c == '\r' ) return;    line[pos++] = c;    if( c == '\n' || pos == sizeof(line) )    {        CYG_INTERRUPT_STATE old;        hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();        // Disable interrupts. This prevents GDB trying to interrupt us        // while we are in the middle of sending a packet. The serial        // receive interrupt will be seen when we re-enable interrupts        // later.#ifdef CYG_HAL_STARTUP_ROM        HAL_DISABLE_INTERRUPTS(old);#else        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);#endif                while(1)        {            static const char hex[] = "0123456789ABCDEF";            cyg_uint8 csum = 0, c1;            int i;                    CYGACC_COMM_IF_PUTC(*__chan, '$');            CYGACC_COMM_IF_PUTC(*__chan, 'O');            csum += 'O';            for( i = 0; i < pos; i++ )            {                char ch = line[i];                char h = hex[(ch>>4)&0xF];                char l = hex[ch&0xF];                CYGACC_COMM_IF_PUTC(*__chan, h);                CYGACC_COMM_IF_PUTC(*__chan, l);                csum += h;                csum += l;            }            CYGACC_COMM_IF_PUTC(*__chan, '#');            CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]);            CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]);        nak:            c1 = CYGACC_COMM_IF_GETC(*__chan);            if( c1 == '+' ) break;            if( cyg_hal_is_break( &c1 , 1 ) ) {                // Caller's responsibility to react on this.                CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);                break;            }            if( c1 != '-' ) goto nak;        }        pos = 0;        // And re-enable interrupts#ifdef CYG_HAL_STARTUP_ROM        HAL_RESTORE_INTERRUPTS(old);#else        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);#endif    }    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_gdb_diag_write(void* __ch_data, const cyg_uint8* __buf,                        cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        cyg_hal_gdb_diag_putc(__ch_data, *__buf++);    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_gdb_diag_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        *__buf++ = cyg_hal_gdb_diag_getc(__ch_data);    CYGARC_HAL_RESTORE_GP();}static intcyg_hal_gdb_diag_control(void *__ch_data, __comm_control_cmd_t __func, ...){    // Do nothing (yet).    return 0;}#endif//-----------------------------------------------------------------------------// eCos stub entry and exit magic.#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORTint cyg_hal_gdb_break;#endif// Called at stub *kill*static void handle_exception_exit( void ){    int i;    for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++)	registers[i] = orig_registers[i];}// Called at stub *entry*static void handle_exception_cleanup( void ){    int i;    static int orig_registers_set = 0;    interruptible(0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -