xref: /original-bsd/lib/libkvm/kvm_hp300.c (revision 2932bec8)
1 /*-
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)kvm_hp300.c	5.24 (Berkeley) 04/29/92";
10 #endif /* LIBC_SCCS and not lint */
11 
12 /*
13  * Hp300 machine depedent routines for kvm.  Hopefully, the forthcoming
14  * vm code will one day obsolete this module.
15  */
16 
17 #include <sys/param.h>
18 #include <sys/user.h>
19 #include <sys/proc.h>
20 #include <sys/stat.h>
21 #include <nlist.h>
22 #include <kvm.h>
23 
24 #include <vm/vm.h>
25 #include <vm/vm_param.h>
26 
27 #include <limits.h>
28 #include <db.h>
29 
30 #include "kvm_private.h"
31 
32 #include <hp300/hp300/pte.h>
33 
34 #ifndef btop
35 #define	btop(x)		(((unsigned)(x)) >> PGSHIFT)	/* XXX */
36 #define	ptob(x)		((caddr_t)((x) << PGSHIFT))	/* XXX */
37 #endif
38 
39 struct vmstate {
40 	u_long lowram;
41 	struct ste *Sysseg;
42 };
43 
44 #define KREAD(kd, addr, p)\
45 	(kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
46 
47 void
48 _kvm_freevtop(kd)
49 	kvm_t *kd;
50 {
51 	if (kd->vmst != 0)
52 		free(kd->vmst);
53 }
54 
55 int
56 _kvm_initvtop(kd)
57 	kvm_t *kd;
58 {
59 	struct vmstate *vm;
60 	struct nlist nlist[3];
61 
62 	vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
63 	if (vm == 0)
64 		return (-1);
65 	kd->vmst = vm;
66 
67 	nlist[0].n_name = "_lowram";
68 	nlist[1].n_name = "_Sysseg";
69 	nlist[2].n_name = 0;
70 
71 	if (kvm_nlist(kd, nlist) != 0) {
72 		_kvm_err(kd, kd->program, "bad namelist");
73 		return (-1);
74 	}
75 	vm->Sysseg = 0;
76 	if (KREAD(kd, (u_long)nlist[0].n_value, &vm->lowram)) {
77 		_kvm_err(kd, kd->program, "cannot read lowram");
78 		return (-1);
79 	}
80 	if (KREAD(kd, (u_long)nlist[1].n_value, &vm->Sysseg)) {
81 		_kvm_err(kd, kd->program, "cannot read segment table");
82 		return (-1);
83 	}
84 	return (0);
85 }
86 
87 static int
88 _kvm_vatop(kd, sta, va, pa)
89 	kvm_t *kd;
90 	struct ste *sta;
91 	u_long va;
92 	u_long *pa;
93 {
94 	register struct vmstate *vm;
95 	register u_long addr;
96 	int p, ste, pte;
97 	int offset;
98 	register u_long lowram;
99 
100 	vm = kd->vmst;
101 	/*
102 	 * If processing a post-mortem and we are initializing
103 	 * (kernel segment table pointer not yet set) then return
104 	 * pa == va to avoid infinite recursion.
105 	 */
106 	if (!ISALIVE(kd) && vm->Sysseg == 0) {
107 		*pa = va;
108 		return (NBPG - (va & PGOFSET));
109 	}
110 	addr = (u_long)&sta[va >> SEGSHIFT];
111 	/*
112 	 * Can't use KREAD to read kernel segment table entries.
113 	 * Fortunately it is 1-to-1 mapped so we don't have to.
114 	 */
115 	if (sta == vm->Sysseg) {
116 		if (lseek(kd->pmfd, (off_t)addr, 0) == -1 ||
117 		    read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
118 			goto invalid;
119 	} else if (KREAD(kd, addr, &ste))
120 		goto invalid;
121 	if ((ste & SG_V) == 0) {
122 		_kvm_err(kd, 0, "invalid segment (%x)", ste);
123 		return((off_t)0);
124 	}
125 	p = btop(va & SG_PMASK);
126 	addr = (ste & SG_FRAME) + (p * sizeof(struct pte));
127 	lowram = vm->lowram;
128 
129 	/*
130 	 * Address from STE is a physical address so don't use kvm_read.
131 	 */
132 	if (lseek(kd->pmfd, (off_t)addr - lowram, 0) == -1 ||
133 	    read(kd->pmfd, (char *)&pte, sizeof(pte)) < 0)
134 		goto invalid;
135 	addr = pte & PG_FRAME;
136 	if (pte == PG_NV || addr < lowram) {
137 		_kvm_err(kd, 0, "page not valid");
138 		return (0);
139 	}
140 	offset = va & PGOFSET;
141 	*pa = addr - lowram + offset;
142 
143 	return (NBPG - offset);
144 invalid:
145 	_kvm_err(kd, 0, "invalid address (%x)", va);
146 	return (0);
147 }
148 
149 int
150 _kvm_kvatop(kd, va, pa)
151 	kvm_t *kd;
152 	u_long va;
153 	u_long *pa;
154 {
155 	if (va >= KERNBASE)
156 		return (_kvm_vatop(kd, (u_long)kd->vmst->Sysseg, va, pa));
157 	_kvm_err(kd, 0, "invalid address (%x)", va);
158 	return (0);
159 }
160 
161 /*
162  * Translate a user virtual address to a physical address.
163  */
164 int
165 _kvm_uvatop(kd, p, va, pa)
166 	kvm_t *kd;
167 	const struct proc *p;
168 	u_long va;
169 	u_long *pa;
170 {
171 	register struct vmspace *vms = p->p_vmspace;
172 	int kva;
173 
174 	kva = (int)&vms->vm_pmap.pm_stab;
175 	if (kvm_read(kd, kva, (char *)&kva, 4) != 4) {
176 		_kvm_err(kd, 0, "invalid address (%x)", va);
177 		return (0);
178 	}
179 	return (_kvm_vatop(kd, kva, va, pa));
180 }
181