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

📄 hal_stub.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        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
    }
}

//-----------------------------------------------------------------------------
// eCos stub entry and exit magic.

#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
int cyg_hal_gdb_break;
#endif

#ifdef CYGPKG_REDBOOT
// Trampoline for returning to RedBoot from exception/stub code
static void
return_from_stub(int exit_status)
{
    CYGACC_CALL_IF_MONITOR_RETURN(exit_status);
}
#endif

// Called at stub *kill*
static void 
handle_exception_exit( void )
{
#ifdef CYGPKG_REDBOOT
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
    {   // Reset the timer to default and cancel any callback
	extern void sys_profile_reset(void);
	sys_profile_reset();
    }
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
    set_pc((target_register_t)return_from_stub);
#else
    int i;

    for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++)
	registers[i] = orig_registers[i];
#endif
}

// Called at stub *entry*
static void 
handle_exception_cleanup( void )
{
#ifndef CYGPKG_REDBOOT
    static int orig_registers_set = 0;
#endif

    interruptible(0);

    // Expand the HAL_SavedRegisters structure into the GDB register
    // array format.
    HAL_GET_GDB_REGISTERS(&registers[0], _hal_registers);
    _registers = &registers[0];

#ifndef CYGPKG_REDBOOT
    if (!orig_registers_set) {
	int i;
	for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++)
	    orig_registers[i] = registers[i];
	_registers = &orig_registers[0];
	if (__is_breakpoint_function ())
	    __skipinst ();
	_registers = &registers[0];
	orig_registers_set = 1;
    }
#endif
	
#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.
    cyg_hal_gdb_break = cyg_hal_gdb_remove_break(get_register (PC));
#endif

#if defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT)
    // For HW watchpoint/breakpoint support, we need to know if we
    // stopped because of watchpoint or hw break. We do that here
    // before GDB has a chance to remove the watchpoints and save
    // the information for later use in building response packets.
    _hw_stop_reason = HAL_STUB_IS_STOPPED_BY_HARDWARE(_watch_data_addr);
#endif    
}

// Called at stub *exit*
static void 
handle_exception_init( void )
{
    // Compact register array again.
    HAL_SET_GDB_REGISTERS(_hal_registers, &registers[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;
    __process_exit_vec = &handle_exception_exit;

    __cleanup_vec = &handle_exception_cleanup;
    __init_vec    = &handle_exception_init;

#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
    // Control of GDB interrupts.
    __interruptible_control = HAL_STUB_PLATFORM_INTERRUPTIBLE;
#endif
#endif

    // Nothing further to do, handle_exception will be called when an
    // exception occurs.
}

// Initialize the hardware.
void 
initHardware (void) 
{
    static int initialized = 0;

    if (initialized)
        return;
    initialized = 1;

    // Get serial port initialized.
    HAL_STUB_PLATFORM_INIT_SERIAL();

#ifdef HAL_STUB_PLATFORM_INIT
    // If the platform defines any initialization code, call it here.
    HAL_STUB_PLATFORM_INIT();
#endif        

#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
    // Get interrupt handler initialized.
    HAL_STUB_PLATFORM_INIT_BREAK_IRQ();
#endif
#endif // !CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
}

// Reset the board.
void 
__reset (void)
{
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
    __call_if_reset_t *__rom_reset = CYGACC_CALL_IF_RESET_GET();
    if (__rom_reset)
        (*__rom_reset)();
#else
    HAL_PLATFORM_RESET();
#endif
}

//-----------------------------------------------------------------------------
// Breakpoint support.

#ifndef CYGPKG_HAL_ARM
// This function will generate a breakpoint exception.  It is used at
// the beginning of a program to sync up with a debugger and can be
// used otherwise as a quick means to stop program execution and
// "break" into the debugger.
void
breakpoint()
{
    HAL_BREAKPOINT(_breakinst);
}

// This function returns the opcode for a 'trap' instruction.
unsigned long 
__break_opcode ()
{
  return HAL_BREAKINST;
}
#endif

//-----------------------------------------------------------------------------
// Write the 'T' packet in BUFFER. SIGVAL is the signal the program received.
void 
__build_t_packet (int sigval, char *buf)
{
    target_register_t addr;
    char *ptr = buf;
    target_register_t extend_val = 0;

    *ptr++ = 'T';
    *ptr++ = __tohex (sigval >> 4);
    *ptr++ = __tohex (sigval);

#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
    // Include thread ID if thread manipulation is required.
    {
        int id = dbg_currthread_id ();

        if (id != 0) {
	    *ptr++ = 't';
	    *ptr++ = 'h';
	    *ptr++ = 'r';
	    *ptr++ = 'e';
	    *ptr++ = 'a';
	    *ptr++ = 'd';
	    *ptr++ = ':';

#if (CYG_BYTEORDER == CYG_LSBFIRST)
	    // FIXME: Temporary workaround for PR 18903. Thread ID must be
	    // big-endian in the T packet.
	    {
		unsigned char* bep = (unsigned char*)&id;
		int be_id;

		be_id = id;
		*bep++ = (be_id >> 24) & 0xff ;
		*bep++ = (be_id >> 16) & 0xff ;
		*bep++ = (be_id >> 8) & 0xff ;
		*bep++ = (be_id & 0xff) ;
	    }
#endif
	    ptr = __mem2hex((char *)&id, ptr, sizeof(id), 0);
	    *ptr++ = ';';
	}
    }
#endif

#ifdef HAL_STUB_HW_WATCHPOINT
    switch(_hw_stop_reason) {
      case HAL_STUB_HW_STOP_WATCH:
      case HAL_STUB_HW_STOP_RWATCH:
      case HAL_STUB_HW_STOP_AWATCH:
#ifdef HAL_STUB_HW_SEND_STOP_REASON_TEXT
        // Not all GDBs understand this.
	strcpy(ptr, _hw_stop_str[_hw_stop_reason]);
	ptr += strlen(_hw_stop_str[_hw_stop_reason]);
#endif
	*ptr++ = ':';
	// Send address MSB first
	ptr += __intToHex(ptr, (target_register_t)_watch_data_addr,
			  sizeof(_watch_data_addr) * 8);
	*ptr++ = ';';
	break;
      default:
	break;
    }
#endif

    *ptr++ = __tohex (PC >> 4);
    *ptr++ = __tohex (PC);
    *ptr++ = ':';
    addr = get_register (PC);
    if (sizeof(addr) < REGSIZE(PC))
    {
        // GDB is expecting REGSIZE(PC) number of bytes.
        // We only have sizeof(addr) number.  Let's fill
        // the appropriate number of bytes intelligently.
#ifdef CYGARC_SIGN_EXTEND_REGISTERS
        {
            unsigned long bits_in_addr = (sizeof(addr) << 3);  // ie Size in bytes * 8
            target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));
            if ((addr & sign_bit_mask) == sign_bit_mask)
                extend_val = ~0;
        }
#endif
    }
#if (CYG_BYTEORDER == CYG_MSBFIRST)
    ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
#endif
    ptr = __mem2hex((char *)&addr, ptr, sizeof(addr), 0);
#if (CYG_BYTEORDER == CYG_LSBFIRST)
    ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
#endif
    *ptr++ = ';';

    *ptr++ = __tohex (SP >> 4);
    *ptr++ = __tohex (SP);
    *ptr++ = ':';
    addr = (target_register_t) get_register (SP);
    if (sizeof(addr) < REGSIZE(SP))
    {
        // GDB is expecting REGSIZE(SP) number of bytes.
        // We only have sizeof(addr) number.  Let's fill
        // the appropriate number of bytes intelligently.
        extend_val = 0;
#ifdef CYGARC_SIGN_EXTEND_REGISTERS
        {
            unsigned long bits_in_addr = (sizeof(addr) << 3);  // ie Size in bytes * 8
            target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));
            if ((addr & sign_bit_mask) == sign_bit_mask)
                extend_val = ~0;
        }
#endif

⌨️ 快捷键说明

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