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 + -
显示快捷键?