1 /* $FreeBSD: src/lib/libkvm/kvm_alpha.c,v 1.4 1999/12/27 07:14:56 peter Exp $ */
2 /* $NetBSD: kvm_alpha.c,v 1.7.2.1 1997/11/02 20:34:26 mellon Exp $ */
5 * Copyright (c) 1994, 1995 Carnegie-Mellon University.
8 * Author: Chris G. Demetriou
10 * Permission to use, copy, modify and distribute this software and
11 * its documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
20 * Carnegie Mellon requests users of this software to return to
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
31 #include <sys/param.h>
35 #include <sys/types.h>
42 #include <vm/vm_param.h>
46 #include <machine/pmap.h>
47 #include "kvm_private.h"
49 static off_t _kvm_pa2off(kvm_t *kd, u_long pa);
52 u_int64_t lev1map_pa; /* PA of Lev1map */
53 u_int64_t page_size; /* Page size */
54 u_int64_t nmemsegs; /* Number of RAM segm */
62 /* Not actually used for anything right now, but safe. */
72 struct nlist nlist[2];
75 vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
77 _kvm_err(kd, kd->program, "cannot allocate vm");
81 vm->page_size = ALPHA_PGBYTES;
83 nlist[0].n_name = "_Lev1map";
86 if (kvm_nlist(kd, nlist) != 0) {
87 _kvm_err(kd, kd->program, "bad namelist");
92 if (kvm_read(kd, (nlist[0].n_value), &pa, sizeof(pa)) != sizeof(pa)) {
93 _kvm_err(kd, kd->program, "cannot read Lev1map");
97 if (kvm_read(kd, (nlist[0].n_value), &pa, sizeof(pa)) != sizeof(pa)) {
98 _kvm_err(kd, kd->program, "cannot read Lev1map");
107 _kvm_kvatop(kd, va, pa)
112 u_int64_t lev1map_pa; /* PA of Lev1map */
115 alpha_pt_entry_t pte;
122 _kvm_err(kd, 0, "vatop called in live kernel!");
125 lev1map_pa = vm->lev1map_pa;
126 page_size = vm->page_size;
128 page_off = va & (page_size - 1);
129 if (va >= ALPHA_K0SEG_BASE && va <= ALPHA_K0SEG_END) {
131 * Direct-mapped address: just convert it.
134 *pa = ALPHA_K0SEG_TO_PHYS(va);
135 rv = page_size - page_off;
136 } else if (va >= ALPHA_K1SEG_BASE && va <= ALPHA_K1SEG_END) {
138 * Real kernel virtual address: do the translation.
140 #define PTMASK ((1 << ALPHA_PTSHIFT) - 1)
141 #define pmap_lev1_index(va) (((va) >> ALPHA_L1SHIFT) & PTMASK)
142 #define pmap_lev2_index(va) (((va) >> ALPHA_L2SHIFT) & PTMASK)
143 #define pmap_lev3_index(va) (((va) >> ALPHA_L3SHIFT) & PTMASK)
145 /* Find and read the L1 PTE. */
146 pteoff = lev1map_pa +
147 pmap_lev1_index(va) * sizeof(alpha_pt_entry_t);
148 if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
149 read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
150 _kvm_syserr(kd, 0, "could not read L1 PTE");
154 /* Find and read the L2 PTE. */
155 if ((pte & ALPHA_PTE_VALID) == 0) {
156 _kvm_err(kd, 0, "invalid translation (invalid L1 PTE)");
159 pteoff = ALPHA_PTE_TO_PFN(pte) * page_size +
160 pmap_lev2_index(va) * sizeof(alpha_pt_entry_t);
161 if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
162 read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
163 _kvm_syserr(kd, 0, "could not read L2 PTE");
167 /* Find and read the L3 PTE. */
168 if ((pte & ALPHA_PTE_VALID) == 0) {
169 _kvm_err(kd, 0, "invalid translation (invalid L2 PTE)");
172 pteoff = ALPHA_PTE_TO_PFN(pte) * page_size +
173 pmap_lev3_index(va) * sizeof(alpha_pt_entry_t);
174 if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
175 read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
176 _kvm_syserr(kd, 0, "could not read L3 PTE");
180 /* Fill in the PA. */
181 if ((pte & ALPHA_PTE_VALID) == 0) {
182 _kvm_err(kd, 0, "invalid translation (invalid L3 PTE)");
185 *pa = ALPHA_PTE_TO_PFN(pte) * page_size + page_off;
186 rv = page_size - page_off;
189 * Bogus address (not in KV space): punt.
192 _kvm_err(kd, 0, "invalid kernel virtual address");
202 * Translate a physical address to a file-offset in the crash-dump.
209 return ALPHA_K0SEG_TO_PHYS(pa);