xref: /netbsd/lib/libkvm/kvm_i386pae.c (revision f15c6971)
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