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

📄 mips-stub.c

📁 ecos为实时嵌入式操作系统
💻 C
字号:
/* mips-stub.c - helper functions for stub, generic to all MIPS processors *  * Copyright (c) 1998,1999 Cygnus Solutions * * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose, provided * that existing copyright notices are retained in all copies and that this * notice is included verbatim in any distributions. No written agreement, * license, or royalty fee is required for any of the authorized uses. * Modifications to this software may be copyrighted by their authors * and need not follow the licensing terms described here, provided that * the new terms are clearly indicated on the first page of each file where * they apply. */#include <stddef.h>#include <pkgconf/hal.h>#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS#include <cyg/hal/hal_stub.h>#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS#include <cyg/hal/mips-regs.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/mips_opcode.h>/* Given a trap value TRAP, return the corresponding signal. */int __computeSignal (unsigned int trap_number){  switch (trap_number)    {    case EXC_INT:      /* External interrupt */      return SIGINT;    case EXC_RI:      /* Reserved instruction */    case EXC_CPU:      /* Coprocessor unusable */      return SIGILL;    case EXC_BP:      /* Break point */      return SIGTRAP;    case EXC_OVF:      /* Arithmetic overflow */    case EXC_TRAP:      /* Trap exception */    case EXC_FPE:      /* Floating Point Exception */      return SIGFPE;    case EXC_IBE:      /* Bus error (Ifetch) */    case EXC_DBE:      /* Bus error (data load or store) */      return SIGBUS;    case EXC_MOD:      /* TLB modification exception */    case EXC_TLBL:      /* TLB miss (Load or Ifetch) */    case EXC_TLBS:      /* TLB miss (Store) */    case EXC_ADEL:      /* Address error (Load or Ifetch) */    case EXC_ADES:      /* Address error (Store) */      return SIGSEGV;    case EXC_SYS:      /* System call */      return SIGSYS;    default:      return SIGTERM;    }}/* Return the trap number corresponding to the last-taken trap. */int __get_trap_number (void){  return (get_register (CAUSE) & CAUSE_EXCMASK) >> CAUSE_EXCSHIFT;}/* Set the currently-saved pc register value to PC. This also updates NPC   as needed. */void set_pc (target_register_t pc){  put_register (PC, pc);}/*---------------------------------------------------------------------- * Single-step support *//* Saved instruction data for single step support.  */typedef unsigned long t_inst;static struct{  t_inst *targetAddr;  t_inst savedInstr;} instrBuffer;/* Set things up so that the next user resume will execute one instruction.   This may be done by setting breakpoints or setting a single step flag   in the saved user registers, for example. */void __single_step (void){  InstFmt inst;  t_inst *pc = (t_inst *) get_register (PC);  instrBuffer.targetAddr = pc + 1;              /* set default */  inst.word = *pc;                              /* read the next instruction  *///diag_printf("pc %08x %08x\n",pc,inst.word);   switch (inst.RType.op) {                    /* override default if branch */    case OP_SPECIAL:      switch (inst.RType.func) {        case OP_JR:        case OP_JALR:          instrBuffer.targetAddr = (t_inst *) get_register (inst.RType.rs);          break;      };      break;    case OP_REGIMM:      switch (inst.IType.rt) {        case OP_BLTZ:        case OP_BLTZL:        case OP_BLTZAL:        case OP_BLTZALL:          if (get_register (inst.IType.rs) < 0 )            instrBuffer.targetAddr =              (t_inst *)(((signed short)inst.IType.imm<<2)                                        + (get_register (PC) + 4));          else            instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);          break;        case OP_BGEZ:        case OP_BGEZL:        case OP_BGEZAL:        case OP_BGEZALL:          if (get_register (inst.IType.rs) >= 0 )            instrBuffer.targetAddr =              (t_inst *)(((signed short)inst.IType.imm<<2)                                        + (get_register (PC) + 4));          else            instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);          break;      };      break;    case OP_J:    case OP_JAL:      instrBuffer.targetAddr =        (t_inst *)((inst.JType.target<<2)                   + ((get_register (PC) + 4)&0xf0000000));      break;    case OP_BEQ:    case OP_BEQL:      if (get_register (inst.IType.rs) == get_register (inst.IType.rt))        instrBuffer.targetAddr =          (t_inst *)(((signed short)inst.IType.imm<<2)                     + (get_register (PC) + 4));      else        instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);      break;    case OP_BNE:    case OP_BNEL:      if (get_register (inst.IType.rs) != get_register (inst.IType.rt))        instrBuffer.targetAddr =          (t_inst *)(((signed short)inst.IType.imm<<2)                     + (get_register (PC) + 4));      else        instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);      break;    case OP_BLEZ:    case OP_BLEZL:      if (get_register (inst.IType.rs) <= 0)        instrBuffer.targetAddr =          (t_inst *)(((signed short)inst.IType.imm<<2) + (get_register (PC) + 4));      else        instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);      break;    case OP_BGTZ:    case OP_BGTZL:      if (get_register (inst.IType.rs) > 0)        instrBuffer.targetAddr =          (t_inst *)(((signed short)inst.IType.imm<<2) + (get_register (PC) + 4));      else        instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);      break;#if 0   /* no floating point support at the moment */    case OP_COP1:      if (inst.RType.rs == OP_BC)          switch (inst.RType.rt) {            case COPz_BCF:            case COPz_BCFL:              if (get_register (FCSR) & CSR_C)                instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);              else                instrBuffer.targetAddr =                  (t_inst *)(((signed short)inst.IType.imm<<2)                                            + (get_register (PC) + 4));              break;            case COPz_BCT:            case COPz_BCTL:              if (get_register (FCSR) & CSR_C)                instrBuffer.targetAddr =                  (t_inst *)(((signed short)inst.IType.imm<<2)                                            + (get_register (PC) + 4));              else                instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8);              break;          };      break;#endif  }}/* Clear the single-step state. */void __clear_single_step (void){//diag_printf("clear_ss ta %08x\n",instrBuffer.targetAddr);  if (instrBuffer.targetAddr != NULL)    {      *instrBuffer.targetAddr = instrBuffer.savedInstr;      instrBuffer.targetAddr = NULL;    }  instrBuffer.savedInstr = NOP_INSTR;}void __install_breakpoints (){//diag_printf("install_bpt ta %08x\n",instrBuffer.targetAddr);  if (instrBuffer.targetAddr != NULL)    {      instrBuffer.savedInstr = *instrBuffer.targetAddr;      *instrBuffer.targetAddr = __break_opcode ();//diag_printf("ta %08x si %08x *ta %08x\n",//            instrBuffer.targetAddr,instrBuffer.savedInstr,*instrBuffer.targetAddr);    }}void __clear_breakpoints (void){}/* If the breakpoint we hit is in the breakpoint() instruction, return a   non-zero value. */int__is_breakpoint_function (){    return get_register (PC) == (target_register_t)&CYG_LABEL_NAME(breakinst);}/* Skip the current instruction.  Since this is only called by the   stub when the PC points to a breakpoint or trap instruction,   we can safely just skip 4. */void __skipinst (void){    put_register (PC, get_register (PC) + 4);}#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS

⌨️ 快捷键说明

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