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

📄 machdep.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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	 */	if ((pg & PTE_CE_MASK) && 		!((cache == CACHE_PAC) || (cache == CACHE_PAC_E))) {		vac_pageflush(addr);		if (btop(addr + sizeof (int) - 1) != btop(addr))			vac_pageflush(addr + sizeof (int) - 1);	}	/* XXX - why not referenced also? */	Setpgmap(addr, pg | PTE_MOD(1));	mmu_flushall();	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 addr;	dorun = 0;	/*	 * See if the sp says that we are already on the debugger stack	 */	reg = (struct regs *)&regsave;	addr = getsp();	if (addr > (int)etext && addr < (int)estack) {		printf("Already in debugger!\n");		return;	}	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 */}/* * 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() * NOTE: we use the fact that the per- * processor clocks are available and * mapped properly at "utimers". */staticsetcpudelay(){	/* If need this call grab the latest from kernels machdep.c */} /* * Set the pte (level-3) for address v using the software pte given. * Setpgmap() automatically turns off the `cacheable' bit * for all mappings between DEBUGSTART and DEBUGEND. */voidSetpgmap(v, pte)	caddr_t v;	u_int pte;{	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->op2_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) {	/*	 * Cant test against BT_ or SP_ because using the 32-bit space	 * as bustype.  So since no define for OBMEM space, hardcoding	 * in the value of 0x0.	 */                if (rp[i].reg_bustype != 0x0)                        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);}/* * setpgmap: *  set the pte that maps virtual address `v' to `pte'. *  for success `v' must be mapped by a level-3 pte *  XXX - fix this so that we can look at monitors pages. */setpgmap(v, pte)caddr_t v;u_int pte;{	union ptpe *l2ptr;	union ptpe l2ptpe;	union ptes *l3ptr;	union ptes l3ptes;	l2ptr = get_l2_ptr(v);	l2ptpe.ptpe_int = ldphys(l2ptr);	l3ptr = ((union ptes *)(l2ptpe.ptp.PageTablePointer << 			       MMU_STD_PTPSHIFT)) + MMU_L3_INDEX((u_int)v);	l3ptes.pte_int = ldphys((u_int *)l3ptr);	stphys((u_int *)l3ptr, pte);	/* Flush the TLB after fiddling with PTE */	srmmu_mmu_flushpage(v);	return (0);}/* * getpgmap: *  return the pte that maps virtual address `v'. *  for success `v' must be mapped by a level-3 pte */getpgmap(v)caddr_t v;{	union ptpe *l2ptr;	union ptpe l2ptpe;	union ptes *l3ptr;	union ptes l3ptes;	l2ptr = get_l2_ptr(v);	l2ptpe.ptpe_int = ldphys(l2ptr);	l3ptr = ((union ptes *)(l2ptpe.ptp.PageTablePointer << 			       MMU_STD_PTPSHIFT)) + MMU_L3_INDEX((u_int)v);	l3ptes.pte_int = ldphys((u_int *)l3ptr);	return (l3ptes.pte_int);}#ifdef	MULTIPROCESSOR/* * XXX-These functions should eventually implement the cross-call * mechanism, or someother such method. */idle_cpus(mid)dnode_t	mid;{int	cur_cpuid, i;	cur_cpuid = MIDTOCPU(mid);	/*	 * Only print which cpu we are on, if we have more	 * than one cpu.  Else, its unnecessary.	 */	for (i=1; i < NCPU; i++) {		if (cpus_enabled[i]) {			if (!print_cpu_done)				printf("currently on cpu%d\n", cur_cpuid);			break;		}	}#ifdef	PROM_IDLECPU_WORKS	for (i=0; i < NCPU; i++) {		if (cpus_enabled[i] && (i != cur_cpuid)) {		/*		 * prom_idlecpu returns 0 on success, -1 on failure		 */		    if (prom_idlecpu(cpus_nodeid[i]))			printf("-->failed to idle cpu%d\n", i);		}	}	/* Now back to the regularly scheduled program */#endif	/* PROM_IDLECPU_WORKS */	cmd();}#ifdef	PROM_IDLECPUS_WORKS/* * On way out of kadb have to get other cpu's back up. */resume_cpus(mid)dnode_t	mid;{int	cur_cpuid, i;	cur_cpuid = MIDTOCPU(mid);	for (i=0; i < NCPU; i++) {		if (cpus_enabled[i] && (i != cur_cpuid)) {		/*		 * prom_resumecpu returns 0 on success, -1 on failure		 */		    if (prom_resumecpu(cpus_nodeid[i]))			printf("-->failed to resume cpu%d\n", i);		}	}}#endif	/* PROM_IDLECPUS_WORKS */#endif	MULTIPROCESSOR

⌨️ 快捷键说明

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