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

📄 kdb_mtpr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)kdb_mtpr.c	4.1	ULTRIX	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* *	UNIX debugger * *	Oct-06-88	gmm *	Update the P[01][BL]R registers correctly in getpcb(). Otherwise *	a process's context is not fully mapped correctly * *	Jul-19-88	gmm *	Store all register information in noproc_usr if no proc present *	while entering kdb * *	Jun-03-88	gmm *	Check if the processor has a process context while entering kdb. If * 	there is no process context, do not update the user pcb with  *	register values. This prevents some of the panics on :c *	Jim Woodward's changes to the routine kdb_chgprot() to make it work *	correctly. */#include "../machine/mtpr.h"#include "../machine/reg.h"#include "../machine/psl.h"#include "../machine/pte.h"#include "../machine/cons.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"/* pcb.h is included by user.h */#include "../h/user.h"#include "../h/smp_lock.h"#include "../h/cpudata.h"#include "../h/proc.h"#include "mac.h"#include "mode.h"#include "../machine/trap.h"extern MAP kdb_datmap, kdb_txtmap;extern int *kdb_psl_ptr, *kdb_pc_ptr, *kdb_regs_ptr;extern ADDR kdb_userpc;extern lbolt;extern struct user *uptr;struct proc *kdb_firstprocp;struct	user kdbusr, noproc_usr;extern REGLIST kdb_reglist[];/*  * Flush any garbage from the console. * Should really be in kdb_misc.c but that file * doesn't get run through inline and i'm lazy. */kdb_flush_input(){	int i = 20;	register c; 	while ((c=(mfpr(RXCS)&RXCS_DONE)) == 0 && i--)		;	if (c) c = mfpr(RXDB)&0177;  /* flush char */}getpcb(pte)struct pte *pte;{	register int i;	register struct pte *map,*mp;	register REGPTR p;	register int *pcbptr;	/* This is used to change who we are mapping */	/* following code lifted from uaccess() in sys/vm_subr.c */	mp = map = &Kdbmap;	for (i = 0; i< UPAGES; i++) {		*(int *)map = 0;		map->pg_pfnum = pte[i].pg_pfnum;		map++;	}	vmaccess(mp, (caddr_t)&kdbusr, UPAGES);	uptr = &kdbusr;	pcbptr = &uptr->u_pcb;	p = kdb_reglist;	for(p = kdb_reglist; p < &kdb_reglist[24]; p++ ) { 		p->roffs = pcbptr++;	}	mtpr(P0BR,uptr->u_pcb.pcb_p0br);	mtpr(P0LR,uptr->u_pcb.pcb_p0lr);	mtpr(P1BR,uptr->u_pcb.pcb_p1br);	mtpr(P1LR,uptr->u_pcb.pcb_p1lr);	mtpr(TBIA,0);	cprintf("p0br %X p0lr %X p1br %X p1lr %X\n",	uptr->u_pcb.pcb_p0br, uptr->u_pcb.pcb_p0lr,	uptr->u_pcb.pcb_p1br, uptr->u_pcb.pcb_p1lr);}setcor(){	/*		 * There is only one image, and no core file,		 * so just do a structure copy		 */	extern struct pte *kdb_sbr, *kdb_slr;	kdb_datmap.b1 = kdb_datmap.b2 = KERNOFF - (NBPG*UPAGES);	kdb_datmap.e1 = kdb_datmap.e2 = 0xffffffff;	kdb_datmap.f1 = kdb_datmap.f2 = KERNOFF - (NBPG*UPAGES);	kdb_sbr = (struct pte *)mfpr(SBR);	kdb_slr = (struct pte *)mfpr(SLR);	cprintf("kdb_sbr %X kdb_slr %X\n", kdb_sbr, kdb_slr);}extern lbolt;kdb_chgprot(va, prot)char * va;	/* virtual address */{	struct pte *pte, *sbr;	unsigned page;	int old_protection;	pte = 	&Sysmap[btop(((int) va) & ~0x80000000)];	old_protection = *(int *)pte & PG_PROT;	*(int *)pte &= ~PG_PROT;	*(int *)pte |= prot;	mtpr(TBIS,va);	return (old_protection);}readregs(){	/*		 * Load values from the trap into the pcb		 * of the currently executing process.		 * This should only be called on entering kdb.		 * kdb_regs_ptr points to the (0 of the trap) frame.		 */	register struct cpudata *pcpu;	pcpu = CURRENT_CPUDATA;  /* kdb assumed to be running on PRIMARY */	uptr = &u;	kdb_firstprocp = u.u_procp;	if (pcpu->cpu_noproc) {		cprintf("No process context exists. Use $p to get a process context\n");		if(pcpu->cpu_proc)			cprintf("Last running proc = 0x%X, p_addr = 0x%X\n",pcpu->cpu_proc,pcpu->cpu_proc->p_addr);		uptr = &noproc_usr;	}	else {		uptr = &u;		kdb_userpc = u.u_pcb.pcb_pc;	}	uptr->u_pcb.pcb_ksp = mfpr(KSP);	uptr->u_pcb.pcb_esp = mfpr(ESP);	uptr->u_pcb.pcb_ssp = mfpr(SSP);	uptr->u_pcb.pcb_usp = mfpr(USP);	uptr->u_pcb.pcb_r0 = kdb_regs_ptr[5]; 	uptr->u_pcb.pcb_r1 = kdb_regs_ptr[6]; 	uptr->u_pcb.pcb_r2 = kdb_regs_ptr[7]; 	uptr->u_pcb.pcb_r3 = kdb_regs_ptr[8]; 	uptr->u_pcb.pcb_r4 = kdb_regs_ptr[9]; 	uptr->u_pcb.pcb_r5 = kdb_regs_ptr[10]; 	uptr->u_pcb.pcb_r6 = kdb_regs_ptr[11]; 	uptr->u_pcb.pcb_r7 = kdb_regs_ptr[12]; 	uptr->u_pcb.pcb_r8 = kdb_regs_ptr[13]; 	uptr->u_pcb.pcb_r9 = kdb_regs_ptr[14]; 	uptr->u_pcb.pcb_r10 = kdb_regs_ptr[15]; 	uptr->u_pcb.pcb_r11 = kdb_regs_ptr[16]; 	uptr->u_pcb.pcb_ap = kdb_regs_ptr[2]; 	uptr->u_pcb.pcb_fp = kdb_regs_ptr[3]; 	uptr->u_pcb.pcb_pc = *kdb_pc_ptr;	uptr->u_pcb.pcb_psl = *kdb_psl_ptr;	uptr->u_ar0 = &uptr->u_pcb.pcb_r0;}struct proc *get_proc(cpunum){	register struct cpudata *pcpu;	pcpu = CPUDATA(cpunum);	if (pcpu->cpu_noproc)		return(0);	else		return(pcpu->cpu_proc);}extern kdb_saved_ipl;struct state	single_step_state;struct state	kdb_bkpt_state;struct state	kdb_continue_state;force_call(type){	/* This gives the state changes room to happen		 * without trodding the rest of my stack		 */	char take_up_space[2048];	register int *r11;	struct state *l;	l = &kdb_continue_state;	/* This must be done in-line, as otherwise the values		 * change when you return, and we write over what had		 * been saved.  Note that we lie and say that the sp		 * is the same as the frame pointer.  The idea is that		 * when we return to this spot, we want to continue		 * executing in the 2048 bytes we reserved in 'take_up_space'.		 * If we execute other than in that spot, the longjmp to		 * where we came from (another long jmp) will not succeed.		 */	asm("movl ap,r11"); 	l->kdb_ap = r11;	asm("movl fp,r11"); 	l->kdb_fp = r11;	l->kdb_sp = l->kdb_fp;	asm("moval fclabel,r11"); 	l->kdb_pc = r11;	/*		 * Move the stack pointer to the end of the 'take_up_space'		 * variable when we are here on the breakpoint path, so		 * that the * longjmps will use it instead of trodding our		 * carefully preserved stack.  The calls just works with		 * the stack pointer, the potential subsequent return just		 * uses the frame pointer, so this should work.		 */	if (type == T_BPTFLT) {		r11 = &take_up_space[2044];		asm("movl r11,sp");		kdb_longjmp(&kdb_bkpt_state);	} 	else if (type == T_TRCTRAP) {		r11 = &take_up_space[2044];		asm("movl r11,sp");		kdb_longjmp(&single_step_state);	} 	else if (type == T_KDB_ENTRY) {		cprintf("type is T_KDB_ENTRY\n"); 		kern_debugger();	}	asm("fclabel:");}extern char kdb_redzone[];kdbred(){	register int *ip,i;	ip = (int *)Sysmap + (btop(((int) &kdb_redzone[512]) & 0x7fffffff));	*ip &= ~PG_PROT; *ip |= PG_KR;	mtpr(TBIS, &kdb_redzone[512]);}

⌨️ 快捷键说明

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