1f95a0250SRodney W. Grimes /*- 2f95a0250SRodney W. Grimes * Copyright (c) 1989, 1992, 1993 3f95a0250SRodney W. Grimes * The Regents of the University of California. All rights reserved. 4f95a0250SRodney W. Grimes * 5f95a0250SRodney W. Grimes * This code is derived from software developed by the Computer Systems 6f95a0250SRodney W. Grimes * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 7f95a0250SRodney W. Grimes * BG 91-66 and contributed to Berkeley. 8f95a0250SRodney W. Grimes * 9f95a0250SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 10f95a0250SRodney W. Grimes * modification, are permitted provided that the following conditions 11f95a0250SRodney W. Grimes * are met: 12f95a0250SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 13f95a0250SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 14f95a0250SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 15f95a0250SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 16f95a0250SRodney W. Grimes * documentation and/or other materials provided with the distribution. 17f95a0250SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 18f95a0250SRodney W. Grimes * must display the following acknowledgement: 19f95a0250SRodney W. Grimes * This product includes software developed by the University of 20f95a0250SRodney W. Grimes * California, Berkeley and its contributors. 21f95a0250SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 22f95a0250SRodney W. Grimes * may be used to endorse or promote products derived from this software 23f95a0250SRodney W. Grimes * without specific prior written permission. 24f95a0250SRodney W. Grimes * 25f95a0250SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26f95a0250SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27f95a0250SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28f95a0250SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29f95a0250SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30f95a0250SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31f95a0250SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32f95a0250SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33f95a0250SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34f95a0250SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35f95a0250SRodney W. Grimes * SUCH DAMAGE. 36f95a0250SRodney W. Grimes */ 37f95a0250SRodney W. Grimes 38f95a0250SRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 39f95a0250SRodney W. Grimes static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; 40f95a0250SRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 41f95a0250SRodney W. Grimes 42f95a0250SRodney W. Grimes /* 4321d54b07SRodney W. Grimes * i386 machine dependent routines for kvm. Hopefully, the forthcoming 44f95a0250SRodney W. Grimes * vm code will one day obsolete this module. 45f95a0250SRodney W. Grimes */ 46f95a0250SRodney W. Grimes 47f95a0250SRodney W. Grimes #include <sys/param.h> 48f95a0250SRodney W. Grimes #include <sys/user.h> 49f95a0250SRodney W. Grimes #include <sys/proc.h> 50f95a0250SRodney W. Grimes #include <sys/stat.h> 5151295a4dSJordan K. Hubbard #include <stdlib.h> 52f95a0250SRodney W. Grimes #include <unistd.h> 53f95a0250SRodney W. Grimes #include <nlist.h> 54f95a0250SRodney W. Grimes #include <kvm.h> 55f95a0250SRodney W. Grimes 56f95a0250SRodney W. Grimes #include <vm/vm.h> 57f95a0250SRodney W. Grimes #include <vm/vm_param.h> 58f95a0250SRodney W. Grimes 59f95a0250SRodney W. Grimes #include <limits.h> 60f95a0250SRodney W. Grimes #include <db.h> 61f95a0250SRodney W. Grimes 62f95a0250SRodney W. Grimes #include "kvm_private.h" 63f95a0250SRodney W. Grimes 64f95a0250SRodney W. Grimes #ifndef btop 6521d54b07SRodney W. Grimes #define btop(x) (i386_btop(x)) 6621d54b07SRodney W. Grimes #define ptob(x) (i386_ptob(x)) 67f95a0250SRodney W. Grimes #endif 68f95a0250SRodney W. Grimes 69f95a0250SRodney W. Grimes struct vmstate { 702f85bf6eSPeter Wemm pd_entry_t *PTD; 71f95a0250SRodney W. Grimes }; 72f95a0250SRodney W. Grimes 73f95a0250SRodney W. Grimes void 742f85bf6eSPeter Wemm _kvm_freevtop(kvm_t *kd) 752f85bf6eSPeter Wemm { 762f85bf6eSPeter Wemm if (kd->vmst != 0) { 7721d54b07SRodney W. Grimes if (kd->vmst->PTD) { 7821d54b07SRodney W. Grimes free(kd->vmst->PTD); 7921d54b07SRodney W. Grimes } 80f95a0250SRodney W. Grimes free(kd->vmst); 81f95a0250SRodney W. Grimes } 8221d54b07SRodney W. Grimes } 83f95a0250SRodney W. Grimes 84f95a0250SRodney W. Grimes int 852f85bf6eSPeter Wemm _kvm_initvtop(kvm_t *kd) 862f85bf6eSPeter Wemm { 87f95a0250SRodney W. Grimes struct vmstate *vm; 8821d54b07SRodney W. Grimes struct nlist nlist[2]; 892f85bf6eSPeter Wemm u_long pa; 902f85bf6eSPeter Wemm pd_entry_t *PTD; 91f95a0250SRodney W. Grimes 92f95a0250SRodney W. Grimes vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm)); 9321d54b07SRodney W. Grimes if (vm == 0) { 9421d54b07SRodney W. Grimes _kvm_err(kd, kd->program, "cannot allocate vm"); 95f95a0250SRodney W. Grimes return (-1); 9621d54b07SRodney W. Grimes } 97f95a0250SRodney W. Grimes kd->vmst = vm; 982f85bf6eSPeter Wemm vm->PTD = 0; 99f95a0250SRodney W. Grimes 10021d54b07SRodney W. Grimes nlist[0].n_name = "_IdlePTD"; 10121d54b07SRodney W. Grimes nlist[1].n_name = 0; 102f95a0250SRodney W. Grimes 103f95a0250SRodney W. Grimes if (kvm_nlist(kd, nlist) != 0) { 104f95a0250SRodney W. Grimes _kvm_err(kd, kd->program, "bad namelist"); 105f95a0250SRodney W. Grimes return (-1); 106f95a0250SRodney W. Grimes } 1072f85bf6eSPeter Wemm if (kvm_read(kd, (nlist[0].n_value - KERNBASE), &pa, sizeof(pa)) != sizeof(pa)) { 10821d54b07SRodney W. Grimes _kvm_err(kd, kd->program, "cannot read IdlePTD"); 109f95a0250SRodney W. Grimes return (-1); 110f95a0250SRodney W. Grimes } 1112f85bf6eSPeter Wemm PTD = _kvm_malloc(kd, PAGE_SIZE); 1122f85bf6eSPeter Wemm if (kvm_read(kd, pa, PTD, PAGE_SIZE) != PAGE_SIZE) { 11321d54b07SRodney W. Grimes _kvm_err(kd, kd->program, "cannot read PTD"); 114f95a0250SRodney W. Grimes return (-1); 115f95a0250SRodney W. Grimes } 1162f85bf6eSPeter Wemm vm->PTD = PTD; 117f95a0250SRodney W. Grimes return (0); 118f95a0250SRodney W. Grimes } 119f95a0250SRodney W. Grimes 120f95a0250SRodney W. Grimes static int 1212f85bf6eSPeter Wemm _kvm_vatop(kvm_t *kd, u_long va, u_long *pa) 1222f85bf6eSPeter Wemm { 1232f85bf6eSPeter Wemm struct vmstate *vm; 1242f85bf6eSPeter Wemm u_long offset; 1252f85bf6eSPeter Wemm u_long pte_pa; 1262f85bf6eSPeter Wemm pd_entry_t pde; 1272f85bf6eSPeter Wemm pt_entry_t pte; 1282f85bf6eSPeter Wemm u_long pdeindex; 1292f85bf6eSPeter Wemm u_long pteindex; 1302f85bf6eSPeter Wemm int i; 131f95a0250SRodney W. Grimes 132f95a0250SRodney W. Grimes if (ISALIVE(kd)) { 133f95a0250SRodney W. Grimes _kvm_err(kd, 0, "vatop called in live kernel!"); 134f95a0250SRodney W. Grimes return((off_t)0); 135f95a0250SRodney W. Grimes } 1362f85bf6eSPeter Wemm 1372f85bf6eSPeter Wemm vm = kd->vmst; 1382f85bf6eSPeter Wemm offset = va & (PAGE_SIZE - 1); 1392f85bf6eSPeter Wemm 1402f85bf6eSPeter Wemm /* 1412f85bf6eSPeter Wemm * If we are initializing (kernel page table descriptor pointer 1422f85bf6eSPeter Wemm * not yet set) then return pa == va to avoid infinite recursion. 1432f85bf6eSPeter Wemm */ 1442f85bf6eSPeter Wemm if (vm->PTD == 0) { 1452f85bf6eSPeter Wemm *pa = va; 1462f85bf6eSPeter Wemm return (PAGE_SIZE - offset); 1472f85bf6eSPeter Wemm } 1482f85bf6eSPeter Wemm 1492f85bf6eSPeter Wemm pdeindex = va >> PDRSHIFT; 1502f85bf6eSPeter Wemm pde = vm->PTD[pdeindex]; 1512f85bf6eSPeter Wemm if (((u_long)pde & PG_V) == 0) 1522f85bf6eSPeter Wemm goto invalid; 1532f85bf6eSPeter Wemm 1542f85bf6eSPeter Wemm pteindex = (va >> PAGE_SHIFT) & (NPTEPG-1); 1552f85bf6eSPeter Wemm pte_pa = ((u_long)pde & PG_FRAME) + (pteindex * sizeof(pt_entry_t)); 1562f85bf6eSPeter Wemm 1572f85bf6eSPeter Wemm /* XXX This has to be a physical address read, kvm_read is virtual */ 1582f85bf6eSPeter Wemm if (lseek(kd->pmfd, pte_pa, 0) == -1) { 1592f85bf6eSPeter Wemm _kvm_syserr(kd, kd->program, "_kvm_vatop: lseek"); 1602f85bf6eSPeter Wemm goto invalid; 1612f85bf6eSPeter Wemm } 1622f85bf6eSPeter Wemm if (read(kd->pmfd, &pte, sizeof pte) != sizeof pte) { 1632f85bf6eSPeter Wemm _kvm_syserr(kd, kd->program, "_kvm_vatop: read"); 1642f85bf6eSPeter Wemm goto invalid; 1652f85bf6eSPeter Wemm } 1662f85bf6eSPeter Wemm if (((u_long)pte & PG_V) == 0) 1672f85bf6eSPeter Wemm goto invalid; 1682f85bf6eSPeter Wemm 1692f85bf6eSPeter Wemm *pa = ((u_long)pte & PG_FRAME) + offset; 1702f85bf6eSPeter Wemm return (PAGE_SIZE - offset); 1712f85bf6eSPeter Wemm 1722f85bf6eSPeter Wemm invalid: 173f95a0250SRodney W. Grimes _kvm_err(kd, 0, "invalid address (%x)", va); 1742f85bf6eSPeter Wemm return (0); 175f95a0250SRodney W. Grimes } 176f95a0250SRodney W. Grimes 177f95a0250SRodney W. Grimes int 1782f85bf6eSPeter Wemm _kvm_kvatop(kvm_t *kd, u_long va, u_long *pa) 1792f85bf6eSPeter Wemm { 18021d54b07SRodney W. Grimes return (_kvm_vatop(kd, va, pa)); 181f95a0250SRodney W. Grimes } 182