📄 hppah-tdep.c
字号:
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 + -