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

📄 hppah-tdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0,	     1, 0, Val_pretty_default);  printf_filtered ("\n");}/* * Virtual to physical translation routines for Utah's Mach 3.0 */#ifdef MACHKERNELDEBUG#define STATIC#if 0	/* too many includes to resolve, too much crap */#include <kern/queue.h>#include <vm/pmap.h>	#include <mach/vm_prot.h>#else/* queue.h */struct queue_entry {	struct queue_entry	*next;		/* next element */	struct queue_entry	*prev;		/* previous element */};typedef struct queue_entry	*queue_t;typedef	struct queue_entry	queue_head_t;typedef	struct queue_entry	queue_chain_t;typedef	struct queue_entry	*queue_entry_t;/* pmap.h */#define HP800_HASHSIZE		1024#define HP800_HASHSIZE_LOG2	10#define pmap_hash(space, offset) \	(((unsigned) (space) << 5 ^ \	  ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \	  (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))struct mapping {	queue_head_t	hash_link;	/* hash table links */	queue_head_t	phys_link;	/* for mappings of a given PA */	space_t		space;		/* virtual space */	unsigned	offset;		/* virtual page number */	unsigned	tlbpage;	/* physical page (for TLB load) */	unsigned	tlbprot;	/* prot/access rights (for TLB load) */	struct pmap	*pmap;		/* pmap mapping belongs to */};struct phys_entry {	queue_head_t	phys_link;	/* head of mappings of a given PA */	struct mapping	*writer;	/* mapping with R/W access */	unsigned	tlbprot;	/* TLB format protection */};#endif#define atop(a)		((unsigned)(a) >> 11)#define ptoa(p)		((unsigned)(p) << 11)#define trunc_page(a)	((unsigned)(a) & ~2047)STATIC long equiv_end;STATIC queue_head_t *Ovtop_table, *vtop_table, *Ofree_mapping, free_mapping;STATIC struct phys_entry *Ophys_table, *phys_table;STATIC long vm_last_phys, vm_first_phys;STATIC struct mapping *firstmap, *lastmap, *Omap_table, *map_table;STATIC unsigned Omlow, Omhigh, Omhead, Ovlow, Ovhigh, Oplow, Ophigh;STATIC unsigned mlow, mhigh, mhead, vlow, vhigh, plow, phigh;STATIC int vtopsize, physsize, mapsize;STATIC int kmemfd;#define IS_OVTOPPTR(p)	((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)#define IS_OMAPPTR(p)	((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)#define IS_OPHYSPTR(p)	((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)#define IS_VTOPPTR(p)	((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)#define IS_MAPPTR(p)	((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)#define IS_PHYSPTR(p)	((unsigned)(p) >= plow && (unsigned)(p) < phigh)struct mapstate {	char	unused;	char	flags;	short	hashix;	short	physix;} *mapstate;/* flags */#define M_ISFREE	1#define M_ISHASH	2#define M_ISPHYS	4mach_vtophys_init(){	int errors = 0;	if (!readdata())		errors++;	if (!verifydata())		errors++;	if (!errors)		return(1);	fflush(stdout);	fprintf(stderr,		"translate: may not be able to translate all addresses\n");	return(0);}mach_vtophys(space, off, pa)	unsigned space, off, *pa;{	register int i;	register queue_t qp;	register struct mapping *mp;	int poff;	/*	 * Kernel IO or equivilently mapped, one to one.	 */	if (space == 0 && (long)off < equiv_end) {		*pa = off;		return(1);	}	/*	 * Else look it up in specified space	 */	poff = off - trunc_page(off);	off = trunc_page(off);	qp = &vtop_table[pmap_hash(space, off)];	for (mp = (struct mapping *)qp->next;	     qp != (queue_entry_t)mp;	     mp = (struct mapping *)mp->hash_link.next) {		if (mp->space == space && mp->offset == off) {			*pa = (mp->tlbpage << 7) | poff;			return(1);		}	}	return(0);}STATICreaddata(){	char *tmp, *mach_malloc();	long size;	/* easy scalars */	mach_read("equiv_end", ~0, (char *)&equiv_end, sizeof equiv_end);	mach_read("vm_first_phys", ~0,		  (char *)&vm_first_phys, sizeof vm_first_phys);	mach_read("vm_last_phys", ~0,		  (char *)&vm_last_phys, sizeof vm_last_phys);	mach_read("firstmap", ~0, (char *)&firstmap, sizeof firstmap);	mach_read("lastmap", ~0, (char *)&lastmap, sizeof lastmap);	/* virtual to physical hash table */	vtopsize = HP800_HASHSIZE;	size = vtopsize * sizeof(queue_head_t);	tmp = mach_malloc("vtop table", size);	mach_read("vtop_table", ~0, (char *)&Ovtop_table, sizeof Ovtop_table);	mach_read("vtop table", (CORE_ADDR)Ovtop_table, tmp, size);	vtop_table = (queue_head_t *) tmp;	/* inverted page table */	physsize = atop(vm_last_phys - vm_first_phys);	size = physsize * sizeof(struct phys_entry);	tmp = mach_malloc("phys table", size);	mach_read("phys_table", ~0, (char *)&Ophys_table, sizeof Ophys_table);	mach_read("phys table", (CORE_ADDR)Ophys_table, tmp, size);	phys_table = (struct phys_entry *) tmp;	/* mapping structures */	Ofree_mapping = (queue_head_t *) ksym_lookup("free_mapping");	mach_read("free mapping", (CORE_ADDR)Ofree_mapping,		  (char *) &free_mapping, sizeof free_mapping);	Omap_table = firstmap;	mapsize = lastmap - firstmap;	size = mapsize * sizeof(struct mapping);	tmp = mach_malloc("mapping table", size);	mach_read("mapping table", (CORE_ADDR)Omap_table, tmp, size);	map_table = (struct mapping *) tmp;	/* set limits */	Ovlow = (unsigned) Ovtop_table;	Ovhigh = (unsigned) &Ovtop_table[vtopsize];	Oplow = (unsigned) Ophys_table;	Ophigh = (unsigned) &Ophys_table[physsize];	Omhead = (unsigned) Ofree_mapping;	Omlow = (unsigned) firstmap;	Omhigh = (unsigned) lastmap;	mlow = (unsigned) map_table;	mhigh = (unsigned) &map_table[mapsize];	mhead = (unsigned) &free_mapping;	vlow = (unsigned) vtop_table;	vhigh = (unsigned) &vtop_table[vtopsize];	plow = (unsigned) phys_table;	phigh = (unsigned) &phys_table[physsize];#if 0	fprintf(stderr, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",		Ovlow, Ovhigh, Oplow, Ophigh, Omhead, Omlow, Omhigh);	fprintf(stderr, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",		vlow, vhigh, plow, phigh, mhead, mlow, mhigh);#endif	return(adjustdata());}STATIC unsignedptrcvt(ptr)	unsigned ptr;{	unsigned ret;	char *str;	if (ptr == 0) {		ret = ptr;		str = "null";	} else if (IS_OVTOPPTR(ptr)) {		ret = vlow + (ptr - Ovlow);		str = "vtop";	} else if (IS_OPHYSPTR(ptr)) {		ret = plow + (ptr - Oplow);		str = "phys";	} else if (IS_OMAPPTR(ptr)) {		ret = mlow + (ptr - Omlow);		str = "map";	} else if (ptr == Omhead) {		ret = mhead;		str = "maphead";	} else {		error("bogus pointer %#x", ptr);		str = "wild";		ret = ptr;	}#if 0	fprintf(stderr, "%x (%s) -> %x\n", ptr, str, ret);#endif	return(ret);}STATIC intadjustdata(){	register int i, lim;	queue_head_t *nq;	struct phys_entry *np;	struct mapping *nm;	/* hash table */	lim = vtopsize;	for (nq = vtop_table; nq < &vtop_table[lim]; nq++) {		nq->next = (queue_entry_t) ptrcvt((unsigned)nq->next);		nq->prev = (queue_entry_t) ptrcvt((unsigned)nq->prev);	}	/* IPT */	lim = physsize;	for (np = phys_table; np < &phys_table[lim]; np++) {		np->phys_link.next = (queue_entry_t)			ptrcvt((unsigned)np->phys_link.next);		np->phys_link.prev = (queue_entry_t)			ptrcvt((unsigned)np->phys_link.prev);		np->writer = (struct mapping *) ptrcvt((unsigned)np->writer);	}	/* mapping table */	free_mapping.next = (queue_entry_t)ptrcvt((unsigned)free_mapping.next);	free_mapping.prev = (queue_entry_t)ptrcvt((unsigned)free_mapping.prev);	lim = mapsize;	for (nm = map_table; nm < &map_table[lim]; nm++) {		nm->hash_link.next = (queue_entry_t)			ptrcvt((unsigned)nm->hash_link.next);		nm->hash_link.prev = (queue_entry_t)			ptrcvt((unsigned)nm->hash_link.prev);		nm->phys_link.next = (queue_entry_t)			ptrcvt((unsigned)nm->phys_link.next);		nm->phys_link.prev = (queue_entry_t)			ptrcvt((unsigned)nm->phys_link.prev);	}	return(1);}/* * Consistency checks, make sure: * *	1. all mappings are accounted for *	2. no cycles *	3. no wild pointers *	4. consisent TLB state */STATIC intverifydata(){	register struct mapstate *ms;	register int i;	int errors = 0;	mapstate = (struct mapstate *)		mach_malloc("map state", mapsize * sizeof(struct mapstate));	for (ms = mapstate; ms < &mapstate[mapsize]; ms++) {		ms->flags = 0;		ms->hashix = ms->physix = -2;	}	/*	 * Check the free list	 */	checkhashchain(&free_mapping, M_ISFREE, -1);	/*	 * Check every hash chain	 */	for (i = 0; i < vtopsize; i++)		checkhashchain(&vtop_table[i], M_ISHASH, i);	/*	 * Check every phys chain	 */	for (i = 0; i < physsize; i++)		checkphyschain(&phys_table[i].phys_link, M_ISPHYS, i);	/*	 * Cycle through mapstate looking for anomolies	 */	ms = mapstate;	for (i = 0; i < mapsize; i++) {		switch (ms->flags) {		case M_ISFREE:		case M_ISHASH|M_ISPHYS:			break;		case 0:			merror(ms, "not found");			errors++;			break;		case M_ISHASH:			merror(ms, "in vtop but not phys");			errors++;			break;		case M_ISPHYS:			merror(ms, "in phys but not vtop");			errors++;			break;		default:			merror(ms, "totally bogus");			errors++;			break;		}		ms++;	}	return(errors ? 0 : 1);}STATIC voidcheckhashchain(qhp, flag, ix)	queue_entry_t qhp;{	register queue_entry_t qp, pqp;	register struct mapping *mp;	struct mapstate *ms;	qp = qhp->next;	/*	 * First element is not a mapping structure,	 * chain must be empty.	 */	if (!IS_MAPPTR(qp)) {		if (qp != qhp || qp != qhp->prev)			fatal("bad vtop_table header pointer");	} else {		pqp = qhp;		do {			mp = (struct mapping *) qp;			qp = &mp->hash_link;			if (qp->prev != pqp)				fatal("bad hash_link prev pointer");			ms = &mapstate[mp-map_table];			ms->flags |= flag;			ms->hashix = ix;			pqp = (queue_entry_t) mp;			qp = qp->next;		} while (IS_MAPPTR(qp));		if (qp != qhp)			fatal("bad hash_link next pointer");	}}STATIC voidcheckphyschain(qhp, flag, ix)	queue_entry_t qhp;{	register queue_entry_t qp, pqp;	register struct mapping *mp;	struct mapstate *ms;	qp = qhp->next;	/*	 * First element is not a mapping structure,	 * chain must be empty.	 */	if (!IS_MAPPTR(qp)) {		if (qp != qhp || qp != qhp->prev)			fatal("bad phys_table header pointer");	} else {		pqp = qhp;		do {			mp = (struct mapping *) qp;			qp = &mp->phys_link;			if (qp->prev != pqp)				fatal("bad phys_link prev pointer");			ms = &mapstate[mp-map_table];			ms->flags |= flag;			ms->physix = ix;			pqp = (queue_entry_t) mp;			qp = qp->next;		} while (IS_MAPPTR(qp));		if (qp != qhp)			fatal("bad phys_link next pointer");	}}STATIC voidmerror(ms, str)	struct mapstate *ms;	char *str;{	terminal_ours();	fflush(stdout);	fprintf(stderr,		"vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",		str,		(ms->flags & M_ISFREE) ? 'F' : '-',		(ms->flags & M_ISHASH) ? 'H' : '-',		(ms->flags & M_ISPHYS) ? 'P' : '-',		ms->hashix, ms->physix, &map_table[ms-mapstate]);	return_to_top_level();}STATIC intmach_read(str, from, top, size)	char *str;	CORE_ADDR from;	char *top;	int size;{	CORE_ADDR paddr;	if (from == ~0)		from = ksym_lookup(str);	paddr = vtophys(0, from);	if (paddr == ~0 || physrd(paddr, top, size) != 0)		fatal("cannot read %s", str);}STATIC char *mach_malloc(str, size)	char *str;	int size;{	char *ptr = (char *) malloc(size);	if (ptr == 0)		fatal("no memory for %s", str);	return(ptr);}#endif#ifdef KERNELDEBUGvoid_initialize_hp9k8_dep(){	add_com ("process-address", class_obscure, set_paddr_command,"The process identified by (ps-style) ADDR becomes the\n\\"current\" process context for kernel debugging.");	add_com_alias ("paddr", "process-address", class_obscure, 0);	add_com ("virtual-to-physical", class_obscure, vtop_command,"Translates the kernel virtual address ADDR into a physical address.");	add_com_alias ("vtop", "virtual-to-physical", class_obscure, 0);}#endif

⌨️ 快捷键说明

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