debug.c

来自「一个用在mips体系结构中的操作系统」· C语言 代码 · 共 589 行 · 第 1/2 页

C
589
字号
 * embraDebug.statusCode  * *************************************************************/Result Embra_GetRegister(int cpuNum, int regnum, Reg *val){   EmbraState* P = &EMP[cpuNum];   if (regnum < 0) {       return FAILURE;   }      if (regnum <= RA_REGNUM) {      *val = P->R[regnum];      return SUCCESS;   }      if ((regnum >= FP0_REGNUM) && (regnum < FP0_REGNUM+32))  {      *val = P->FPR[regnum-FP0_REGNUM];      return SUCCESS;   }      switch (regnum) {   case LO_REGNUM: *val =  P->LO;   break;   case HI_REGNUM: *val =  P->HI;   break;   case PC_REGNUM: *val = CLEAR_BD(P->PC); 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 PRID_REGNUM: *val =  P->CP0[C0_PRID];   break;   case CAUSE_REGNUM: *val = P->CP0[C0_CAUSE];  break;   case BAD_REGNUM:   *val = P->CP0[C0_BADVADDR]; 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;         default:      return FAILURE;   }      return SUCCESS;}Result Embra_PutRegister(int cpuNum, int regnum, Reg val){   EmbraState* P = &EMP[cpuNum];   if (embraDebug.processingAnn == ANNFM_LD_TYPE ||       embraDebug.processingAnn == ANNFM_ST_TYPE) {       embraDebug.statusCode |= SIDE_EFFECT;   } else {      ASSERT(!embraDebug.processingAnn ||             embraDebug.processingAnn==ANNFM_PC_TYPE ||             embraDebug.processingAnn==ANNFM_PRE_PC_TYPE);   }   if ((regnum < 0) || (regnum >= GDB_NUM_REGS)) {      return FAILURE;   }      if (regnum <= RA_REGNUM)  {      P->R[regnum] = val;      return SUCCESS;   }      if ((regnum >= FP0_REGNUM) && (regnum < FP0_REGNUM+32))  {      P->FPR[regnum-FP0_REGNUM] = val;      return SUCCESS;   }   /*    * for those, assume a side-effect, even from a pc annotation    */   embraDebug.statusCode |= SIDE_EFFECT;   switch (regnum) {   case LO_REGNUM: P->LO = val;  break;   case HI_REGNUM: P->HI = val;  break;   case PC_REGNUM: P->PC = 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 PRID_REGNUM: P->CP0[C0_PRID] = val;  break;   case CAUSE_REGNUM:  P->CP0[C0_CAUSE] = val;  break;   case BAD_REGNUM:    P->CP0[C0_BADVADDR] = 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;}/* static */K0A debug_non_excepting_tv( int cpuNum, VA vAddr){   MA mAddr;   PA pAddr;   int machine = M_FROM_CPU(cpuNum);      if (IS_BACKDOOR(vAddr)) {      return 0;   }   if (!EMP[cpuNum].mmu) {      CPUWarning("\n\nEMBRA: non_excepting_tc called before init\n\n");      return 0;   }   /* KSEG0 addresses don't have to go through the mmu in the    * debugger. We don't care about the firewall, or about whether a    * translation is in the mmu or not. We have to be sure to do    * the remapping, tho.    */   if (IS_CKSEG0(vAddr) && IS_VALID_PA(machine, K0_TO_PHYS(vAddr)))      return PHYS_TO_K0(K0_TO_PHYS_REMAP(vAddr, cpuNum));   #if defined(SIM_MIPS64)   if (IS_XKPHYS(vAddr) && IS_VALID_PA(machine, XKPHYS_TO_PHYS(vAddr)))     return PHYS_TO_K0(K0_TO_PHYS_REMAP(vAddr, cpuNum));#endif#ifdef EMBRA_USE_QC64   mAddr = (MA)((VA)Em_QC64Reload(vAddr,0) & ~(DEFAULT_PAGESZ-1));#else   mAddr = EMP[cpuNum].mmu[PAGE_NUMBER(vAddr)];#endif      if (!mAddr && IS_KSEG0(vAddr)) {      ASSERT( IS_VALID_PA(machine, K0_TO_PHYS(vAddr)));      return vAddr;   }   if (!mAddr) {       int indx = Tlb_Lookup(cpuNum, GET_REGION(vAddr), GET_VPN2(vAddr),                            CURRENT_ASID(cpuNum));      if (indx) {         Reg lo_reg;         PA pAddr;#ifdef SIM_MIPS64         int szEntry = curEmp->tlbEntrySize[indx-1];	 int way = !(vAddr & PgSz[szEntry].loBit);#else	 int way = IS_LO_0(PAGE_NUMBER(vAddr));#endif	 if (way) {             lo_reg = EMP[cpuNum].tlbEntry[indx-1].Lo0;         } else {            lo_reg = EMP[cpuNum].tlbEntry[indx-1].Lo1;         }         if (IS_VALID(lo_reg)) {#ifdef SIM_MIPS64#define SZ2MASK(_s) PgSz[(_s)].mask	   pAddr = (((GET_PFN(lo_reg)&SZ2MASK(szEntry))*4*1024) |                (vAddr & PgSz[szEntry].offset_mask));#else            pAddr = FORM_ADDR(GET_PFN(lo_reg),  PAGE_OFFSET(vAddr));#endif            ASSERT(IS_VALID_PA(machine, pAddr));            return PHYS_TO_K0(pAddr);         }      }   }   if (!mAddr) {      /* We couldn't translate the virtual address using anything in the        * hardware. Callout to tcl to walk the OS data structures.       */      if (pAddr = TclTranslateVirtual(cpuNum, vAddr)) {         ASSERT(IS_VALID_PA(machine, pAddr));         return PHYS_TO_K0(pAddr);      }   }   if (mAddr) {       mAddr += PAGE_OFFSET( vAddr );      /* Only needed for page mode, but instead of checking its */      /* cheaper to just do it */        ASSERT(IS_VALID_PA(machine, MEMADDR_TO_PHYS(machine, MMU2ADDR(mAddr))));      return MEMADDR_TO_K0(machine, MMU2ADDR(mAddr));   }   return 0;}Result Embra_GetMemory(int cpuNum, VA vAddr, uint nbytes, char *buf){   int machine = M_FROM_CPU(cpuNum);   K0A k0Addr = debug_non_excepting_tv(cpuNum, vAddr);   PA pAddr;   if (!k0Addr) {      return FAILURE;   }   ASSERT( IS_KSEG0(k0Addr));   pAddr = K0_TO_PHYS(k0Addr);   ASSERT(IS_VALID_PA(machine, pAddr));      if (PAGE_NUMBER(vAddr + nbytes - 1) == PAGE_NUMBER(vAddr)) {      /* entire range fits on a page */      bcopy((void*)PHYS_TO_MEMADDR(machine,pAddr), buf, nbytes);   } else {      int bytes_on_first_page = (1 << NUM_OFFSET_BITS) - PAGE_OFFSET(vAddr);      VA vAddr2 = ((VA) vAddr) + bytes_on_first_page;      K0A k0Addr2 = debug_non_excepting_tv(cpuNum, vAddr2);      PA pAddr2 = K0_TO_PHYS(k0Addr2);      ASSERT(nbytes <= (1 << NUM_OFFSET_BITS));            if (!k0Addr2) {         return FAILURE;      }      ASSERT( IS_KSEG0(k0Addr2));      ASSERT(IS_VALID_PA(machine, pAddr));            bcopy(PHYS_TO_MEMADDR(machine, pAddr),            buf, bytes_on_first_page);      bcopy(PHYS_TO_MEMADDR(machine, pAddr2),             ((void*)((unsigned)buf + bytes_on_first_page)),             nbytes - bytes_on_first_page);   }   return SUCCESS;}Result Embra_PutMemory(int cpuNum, VA vAddr, uint nbytes, char *buf){   K0A k0Addr = debug_non_excepting_tv(cpuNum, vAddr);   embraDebug.statusCode |= SIDE_EFFECT;   if (!k0Addr) {      return FAILURE;   }      if (PAGE_NUMBER(vAddr + nbytes - 1) == PAGE_NUMBER(vAddr)) {      /* entire range fits on a page */      if (buf != (char*) K0_TO_MEMADDR(M_FROM_CPU(cpuNum), k0Addr))         bcopy( buf, (void*)K0_TO_MEMADDR(M_FROM_CPU(cpuNum), k0Addr), nbytes);      embraDebug.statusCode |= FLUSH_TC;   } else {      int bytes_on_first_page = (1 << NUM_OFFSET_BITS) - PAGE_OFFSET(vAddr);      VA vAddr2 = ((VA) vAddr) + bytes_on_first_page;      K0A k0Addr2 = debug_non_excepting_tv(cpuNum, vAddr2);      ASSERT(nbytes <= (1 << NUM_OFFSET_BITS));            if (!k0Addr2) {         return FAILURE;      }            bcopy(buf, (void*)K0_TO_MEMADDR(M_FROM_CPU(cpuNum), k0Addr),            bytes_on_first_page);      bcopy(((void*)((unsigned)buf + bytes_on_first_page)),             (void*) K0_TO_MEMADDR(M_FROM_CPU(cpuNum), k0Addr2),             nbytes - bytes_on_first_page );      embraDebug.statusCode |= FLUSH_TC;   }   return SUCCESS;}Result Embra_TranslateVirtualNoSE(int cpuNum, VA vAddr, PA *pAddr){   K0A k0A = debug_non_excepting_tv(cpuNum,vAddr);   if (k0A) {      *pAddr = K0_TO_PHYS(k0A);      return SUCCESS;   } else {      return FAILURE;   }}

⌨️ 快捷键说明

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