summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-06-19 20:25:50 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-06-19 20:25:50 +0000
commitec0cd072e33631cd57cac617087eff4a10a713fa (patch)
tree0649c76b6a36bcae7bed49e396d82e4fb171595e
parent8e4e0d00306b9b02302711a0e35d18baa2e744d7 (diff)
Real kvm routines for vax; allows ``target kvm'' to work in gdb for kernel
crash dumps. ok kettenis@
-rw-r--r--lib/libkvm/kvm_vax.c79
1 files changed, 29 insertions, 50 deletions
diff --git a/lib/libkvm/kvm_vax.c b/lib/libkvm/kvm_vax.c
index ad080b0bc76..5a5fb249aca 100644
--- a/lib/libkvm/kvm_vax.c
+++ b/lib/libkvm/kvm_vax.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_vax.c,v 1.12 2006/03/20 15:11:48 mickey Exp $ */
+/* $OpenBSD: kvm_vax.c,v 1.13 2006/06/19 20:25:49 miod Exp $ */
/* $NetBSD: kvm_vax.c,v 1.3 1996/03/18 22:34:06 thorpej Exp $ */
/*-
@@ -36,15 +36,14 @@
/*
* VAX machine dependent routines for kvm. Hopefully, the forthcoming
- * vm code will one day obsolete this module. Furthermore, I hope it
- * gets here soon, because this basically is an error stub! (sorry)
- * This code may not work anyway.
+ * vm code will one day obsolete this module.
*/
#include <sys/param.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/stat.h>
+#include <sys/kcore.h>
#include <unistd.h>
#include <stdlib.h>
#include <nlist.h>
@@ -52,57 +51,26 @@
#include <uvm/uvm_extern.h>
#include <machine/vmparam.h>
+#include <machine/kcore.h>
#include <machine/pmap.h>
+#include <machine/pte.h>
#include <limits.h>
#include <db.h>
#include "kvm_private.h"
-struct vmstate {
- u_long end;
-};
-
void
_kvm_freevtop(kvm_t *kd)
{
- if (kd->vmst != NULL) {
- free(kd->vmst);
- kd->vmst = NULL;
- }
}
int
_kvm_initvtop(kvm_t *kd)
{
- struct nlist nlist[2];
- struct vmstate *vm;
- struct stat st;
- int i, off;
-
- vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
- if (vm == 0)
- return (-1);
-
- kd->vmst = vm;
-
- if (fstat(kd->pmfd, &st) < 0)
- return (-1);
-
- /* Get end of kernel address */
- nlist[0].n_name = "_end";
- nlist[1].n_name = 0;
- if (kvm_nlist(kd, nlist) != 0) {
- _kvm_err(kd, kd->program, "pmap_stod: no such symbol");
- return (-1);
- }
- vm->end = (u_long)nlist[0].n_value;
-
return (0);
}
-#define VA_OFF(va) (va & (NBPG - 1))
-
/*
* Translate a kernel virtual address to a physical address using the
* mapping information in kd->vm. Returns the result in pa, and returns
@@ -112,34 +80,45 @@ _kvm_initvtop(kvm_t *kd)
int
_kvm_kvatop(kvm_t *kd, u_long va, paddr_t *pa)
{
- u_long end;
+ paddr_t ofs;
+ u_long pteaddr;
+ pt_entry_t pte;
+ cpu_kcore_hdr_t *cpu_kh;
- if (va < KERNBASE) {
- _kvm_err(kd, 0, "invalid address (%lx<%lx)", va, KERNBASE);
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
return (0);
}
- if (!kd->vmst) {
- _kvm_err(kd, 0, "vatop called before initvtop");
+ if (va < (u_long)KERNBASE) {
+ _kvm_err(kd, 0, "invalid address (%lx<%lx)", va, KERNBASE);
return (0);
}
- end = kd->vmst->end;
- if (va >= end) {
- _kvm_err(kd, 0, "invalid address (%lx>=%lx)", va, end);
+ /* read pte from Sysmap */
+ cpu_kh = kd->cpu_data;
+ pteaddr = (cpu_kh->sysmap - KERNBASE) +
+ PG_PFNUM(va) * sizeof(pt_entry_t);
+ if (_kvm_pread(kd, kd->pmfd, (char *)&pte, sizeof(pte),
+ (off_t)_kvm_pa2off(kd, pteaddr)) < 0) {
+ _kvm_err(kd, 0, "invalid address (%lx)", va);
+ return (0);
+ }
+ if ((pte & PG_V) == 0) {
+ _kvm_err(kd, 0, "invalid pte %lx (address %lx)", pte, va);
return (0);
}
- *pa = (va - KERNBASE);
- return (end - va);
+ ofs = va & PAGE_MASK;
+ *pa = ((pte & PG_FRAME) << VAX_PGSHIFT) | ofs;
+ return (int)(PAGE_SIZE - ofs);
}
/*
- * Translate a physical address to an offset in the crash dump
- * XXX crashdumps not working yet anyway
+ * Translate a physical address to an offset in the crash dump.
*/
off_t
_kvm_pa2off(kvm_t *kd, paddr_t pa)
{
- return (kd->dump_off+pa);
+ return (kd->dump_off + pa);
}