File:  [DragonFly] / src / lib / libkvm / Attic / kvm_alpha.c
Revision 1.2: download - view: text, annotated - select for diffs
Tue Jun 17 04:26:49 2003 UTC (10 years, 10 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids.  Most
ids have been removed from !lint sections and moved into comment sections.

    1: /* $FreeBSD: src/lib/libkvm/kvm_alpha.c,v 1.4 1999/12/27 07:14:56 peter Exp $ */
    2: /* $DragonFly: src/lib/libkvm/kvm_alpha.c,v 1.2 2003/06/17 04:26:49 dillon Exp $ */
    3: /*	$NetBSD: kvm_alpha.c,v 1.7.2.1 1997/11/02 20:34:26 mellon Exp $	*/
    4: 
    5: /*
    6:  * Copyright (c) 1994, 1995 Carnegie-Mellon University.
    7:  * All rights reserved.
    8:  *
    9:  * Author: Chris G. Demetriou
   10:  * 
   11:  * Permission to use, copy, modify and distribute this software and
   12:  * its documentation is hereby granted, provided that both the copyright
   13:  * notice and this permission notice appear in all copies of the
   14:  * software, derivative works or modified versions, and any portions
   15:  * thereof, and that both notices appear in supporting documentation.
   16:  * 
   17:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
   18:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
   19:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   20:  * 
   21:  * Carnegie Mellon requests users of this software to return to
   22:  *
   23:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   24:  *  School of Computer Science
   25:  *  Carnegie Mellon University
   26:  *  Pittsburgh PA 15213-3890
   27:  *
   28:  * any improvements or extensions that they make and grant Carnegie the
   29:  * rights to redistribute these changes.
   30:  */
   31: 
   32: #include <sys/param.h>
   33: #include <sys/user.h>
   34: #include <sys/proc.h>
   35: #include <sys/stat.h>
   36: #include <sys/types.h>
   37: #include <sys/uio.h>
   38: #include <unistd.h>
   39: #include <nlist.h>
   40: #include <kvm.h>
   41: 
   42: #include <vm/vm.h>
   43: #include <vm/vm_param.h>
   44: 
   45: #include <limits.h>
   46: #include <stdlib.h>
   47: #include <machine/pmap.h>
   48: #include "kvm_private.h"
   49: 
   50: static off_t   _kvm_pa2off(kvm_t *kd, u_long pa);
   51: 
   52: struct vmstate {
   53: 	u_int64_t       lev1map_pa;             /* PA of Lev1map */
   54:         u_int64_t       page_size;              /* Page size */
   55:         u_int64_t       nmemsegs;               /* Number of RAM segm */
   56: };
   57: 
   58: void
   59: _kvm_freevtop(kd)
   60: 	kvm_t *kd;
   61: {
   62: 
   63: 	/* Not actually used for anything right now, but safe. */
   64: 	if (kd->vmst != 0)
   65: 		free(kd->vmst);
   66: }
   67: 
   68: int
   69: _kvm_initvtop(kd)
   70: 	kvm_t *kd;
   71: {
   72: 	struct vmstate *vm;
   73: 	struct nlist nlist[2];
   74: 	u_long pa;
   75: 
   76: 	vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
   77: 	if (vm == 0) {
   78: 		_kvm_err(kd, kd->program, "cannot allocate vm");
   79: 		return (-1);
   80: 	}
   81: 	kd->vmst = vm;
   82: 	vm->page_size = ALPHA_PGBYTES;
   83: 
   84: 	nlist[0].n_name = "_Lev1map";
   85: 	nlist[1].n_name = 0;
   86: 
   87: 	if (kvm_nlist(kd, nlist) != 0) {
   88: 		_kvm_err(kd, kd->program, "bad namelist");
   89: 		return (-1);
   90: 	}
   91: 
   92: 	if(!ISALIVE(kd)) {
   93: 		if (kvm_read(kd, (nlist[0].n_value), &pa, sizeof(pa)) != sizeof(pa)) {
   94: 			_kvm_err(kd, kd->program, "cannot read Lev1map");
   95: 			return (-1);
   96: 		}
   97: 	} else 
   98: 		if (kvm_read(kd, (nlist[0].n_value), &pa, sizeof(pa)) != sizeof(pa)) {
   99: 			_kvm_err(kd, kd->program, "cannot read Lev1map");
  100: 			return (-1);
  101: 		}
  102: 	vm->lev1map_pa = pa;
  103: 	return (0);
  104: 
  105: }
  106: 
  107: int
  108: _kvm_kvatop(kd, va, pa)
  109: 	kvm_t *kd;
  110: 	u_long va;
  111: 	u_long *pa;
  112: {
  113: 	u_int64_t       lev1map_pa;             /* PA of Lev1map */
  114:         u_int64_t       page_size;
  115: 	int rv, page_off;
  116: 	alpha_pt_entry_t pte;
  117: 	off_t pteoff;
  118: 	struct vmstate *vm;
  119: 	vm = kd->vmst ;
  120: 	
  121: 
  122:         if (ISALIVE(kd)) {
  123:                 _kvm_err(kd, 0, "vatop called in live kernel!");
  124:                 return(0);
  125:         }
  126: 	lev1map_pa = vm->lev1map_pa;
  127: 	page_size  = vm->page_size;
  128: 
  129: 	page_off = va & (page_size - 1);
  130: 	if (va >= ALPHA_K0SEG_BASE && va <= ALPHA_K0SEG_END) {
  131: 		/*
  132: 		 * Direct-mapped address: just convert it.
  133: 		 */
  134: 
  135: 		*pa = ALPHA_K0SEG_TO_PHYS(va);
  136: 		rv = page_size - page_off;
  137: 	} else if (va >= ALPHA_K1SEG_BASE && va <= ALPHA_K1SEG_END) {
  138: 		/*
  139: 		 * Real kernel virtual address: do the translation.
  140: 		 */
  141: #define PTMASK			((1 << ALPHA_PTSHIFT) - 1)
  142: #define pmap_lev1_index(va)	(((va) >> ALPHA_L1SHIFT) & PTMASK)
  143: #define pmap_lev2_index(va)	(((va) >> ALPHA_L2SHIFT) & PTMASK)
  144: #define pmap_lev3_index(va)	(((va) >> ALPHA_L3SHIFT) & PTMASK)
  145: 
  146: 		/* Find and read the L1 PTE. */
  147: 		pteoff = lev1map_pa +
  148: 			pmap_lev1_index(va)  * sizeof(alpha_pt_entry_t);
  149: 		if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
  150: 		    read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
  151: 			_kvm_syserr(kd, 0, "could not read L1 PTE");
  152: 			goto lose;
  153: 		}
  154: 
  155: 		/* Find and read the L2 PTE. */
  156: 		if ((pte & ALPHA_PTE_VALID) == 0) {
  157: 			_kvm_err(kd, 0, "invalid translation (invalid L1 PTE)");
  158: 			goto lose;
  159: 		}
  160: 		pteoff = ALPHA_PTE_TO_PFN(pte) * page_size +
  161: 		    pmap_lev2_index(va) * sizeof(alpha_pt_entry_t);
  162: 		if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
  163: 		    read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
  164: 			_kvm_syserr(kd, 0, "could not read L2 PTE");
  165: 			goto lose;
  166: 		}
  167: 
  168: 		/* Find and read the L3 PTE. */
  169: 		if ((pte & ALPHA_PTE_VALID) == 0) {
  170: 			_kvm_err(kd, 0, "invalid translation (invalid L2 PTE)");
  171: 			goto lose;
  172: 		}
  173: 		pteoff = ALPHA_PTE_TO_PFN(pte) * page_size +
  174: 		    pmap_lev3_index(va) * sizeof(alpha_pt_entry_t);
  175: 		if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
  176: 		    read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
  177: 			_kvm_syserr(kd, 0, "could not read L3 PTE");
  178: 			goto lose;
  179: 		}
  180: 
  181: 		/* Fill in the PA. */
  182: 		if ((pte & ALPHA_PTE_VALID) == 0) {
  183: 			_kvm_err(kd, 0, "invalid translation (invalid L3 PTE)");
  184: 			goto lose;
  185: 		}
  186: 		*pa = ALPHA_PTE_TO_PFN(pte) * page_size + page_off;
  187: 		rv = page_size - page_off;
  188: 	} else {
  189: 		/*
  190: 		 * Bogus address (not in KV space): punt.
  191: 		 */
  192: 
  193: 		_kvm_err(kd, 0, "invalid kernel virtual address");
  194: lose:
  195: 		*pa = -1;
  196: 		rv = 0;
  197: 	}
  198: 
  199: 	return (rv);
  200: }
  201: 
  202: /*
  203:  * Translate a physical address to a file-offset in the crash-dump.
  204:  */
  205: off_t   
  206: _kvm_pa2off(kd, pa)
  207: 	kvm_t *kd;
  208: 	u_long pa;
  209: {
  210: 	return ALPHA_K0SEG_TO_PHYS(pa);
  211: }
  212: