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