1*f15c6971Sjym /* $NetBSD: kvm_i386pae.c,v 1.1 2010/10/05 23:48:16 jym Exp $ */ 2*f15c6971Sjym 3*f15c6971Sjym /* 4*f15c6971Sjym * Copyright (c) 2010 Jean-Yves Migeon. 5*f15c6971Sjym * 6*f15c6971Sjym * Redistribution and use in source and binary forms, with or without 7*f15c6971Sjym * modification, are permitted provided that the following conditions 8*f15c6971Sjym * are met: 9*f15c6971Sjym * 1. Redistributions of source code must retain the above copyright 10*f15c6971Sjym * notice, this list of conditions and the following disclaimer. 11*f15c6971Sjym * 2. Redistributions in binary form must reproduce the above copyright 12*f15c6971Sjym * notice, this list of conditions and the following disclaimer in the 13*f15c6971Sjym * documentation and/or other materials provided with the distribution. 14*f15c6971Sjym * 15*f15c6971Sjym * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16*f15c6971Sjym * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17*f15c6971Sjym * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18*f15c6971Sjym * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19*f15c6971Sjym * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*f15c6971Sjym * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*f15c6971Sjym * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*f15c6971Sjym * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*f15c6971Sjym * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*f15c6971Sjym * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*f15c6971Sjym * POSSIBILITY OF SUCH DAMAGE. 26*f15c6971Sjym */ 27*f15c6971Sjym 28*f15c6971Sjym #include <sys/cdefs.h> 29*f15c6971Sjym __RCSID("$NetBSD: kvm_i386pae.c,v 1.1 2010/10/05 23:48:16 jym Exp $"); 30*f15c6971Sjym 31*f15c6971Sjym /* 32*f15c6971Sjym * This will expose PAE functions, macros, definitions and constants. 33*f15c6971Sjym * Note: this affects all virtual memory related functions. Only their 34*f15c6971Sjym * PAE versions can be used below. 35*f15c6971Sjym */ 36*f15c6971Sjym #define PAE 37*f15c6971Sjym 38*f15c6971Sjym #include <sys/param.h> 39*f15c6971Sjym #include <sys/user.h> 40*f15c6971Sjym #include <sys/stat.h> 41*f15c6971Sjym #include <sys/kcore.h> 42*f15c6971Sjym #include <sys/types.h> 43*f15c6971Sjym 44*f15c6971Sjym #include <stdlib.h> 45*f15c6971Sjym #include <unistd.h> 46*f15c6971Sjym #include <nlist.h> 47*f15c6971Sjym #include <kvm.h> 48*f15c6971Sjym 49*f15c6971Sjym #include <uvm/uvm_extern.h> 50*f15c6971Sjym 51*f15c6971Sjym #include <limits.h> 52*f15c6971Sjym #include <db.h> 53*f15c6971Sjym 54*f15c6971Sjym #include "kvm_private.h" 55*f15c6971Sjym 56*f15c6971Sjym #include <i386/kcore.h> 57*f15c6971Sjym #include <i386/pmap.h> 58*f15c6971Sjym #include <i386/pte.h> 59*f15c6971Sjym #include <i386/vmparam.h> 60*f15c6971Sjym 61*f15c6971Sjym int _kvm_kvatop_i386pae(kvm_t *, vaddr_t, paddr_t *); 62*f15c6971Sjym 63*f15c6971Sjym /* 64*f15c6971Sjym * Used to translate a virtual address to a physical address for systems 65*f15c6971Sjym * running under PAE mode. Three levels of virtual memory pages are handled 66*f15c6971Sjym * here: the per-CPU L3 page, the 4 L2 PDs and the PTs. 67*f15c6971Sjym */ 68*f15c6971Sjym int 69*f15c6971Sjym _kvm_kvatop_i386pae(kvm_t *kd, vaddr_t va, paddr_t *pa) 70*f15c6971Sjym { 71*f15c6971Sjym cpu_kcore_hdr_t *cpu_kh; 72*f15c6971Sjym u_long page_off; 73*f15c6971Sjym pd_entry_t pde; 74*f15c6971Sjym pt_entry_t pte; 75*f15c6971Sjym paddr_t pde_pa, pte_pa; 76*f15c6971Sjym 77*f15c6971Sjym cpu_kh = kd->cpu_data; 78*f15c6971Sjym page_off = va & PGOFSET; 79*f15c6971Sjym 80*f15c6971Sjym /* 81*f15c6971Sjym * Find and read the PDE. Ignore the L3, as it is only a per-CPU 82*f15c6971Sjym * page, not needed for kernel VA => PA translations. 83*f15c6971Sjym * Remember that the 4 L2 pages are contiguous, so it is safe 84*f15c6971Sjym * to increment pdppaddr to compute the address of the PDE. 85*f15c6971Sjym * pdppaddr being PAGE_SIZE aligned, we mask the option bits. 86*f15c6971Sjym */ 87*f15c6971Sjym pde_pa = (cpu_kh->pdppaddr & PG_FRAME) + (pl2_pi(va) * sizeof(pde)); 88*f15c6971Sjym if (_kvm_pread(kd, kd->pmfd, (void *)&pde, sizeof(pde), 89*f15c6971Sjym _kvm_pa2off(kd, pde_pa)) != sizeof(pde)) { 90*f15c6971Sjym _kvm_syserr(kd, 0, "could not read PDE"); 91*f15c6971Sjym goto lose; 92*f15c6971Sjym } 93*f15c6971Sjym 94*f15c6971Sjym /* 95*f15c6971Sjym * Find and read the page table entry. 96*f15c6971Sjym */ 97*f15c6971Sjym if ((pde & PG_V) == 0) { 98*f15c6971Sjym _kvm_err(kd, 0, "invalid translation (invalid PDE)"); 99*f15c6971Sjym goto lose; 100*f15c6971Sjym } 101*f15c6971Sjym if ((pde & PG_PS) != 0) { 102*f15c6971Sjym /* 103*f15c6971Sjym * This is a 2MB page. 104*f15c6971Sjym */ 105*f15c6971Sjym page_off = va & ((vaddr_t)~PG_LGFRAME); 106*f15c6971Sjym *pa = (pde & PG_LGFRAME) + page_off; 107*f15c6971Sjym return (int)(NBPD_L2 - page_off); 108*f15c6971Sjym } 109*f15c6971Sjym 110*f15c6971Sjym pte_pa = (pde & PG_FRAME) + (pl1_pi(va) * sizeof(pt_entry_t)); 111*f15c6971Sjym if (_kvm_pread(kd, kd->pmfd, (void *) &pte, sizeof(pte), 112*f15c6971Sjym _kvm_pa2off(kd, pte_pa)) != sizeof(pte)) { 113*f15c6971Sjym _kvm_syserr(kd, 0, "could not read PTE"); 114*f15c6971Sjym goto lose; 115*f15c6971Sjym } 116*f15c6971Sjym 117*f15c6971Sjym /* 118*f15c6971Sjym * Validate the PTE and return the physical address. 119*f15c6971Sjym */ 120*f15c6971Sjym if ((pte & PG_V) == 0) { 121*f15c6971Sjym _kvm_err(kd, 0, "invalid translation (invalid PTE)"); 122*f15c6971Sjym goto lose; 123*f15c6971Sjym } 124*f15c6971Sjym *pa = (pte & PG_FRAME) + page_off; 125*f15c6971Sjym return (int)(NBPG - page_off); 126*f15c6971Sjym 127*f15c6971Sjym lose: 128*f15c6971Sjym *pa = (paddr_t)~0L; 129*f15c6971Sjym return 0; 130*f15c6971Sjym 131*f15c6971Sjym } 132