📄 machdep.c
字号:
nofault = saved_jb; errno = EFAULT; return (-1);}intpokec(addr, val) char *addr; char val;{ saved_jb = nofault; nofault = jb; errno = 0; if (!_setjmp(jb)) { *addr = val; /* if we get here, it worked */ nofault = saved_jb; return (0); } /* a fault occured */ nofault = saved_jb; errno = EFAULT; return (-1);}intpokel(addr, val) long *addr; long val;{ saved_jb = nofault; nofault = jb; errno = 0; if (!_setjmp(jb)) { *addr = val; /* if we get here, it worked */ nofault = saved_jb; return (0); } /* a fault occured */ nofault = saved_jb; errno = EFAULT; return (-1);}poketext(addr, val) int *addr; int val;{ int pg = 0; pg = getpgmap((int)addr); if ((pg & PG_V) == 0) { if (debugging > 2) printf("poketext: invalid page map %X at %X\n", pg, addr); goto err; } if ((pg & PGT_MASK) != PGT_OBMEM) { if (debugging > 2) printf("poketext: incorrect page type %X at %X\n", pg, addr); goto err; } vac_pageflush(addr); if (btop(addr + sizeof (int) - 1) != btop(addr)) vac_pageflush(addr + sizeof (int) - 1); if ((pg & PG_PROT) == PG_KR) Setpgmap(addr, (pg & ~PG_PROT) | PG_KW); else if ((pg & PG_PROT) == PG_URKR) Setpgmap(addr, (pg & ~PG_PROT) | PG_UW); /* otherwise it is already writeable */ *addr = val; /* should be prepared to catch a fault here? */ /* * Reset to page map to previous entry, * but mark as modified */ vac_pageflush(addr); if (btop(addr + sizeof (int) - 1) != btop(addr)) vac_pageflush(addr + sizeof (int) - 1); Setpgmap(addr, pg | PG_M); errno = 0; return (0);err: errno = EFAULT; return (-1);}scopy(from, to, count) register char *from; register char *to; register int count;{ register int val; for (; count > 0; count--) { if ((val = Peekc(from++)) == -1) goto err; if (pokec(to++, val) == -1) goto err; } return (0);err: errno = EFAULT; return (-1);}/* * Setup a new context to run at routine using stack whose * top (end) is at sp. Assumes that the current context * is to be initialized for mainregs and new context is * to be set up in debugregs. */spawn(sp, routine) char *sp; func_t routine;{ char *fp; int res; if (curregs != 0) { printf("bad call to spawn\n"); exit(1); } if ((res = _setjmp(mainregs)) == 0) { /* * Setup top (null) window. */ sp -= WINDOWSIZE; ((struct rwindow *)sp)->rw_rtn = 0; ((struct rwindow *)sp)->rw_fp = 0; /* * Setup window for routine with return to exit. */ fp = sp; sp -= WINDOWSIZE; ((struct rwindow *)sp)->rw_rtn = (int)exit - 8; ((struct rwindow *)sp)->rw_fp = (int)fp; /* * Setup new return window with routine return value. */ fp = sp; sp -= WINDOWSIZE; ((struct rwindow *)sp)->rw_rtn = (int)routine - 8; ((struct rwindow *)sp)->rw_fp = (int)fp; /* copy entire jump buffer to debugregs */ bcopy((caddr_t)mainregs, (caddr_t)debugregs, sizeof (jmp_buf)); debugregs[JB_SP] = (int)sp; /* set sp */ curregs = debugregs; regsave.r_npc = (int)&fake_bpt; _longjmp(debugregs, 1); /* jump to new context */ /*NOTREACHED*/ }}doswitch(){ int res; if ((res = _setjmp(curregs)) == 0) { /* * Switch curregs to other descriptor */ if (curregs == mainregs) { curregs = debugregs; } else /* curregs == debugregs */ { curregs = mainregs; } _longjmp(curregs, 1); /*NOTREACHED*/ } /* * else continue on in new context */}/* * Main interpreter command loop. */cmd(){ int resetclk = 0; u_char intreg; int addr, t; int i; u_char interreg; int s; dorun = 0; i = 0; /* * See if the sp says that we are already on the debugger stack */ reg = (struct regs *)®save; addr = getsp(); if (addr > (int)etext && addr < (int)estack) { printf("Already in debugger!\n"); return; } cache_on = getenablereg() & ENA_CACHE; if (cache_on) setdelay(mips_on); else setdelay(mips_off); do { doswitch(); if (dorun == 0) printf("cmd: nothing to do\n"); } while (dorun == 0); /* we don't need to splx since we are returning to the caller */ /* and will reset his/her state */}/* * Return an available physical page number */intgetapage(){ register struct memlist *pmem; register caddr_t addr; /* * Find the top of physical memory and take the top pages. * We assume the physmem chunks are in ascending order and * the last chunk is non-zero. */ pmem = *romp->v_availmemory; for( ; pmem->next != (struct memlist *)NULL; pmem = pmem->next) ; if (pmem->size < MMU_PAGESIZE) { printf("panic: getapage: last physmem chunk too small\n"); _exit(); } pmem->size -= MMU_PAGESIZE; return (mmu_btop(pmem->address + pmem->size));}/* * Call into the monitor (hopefully) */montrap(funcptr) int (*funcptr)();{ our_tbr = gettbr(); if (use_kern_tbr) { settbr(regsave.r_tbr); } else settbr(mon_tbr); /* * Must do the following because libprom calls * montrap to "enter" and "exit_to" the prom. * Since kadb has this montrap function we * are calling through here. Thus, if an argument * is passed do as libprom's routine does, else * do as before. */ if (funcptr) (*funcptr)(); else (*romp->op_exit)(); settbr(our_tbr);}/* * set delay constant for usec_delay() * delay ~= (usecs * (Cpudelay * 2 + 3) + 8) / mips * => Cpudelay = ceil((mips - 3) / 2) */staticsetdelay(mips) int mips;{ extern int Cpudelay; Cpudelay = 0; if (mips > 3) Cpudelay = (mips - 2) >> 1;}/* * Set the pme for address v using the software pte given. * Setpgmap() automatically turns on the ``no cache'' bit * for all mappings between DEBUGSTART and DEBUGEND. */voidSetpgmap(v, pte) caddr_t v; int pte;{ if (v >= (caddr_t)DEBUGSTART && v <= (caddr_t)DEBUGEND) pte |= PG_NC; setpgmap(v, pte);}traceback(sp) caddr_t sp;{ register u_int tospage; register struct frame *fp; static int done = 0;#ifdef PARTIAL_ALIGN if (partial_align? ((int)sp & 0x3): ((int)sp & 0x7)) {#else if ((int)sp & (STACK_ALIGN-1)) {#endif PARTIAL_ALIGN printf("traceback: misaligned sp = %x\n", sp); return; } flush_windows(); tospage = (u_int)btoc(sp); fp = (struct frame *)sp; printf("Begin traceback... sp = %x\n", sp); while (btoc((u_int)fp) == tospage) { if (fp == fp->fr_savfp) { printf("FP loop at %x", fp); break; } printf("Called from %x, fp=%x, args=%x %x %x %x %x %x\n", fp->fr_savpc, fp->fr_savfp, fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3], fp->fr_arg[4], fp->fr_arg[5]);#ifdef notdef printf("\tl0-l7: %x, %x, %x, %x, %x, %x, %x, %x\n", fp->fr_local[0], fp->fr_local[1], fp->fr_local[2], fp->fr_local[3], fp->fr_local[4], fp->fr_local[5], fp->fr_local[6], fp->fr_local[7]);#endif fp = fp->fr_savfp; if (fp == 0) break; } printf("End traceback...\n");}our_die_routine(retaddr) register caddr_t retaddr;{#ifdef NOTYET (*romp->op_chain)(0, 0, retaddr+8); /* NOTREACHED */#endif ;}struct memlist *getmemlist(name, prop) char *name, *prop;{ int nodeid; int i, j, k, chunks; u_int propsize; struct dev_reg *rp; struct memlist *pmem; static caddr_t bufp = (caddr_t)0; static u_int left; if (bufp == (caddr_t) 0) { bufp = (caddr_t)(*romp->op2_alloc)((caddr_t)0, PAGESIZE); left = PAGESIZE; } /* * First find the right node. */ nodeid = search(NEXT(0), name, bufp); if (nodeid == 0) return ((struct memlist *)0); /* * Allocate memlist elements, one per dev_reg struct. */ propsize = (u_int)GETPROPLEN(nodeid, prop); chunks = propsize / sizeof (struct dev_reg); if (chunks == 0) return ((struct memlist *)0); if (left < (chunks * sizeof (struct memlist))) { printf("memlists too big"); return ((struct memlist *)0); } pmem = (struct memlist *)bufp; bzero((caddr_t)pmem, (u_int) chunks * sizeof (struct memlist)); left -= (u_int) chunks * sizeof (struct memlist); bufp += (u_int) chunks * sizeof (struct memlist); if (left < propsize) { printf("buffer too small"); return ((struct memlist *)0); } /* * Fill in memlist chunks. */ rp = (struct dev_reg *)bufp; bzero((caddr_t)rp, propsize); left -= propsize; bufp += propsize; (void)GETPROP(nodeid, prop, rp); for (i = 0; i < chunks; ++i) { if (rp[i].reg_bustype != OBMEM) continue; /* * Insert the new element into the array of list nodes * so that the array remains sorted in ascending order. */ /* Find the first element with a larger address */ for (j = 0; j < i; j++) if (pmem[j].address > (u_int)rp[i].reg_addr) break; /* Copy following elements up to make room for the new one */ for (k = i; k > j; --k) pmem[k] = pmem[k-1]; /* Insert the new element */ pmem[j].address = (u_int)rp[i].reg_addr; pmem[j].size = rp[i].reg_size; } for (i = 1; i < chunks; ++i) { if (pmem[i].address) pmem[i-1].next = &pmem[i]; } return (pmem);}search(node, name, buf) int node; char *name; char *buf;{ int id; *buf = '\0'; (void)GETPROP(node, "name", buf); if (strcmp(buf, name) == 0) { return (node); } id = NEXT(node); if (id && (id = search(id, name, buf))) return (id); id = CHILD(node); if (id && (id = search(id, name, buf))) return (id); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -