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

📄 debug.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//***************************************************************** * debug.c *  * Support for running gdb on programs that are executing under * mipsy. Right now this will only work under simos, but it would be * nice to have it work for Solo Mipsy as well.  * $Author: bosch $ * $File$ *****************************************************************/#include <sys/signal.h>#include "mipsy.h"#include "cp0.h"#include "fpu.h"#include "cpu_state.h"#include "sim_error.h"#include "memref.h"#include "cpu_interface.h"#include "gdb_interface.h"#include "mips_gdb.h"#ifdef USE_FLASHLITE#include "mipsy_interface.h"#include "flash_interface.h"#endif/* Local Variables */static Reg cached_pc;static uint cached_inst;/* Global Variables */int mipsy_sigusr = 0;int mipsy_break_nexti = MIPSY_NOBREAK;int mipsy_debug_mode = 0;/***************************************************************** * mipsy_getreg *****************************************************************/ResultMipsyGetReg(int cpunum, int regnum, Reg *val){   CPUState* P;#ifdef MIPSY_MXS   if (PE[cpunum].inMXS) {      CopyFromMXS(PE + cpunum);   }#endif        P = &PE[cpunum];      if(regnum < 0) {      return FAILURE;   }      if (regnum <= RA_REGNUM) {      *val = P->R[regnum];      return SUCCESS;   }      if ((regnum >= FP0_REGNUM) && (regnum <= FP31_REGNUM)) {      *val = IntReg(regnum-FP0_REGNUM);      return SUCCESS;   }      switch (regnum) {   case PC_REGNUM:    *val = P->PC;               break;   case CAUSE_REGNUM: *val = P->CP0[C0_CAUSE];    break;   case BAD_REGNUM:   *val = P->CP0[C0_BADVADDR]; break;   case HI_REGNUM:    *val = P->HI;               break;   case LO_REGNUM:    *val = P->LO;               break;   case FCRCS_REGNUM: *val = P->FCR[31];          break;   case FCRIR_REGNUM: *val = P->FCR[30];          break;   case INX_REGNUM:   *val = P->CP0[C0_INX];      break;   case RAND_REGNUM:  *val = P->CP0[C0_RAND];     break;   case TLBLO_REGNUM: *val = P->CP0[C0_TLBLO_0];   break;   case CTXT_REGNUM:  *val = P->CP0[C0_CTXT];     break;   case TLBHI_REGNUM: *val = P->CP0[C0_TLBHI];    break;   case SR_REGNUM:    *val = P->CP0[C0_SR];       break;   case EPC_REGNUM:   *val = P->CP0[C0_EPC];      break;   case ERROR_EPC_REGNUM: *val = P->CP0[C0_ERROR_EPC]; break;   case COUNT_REGNUM:    *val = P->CP0[C0_COUNT];       break;   case COMPARE_REGNUM:  *val = P->CP0[C0_COMPARE];       break;   case TLBLO1_REGNUM:   *val = P->CP0[C0_TLBLO_1];       break;   case PGMASK_REGNUM:   *val = P->CP0[C0_PGMASK];       break;   case NPC_REGNUM:   *val = P->nPC;              break;   default:           return FAILURE;   }      return SUCCESS;}/***************************************************************** * MipsyPutReg *****************************************************************/Result MipsyPutReg(int cpunum, int regnum, Reg val){   CPUState* P;#ifdef MIPSY_MXS   if (PE->inMXS) {      CPUWarning("mipsy_putreg doesn't work in MXS mode\n");   }#endif        P = &PE[cpunum];   if ((regnum < 0) || (regnum >= GDB_NUM_REGS)) {      return FAILURE;   }      if (regnum <= RA_REGNUM) {       P->R[regnum] = val;      return SUCCESS;   }      if ((regnum >= FP0_REGNUM) && (regnum <= FP31_REGNUM)) {      IntReg(regnum-FP0_REGNUM) = val;      return SUCCESS;   }   switch (regnum) {   case PC_REGNUM:          /*        * This one is a little tricky. If this is set from a PC       * annotation, then everything should work fine. By also setting       * the P->PC, I cover the case where this is set from gdb.       */      P->PC                = val;       P->nPC               = val;       P->branchTarget      = 0;      P->branchStatus      = BranchStatus_none;      break;   case CAUSE_REGNUM: P->CP0[C0_CAUSE]    = val; break;   case BAD_REGNUM:   P->CP0[C0_BADVADDR] = val; break;   case HI_REGNUM:    P->HI               = val; break;   case LO_REGNUM:    P->LO               = val; break;   case FCRCS_REGNUM: P->FCR[31]          = val; break;   case FCRIR_REGNUM: P->FCR[30]          = val; break;   case INX_REGNUM:   P->CP0[C0_INX]      = val; break;   case RAND_REGNUM:  P->CP0[C0_RAND]     = val; break;   case TLBLO_REGNUM: P->CP0[C0_TLBLO_0]  = val; break;   case CTXT_REGNUM:  P->CP0[C0_CTXT]     = val; break;   case TLBHI_REGNUM: P->CP0[C0_TLBHI]    = val; break;   case SR_REGNUM:    P->CP0[C0_SR]       = val; break;   case EPC_REGNUM:   P->CP0[C0_EPC]      = val; break;   case ERROR_EPC_REGNUM: P->CP0[C0_ERROR_EPC] = val; break;   case COUNT_REGNUM:    P->CP0[C0_COUNT]      = val; break;   case COMPARE_REGNUM:  P->CP0[C0_COMPARE]    = val; break;   case TLBLO1_REGNUM:   P->CP0[C0_TLBLO_1]    = val; break;   case PGMASK_REGNUM:   P->CP0[C0_PGMASK]     = val; break;   default:           return FAILURE;   }      return SUCCESS;}/***************************************************************** * MipsyGetMem *****************************************************************/ResultMipsyGetMem(int cpuNum, VA vAddr, uint nbytes, char *buf){   PA pAddr;   CPUState *P = &PE[cpuNum];#ifdef MIPSY_MXS   if (PE[cpuNum].inMXS) {      CopyFromMXS(P);   }#endif     #ifdef USE_FLASHLITE      #ifndef SOLO   /* Check for SIMRAMALIAS or SIMPROMALIAS.    * These are special-cased. At init time, the contents of those    * areas are copied from the backdoor into PP-private memory.    * We don't want to access the backdoor copies here, but rather    * the copies each node sees.    */   if (GetFPROMAndFRAM(cpuNum, vAddr, nbytes, buf)) {      return SUCCESS;   }#endif#endif   if (PAGE_NUMBER(vAddr+nbytes-1) == PAGE_NUMBER(vAddr)) {      /* common case: entire range fits on one page */      if (TranslateVirtualNoSideeffect(P, vAddr, &pAddr) != SUCCESS) {         return FAILURE;     /* for now, give up if not in TLB */      }      MemRefDebugReadData(cpuNum, vAddr, pAddr, buf, nbytes);         } else {      PA pAddr2;      int bytes_on_first_page = (1<<12) - PAGE_OFFSET(vAddr);      VA vaddr2 = (vAddr) + bytes_on_first_page;      ASSERT(nbytes <= (1 << NUM_OFFSET_BITS));      if (TranslateVirtualNoSideeffect(P, vAddr, &pAddr) != SUCCESS) {         return FAILURE;              }            if (TranslateVirtualNoSideeffect(P, vaddr2, &pAddr2) != SUCCESS) {         return FAILURE;              }      MemRefDebugReadData(cpuNum, vAddr, pAddr, buf, bytes_on_first_page);      MemRefDebugReadData(cpuNum, vaddr2, pAddr2,                           buf + bytes_on_first_page,                          nbytes - bytes_on_first_page);   }   return SUCCESS;}/***************************************************************** * MipsyPutMem *****************************************************************/ResultMipsyPutMem(int cpuNum, VA vAddr, uint nbytes, char *buf){   PA pAddr;   CPUState *P = &PE[cpuNum];#ifdef MIPSY_MXS   if (PE[cpuNum].inMXS) {      CopyFromMXS(P);   }#endif     #ifdef USE_FLASHLITE      #ifndef SOLO   /* Check for SIMRAMALIAS or SIMPROMALIAS.    * These are special-cased. At init time, the contents of those    * areas are copied from the backdoor into PP-private memory.    * We don't want to access the backdoor copies here, but rather    * the copies each node sees.    */   if (PutFPROMAndFRAM(cpuNum, vAddr, nbytes, buf)) {      return SUCCESS;   }#endif#endif      if (PAGE_NUMBER(vAddr+nbytes-1) == PAGE_NUMBER(vAddr)) {      /* common case: entire range fits on one page */      if (TranslateVirtualNoSideeffect(P, vAddr, &pAddr) != SUCCESS) {         return FAILURE;     /* for now, give up if not in TLB */      }      MemRefDebugWriteData(cpuNum, vAddr, pAddr, buf, nbytes);         } else {      PA pAddr2;      int bytes_on_first_page = (1<<12) - PAGE_OFFSET(vAddr);      VA vaddr2 = (vAddr) + bytes_on_first_page;      ASSERT(nbytes <= (1 << NUM_OFFSET_BITS));      if (TranslateVirtualNoSideeffect(P, vAddr, &pAddr) != SUCCESS) {         return FAILURE;              }            if (TranslateVirtualNoSideeffect(P, vaddr2, &pAddr2) != SUCCESS) {         return FAILURE;              }      MemRefDebugWriteData(cpuNum, nbytes, pAddr, buf, bytes_on_first_page);      MemRefDebugWriteData(cpuNum, vaddr2, pAddr2,                            buf + bytes_on_first_page,                           nbytes - bytes_on_first_page);   }   return SUCCESS;}Result MipsyTranslateVirtualNoSE(int cpuNum, VA vAddr, PA *pAddr){   return TranslateVirtualNoSideeffect(&PE[cpuNum], vAddr, pAddr) ;}/***************************************************************** * MipsyDebug * * Main entry point into the debugger from normal execution.  * * NOTE: the second argument is_break_instruction is set when * we call in due to a single-step trap (from cpu.c) even though * there is no break instruction at the PC.  We need to send * the SIGTRAP to gdb in this case.  If we send a SIGUSR2 it * stops single-stepping immediately even though we may not * have yet reached the next line boundary (for 'n' or 's'). * * Return value 0 means nothing has changed, go through normal * instruction completion (pc = npc, npc += 4, annotations, etc). * * Return value 1 means PC has changed or instruction at PC has * been overwritten.  If you entered the debugger between instructions * abort anything you have read about the next instruction and restart. * If you entered the debugger from a breakpoint, reexecute the * instruction at that PC. * *****************************************************************/int MipsyDebug(int cpunum, int is_break_instruction){   Simdebug_result res;   Inst new_inst=0;   cached_pc = PE[cpunum].PC;   if (MipsyGetMem(cpunum, cached_pc, 4, (char *)&cached_inst) != SUCCESS) {      CPUWarning("Debug -- Current instruction at PC=0x%x not mapped!\n",                  cached_pc);      cached_inst = 0; /* nop */   }   res = Simdebug_run(is_break_instruction ? SIGTRAP : SIGUSR2, cpunum);   switch (res) {   case SD_CONTINUE:      mipsy_break_nexti = MIPSY_NOBREAK;      mipsy_debug_mode = 0;      break;   case SD_NEXTI_ANYCPU:      mipsy_break_nexti = MIPSY_BREAKANYCPU;      mipsy_debug_mode = 1;      break;   default:      mipsy_break_nexti = res;      mipsy_debug_mode = 1;      break;   }      if (PE[cpunum].PC != cached_pc) {       return 1;   }      if (MipsyGetMem(cpunum,cached_pc,4,(char*)&new_inst) != SUCCESS) {      CPUWarning("Debug -- Current instruction at PC=0x%x not mapped!\n");      return 1;   }   if( cached_inst != new_inst ) {       return 1;   }   return 0;}/***************************************************************** * HandleDebugSignal *****************************************************************/void HandleDebugSignal(int cpuid, int sigusr){   mipsy_debug_mode = 1;   if (sigusr) {      mipsy_sigusr = 1;   } else {       if (cpuid == -1) {         mipsy_break_nexti = MIPSY_BREAKANYCPU;      } else {         mipsy_break_nexti = cpuid;      }   }}

⌨️ 快捷键说明

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