-/*
- * Map a virtual address to a physical address.
- */
-
-private Address vmap (addr)
-Address addr;
-{
- Address r;
- integer v, n;
- struct pte pte;
-
- r = addr & ~0xc0000000;
- v = btop(r);
- switch (addr&0xc0000000) {
- case 0xc0000000:
- case 0x80000000:
- /*
- * In system space, so get system pte.
- * If it is valid or reclaimable then the physical address
- * is the combination of its page number and the page offset
- * of the original address.
- */
- if (v >= slr) {
- error("address %x out of segment", addr);
- }
- r = ((long) (sbr + v)) & ~0x80000000;
- goto simple;
-
- case 0x40000000:
- /*
- * In p1 space, must not be in shadow region.
- */
- if (v < pcb.pcb_p1lr) {
- error("address %x out of segment", addr);
- }
- r = (Address) (pcb.pcb_p1br + v);
- break;
-
- case 0x00000000:
- /*
- * In p0 space, must not be off end of region.
- */
- if (v >= pcb.pcb_p0lr) {
- error("address %x out of segment", addr);
- }
- r = (Address) (pcb.pcb_p0br + v);
- break;
-
- default:
- /* do nothing */
- break;
- }
- /*
- * For p0/p1 address, user-level page table should be in
- * kernel virtual memory. Do second-level indirect by recursing.
- */
- if ((r & 0x80000000) == 0) {
- error("bad p0br or p1br in pcb");
- }
- r = vmap(r);
-simple:
- /*
- * "r" is now the address of the pte of the page
- * we are interested in; get the pte and paste up the physical address.
- */
- fseek(corefile, r, 0);
- n = fread(&pte, sizeof(pte), 1, corefile);
- if (n != 1) {
- error("page table botch (fread at %x returns %d)", r, n);
- }
- if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
- error("page no valid or reclamable");
- }
- return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
-}
-