Fri Dec 2 16:33:10 2011 UTC ()
adapt sparc64.  compile tested.


(yamt)
diff -r1.55 -r1.55.2.1 src/sys/arch/sparc64/include/pmap.h
diff -r1.275 -r1.275.2.1 src/sys/arch/sparc64/sparc64/pmap.c

cvs diff -r1.55 -r1.55.2.1 src/sys/arch/sparc64/include/pmap.h (switch to unified diff)

--- src/sys/arch/sparc64/include/pmap.h 2011/10/06 06:55:34 1.55
+++ src/sys/arch/sparc64/include/pmap.h 2011/12/02 16:33:09 1.55.2.1
@@ -1,241 +1,239 @@ @@ -1,241 +1,239 @@
1/* $NetBSD: pmap.h,v 1.55 2011/10/06 06:55:34 mrg Exp $ */ 1/* $NetBSD: pmap.h,v 1.55.2.1 2011/12/02 16:33:09 yamt Exp $ */
2 2
3/*- 3/*-
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH. 5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH. 18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#ifndef _MACHINE_PMAP_H_ 34#ifndef _MACHINE_PMAP_H_
35#define _MACHINE_PMAP_H_ 35#define _MACHINE_PMAP_H_
36 36
37#ifndef _LOCORE 37#ifndef _LOCORE
38#include <machine/pte.h> 38#include <machine/pte.h>
39#include <sys/queue.h> 39#include <sys/queue.h>
40#include <uvm/uvm_object.h> 40#include <uvm/uvm_object.h>
41#ifdef _KERNEL 41#ifdef _KERNEL
42#include <machine/cpuset.h> 42#include <machine/cpuset.h>
43#endif 43#endif
44#endif 44#endif
45 45
46/* 46/*
47 * This scheme uses 2-level page tables. 47 * This scheme uses 2-level page tables.
48 * 48 *
49 * While we're still in 32-bit mode we do the following: 49 * While we're still in 32-bit mode we do the following:
50 * 50 *
51 * offset: 13 bits 51 * offset: 13 bits
52 * 1st level: 1024 64-bit TTEs in an 8K page for 10 bits 52 * 1st level: 1024 64-bit TTEs in an 8K page for 10 bits
53 * 2nd level: 512 32-bit pointers in the pmap for 9 bits 53 * 2nd level: 512 32-bit pointers in the pmap for 9 bits
54 * ------- 54 * -------
55 * total: 32 bits 55 * total: 32 bits
56 * 56 *
57 * In 64-bit mode the Spitfire and Blackbird CPUs support only 57 * In 64-bit mode the Spitfire and Blackbird CPUs support only
58 * 44-bit virtual addresses. All addresses between 58 * 44-bit virtual addresses. All addresses between
59 * 0x0000 07ff ffff ffff and 0xffff f800 0000 0000 are in the 59 * 0x0000 07ff ffff ffff and 0xffff f800 0000 0000 are in the
60 * "VA hole" and trap, so we don't have to track them. However, 60 * "VA hole" and trap, so we don't have to track them. However,
61 * we do need to keep them in mind during PT walking. If they 61 * we do need to keep them in mind during PT walking. If they
62 * ever change the size of the address "hole" we need to rework 62 * ever change the size of the address "hole" we need to rework
63 * all the page table handling. 63 * all the page table handling.
64 * 64 *
65 * offset: 13 bits 65 * offset: 13 bits
66 * 1st level: 1024 64-bit TTEs in an 8K page for 10 bits 66 * 1st level: 1024 64-bit TTEs in an 8K page for 10 bits
67 * 2nd level: 1024 64-bit pointers in an 8K page for 10 bits 67 * 2nd level: 1024 64-bit pointers in an 8K page for 10 bits
68 * 3rd level: 1024 64-bit pointers in the segmap for 10 bits 68 * 3rd level: 1024 64-bit pointers in the segmap for 10 bits
69 * ------- 69 * -------
70 * total: 43 bits 70 * total: 43 bits
71 * 71 *
72 * Of course, this means for 32-bit spaces we always have a (practically) 72 * Of course, this means for 32-bit spaces we always have a (practically)
73 * wasted page for the segmap (only one entry used) and half a page wasted 73 * wasted page for the segmap (only one entry used) and half a page wasted
74 * for the page directory. We still have need of one extra bit 8^(. 74 * for the page directory. We still have need of one extra bit 8^(.
75 */ 75 */
76 76
77#define HOLESHIFT (43) 77#define HOLESHIFT (43)
78 78
79#define PTSZ (PAGE_SIZE/8) /* page table entry */ 79#define PTSZ (PAGE_SIZE/8) /* page table entry */
80#define PDSZ (PTSZ) /* page directory */ 80#define PDSZ (PTSZ) /* page directory */
81#define STSZ (PTSZ) /* psegs */ 81#define STSZ (PTSZ) /* psegs */
82 82
83#define PTSHIFT (13) 83#define PTSHIFT (13)
84#define PDSHIFT (10+PTSHIFT) 84#define PDSHIFT (10+PTSHIFT)
85#define STSHIFT (10+PDSHIFT) 85#define STSHIFT (10+PDSHIFT)
86 86
87#define PTMASK (PTSZ-1) 87#define PTMASK (PTSZ-1)
88#define PDMASK (PDSZ-1) 88#define PDMASK (PDSZ-1)
89#define STMASK (STSZ-1) 89#define STMASK (STSZ-1)
90 90
91#ifndef _LOCORE 91#ifndef _LOCORE
92 92
93/* 93/*
94 * Support for big page sizes. This maps the page size to the 94 * Support for big page sizes. This maps the page size to the
95 * page bits. 95 * page bits.
96 */ 96 */
97struct page_size_map { 97struct page_size_map {
98 uint64_t mask; 98 uint64_t mask;
99 uint64_t code; 99 uint64_t code;
100#if defined(DEBUG) || 1 100#if defined(DEBUG) || 1
101 uint64_t use; 101 uint64_t use;
102#endif 102#endif
103}; 103};
104extern struct page_size_map page_size_map[]; 104extern struct page_size_map page_size_map[];
105 105
106/* 106/*
107 * Pmap stuff 107 * Pmap stuff
108 */ 108 */
109 109
110#define va_to_seg(v) (int)((((paddr_t)(v))>>STSHIFT)&STMASK) 110#define va_to_seg(v) (int)((((paddr_t)(v))>>STSHIFT)&STMASK)
111#define va_to_dir(v) (int)((((paddr_t)(v))>>PDSHIFT)&PDMASK) 111#define va_to_dir(v) (int)((((paddr_t)(v))>>PDSHIFT)&PDMASK)
112#define va_to_pte(v) (int)((((paddr_t)(v))>>PTSHIFT)&PTMASK) 112#define va_to_pte(v) (int)((((paddr_t)(v))>>PTSHIFT)&PTMASK)
113 113
114#ifdef MULTIPROCESSOR 114#ifdef MULTIPROCESSOR
115#define PMAP_LIST_MAXNUMCPU CPUSET_MAXNUMCPU 115#define PMAP_LIST_MAXNUMCPU CPUSET_MAXNUMCPU
116#else 116#else
117#define PMAP_LIST_MAXNUMCPU 1 117#define PMAP_LIST_MAXNUMCPU 1
118#endif 118#endif
119 119
120struct pmap { 120struct pmap {
121 struct uvm_object pm_obj; 121 unsigned int pm_refs;
122 kmutex_t pm_obj_lock; 122 TAILQ_HEAD(, vm_page) pm_ptps;
123#define pm_lock pm_obj.vmobjlock 
124#define pm_refs pm_obj.uo_refs 
125 LIST_ENTRY(pmap) pm_list[PMAP_LIST_MAXNUMCPU]; /* per cpu ctx used list */ 123 LIST_ENTRY(pmap) pm_list[PMAP_LIST_MAXNUMCPU]; /* per cpu ctx used list */
126 124
127 struct pmap_statistics pm_stats; 125 struct pmap_statistics pm_stats;
128 126
129 /* 127 /*
130 * We record the context used on any cpu here. If the context 128 * We record the context used on any cpu here. If the context
131 * is actually present in the TLB, it will be the plain context 129 * is actually present in the TLB, it will be the plain context
132 * number. If the context is allocated, but has been flushed 130 * number. If the context is allocated, but has been flushed
133 * from the tlb, the number will be negative. 131 * from the tlb, the number will be negative.
134 * If this pmap has no context allocated on that cpu, the entry 132 * If this pmap has no context allocated on that cpu, the entry
135 * will be 0. 133 * will be 0.
136 */ 134 */
137 int pm_ctx[PMAP_LIST_MAXNUMCPU]; /* Current context per cpu */ 135 int pm_ctx[PMAP_LIST_MAXNUMCPU]; /* Current context per cpu */
138 136
139 /* 137 /*
140 * This contains 64-bit pointers to pages that contain 138 * This contains 64-bit pointers to pages that contain
141 * 1024 64-bit pointers to page tables. All addresses 139 * 1024 64-bit pointers to page tables. All addresses
142 * are physical. 140 * are physical.
143 * 141 *
144 * !!! Only touch this through pseg_get() and pseg_set() !!! 142 * !!! Only touch this through pseg_get() and pseg_set() !!!
145 */ 143 */
146 paddr_t pm_physaddr; /* physical address of pm_segs */ 144 paddr_t pm_physaddr; /* physical address of pm_segs */
147 int64_t *pm_segs; 145 int64_t *pm_segs;
148}; 146};
149 147
150/* 148/*
151 * This comes from the PROM and is used to map prom entries. 149 * This comes from the PROM and is used to map prom entries.
152 */ 150 */
153struct prom_map { 151struct prom_map {
154 uint64_t vstart; 152 uint64_t vstart;
155 uint64_t vsize; 153 uint64_t vsize;
156 uint64_t tte; 154 uint64_t tte;
157}; 155};
158 156
159#define PMAP_NC 0x001 /* Set the E bit in the page */ 157#define PMAP_NC 0x001 /* Set the E bit in the page */
160#define PMAP_NVC 0x002 /* Don't enable the virtual cache */ 158#define PMAP_NVC 0x002 /* Don't enable the virtual cache */
161#define PMAP_LITTLE 0x004 /* Map in little endian mode */ 159#define PMAP_LITTLE 0x004 /* Map in little endian mode */
162/* Large page size hints -- 160/* Large page size hints --
163 we really should use another param to pmap_enter() */ 161 we really should use another param to pmap_enter() */
164#define PMAP_8K 0x000 162#define PMAP_8K 0x000
165#define PMAP_64K 0x008 /* Use 64K page */ 163#define PMAP_64K 0x008 /* Use 64K page */
166#define PMAP_512K 0x010 164#define PMAP_512K 0x010
167#define PMAP_4M 0x018 165#define PMAP_4M 0x018
168#define PMAP_SZ_TO_TTE(x) (((x)&0x018)<<58) 166#define PMAP_SZ_TO_TTE(x) (((x)&0x018)<<58)
169/* If these bits are different in va's to the same PA 167/* If these bits are different in va's to the same PA
170 then there is an aliasing in the d$ */ 168 then there is an aliasing in the d$ */
171#define VA_ALIAS_MASK (1 << 13) 169#define VA_ALIAS_MASK (1 << 13)
172 170
173#ifdef _KERNEL 171#ifdef _KERNEL
174#ifdef PMAP_COUNT_DEBUG 172#ifdef PMAP_COUNT_DEBUG
175/* diagnostic versions if PMAP_COUNT_DEBUG option is used */ 173/* diagnostic versions if PMAP_COUNT_DEBUG option is used */
176int pmap_count_res(struct pmap *); 174int pmap_count_res(struct pmap *);
177int pmap_count_wired(struct pmap *); 175int pmap_count_wired(struct pmap *);
178#define pmap_resident_count(pm) pmap_count_res((pm)) 176#define pmap_resident_count(pm) pmap_count_res((pm))
179#define pmap_wired_count(pm) pmap_count_wired((pm)) 177#define pmap_wired_count(pm) pmap_count_wired((pm))
180#else 178#else
181#define pmap_resident_count(pm) ((pm)->pm_stats.resident_count) 179#define pmap_resident_count(pm) ((pm)->pm_stats.resident_count)
182#define pmap_wired_count(pm) ((pm)->pm_stats.wired_count) 180#define pmap_wired_count(pm) ((pm)->pm_stats.wired_count)
183#endif 181#endif
184 182
185#define pmap_phys_address(x) (x) 183#define pmap_phys_address(x) (x)
186 184
187void pmap_activate_pmap(struct pmap *); 185void pmap_activate_pmap(struct pmap *);
188void pmap_update(struct pmap *); 186void pmap_update(struct pmap *);
189void pmap_bootstrap(u_long, u_long); 187void pmap_bootstrap(u_long, u_long);
190/* make sure all page mappings are modulo 16K to prevent d$ aliasing */ 188/* make sure all page mappings are modulo 16K to prevent d$ aliasing */
191#define PMAP_PREFER(pa, va, sz, td) (*(va)+=(((*(va))^(pa))&(1<<(PGSHIFT)))) 189#define PMAP_PREFER(pa, va, sz, td) (*(va)+=(((*(va))^(pa))&(1<<(PGSHIFT))))
192 190
193#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */ 191#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */
194#define PMAP_NEED_PROCWR 192#define PMAP_NEED_PROCWR
195 193
196void pmap_procwr(struct proc *, vaddr_t, size_t); 194void pmap_procwr(struct proc *, vaddr_t, size_t);
197 195
198/* SPARC specific? */ 196/* SPARC specific? */
199int pmap_dumpsize(void); 197int pmap_dumpsize(void);
200int pmap_dumpmmu(int (*)(dev_t, daddr_t, void *, size_t), 198int pmap_dumpmmu(int (*)(dev_t, daddr_t, void *, size_t),
201 daddr_t); 199 daddr_t);
202int pmap_pa_exists(paddr_t); 200int pmap_pa_exists(paddr_t);
203void switchexit(struct lwp *, int); 201void switchexit(struct lwp *, int);
204void pmap_kprotect(vaddr_t, vm_prot_t); 202void pmap_kprotect(vaddr_t, vm_prot_t);
205 203
206/* SPARC64 specific */ 204/* SPARC64 specific */
207void pmap_copy_page_phys(paddr_t, paddr_t); 205void pmap_copy_page_phys(paddr_t, paddr_t);
208void pmap_zero_page_phys(paddr_t); 206void pmap_zero_page_phys(paddr_t);
209 207
210/* Installed physical memory, as discovered during bootstrap. */ 208/* Installed physical memory, as discovered during bootstrap. */
211extern int phys_installed_size; 209extern int phys_installed_size;
212extern struct mem_region *phys_installed; 210extern struct mem_region *phys_installed;
213 211
214#define __HAVE_VM_PAGE_MD 212#define __HAVE_VM_PAGE_MD
215 213
216/* 214/*
217 * For each struct vm_page, there is a list of all currently valid virtual 215 * For each struct vm_page, there is a list of all currently valid virtual
218 * mappings of that page. An entry is a pv_entry_t. 216 * mappings of that page. An entry is a pv_entry_t.
219 */ 217 */
220struct pmap; 218struct pmap;
221typedef struct pv_entry { 219typedef struct pv_entry {
222 struct pv_entry *pv_next; /* next pv_entry */ 220 struct pv_entry *pv_next; /* next pv_entry */
223 struct pmap *pv_pmap; /* pmap where mapping lies */ 221 struct pmap *pv_pmap; /* pmap where mapping lies */
224 vaddr_t pv_va; /* virtual address for mapping */ 222 vaddr_t pv_va; /* virtual address for mapping */
225} *pv_entry_t; 223} *pv_entry_t;
226/* PV flags encoded in the low bits of the VA of the first pv_entry */ 224/* PV flags encoded in the low bits of the VA of the first pv_entry */
227 225
228struct vm_page_md { 226struct vm_page_md {
229 struct pv_entry mdpg_pvh; 227 struct pv_entry mdpg_pvh;
230}; 228};
231#define VM_MDPAGE_INIT(pg) \ 229#define VM_MDPAGE_INIT(pg) \
232do { \ 230do { \
233 (pg)->mdpage.mdpg_pvh.pv_next = NULL; \ 231 (pg)->mdpage.mdpg_pvh.pv_next = NULL; \
234 (pg)->mdpage.mdpg_pvh.pv_pmap = NULL; \ 232 (pg)->mdpage.mdpg_pvh.pv_pmap = NULL; \
235 (pg)->mdpage.mdpg_pvh.pv_va = 0; \ 233 (pg)->mdpage.mdpg_pvh.pv_va = 0; \
236} while (/*CONSTCOND*/0) 234} while (/*CONSTCOND*/0)
237 235
238#endif /* _KERNEL */ 236#endif /* _KERNEL */
239 237
240#endif /* _LOCORE */ 238#endif /* _LOCORE */
241#endif /* _MACHINE_PMAP_H_ */ 239#endif /* _MACHINE_PMAP_H_ */

cvs diff -r1.275 -r1.275.2.1 src/sys/arch/sparc64/sparc64/pmap.c (switch to unified diff)

--- src/sys/arch/sparc64/sparc64/pmap.c 2011/07/12 07:51:34 1.275
+++ src/sys/arch/sparc64/sparc64/pmap.c 2011/12/02 16:33:09 1.275.2.1
@@ -1,2823 +1,2817 @@ @@ -1,2823 +1,2817 @@
1/* $NetBSD: pmap.c,v 1.275 2011/07/12 07:51:34 mrg Exp $ */ 1/* $NetBSD: pmap.c,v 1.275.2.1 2011/12/02 16:33:09 yamt Exp $ */
2/* 2/*
3 * 3 *
4 * Copyright (C) 1996-1999 Eduardo Horvath. 4 * Copyright (C) 1996-1999 Eduardo Horvath.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE. 24 * SUCH DAMAGE.
25 * 25 *
26 */ 26 */
27 27
28#include <sys/cdefs.h> 28#include <sys/cdefs.h>
29__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.275 2011/07/12 07:51:34 mrg Exp $"); 29__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.275.2.1 2011/12/02 16:33:09 yamt Exp $");
30 30
31#undef NO_VCACHE /* Don't forget the locked TLB in dostart */ 31#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
32#define HWREF 32#define HWREF
33 33
34#include "opt_ddb.h" 34#include "opt_ddb.h"
35#include "opt_multiprocessor.h" 35#include "opt_multiprocessor.h"
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/queue.h> 39#include <sys/queue.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/msgbuf.h> 41#include <sys/msgbuf.h>
42#include <sys/pool.h> 42#include <sys/pool.h>
43#include <sys/exec.h> 43#include <sys/exec.h>
44#include <sys/core.h> 44#include <sys/core.h>
45#include <sys/kcore.h> 45#include <sys/kcore.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47#include <sys/atomic.h> 47#include <sys/atomic.h>
48#include <sys/cpu.h> 48#include <sys/cpu.h>
49 49
50#include <sys/exec_aout.h> /* for MID_* */ 50#include <sys/exec_aout.h> /* for MID_* */
51 51
52#include <uvm/uvm.h> 52#include <uvm/uvm.h>
53 53
54#include <machine/pcb.h> 54#include <machine/pcb.h>
55#include <machine/sparc64.h> 55#include <machine/sparc64.h>
56#include <machine/ctlreg.h> 56#include <machine/ctlreg.h>
57#include <machine/promlib.h> 57#include <machine/promlib.h>
58#include <machine/kcore.h> 58#include <machine/kcore.h>
59#include <machine/bootinfo.h> 59#include <machine/bootinfo.h>
60 60
61#include <sparc64/sparc64/cache.h> 61#include <sparc64/sparc64/cache.h>
62 62
63#ifdef DDB 63#ifdef DDB
64#include <machine/db_machdep.h> 64#include <machine/db_machdep.h>
65#include <ddb/db_command.h> 65#include <ddb/db_command.h>
66#include <ddb/db_sym.h> 66#include <ddb/db_sym.h>
67#include <ddb/db_variables.h> 67#include <ddb/db_variables.h>
68#include <ddb/db_extern.h> 68#include <ddb/db_extern.h>
69#include <ddb/db_access.h> 69#include <ddb/db_access.h>
70#include <ddb/db_output.h> 70#include <ddb/db_output.h>
71#else 71#else
72#define Debugger() 72#define Debugger()
73#define db_printf printf 73#define db_printf printf
74#endif 74#endif
75 75
76#define MEG (1<<20) /* 1MB */ 76#define MEG (1<<20) /* 1MB */
77#define KB (1<<10) /* 1KB */ 77#define KB (1<<10) /* 1KB */
78 78
79paddr_t cpu0paddr; /* contigious phys memory preallocated for cpus */ 79paddr_t cpu0paddr; /* contigious phys memory preallocated for cpus */
80 80
81/* These routines are in assembly to allow access thru physical mappings */ 81/* These routines are in assembly to allow access thru physical mappings */
82extern int64_t pseg_get_real(struct pmap *, vaddr_t); 82extern int64_t pseg_get_real(struct pmap *, vaddr_t);
83extern int pseg_set_real(struct pmap *, vaddr_t, int64_t, paddr_t); 83extern int pseg_set_real(struct pmap *, vaddr_t, int64_t, paddr_t);
84 84
85/* 85/*
86 * Diatribe on ref/mod counting: 86 * Diatribe on ref/mod counting:
87 * 87 *
88 * First of all, ref/mod info must be non-volatile. Hence we need to keep it 88 * First of all, ref/mod info must be non-volatile. Hence we need to keep it
89 * in the pv_entry structure for each page. (We could bypass this for the 89 * in the pv_entry structure for each page. (We could bypass this for the
90 * vm_page, but that's a long story....) 90 * vm_page, but that's a long story....)
91 * 91 *
92 * This architecture has nice, fast traps with lots of space for software bits 92 * This architecture has nice, fast traps with lots of space for software bits
93 * in the TTE. To accelerate ref/mod counts we make use of these features. 93 * in the TTE. To accelerate ref/mod counts we make use of these features.
94 * 94 *
95 * When we map a page initially, we place a TTE in the page table. It's 95 * When we map a page initially, we place a TTE in the page table. It's
96 * inserted with the TLB_W and TLB_ACCESS bits cleared. If a page is really 96 * inserted with the TLB_W and TLB_ACCESS bits cleared. If a page is really
97 * writable we set the TLB_REAL_W bit for the trap handler. 97 * writable we set the TLB_REAL_W bit for the trap handler.
98 * 98 *
99 * Whenever we take a TLB miss trap, the trap handler will set the TLB_ACCESS 99 * Whenever we take a TLB miss trap, the trap handler will set the TLB_ACCESS
100 * bit in the approprate TTE in the page table. Whenever we take a protection 100 * bit in the approprate TTE in the page table. Whenever we take a protection
101 * fault, if the TLB_REAL_W bit is set then we flip both the TLB_W and TLB_MOD 101 * fault, if the TLB_REAL_W bit is set then we flip both the TLB_W and TLB_MOD
102 * bits to enable writing and mark the page as modified. 102 * bits to enable writing and mark the page as modified.
103 * 103 *
104 * This means that we may have ref/mod information all over the place. The 104 * This means that we may have ref/mod information all over the place. The
105 * pmap routines must traverse the page tables of all pmaps with a given page 105 * pmap routines must traverse the page tables of all pmaps with a given page
106 * and collect/clear all the ref/mod information and copy it into the pv_entry. 106 * and collect/clear all the ref/mod information and copy it into the pv_entry.
107 */ 107 */
108 108
109#ifdef NO_VCACHE 109#ifdef NO_VCACHE
110#define FORCE_ALIAS 1 110#define FORCE_ALIAS 1
111#else 111#else
112#define FORCE_ALIAS 0 112#define FORCE_ALIAS 0
113#endif 113#endif
114 114
115#define PV_ALIAS 0x1LL 115#define PV_ALIAS 0x1LL
116#define PV_REF 0x2LL 116#define PV_REF 0x2LL
117#define PV_MOD 0x4LL 117#define PV_MOD 0x4LL
118#define PV_NVC 0x8LL 118#define PV_NVC 0x8LL
119#define PV_NC 0x10LL 119#define PV_NC 0x10LL
120#define PV_WE 0x20LL /* Debug -- this page was writable somtime */ 120#define PV_WE 0x20LL /* Debug -- this page was writable somtime */
121#define PV_MASK (0x03fLL) 121#define PV_MASK (0x03fLL)
122#define PV_VAMASK (~(PAGE_SIZE - 1)) 122#define PV_VAMASK (~(PAGE_SIZE - 1))
123#define PV_MATCH(pv,va) (!(((pv)->pv_va ^ (va)) & PV_VAMASK)) 123#define PV_MATCH(pv,va) (!(((pv)->pv_va ^ (va)) & PV_VAMASK))
124#define PV_SETVA(pv,va) ((pv)->pv_va = (((va) & PV_VAMASK) | \ 124#define PV_SETVA(pv,va) ((pv)->pv_va = (((va) & PV_VAMASK) | \
125 (((pv)->pv_va) & PV_MASK))) 125 (((pv)->pv_va) & PV_MASK)))
126 126
127struct pool_cache pmap_cache; 127struct pool_cache pmap_cache;
128struct pool_cache pmap_pv_cache; 128struct pool_cache pmap_pv_cache;
129 129
130pv_entry_t pmap_remove_pv(struct pmap *, vaddr_t, struct vm_page *); 130pv_entry_t pmap_remove_pv(struct pmap *, vaddr_t, struct vm_page *);
131void pmap_enter_pv(struct pmap *, vaddr_t, paddr_t, struct vm_page *, 131void pmap_enter_pv(struct pmap *, vaddr_t, paddr_t, struct vm_page *,
132 pv_entry_t); 132 pv_entry_t);
133void pmap_page_cache(struct pmap *, paddr_t, int); 133void pmap_page_cache(struct pmap *, paddr_t, int);
134 134
135/* 135/*
136 * First and last managed physical addresses. 136 * First and last managed physical addresses.
137 * XXX only used for dumping the system. 137 * XXX only used for dumping the system.
138 */ 138 */
139paddr_t vm_first_phys, vm_num_phys; 139paddr_t vm_first_phys, vm_num_phys;
140 140
141/* 141/*
142 * Here's the CPU TSB stuff. It's allocated in pmap_bootstrap. 142 * Here's the CPU TSB stuff. It's allocated in pmap_bootstrap.
143 */ 143 */
144int tsbsize; /* tsbents = 512 * 2^^tsbsize */ 144int tsbsize; /* tsbents = 512 * 2^^tsbsize */
145#define TSBENTS (512<<tsbsize) 145#define TSBENTS (512<<tsbsize)
146#define TSBSIZE (TSBENTS * 16) 146#define TSBSIZE (TSBENTS * 16)
147 147
148static struct pmap kernel_pmap_; 148static struct pmap kernel_pmap_;
149struct pmap *const kernel_pmap_ptr = &kernel_pmap_; 149struct pmap *const kernel_pmap_ptr = &kernel_pmap_;
150 150
151static int ctx_alloc(struct pmap *); 151static int ctx_alloc(struct pmap *);
152static bool pmap_is_referenced_locked(struct vm_page *); 152static bool pmap_is_referenced_locked(struct vm_page *);
153 153
154static void ctx_free(struct pmap *, struct cpu_info *); 154static void ctx_free(struct pmap *, struct cpu_info *);
155 155
156/* 156/*
157 * Check if any MMU has a non-zero context 157 * Check if any MMU has a non-zero context
158 */ 158 */
159static inline bool 159static inline bool
160pmap_has_ctx(struct pmap *p) 160pmap_has_ctx(struct pmap *p)
161{ 161{
162 int i; 162 int i;
163 163
164 /* any context on any cpu? */ 164 /* any context on any cpu? */
165 for (i = 0; i < sparc_ncpus; i++) 165 for (i = 0; i < sparc_ncpus; i++)
166 if (p->pm_ctx[i] > 0) 166 if (p->pm_ctx[i] > 0)
167 return true; 167 return true;
168 168
169 return false;  169 return false;
170} 170}
171 171
172#ifdef MULTIPROCESSOR 172#ifdef MULTIPROCESSOR
173#define pmap_ctx(PM) ((PM)->pm_ctx[cpu_number()]) 173#define pmap_ctx(PM) ((PM)->pm_ctx[cpu_number()])
174#else 174#else
175#define pmap_ctx(PM) ((PM)->pm_ctx[0]) 175#define pmap_ctx(PM) ((PM)->pm_ctx[0])
176#endif 176#endif
177 177
178/* 178/*
179 * Check if this pmap has a live mapping on some MMU. 179 * Check if this pmap has a live mapping on some MMU.
180 */ 180 */
181static inline bool 181static inline bool
182pmap_is_on_mmu(struct pmap *p) 182pmap_is_on_mmu(struct pmap *p)
183{ 183{
184 /* The kernel pmap is always on all MMUs */ 184 /* The kernel pmap is always on all MMUs */
185 if (p == pmap_kernel()) 185 if (p == pmap_kernel())
186 return true; 186 return true;
187 187
188 return pmap_has_ctx(p); 188 return pmap_has_ctx(p);
189} 189}
190 190
191/* 191/*
192 * Virtual and physical addresses of the start and end of kernel text 192 * Virtual and physical addresses of the start and end of kernel text
193 * and data segments. 193 * and data segments.
194 */ 194 */
195vaddr_t ktext; 195vaddr_t ktext;
196paddr_t ktextp; 196paddr_t ktextp;
197vaddr_t ektext; 197vaddr_t ektext;
198paddr_t ektextp; 198paddr_t ektextp;
199vaddr_t kdata; 199vaddr_t kdata;
200paddr_t kdatap; 200paddr_t kdatap;
201vaddr_t ekdata; 201vaddr_t ekdata;
202paddr_t ekdatap; 202paddr_t ekdatap;
203 203
204/* 204/*
205 * Kernel 4MB pages. 205 * Kernel 4MB pages.
206 */ 206 */
207extern struct tlb_entry *kernel_tlbs; 207extern struct tlb_entry *kernel_tlbs;
208extern int kernel_tlb_slots; 208extern int kernel_tlb_slots;
209 209
210static int npgs; 210static int npgs;
211 211
212vaddr_t vmmap; /* one reserved MI vpage for /dev/mem */ 212vaddr_t vmmap; /* one reserved MI vpage for /dev/mem */
213 213
214int phys_installed_size; /* Installed physical memory */ 214int phys_installed_size; /* Installed physical memory */
215struct mem_region *phys_installed; 215struct mem_region *phys_installed;
216 216
217paddr_t avail_start, avail_end; /* These are used by ps & family */ 217paddr_t avail_start, avail_end; /* These are used by ps & family */
218 218
219static int ptelookup_va(vaddr_t va); 219static int ptelookup_va(vaddr_t va);
220 220
221static inline void 221static inline void
222clrx(void *addr) 222clrx(void *addr)
223{ 223{
224 __asm volatile("clrx [%0]" : : "r" (addr) : "memory"); 224 __asm volatile("clrx [%0]" : : "r" (addr) : "memory");
225} 225}
226 226
227static void 227static void
228tsb_invalidate(vaddr_t va, pmap_t pm) 228tsb_invalidate(vaddr_t va, pmap_t pm)
229{ 229{
230 struct cpu_info *ci; 230 struct cpu_info *ci;
231 int ctx; 231 int ctx;
232 bool kpm = (pm == pmap_kernel()); 232 bool kpm = (pm == pmap_kernel());
233 int i; 233 int i;
234 int64_t tag; 234 int64_t tag;
235 235
236 i = ptelookup_va(va); 236 i = ptelookup_va(va);
237#ifdef MULTIPROCESSOR 237#ifdef MULTIPROCESSOR
238 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 238 for (ci = cpus; ci != NULL; ci = ci->ci_next) {
239 if (!CPUSET_HAS(cpus_active, ci->ci_index)) 239 if (!CPUSET_HAS(cpus_active, ci->ci_index))
240 continue; 240 continue;
241#else 241#else
242 ci = curcpu(); 242 ci = curcpu();
243#endif 243#endif
244 ctx = pm->pm_ctx[ci->ci_index]; 244 ctx = pm->pm_ctx[ci->ci_index];
245 if (kpm || ctx > 0) { 245 if (kpm || ctx > 0) {
246 tag = TSB_TAG(0, ctx, va); 246 tag = TSB_TAG(0, ctx, va);
247 if (ci->ci_tsb_dmmu[i].tag == tag) { 247 if (ci->ci_tsb_dmmu[i].tag == tag) {
248 clrx(&ci->ci_tsb_dmmu[i].data); 248 clrx(&ci->ci_tsb_dmmu[i].data);
249 } 249 }
250 if (ci->ci_tsb_immu[i].tag == tag) { 250 if (ci->ci_tsb_immu[i].tag == tag) {
251 clrx(&ci->ci_tsb_immu[i].data); 251 clrx(&ci->ci_tsb_immu[i].data);
252 } 252 }
253 } 253 }
254#ifdef MULTIPROCESSOR 254#ifdef MULTIPROCESSOR
255 } 255 }
256#endif 256#endif
257} 257}
258 258
259struct prom_map *prom_map; 259struct prom_map *prom_map;
260int prom_map_size; 260int prom_map_size;
261 261
262#ifdef DEBUG 262#ifdef DEBUG
263struct { 263struct {
264 int kernel; /* entering kernel mapping */ 264 int kernel; /* entering kernel mapping */
265 int user; /* entering user mapping */ 265 int user; /* entering user mapping */
266 int ptpneeded; /* needed to allocate a PT page */ 266 int ptpneeded; /* needed to allocate a PT page */
267 int pwchange; /* no mapping change, just wiring or protection */ 267 int pwchange; /* no mapping change, just wiring or protection */
268 int wchange; /* no mapping change, just wiring */ 268 int wchange; /* no mapping change, just wiring */
269 int mchange; /* was mapped but mapping to different page */ 269 int mchange; /* was mapped but mapping to different page */
270 int managed; /* a managed page */ 270 int managed; /* a managed page */
271 int firstpv; /* first mapping for this PA */ 271 int firstpv; /* first mapping for this PA */
272 int secondpv; /* second mapping for this PA */ 272 int secondpv; /* second mapping for this PA */
273 int ci; /* cache inhibited */ 273 int ci; /* cache inhibited */
274 int unmanaged; /* not a managed page */ 274 int unmanaged; /* not a managed page */
275 int flushes; /* cache flushes */ 275 int flushes; /* cache flushes */
276 int cachehit; /* new entry forced valid entry out */ 276 int cachehit; /* new entry forced valid entry out */
277} enter_stats; 277} enter_stats;
278struct { 278struct {
279 int calls; 279 int calls;
280 int removes; 280 int removes;
281 int flushes; 281 int flushes;
282 int tflushes; /* TLB flushes */ 282 int tflushes; /* TLB flushes */
283 int pidflushes; /* HW pid stolen */ 283 int pidflushes; /* HW pid stolen */
284 int pvfirst; 284 int pvfirst;
285 int pvsearch; 285 int pvsearch;
286} remove_stats; 286} remove_stats;
287#define ENTER_STAT(x) do { enter_stats.x ++; } while (0) 287#define ENTER_STAT(x) do { enter_stats.x ++; } while (0)
288#define REMOVE_STAT(x) do { remove_stats.x ++; } while (0) 288#define REMOVE_STAT(x) do { remove_stats.x ++; } while (0)
289 289
290#define PDB_CREATE 0x000001 290#define PDB_CREATE 0x000001
291#define PDB_DESTROY 0x000002 291#define PDB_DESTROY 0x000002
292#define PDB_REMOVE 0x000004 292#define PDB_REMOVE 0x000004
293#define PDB_CHANGEPROT 0x000008 293#define PDB_CHANGEPROT 0x000008
294#define PDB_ENTER 0x000010 294#define PDB_ENTER 0x000010
295#define PDB_DEMAP 0x000020 /* used in locore */ 295#define PDB_DEMAP 0x000020 /* used in locore */
296#define PDB_REF 0x000040 296#define PDB_REF 0x000040
297#define PDB_COPY 0x000080 297#define PDB_COPY 0x000080
298#define PDB_MMU_ALLOC 0x000100 298#define PDB_MMU_ALLOC 0x000100
299#define PDB_MMU_STEAL 0x000200 299#define PDB_MMU_STEAL 0x000200
300#define PDB_CTX_ALLOC 0x000400 300#define PDB_CTX_ALLOC 0x000400
301#define PDB_CTX_STEAL 0x000800 301#define PDB_CTX_STEAL 0x000800
302#define PDB_MMUREG_ALLOC 0x001000 302#define PDB_MMUREG_ALLOC 0x001000
303#define PDB_MMUREG_STEAL 0x002000 303#define PDB_MMUREG_STEAL 0x002000
304#define PDB_CACHESTUFF 0x004000 304#define PDB_CACHESTUFF 0x004000
305#define PDB_ALIAS 0x008000 305#define PDB_ALIAS 0x008000
306#define PDB_EXTRACT 0x010000 306#define PDB_EXTRACT 0x010000
307#define PDB_BOOT 0x020000 307#define PDB_BOOT 0x020000
308#define PDB_BOOT1 0x040000 308#define PDB_BOOT1 0x040000
309#define PDB_GROW 0x080000 309#define PDB_GROW 0x080000
310#define PDB_CTX_FLUSHALL 0x100000 310#define PDB_CTX_FLUSHALL 0x100000
311int pmapdebug = 0; 311int pmapdebug = 0;
312/* Number of H/W pages stolen for page tables */ 312/* Number of H/W pages stolen for page tables */
313int pmap_pages_stolen = 0; 313int pmap_pages_stolen = 0;
314 314
315#define BDPRINTF(n, f) if (pmapdebug & (n)) prom_printf f 315#define BDPRINTF(n, f) if (pmapdebug & (n)) prom_printf f
316#define DPRINTF(n, f) if (pmapdebug & (n)) printf f 316#define DPRINTF(n, f) if (pmapdebug & (n)) printf f
317#else 317#else
318#define ENTER_STAT(x) do { /* nothing */ } while (0) 318#define ENTER_STAT(x) do { /* nothing */ } while (0)
319#define REMOVE_STAT(x) do { /* nothing */ } while (0) 319#define REMOVE_STAT(x) do { /* nothing */ } while (0)
320#define BDPRINTF(n, f) 320#define BDPRINTF(n, f)
321#define DPRINTF(n, f) 321#define DPRINTF(n, f)
322#endif 322#endif
323 323
324#define pv_check() 324#define pv_check()
325 325
326static int pmap_get_page(paddr_t *); 326static int pmap_get_page(paddr_t *);
327static void pmap_free_page(paddr_t, sparc64_cpuset_t); 327static void pmap_free_page(paddr_t, sparc64_cpuset_t);
328static void pmap_free_page_noflush(paddr_t); 328static void pmap_free_page_noflush(paddr_t);
329 329
330/* 330/*
331 * Global pmap locks. 331 * Global pmap locks.
332 */ 332 */
333static kmutex_t pmap_lock; 333static kmutex_t pmap_lock;
334static bool lock_available = false; 334static bool lock_available = false;
335 335
336/* 336/*
337 * Support for big page sizes. This maps the page size to the 337 * Support for big page sizes. This maps the page size to the
338 * page bits. That is: these are the bits between 8K pages and 338 * page bits. That is: these are the bits between 8K pages and
339 * larger page sizes that cause aliasing. 339 * larger page sizes that cause aliasing.
340 */ 340 */
341#define PSMAP_ENTRY(MASK, CODE) { .mask = MASK, .code = CODE } 341#define PSMAP_ENTRY(MASK, CODE) { .mask = MASK, .code = CODE }
342struct page_size_map page_size_map[] = { 342struct page_size_map page_size_map[] = {
343#ifdef DEBUG 343#ifdef DEBUG
344 PSMAP_ENTRY(0, PGSZ_8K & 0), /* Disable large pages */ 344 PSMAP_ENTRY(0, PGSZ_8K & 0), /* Disable large pages */
345#endif 345#endif
346 PSMAP_ENTRY((4 * 1024 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_4M), 346 PSMAP_ENTRY((4 * 1024 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_4M),
347 PSMAP_ENTRY((512 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_512K), 347 PSMAP_ENTRY((512 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_512K),
348 PSMAP_ENTRY((64 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_64K), 348 PSMAP_ENTRY((64 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_64K),
349 PSMAP_ENTRY((8 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_8K), 349 PSMAP_ENTRY((8 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_8K),
350 PSMAP_ENTRY(0, 0), 350 PSMAP_ENTRY(0, 0),
351}; 351};
352 352
353/* 353/*
354 * This probably shouldn't be necessary, but it stops USIII machines from 354 * This probably shouldn't be necessary, but it stops USIII machines from
355 * breaking in general, and not just for MULTIPROCESSOR. 355 * breaking in general, and not just for MULTIPROCESSOR.
356 */ 356 */
357#define USE_LOCKSAFE_PSEG_GETSET 357#define USE_LOCKSAFE_PSEG_GETSET
358#if defined(USE_LOCKSAFE_PSEG_GETSET) 358#if defined(USE_LOCKSAFE_PSEG_GETSET)
359 359
360static kmutex_t pseg_lock; 360static kmutex_t pseg_lock;
361 361
362static __inline__ int64_t 362static __inline__ int64_t
363pseg_get_locksafe(struct pmap *pm, vaddr_t va) 363pseg_get_locksafe(struct pmap *pm, vaddr_t va)
364{ 364{
365 int64_t rv; 365 int64_t rv;
366 bool took_lock = lock_available /*&& pm == pmap_kernel()*/; 366 bool took_lock = lock_available /*&& pm == pmap_kernel()*/;
367 367
368 if (__predict_true(took_lock)) 368 if (__predict_true(took_lock))
369 mutex_enter(&pseg_lock); 369 mutex_enter(&pseg_lock);
370 rv = pseg_get_real(pm, va); 370 rv = pseg_get_real(pm, va);
371 if (__predict_true(took_lock)) 371 if (__predict_true(took_lock))
372 mutex_exit(&pseg_lock); 372 mutex_exit(&pseg_lock);
373 return rv; 373 return rv;
374} 374}
375 375
376static __inline__ int 376static __inline__ int
377pseg_set_locksafe(struct pmap *pm, vaddr_t va, int64_t data, paddr_t ptp) 377pseg_set_locksafe(struct pmap *pm, vaddr_t va, int64_t data, paddr_t ptp)
378{ 378{
379 int rv; 379 int rv;
380 bool took_lock = lock_available /*&& pm == pmap_kernel()*/; 380 bool took_lock = lock_available /*&& pm == pmap_kernel()*/;
381 381
382 if (__predict_true(took_lock)) 382 if (__predict_true(took_lock))
383 mutex_enter(&pseg_lock); 383 mutex_enter(&pseg_lock);
384 rv = pseg_set_real(pm, va, data, ptp); 384 rv = pseg_set_real(pm, va, data, ptp);
385 if (__predict_true(took_lock)) 385 if (__predict_true(took_lock))
386 mutex_exit(&pseg_lock); 386 mutex_exit(&pseg_lock);
387 return rv; 387 return rv;
388} 388}
389 389
390#define pseg_get(pm, va) pseg_get_locksafe(pm, va) 390#define pseg_get(pm, va) pseg_get_locksafe(pm, va)
391#define pseg_set(pm, va, data, ptp) pseg_set_locksafe(pm, va, data, ptp) 391#define pseg_set(pm, va, data, ptp) pseg_set_locksafe(pm, va, data, ptp)
392 392
393#else /* USE_LOCKSAFE_PSEG_GETSET */ 393#else /* USE_LOCKSAFE_PSEG_GETSET */
394 394
395#define pseg_get(pm, va) pseg_get_real(pm, va) 395#define pseg_get(pm, va) pseg_get_real(pm, va)
396#define pseg_set(pm, va, data, ptp) pseg_set_real(pm, va, data, ptp) 396#define pseg_set(pm, va, data, ptp) pseg_set_real(pm, va, data, ptp)
397 397
398#endif /* USE_LOCKSAFE_PSEG_GETSET */ 398#endif /* USE_LOCKSAFE_PSEG_GETSET */
399 399
400/* 400/*
401 * Enter a TTE into the kernel pmap only. Don't do anything else. 401 * Enter a TTE into the kernel pmap only. Don't do anything else.
402 * 402 *
403 * Use only during bootstrapping since it does no locking and 403 * Use only during bootstrapping since it does no locking and
404 * can lose ref/mod info!!!! 404 * can lose ref/mod info!!!!
405 * 405 *
406 */ 406 */
407static void pmap_enter_kpage(vaddr_t va, int64_t data) 407static void pmap_enter_kpage(vaddr_t va, int64_t data)
408{ 408{
409 paddr_t newp; 409 paddr_t newp;
410 410
411 newp = 0UL; 411 newp = 0UL;
412 while (pseg_set(pmap_kernel(), va, data, newp) & 1) { 412 while (pseg_set(pmap_kernel(), va, data, newp) & 1) {
413 if (!pmap_get_page(&newp)) { 413 if (!pmap_get_page(&newp)) {
414 prom_printf("pmap_enter_kpage: out of pages\n"); 414 prom_printf("pmap_enter_kpage: out of pages\n");
415 panic("pmap_enter_kpage"); 415 panic("pmap_enter_kpage");
416 } 416 }
417 417
418 ENTER_STAT(ptpneeded); 418 ENTER_STAT(ptpneeded);
419 BDPRINTF(PDB_BOOT1, 419 BDPRINTF(PDB_BOOT1,
420 ("pseg_set: pm=%p va=%p data=%lx newp %lx\n", 420 ("pseg_set: pm=%p va=%p data=%lx newp %lx\n",
421 pmap_kernel(), va, (long)data, (long)newp)); 421 pmap_kernel(), va, (long)data, (long)newp));
422#ifdef DEBUG 422#ifdef DEBUG
423 if (pmapdebug & PDB_BOOT1) 423 if (pmapdebug & PDB_BOOT1)
424 {int i; for (i=0; i<140000000; i++) ;} 424 {int i; for (i=0; i<140000000; i++) ;}
425#endif 425#endif
426 } 426 }
427} 427}
428 428
429/* 429/*
430 * Check the bootargs to see if we need to enable bootdebug. 430 * Check the bootargs to see if we need to enable bootdebug.
431 */ 431 */
432#ifdef DEBUG 432#ifdef DEBUG
433static void pmap_bootdebug(void) 433static void pmap_bootdebug(void)
434{ 434{
435 const char *cp = prom_getbootargs(); 435 const char *cp = prom_getbootargs();
436 436
437 for (;;) 437 for (;;)
438 switch (*++cp) { 438 switch (*++cp) {
439 case '\0': 439 case '\0':
440 return; 440 return;
441 case 'V': 441 case 'V':
442 pmapdebug |= PDB_BOOT|PDB_BOOT1; 442 pmapdebug |= PDB_BOOT|PDB_BOOT1;
443 break; 443 break;
444 case 'D': 444 case 'D':
445 pmapdebug |= PDB_BOOT1; 445 pmapdebug |= PDB_BOOT1;
446 break; 446 break;
447 } 447 }
448} 448}
449#endif 449#endif
450 450
451 451
452/* 452/*
453 * Calculate the correct number of page colors to use. This should be the 453 * Calculate the correct number of page colors to use. This should be the
454 * size of the E$/PAGE_SIZE. However, different CPUs can have different sized 454 * size of the E$/PAGE_SIZE. However, different CPUs can have different sized
455 * E$, so we need to take the GCM of the E$ size. 455 * E$, so we need to take the GCM of the E$ size.
456 */ 456 */
457static int pmap_calculate_colors(void) 457static int pmap_calculate_colors(void)
458{ 458{
459 int node; 459 int node;
460 int size, assoc, color, maxcolor = 1; 460 int size, assoc, color, maxcolor = 1;
461 461
462 for (node = prom_firstchild(prom_findroot()); node != 0; 462 for (node = prom_firstchild(prom_findroot()); node != 0;
463 node = prom_nextsibling(node)) { 463 node = prom_nextsibling(node)) {
464 char *name = prom_getpropstring(node, "device_type"); 464 char *name = prom_getpropstring(node, "device_type");
465 if (strcmp("cpu", name) != 0) 465 if (strcmp("cpu", name) != 0)
466 continue; 466 continue;
467 467
468 /* Found a CPU, get the E$ info. */ 468 /* Found a CPU, get the E$ info. */
469 size = prom_getpropint(node, "ecache-size", -1); 469 size = prom_getpropint(node, "ecache-size", -1);
470 if (size == -1) { 470 if (size == -1) {
471 prom_printf("pmap_calculate_colors: node %x has " 471 prom_printf("pmap_calculate_colors: node %x has "
472 "no ecache-size\n", node); 472 "no ecache-size\n", node);
473 /* If we can't get the E$ size, skip the node */ 473 /* If we can't get the E$ size, skip the node */
474 continue; 474 continue;
475 } 475 }
476 476
477 assoc = prom_getpropint(node, "ecache-associativity", 1); 477 assoc = prom_getpropint(node, "ecache-associativity", 1);
478 color = size/assoc/PAGE_SIZE; 478 color = size/assoc/PAGE_SIZE;
479 if (color > maxcolor) 479 if (color > maxcolor)
480 maxcolor = color; 480 maxcolor = color;
481 } 481 }
482 return (maxcolor); 482 return (maxcolor);
483} 483}
484 484
485static void pmap_alloc_bootargs(void) 485static void pmap_alloc_bootargs(void)
486{ 486{
487 char *v; 487 char *v;
488 488
489 v = OF_claim(NULL, 2*PAGE_SIZE, PAGE_SIZE); 489 v = OF_claim(NULL, 2*PAGE_SIZE, PAGE_SIZE);
490 if ((v == NULL) || (v == (void*)-1)) 490 if ((v == NULL) || (v == (void*)-1))
491 panic("Can't claim two pages of memory."); 491 panic("Can't claim two pages of memory.");
492 492
493 memset(v, 0, 2*PAGE_SIZE); 493 memset(v, 0, 2*PAGE_SIZE);
494 494
495 cpu_args = (struct cpu_bootargs*)v; 495 cpu_args = (struct cpu_bootargs*)v;
496} 496}
497 497
498#if defined(MULTIPROCESSOR) 498#if defined(MULTIPROCESSOR)
499static void pmap_mp_init(void); 499static void pmap_mp_init(void);
500 500
501static void 501static void
502pmap_mp_init(void) 502pmap_mp_init(void)
503{ 503{
504 pte_t *tp; 504 pte_t *tp;
505 char *v; 505 char *v;
506 int i; 506 int i;
507 507
508 extern void cpu_mp_startup(void); 508 extern void cpu_mp_startup(void);
509 509
510 if ((v = OF_claim(NULL, PAGE_SIZE, PAGE_SIZE)) == NULL) { 510 if ((v = OF_claim(NULL, PAGE_SIZE, PAGE_SIZE)) == NULL) {
511 panic("pmap_mp_init: Cannot claim a page."); 511 panic("pmap_mp_init: Cannot claim a page.");
512 } 512 }
513 513
514 memcpy(v, mp_tramp_code, mp_tramp_code_len); 514 memcpy(v, mp_tramp_code, mp_tramp_code_len);
515 *(u_long *)(v + mp_tramp_tlb_slots) = kernel_tlb_slots; 515 *(u_long *)(v + mp_tramp_tlb_slots) = kernel_tlb_slots;
516 *(u_long *)(v + mp_tramp_func) = (u_long)cpu_mp_startup; 516 *(u_long *)(v + mp_tramp_func) = (u_long)cpu_mp_startup;
517 *(u_long *)(v + mp_tramp_ci) = (u_long)cpu_args; 517 *(u_long *)(v + mp_tramp_ci) = (u_long)cpu_args;
518 tp = (pte_t *)(v + mp_tramp_code_len); 518 tp = (pte_t *)(v + mp_tramp_code_len);
519 for (i = 0; i < kernel_tlb_slots; i++) { 519 for (i = 0; i < kernel_tlb_slots; i++) {
520 tp[i].tag = kernel_tlbs[i].te_va; 520 tp[i].tag = kernel_tlbs[i].te_va;
521 tp[i].data = TSB_DATA(0, /* g */ 521 tp[i].data = TSB_DATA(0, /* g */
522 PGSZ_4M, /* sz */ 522 PGSZ_4M, /* sz */
523 kernel_tlbs[i].te_pa, /* pa */ 523 kernel_tlbs[i].te_pa, /* pa */
524 1, /* priv */ 524 1, /* priv */
525 1, /* write */ 525 1, /* write */
526 1, /* cache */ 526 1, /* cache */
527 1, /* aliased */ 527 1, /* aliased */
528 1, /* valid */ 528 1, /* valid */
529 0 /* ie */); 529 0 /* ie */);
530 tp[i].data |= TLB_L | TLB_CV; 530 tp[i].data |= TLB_L | TLB_CV;
531 DPRINTF(PDB_BOOT1, ("xtlb[%d]: Tag: %" PRIx64 " Data: %" 531 DPRINTF(PDB_BOOT1, ("xtlb[%d]: Tag: %" PRIx64 " Data: %"
532 PRIx64 "\n", i, tp[i].tag, tp[i].data)); 532 PRIx64 "\n", i, tp[i].tag, tp[i].data));
533 } 533 }
534 534
535 for (i = 0; i < PAGE_SIZE; i += sizeof(long)) 535 for (i = 0; i < PAGE_SIZE; i += sizeof(long))
536 flush(v + i); 536 flush(v + i);
537 537
538 cpu_spinup_trampoline = (vaddr_t)v; 538 cpu_spinup_trampoline = (vaddr_t)v;
539} 539}
540#else 540#else
541#define pmap_mp_init() ((void)0) 541#define pmap_mp_init() ((void)0)
542#endif 542#endif
543 543
544paddr_t pmap_kextract(vaddr_t va); 544paddr_t pmap_kextract(vaddr_t va);
545 545
546paddr_t 546paddr_t
547pmap_kextract(vaddr_t va) 547pmap_kextract(vaddr_t va)
548{ 548{
549 int i; 549 int i;
550 paddr_t paddr = (paddr_t)-1; 550 paddr_t paddr = (paddr_t)-1;
551 551
552 for (i = 0; i < kernel_tlb_slots; i++) { 552 for (i = 0; i < kernel_tlb_slots; i++) {
553 if ((va & ~PAGE_MASK_4M) == kernel_tlbs[i].te_va) { 553 if ((va & ~PAGE_MASK_4M) == kernel_tlbs[i].te_va) {
554 paddr = kernel_tlbs[i].te_pa + 554 paddr = kernel_tlbs[i].te_pa +
555 (paddr_t)(va & PAGE_MASK_4M); 555 (paddr_t)(va & PAGE_MASK_4M);
556 break; 556 break;
557 } 557 }
558 } 558 }
559 559
560 if (i == kernel_tlb_slots) { 560 if (i == kernel_tlb_slots) {
561 panic("pmap_kextract: Address %p is not from kernel space.\n" 561 panic("pmap_kextract: Address %p is not from kernel space.\n"
562 "Data segment is too small?\n", (void*)va); 562 "Data segment is too small?\n", (void*)va);
563 } 563 }
564 564
565 return (paddr); 565 return (paddr);
566} 566}
567 567
568/* 568/*
569 * Bootstrap kernel allocator, allocates from unused space in 4MB kernel 569 * Bootstrap kernel allocator, allocates from unused space in 4MB kernel
570 * data segment meaning that 570 * data segment meaning that
571 * 571 *
572 * - Access to allocated memory will never generate a trap 572 * - Access to allocated memory will never generate a trap
573 * - Allocated chunks are never reclaimed or freed 573 * - Allocated chunks are never reclaimed or freed
574 * - Allocation calls do not change PROM memlists 574 * - Allocation calls do not change PROM memlists
575 */ 575 */
576static struct mem_region kdata_mem_pool; 576static struct mem_region kdata_mem_pool;
577 577
578static void 578static void
579kdata_alloc_init(vaddr_t va_start, vaddr_t va_end) 579kdata_alloc_init(vaddr_t va_start, vaddr_t va_end)
580{ 580{
581 vsize_t va_size = va_end - va_start; 581 vsize_t va_size = va_end - va_start;
582 582
583 kdata_mem_pool.start = va_start; 583 kdata_mem_pool.start = va_start;
584 kdata_mem_pool.size = va_size; 584 kdata_mem_pool.size = va_size;
585 585
586 BDPRINTF(PDB_BOOT, ("kdata_alloc_init(): %d bytes @%p.\n", va_size, 586 BDPRINTF(PDB_BOOT, ("kdata_alloc_init(): %d bytes @%p.\n", va_size,
587 va_start)); 587 va_start));
588} 588}
589 589
590static vaddr_t 590static vaddr_t
591kdata_alloc(vsize_t size, vsize_t align) 591kdata_alloc(vsize_t size, vsize_t align)
592{ 592{
593 vaddr_t va; 593 vaddr_t va;
594 vsize_t asize; 594 vsize_t asize;
595 595
596 asize = roundup(kdata_mem_pool.start, align) - kdata_mem_pool.start; 596 asize = roundup(kdata_mem_pool.start, align) - kdata_mem_pool.start;
597 597
598 kdata_mem_pool.start += asize; 598 kdata_mem_pool.start += asize;
599 kdata_mem_pool.size -= asize; 599 kdata_mem_pool.size -= asize;
600 600
601 if (kdata_mem_pool.size < size) { 601 if (kdata_mem_pool.size < size) {
602 panic("kdata_alloc(): Data segment is too small.\n"); 602 panic("kdata_alloc(): Data segment is too small.\n");
603 } 603 }
604 604
605 va = kdata_mem_pool.start; 605 va = kdata_mem_pool.start;
606 kdata_mem_pool.start += size; 606 kdata_mem_pool.start += size;
607 kdata_mem_pool.size -= size; 607 kdata_mem_pool.size -= size;
608 608
609 BDPRINTF(PDB_BOOT, ("kdata_alloc(): Allocated %d@%p, %d free.\n", 609 BDPRINTF(PDB_BOOT, ("kdata_alloc(): Allocated %d@%p, %d free.\n",
610 size, (void*)va, kdata_mem_pool.size)); 610 size, (void*)va, kdata_mem_pool.size));
611 611
612 return (va); 612 return (va);
613} 613}
614 614
615/* 615/*
616 * Unified routine for reading PROM properties. 616 * Unified routine for reading PROM properties.
617 */ 617 */
618static void 618static void
619pmap_read_memlist(const char *device, const char *property, void **ml, 619pmap_read_memlist(const char *device, const char *property, void **ml,
620 int *ml_size, vaddr_t (* ml_alloc)(vsize_t, vsize_t)) 620 int *ml_size, vaddr_t (* ml_alloc)(vsize_t, vsize_t))
621{ 621{
622 void *va; 622 void *va;
623 int size, handle; 623 int size, handle;
624 624
625 if ( (handle = prom_finddevice(device)) == 0) { 625 if ( (handle = prom_finddevice(device)) == 0) {
626 prom_printf("pmap_read_memlist(): No %s device found.\n", 626 prom_printf("pmap_read_memlist(): No %s device found.\n",
627 device); 627 device);
628 prom_halt(); 628 prom_halt();
629 } 629 }
630 if ( (size = OF_getproplen(handle, property)) < 0) { 630 if ( (size = OF_getproplen(handle, property)) < 0) {
631 prom_printf("pmap_read_memlist(): %s/%s has no length.\n", 631 prom_printf("pmap_read_memlist(): %s/%s has no length.\n",
632 device, property); 632 device, property);
633 prom_halt(); 633 prom_halt();
634 } 634 }
635 if ( (va = (void*)(* ml_alloc)(size, sizeof(uint64_t))) == NULL) { 635 if ( (va = (void*)(* ml_alloc)(size, sizeof(uint64_t))) == NULL) {
636 prom_printf("pmap_read_memlist(): Cannot allocate memlist.\n"); 636 prom_printf("pmap_read_memlist(): Cannot allocate memlist.\n");
637 prom_halt(); 637 prom_halt();
638 } 638 }
639 if (OF_getprop(handle, property, va, size) <= 0) { 639 if (OF_getprop(handle, property, va, size) <= 0) {
640 prom_printf("pmap_read_memlist(): Cannot read %s/%s.\n", 640 prom_printf("pmap_read_memlist(): Cannot read %s/%s.\n",
641 device, property); 641 device, property);
642 prom_halt(); 642 prom_halt();
643 } 643 }
644 644
645 *ml = va; 645 *ml = va;
646 *ml_size = size; 646 *ml_size = size;
647} 647}
648 648
649/* 649/*
650 * This is called during bootstrap, before the system is really initialized. 650 * This is called during bootstrap, before the system is really initialized.
651 * 651 *
652 * It's called with the start and end virtual addresses of the kernel. We 652 * It's called with the start and end virtual addresses of the kernel. We
653 * bootstrap the pmap allocator now. We will allocate the basic structures we 653 * bootstrap the pmap allocator now. We will allocate the basic structures we
654 * need to bootstrap the VM system here: the page frame tables, the TSB, and 654 * need to bootstrap the VM system here: the page frame tables, the TSB, and
655 * the free memory lists. 655 * the free memory lists.
656 * 656 *
657 * Now all this is becoming a bit obsolete. maxctx is still important, but by 657 * Now all this is becoming a bit obsolete. maxctx is still important, but by
658 * separating the kernel text and data segments we really would need to 658 * separating the kernel text and data segments we really would need to
659 * provide the start and end of each segment. But we can't. The rodata 659 * provide the start and end of each segment. But we can't. The rodata
660 * segment is attached to the end of the kernel segment and has nothing to 660 * segment is attached to the end of the kernel segment and has nothing to
661 * delimit its end. We could still pass in the beginning of the kernel and 661 * delimit its end. We could still pass in the beginning of the kernel and
662 * the beginning and end of the data segment but we could also just as easily 662 * the beginning and end of the data segment but we could also just as easily
663 * calculate that all in here. 663 * calculate that all in here.
664 * 664 *
665 * To handle the kernel text, we need to do a reverse mapping of the start of 665 * To handle the kernel text, we need to do a reverse mapping of the start of
666 * the kernel, then traverse the free memory lists to find out how big it is. 666 * the kernel, then traverse the free memory lists to find out how big it is.
667 */ 667 */
668 668
669void 669void
670pmap_bootstrap(u_long kernelstart, u_long kernelend) 670pmap_bootstrap(u_long kernelstart, u_long kernelend)
671{ 671{
672 extern char etext[], data_start[]; /* start of data segment */ 672 extern char etext[], data_start[]; /* start of data segment */
673 extern int msgbufmapped; 673 extern int msgbufmapped;
674 struct mem_region *mp, *mp1, *avail, *orig; 674 struct mem_region *mp, *mp1, *avail, *orig;
675 int i, j, pcnt, msgbufsiz; 675 int i, j, pcnt, msgbufsiz;
676 size_t s, sz; 676 size_t s, sz;
677 int64_t data; 677 int64_t data;
678 vaddr_t va, intstk; 678 vaddr_t va, intstk;
679 uint64_t phys_msgbuf; 679 uint64_t phys_msgbuf;
680 paddr_t newp = 0; 680 paddr_t newp = 0;
681 681
682 void *prom_memlist; 682 void *prom_memlist;
683 int prom_memlist_size; 683 int prom_memlist_size;
684 684
685 BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\n")); 685 BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\n"));
686 686
687 cache_setup_funcs(); 687 cache_setup_funcs();
688 688
689 /* 689 /*
690 * Calculate kernel size. 690 * Calculate kernel size.
691 */ 691 */
692 ktext = kernelstart; 692 ktext = kernelstart;
693 ktextp = pmap_kextract(ktext); 693 ktextp = pmap_kextract(ktext);
694 ektext = roundup((vaddr_t)etext, PAGE_SIZE_4M); 694 ektext = roundup((vaddr_t)etext, PAGE_SIZE_4M);
695 ektextp = roundup(pmap_kextract((vaddr_t)etext), PAGE_SIZE_4M); 695 ektextp = roundup(pmap_kextract((vaddr_t)etext), PAGE_SIZE_4M);
696 696
697 kdata = (vaddr_t)data_start; 697 kdata = (vaddr_t)data_start;
698 kdatap = pmap_kextract(kdata); 698 kdatap = pmap_kextract(kdata);
699 ekdata = roundup(kernelend, PAGE_SIZE_4M); 699 ekdata = roundup(kernelend, PAGE_SIZE_4M);
700 ekdatap = roundup(pmap_kextract(kernelend), PAGE_SIZE_4M); 700 ekdatap = roundup(pmap_kextract(kernelend), PAGE_SIZE_4M);
701 701
702 BDPRINTF(PDB_BOOT, ("Virtual layout: text %lx-%lx, data %lx-%lx.\n", 702 BDPRINTF(PDB_BOOT, ("Virtual layout: text %lx-%lx, data %lx-%lx.\n",
703 ktext, ektext, kdata, ekdata)); 703 ktext, ektext, kdata, ekdata));
704 BDPRINTF(PDB_BOOT, ("Physical layout: text %lx-%lx, data %lx-%lx.\n", 704 BDPRINTF(PDB_BOOT, ("Physical layout: text %lx-%lx, data %lx-%lx.\n",
705 ktextp, ektextp, kdatap, ekdatap)); 705 ktextp, ektextp, kdatap, ekdatap));
706 706
707 /* Initialize bootstrap allocator. */ 707 /* Initialize bootstrap allocator. */
708 kdata_alloc_init(kernelend + 1 * 1024 * 1024, ekdata); 708 kdata_alloc_init(kernelend + 1 * 1024 * 1024, ekdata);
709 709
710#ifdef DEBUG 710#ifdef DEBUG
711 pmap_bootdebug(); 711 pmap_bootdebug();
712#endif 712#endif
713 713
714 pmap_alloc_bootargs(); 714 pmap_alloc_bootargs();
715 pmap_mp_init(); 715 pmap_mp_init();
716 716
717 /* 717 /*
718 * set machine page size 718 * set machine page size
719 */ 719 */
720 uvmexp.pagesize = NBPG; 720 uvmexp.pagesize = NBPG;
721 uvmexp.ncolors = pmap_calculate_colors(); 721 uvmexp.ncolors = pmap_calculate_colors();
722 uvm_setpagesize(); 722 uvm_setpagesize();
723 723
724 /* 724 /*
725 * Get hold or the message buffer. 725 * Get hold or the message buffer.
726 */ 726 */
727 msgbufp = (struct kern_msgbuf *)(vaddr_t)MSGBUF_VA; 727 msgbufp = (struct kern_msgbuf *)(vaddr_t)MSGBUF_VA;
728/* XXXXX -- increase msgbufsiz for uvmhist printing */ 728/* XXXXX -- increase msgbufsiz for uvmhist printing */
729 msgbufsiz = 4*PAGE_SIZE /* round_page(sizeof(struct msgbuf)) */; 729 msgbufsiz = 4*PAGE_SIZE /* round_page(sizeof(struct msgbuf)) */;
730 BDPRINTF(PDB_BOOT, ("Trying to allocate msgbuf at %lx, size %lx\n", 730 BDPRINTF(PDB_BOOT, ("Trying to allocate msgbuf at %lx, size %lx\n",
731 (long)msgbufp, (long)msgbufsiz)); 731 (long)msgbufp, (long)msgbufsiz));
732 if ((long)msgbufp != 732 if ((long)msgbufp !=
733 (long)(phys_msgbuf = prom_claim_virt((vaddr_t)msgbufp, msgbufsiz))) 733 (long)(phys_msgbuf = prom_claim_virt((vaddr_t)msgbufp, msgbufsiz)))
734 prom_printf( 734 prom_printf(
735 "cannot get msgbuf VA, msgbufp=%p, phys_msgbuf=%lx\n", 735 "cannot get msgbuf VA, msgbufp=%p, phys_msgbuf=%lx\n",
736 (void *)msgbufp, (long)phys_msgbuf); 736 (void *)msgbufp, (long)phys_msgbuf);
737 phys_msgbuf = prom_get_msgbuf(msgbufsiz, MMU_PAGE_ALIGN); 737 phys_msgbuf = prom_get_msgbuf(msgbufsiz, MMU_PAGE_ALIGN);
738 BDPRINTF(PDB_BOOT, 738 BDPRINTF(PDB_BOOT,
739 ("We should have the memory at %lx, let's map it in\n", 739 ("We should have the memory at %lx, let's map it in\n",
740 phys_msgbuf)); 740 phys_msgbuf));
741 if (prom_map_phys(phys_msgbuf, msgbufsiz, (vaddr_t)msgbufp, 741 if (prom_map_phys(phys_msgbuf, msgbufsiz, (vaddr_t)msgbufp,
742 -1/* sunos does this */) == -1) { 742 -1/* sunos does this */) == -1) {
743 prom_printf("Failed to map msgbuf\n"); 743 prom_printf("Failed to map msgbuf\n");
744 } else { 744 } else {
745 BDPRINTF(PDB_BOOT, ("msgbuf mapped at %p\n", 745 BDPRINTF(PDB_BOOT, ("msgbuf mapped at %p\n",
746 (void *)msgbufp)); 746 (void *)msgbufp));
747 } 747 }
748 msgbufmapped = 1; /* enable message buffer */ 748 msgbufmapped = 1; /* enable message buffer */
749 initmsgbuf((void *)msgbufp, msgbufsiz); 749 initmsgbuf((void *)msgbufp, msgbufsiz);
750 750
751 /* 751 /*
752 * Find out how much RAM we have installed. 752 * Find out how much RAM we have installed.
753 */ 753 */
754 BDPRINTF(PDB_BOOT, ("pmap_bootstrap: getting phys installed\n")); 754 BDPRINTF(PDB_BOOT, ("pmap_bootstrap: getting phys installed\n"));
755 pmap_read_memlist("/memory", "reg", &prom_memlist, &prom_memlist_size, 755 pmap_read_memlist("/memory", "reg", &prom_memlist, &prom_memlist_size,
756 kdata_alloc); 756 kdata_alloc);
757 phys_installed = prom_memlist; 757 phys_installed = prom_memlist;
758 phys_installed_size = prom_memlist_size / sizeof(*phys_installed); 758 phys_installed_size = prom_memlist_size / sizeof(*phys_installed);
759 759
760#ifdef DEBUG 760#ifdef DEBUG
761 if (pmapdebug & PDB_BOOT1) { 761 if (pmapdebug & PDB_BOOT1) {
762 /* print out mem list */ 762 /* print out mem list */
763 prom_printf("Installed physical memory:\n"); 763 prom_printf("Installed physical memory:\n");
764 for (i = 0; i < phys_installed_size; i++) { 764 for (i = 0; i < phys_installed_size; i++) {
765 prom_printf("memlist start %lx size %lx\n", 765 prom_printf("memlist start %lx size %lx\n",
766 (u_long)phys_installed[i].start, 766 (u_long)phys_installed[i].start,
767 (u_long)phys_installed[i].size); 767 (u_long)phys_installed[i].size);
768 } 768 }
769 } 769 }
770#endif 770#endif
771 771
772 BDPRINTF(PDB_BOOT1, ("Calculating physmem:")); 772 BDPRINTF(PDB_BOOT1, ("Calculating physmem:"));
773 for (i = 0; i < phys_installed_size; i++) 773 for (i = 0; i < phys_installed_size; i++)
774 physmem += btoc(phys_installed[i].size); 774 physmem += btoc(phys_installed[i].size);
775 BDPRINTF(PDB_BOOT1, (" result %x or %d pages\n", 775 BDPRINTF(PDB_BOOT1, (" result %x or %d pages\n",
776 (int)physmem, (int)physmem)); 776 (int)physmem, (int)physmem));
777 777
778 /* 778 /*
779 * Calculate approx TSB size. This probably needs tweaking. 779 * Calculate approx TSB size. This probably needs tweaking.
780 */ 780 */
781 if (physmem < btoc(64 * 1024 * 1024)) 781 if (physmem < btoc(64 * 1024 * 1024))
782 tsbsize = 0; 782 tsbsize = 0;
783 else if (physmem < btoc(512 * 1024 * 1024)) 783 else if (physmem < btoc(512 * 1024 * 1024))
784 tsbsize = 1; 784 tsbsize = 1;
785 else 785 else
786 tsbsize = 2; 786 tsbsize = 2;
787 787
788 /* 788 /*
789 * Save the prom translations 789 * Save the prom translations
790 */ 790 */
791 pmap_read_memlist("/virtual-memory", "translations", &prom_memlist, 791 pmap_read_memlist("/virtual-memory", "translations", &prom_memlist,
792 &prom_memlist_size, kdata_alloc); 792 &prom_memlist_size, kdata_alloc);
793 prom_map = prom_memlist; 793 prom_map = prom_memlist;
794 prom_map_size = prom_memlist_size / sizeof(struct prom_map); 794 prom_map_size = prom_memlist_size / sizeof(struct prom_map);
795 795
796#ifdef DEBUG 796#ifdef DEBUG
797 if (pmapdebug & PDB_BOOT) { 797 if (pmapdebug & PDB_BOOT) {
798 /* print out mem list */ 798 /* print out mem list */
799 prom_printf("Prom xlations:\n"); 799 prom_printf("Prom xlations:\n");
800 for (i = 0; i < prom_map_size; i++) { 800 for (i = 0; i < prom_map_size; i++) {
801 prom_printf("start %016lx size %016lx tte %016lx\n", 801 prom_printf("start %016lx size %016lx tte %016lx\n",
802 (u_long)prom_map[i].vstart, 802 (u_long)prom_map[i].vstart,
803 (u_long)prom_map[i].vsize, 803 (u_long)prom_map[i].vsize,
804 (u_long)prom_map[i].tte); 804 (u_long)prom_map[i].tte);
805 } 805 }
806 prom_printf("End of prom xlations\n"); 806 prom_printf("End of prom xlations\n");
807 } 807 }
808#endif 808#endif
809 809
810 /* 810 /*
811 * Here's a quick in-lined reverse bubble sort. It gets rid of 811 * Here's a quick in-lined reverse bubble sort. It gets rid of
812 * any translations inside the kernel data VA range. 812 * any translations inside the kernel data VA range.
813 */ 813 */
814 for (i = 0; i < prom_map_size; i++) { 814 for (i = 0; i < prom_map_size; i++) {
815 for (j = i; j < prom_map_size; j++) { 815 for (j = i; j < prom_map_size; j++) {
816 if (prom_map[j].vstart > prom_map[i].vstart) { 816 if (prom_map[j].vstart > prom_map[i].vstart) {
817 struct prom_map tmp; 817 struct prom_map tmp;
818 818
819 tmp = prom_map[i]; 819 tmp = prom_map[i];
820 prom_map[i] = prom_map[j]; 820 prom_map[i] = prom_map[j];
821 prom_map[j] = tmp; 821 prom_map[j] = tmp;
822 } 822 }
823 } 823 }
824 } 824 }
825#ifdef DEBUG 825#ifdef DEBUG
826 if (pmapdebug & PDB_BOOT) { 826 if (pmapdebug & PDB_BOOT) {
827 /* print out mem list */ 827 /* print out mem list */
828 prom_printf("Prom xlations:\n"); 828 prom_printf("Prom xlations:\n");
829 for (i = 0; i < prom_map_size; i++) { 829 for (i = 0; i < prom_map_size; i++) {
830 prom_printf("start %016lx size %016lx tte %016lx\n", 830 prom_printf("start %016lx size %016lx tte %016lx\n",
831 (u_long)prom_map[i].vstart, 831 (u_long)prom_map[i].vstart,
832 (u_long)prom_map[i].vsize, 832 (u_long)prom_map[i].vsize,
833 (u_long)prom_map[i].tte); 833 (u_long)prom_map[i].tte);
834 } 834 }
835 prom_printf("End of prom xlations\n"); 835 prom_printf("End of prom xlations\n");
836 } 836 }
837#endif 837#endif
838 838
839 /* 839 /*
840 * Allocate a ncpu*64KB page for the cpu_info & stack structure now. 840 * Allocate a ncpu*64KB page for the cpu_info & stack structure now.
841 */ 841 */
842 cpu0paddr = prom_alloc_phys(8 * PAGE_SIZE * sparc_ncpus, 8 * PAGE_SIZE); 842 cpu0paddr = prom_alloc_phys(8 * PAGE_SIZE * sparc_ncpus, 8 * PAGE_SIZE);
843 if (cpu0paddr == 0) { 843 if (cpu0paddr == 0) {
844 prom_printf("Cannot allocate cpu_infos\n"); 844 prom_printf("Cannot allocate cpu_infos\n");
845 prom_halt(); 845 prom_halt();
846 } 846 }
847 847
848 /* 848 /*
849 * Now the kernel text segment is in its final location we can try to 849 * Now the kernel text segment is in its final location we can try to
850 * find out how much memory really is free. 850 * find out how much memory really is free.
851 */ 851 */
852 pmap_read_memlist("/memory", "available", &prom_memlist, 852 pmap_read_memlist("/memory", "available", &prom_memlist,
853 &prom_memlist_size, kdata_alloc); 853 &prom_memlist_size, kdata_alloc);
854 orig = prom_memlist; 854 orig = prom_memlist;
855 sz = prom_memlist_size; 855 sz = prom_memlist_size;
856 pcnt = prom_memlist_size / sizeof(*orig); 856 pcnt = prom_memlist_size / sizeof(*orig);
857 857
858 BDPRINTF(PDB_BOOT1, ("Available physical memory:\n")); 858 BDPRINTF(PDB_BOOT1, ("Available physical memory:\n"));
859 avail = (struct mem_region*)kdata_alloc(sz, sizeof(uint64_t)); 859 avail = (struct mem_region*)kdata_alloc(sz, sizeof(uint64_t));
860 for (i = 0; i < pcnt; i++) { 860 for (i = 0; i < pcnt; i++) {
861 avail[i] = orig[i]; 861 avail[i] = orig[i];
862 BDPRINTF(PDB_BOOT1, ("memlist start %lx size %lx\n", 862 BDPRINTF(PDB_BOOT1, ("memlist start %lx size %lx\n",
863 (u_long)orig[i].start, 863 (u_long)orig[i].start,
864 (u_long)orig[i].size)); 864 (u_long)orig[i].size));
865 } 865 }
866 BDPRINTF(PDB_BOOT1, ("End of available physical memory\n")); 866 BDPRINTF(PDB_BOOT1, ("End of available physical memory\n"));
867 867
868 BDPRINTF(PDB_BOOT, ("ktext %08lx[%08lx] - %08lx[%08lx] : " 868 BDPRINTF(PDB_BOOT, ("ktext %08lx[%08lx] - %08lx[%08lx] : "
869 "kdata %08lx[%08lx] - %08lx[%08lx]\n", 869 "kdata %08lx[%08lx] - %08lx[%08lx]\n",
870 (u_long)ktext, (u_long)ktextp, 870 (u_long)ktext, (u_long)ktextp,
871 (u_long)ektext, (u_long)ektextp, 871 (u_long)ektext, (u_long)ektextp,
872 (u_long)kdata, (u_long)kdatap, 872 (u_long)kdata, (u_long)kdatap,
873 (u_long)ekdata, (u_long)ekdatap)); 873 (u_long)ekdata, (u_long)ekdatap));
874#ifdef DEBUG 874#ifdef DEBUG
875 if (pmapdebug & PDB_BOOT1) { 875 if (pmapdebug & PDB_BOOT1) {
876 /* print out mem list */ 876 /* print out mem list */
877 prom_printf("Available %lx physical memory before cleanup:\n", 877 prom_printf("Available %lx physical memory before cleanup:\n",
878 (u_long)avail); 878 (u_long)avail);
879 for (i = 0; i < pcnt; i++) { 879 for (i = 0; i < pcnt; i++) {
880 prom_printf("memlist start %lx size %lx\n", 880 prom_printf("memlist start %lx size %lx\n",
881 (u_long)avail[i].start, 881 (u_long)avail[i].start,
882 (u_long)avail[i].size); 882 (u_long)avail[i].size);
883 } 883 }
884 prom_printf("End of available physical memory before cleanup\n"); 884 prom_printf("End of available physical memory before cleanup\n");
885 prom_printf("kernel physical text size %08lx - %08lx\n", 885 prom_printf("kernel physical text size %08lx - %08lx\n",
886 (u_long)ktextp, (u_long)ektextp); 886 (u_long)ktextp, (u_long)ektextp);
887 prom_printf("kernel physical data size %08lx - %08lx\n", 887 prom_printf("kernel physical data size %08lx - %08lx\n",
888 (u_long)kdatap, (u_long)ekdatap); 888 (u_long)kdatap, (u_long)ekdatap);
889 } 889 }
890#endif 890#endif
891 /* 891 /*
892 * Here's a another quick in-lined bubble sort. 892 * Here's a another quick in-lined bubble sort.
893 */ 893 */
894 for (i = 0; i < pcnt; i++) { 894 for (i = 0; i < pcnt; i++) {
895 for (j = i; j < pcnt; j++) { 895 for (j = i; j < pcnt; j++) {
896 if (avail[j].start < avail[i].start) { 896 if (avail[j].start < avail[i].start) {
897 struct mem_region tmp; 897 struct mem_region tmp;
898 tmp = avail[i]; 898 tmp = avail[i];
899 avail[i] = avail[j]; 899 avail[i] = avail[j];
900 avail[j] = tmp; 900 avail[j] = tmp;
901 } 901 }
902 } 902 }
903 } 903 }
904 904
905 /* Throw away page zero if we have it. */ 905 /* Throw away page zero if we have it. */
906 if (avail->start == 0) { 906 if (avail->start == 0) {
907 avail->start += PAGE_SIZE; 907 avail->start += PAGE_SIZE;
908 avail->size -= PAGE_SIZE; 908 avail->size -= PAGE_SIZE;
909 } 909 }
910 910
911 /* 911 /*
912 * Now we need to remove the area we valloc'ed from the available 912 * Now we need to remove the area we valloc'ed from the available
913 * memory lists. (NB: we may have already alloc'ed the entire space). 913 * memory lists. (NB: we may have already alloc'ed the entire space).
914 */ 914 */
915 npgs = 0; 915 npgs = 0;
916 for (mp = avail, i = 0; i < pcnt; i++, mp = &avail[i]) { 916 for (mp = avail, i = 0; i < pcnt; i++, mp = &avail[i]) {
917 /* 917 /*
918 * Now page align the start of the region. 918 * Now page align the start of the region.
919 */ 919 */
920 s = mp->start % PAGE_SIZE; 920 s = mp->start % PAGE_SIZE;
921 if (mp->size >= s) { 921 if (mp->size >= s) {
922 mp->size -= s; 922 mp->size -= s;
923 mp->start += s; 923 mp->start += s;
924 } 924 }
925 /* 925 /*
926 * And now align the size of the region. 926 * And now align the size of the region.
927 */ 927 */
928 mp->size -= mp->size % PAGE_SIZE; 928 mp->size -= mp->size % PAGE_SIZE;
929 /* 929 /*
930 * Check whether some memory is left here. 930 * Check whether some memory is left here.
931 */ 931 */
932 if (mp->size == 0) { 932 if (mp->size == 0) {
933 memcpy(mp, mp + 1, 933 memcpy(mp, mp + 1,
934 (pcnt - (mp - avail)) * sizeof *mp); 934 (pcnt - (mp - avail)) * sizeof *mp);
935 pcnt--; 935 pcnt--;
936 mp--; 936 mp--;
937 continue; 937 continue;
938 } 938 }
939 s = mp->start; 939 s = mp->start;
940 sz = mp->size; 940 sz = mp->size;
941 npgs += btoc(sz); 941 npgs += btoc(sz);
942 for (mp1 = avail; mp1 < mp; mp1++) 942 for (mp1 = avail; mp1 < mp; mp1++)
943 if (s < mp1->start) 943 if (s < mp1->start)
944 break; 944 break;
945 if (mp1 < mp) { 945 if (mp1 < mp) {
946 memcpy(mp1 + 1, mp1, (char *)mp - (char *)mp1); 946 memcpy(mp1 + 1, mp1, (char *)mp - (char *)mp1);
947 mp1->start = s; 947 mp1->start = s;
948 mp1->size = sz; 948 mp1->size = sz;
949 } 949 }
950#ifdef DEBUG 950#ifdef DEBUG
951/* Clear all memory we give to the VM system. I want to make sure 951/* Clear all memory we give to the VM system. I want to make sure
952 * the PROM isn't using it for something, so this should break the PROM. 952 * the PROM isn't using it for something, so this should break the PROM.
953 */ 953 */
954 954
955/* Calling pmap_zero_page() at this point also hangs some machines 955/* Calling pmap_zero_page() at this point also hangs some machines
956 * so don't do it at all. -- pk 26/02/2002 956 * so don't do it at all. -- pk 26/02/2002
957 */ 957 */
958#if 0 958#if 0
959 { 959 {
960 paddr_t p; 960 paddr_t p;
961 for (p = mp->start; p < mp->start+mp->size; 961 for (p = mp->start; p < mp->start+mp->size;
962 p += PAGE_SIZE) 962 p += PAGE_SIZE)
963 pmap_zero_page(p); 963 pmap_zero_page(p);
964 } 964 }
965#endif 965#endif
966#endif /* DEBUG */ 966#endif /* DEBUG */
967 /* 967 /*
968 * In future we should be able to specify both allocated 968 * In future we should be able to specify both allocated
969 * and free. 969 * and free.
970 */ 970 */
971 BDPRINTF(PDB_BOOT1, ("uvm_page_physload(%lx, %lx)\n", 971 BDPRINTF(PDB_BOOT1, ("uvm_page_physload(%lx, %lx)\n",
972 (long)mp->start, 972 (long)mp->start,
973 (long)(mp->start + mp->size))); 973 (long)(mp->start + mp->size)));
974 uvm_page_physload( 974 uvm_page_physload(
975 atop(mp->start), 975 atop(mp->start),
976 atop(mp->start+mp->size), 976 atop(mp->start+mp->size),
977 atop(mp->start), 977 atop(mp->start),
978 atop(mp->start+mp->size), 978 atop(mp->start+mp->size),
979 VM_FREELIST_DEFAULT); 979 VM_FREELIST_DEFAULT);
980 } 980 }
981 981
982#ifdef DEBUG 982#ifdef DEBUG
983 if (pmapdebug & PDB_BOOT) { 983 if (pmapdebug & PDB_BOOT) {
984 /* print out mem list */ 984 /* print out mem list */
985 prom_printf("Available physical memory after cleanup:\n"); 985 prom_printf("Available physical memory after cleanup:\n");
986 for (i = 0; i < pcnt; i++) { 986 for (i = 0; i < pcnt; i++) {
987 prom_printf("avail start %lx size %lx\n", 987 prom_printf("avail start %lx size %lx\n",
988 (long)avail[i].start, (long)avail[i].size); 988 (long)avail[i].start, (long)avail[i].size);
989 } 989 }
990 prom_printf("End of available physical memory after cleanup\n"); 990 prom_printf("End of available physical memory after cleanup\n");
991 } 991 }
992#endif 992#endif
993 /* 993 /*
994 * Allocate and clear out pmap_kernel()->pm_segs[] 994 * Allocate and clear out pmap_kernel()->pm_segs[]
995 */ 995 */
996 pmap_kernel()->pm_refs = 1; 996 pmap_kernel()->pm_refs = 1;
997 memset(&pmap_kernel()->pm_ctx, 0, sizeof(pmap_kernel()->pm_ctx)); 997 memset(&pmap_kernel()->pm_ctx, 0, sizeof(pmap_kernel()->pm_ctx));
998 998
999 /* Throw away page zero */ 999 /* Throw away page zero */
1000 do { 1000 do {
1001 pmap_get_page(&newp); 1001 pmap_get_page(&newp);
1002 } while (!newp); 1002 } while (!newp);
1003 pmap_kernel()->pm_segs=(paddr_t *)(u_long)newp; 1003 pmap_kernel()->pm_segs=(paddr_t *)(u_long)newp;
1004 pmap_kernel()->pm_physaddr = newp; 1004 pmap_kernel()->pm_physaddr = newp;
1005 1005
1006 /* 1006 /*
1007 * finish filling out kernel pmap. 1007 * finish filling out kernel pmap.
1008 */ 1008 */
1009 1009
1010 BDPRINTF(PDB_BOOT, ("pmap_kernel()->pm_physaddr = %lx\n", 1010 BDPRINTF(PDB_BOOT, ("pmap_kernel()->pm_physaddr = %lx\n",
1011 (long)pmap_kernel()->pm_physaddr)); 1011 (long)pmap_kernel()->pm_physaddr));
1012 /* 1012 /*
1013 * Tell pmap about our mesgbuf -- Hope this works already 1013 * Tell pmap about our mesgbuf -- Hope this works already
1014 */ 1014 */
1015#ifdef DEBUG 1015#ifdef DEBUG
1016 BDPRINTF(PDB_BOOT1, ("Calling consinit()\n")); 1016 BDPRINTF(PDB_BOOT1, ("Calling consinit()\n"));
1017 if (pmapdebug & PDB_BOOT1) 1017 if (pmapdebug & PDB_BOOT1)
1018 consinit(); 1018 consinit();
1019 BDPRINTF(PDB_BOOT1, ("Inserting mesgbuf into pmap_kernel()\n")); 1019 BDPRINTF(PDB_BOOT1, ("Inserting mesgbuf into pmap_kernel()\n"));
1020#endif 1020#endif
1021 /* it's not safe to call pmap_enter so we need to do this ourselves */ 1021 /* it's not safe to call pmap_enter so we need to do this ourselves */
1022 va = (vaddr_t)msgbufp; 1022 va = (vaddr_t)msgbufp;
1023 prom_map_phys(phys_msgbuf, msgbufsiz, (vaddr_t)msgbufp, -1); 1023 prom_map_phys(phys_msgbuf, msgbufsiz, (vaddr_t)msgbufp, -1);
1024 while (msgbufsiz) { 1024 while (msgbufsiz) {
1025 data = TSB_DATA(0 /* global */, 1025 data = TSB_DATA(0 /* global */,
1026 PGSZ_8K, 1026 PGSZ_8K,
1027 phys_msgbuf, 1027 phys_msgbuf,
1028 1 /* priv */, 1028 1 /* priv */,
1029 1 /* Write */, 1029 1 /* Write */,
1030 1 /* Cacheable */, 1030 1 /* Cacheable */,
1031 FORCE_ALIAS /* ALIAS -- Disable D$ */, 1031 FORCE_ALIAS /* ALIAS -- Disable D$ */,
1032 1 /* valid */, 1032 1 /* valid */,
1033 0 /* IE */); 1033 0 /* IE */);
1034 pmap_enter_kpage(va, data); 1034 pmap_enter_kpage(va, data);
1035 va += PAGE_SIZE; 1035 va += PAGE_SIZE;
1036 msgbufsiz -= PAGE_SIZE; 1036 msgbufsiz -= PAGE_SIZE;
1037 phys_msgbuf += PAGE_SIZE; 1037 phys_msgbuf += PAGE_SIZE;
1038 } 1038 }
1039 BDPRINTF(PDB_BOOT1, ("Done inserting mesgbuf into pmap_kernel()\n")); 1039 BDPRINTF(PDB_BOOT1, ("Done inserting mesgbuf into pmap_kernel()\n"));
1040 1040
1041 BDPRINTF(PDB_BOOT1, ("Inserting PROM mappings into pmap_kernel()\n")); 1041 BDPRINTF(PDB_BOOT1, ("Inserting PROM mappings into pmap_kernel()\n"));
1042 for (i = 0; i < prom_map_size; i++) 1042 for (i = 0; i < prom_map_size; i++)
1043 if (prom_map[i].vstart && ((prom_map[i].vstart >> 32) == 0)) 1043 if (prom_map[i].vstart && ((prom_map[i].vstart >> 32) == 0))
1044 for (j = 0; j < prom_map[i].vsize; j += PAGE_SIZE) { 1044 for (j = 0; j < prom_map[i].vsize; j += PAGE_SIZE) {
1045 int k; 1045 int k;
1046 1046
1047 for (k = 0; page_size_map[k].mask; k++) { 1047 for (k = 0; page_size_map[k].mask; k++) {
1048 if (((prom_map[i].vstart | 1048 if (((prom_map[i].vstart |
1049 prom_map[i].tte) & 1049 prom_map[i].tte) &
1050 page_size_map[k].mask) == 0 && 1050 page_size_map[k].mask) == 0 &&
1051 page_size_map[k].mask < 1051 page_size_map[k].mask <
1052 prom_map[i].vsize) 1052 prom_map[i].vsize)
1053 break; 1053 break;
1054 } 1054 }
1055#ifdef DEBUG 1055#ifdef DEBUG
1056 page_size_map[k].use++; 1056 page_size_map[k].use++;
1057#endif 1057#endif
1058 /* Enter PROM map into pmap_kernel() */ 1058 /* Enter PROM map into pmap_kernel() */
1059 pmap_enter_kpage(prom_map[i].vstart + j, 1059 pmap_enter_kpage(prom_map[i].vstart + j,
1060 (prom_map[i].tte + j) | TLB_EXEC | 1060 (prom_map[i].tte + j) | TLB_EXEC |
1061 page_size_map[k].code); 1061 page_size_map[k].code);
1062 } 1062 }
1063 BDPRINTF(PDB_BOOT1, ("Done inserting PROM mappings into pmap_kernel()\n")); 1063 BDPRINTF(PDB_BOOT1, ("Done inserting PROM mappings into pmap_kernel()\n"));
1064 1064
1065 /* 1065 /*
1066 * Fix up start of kernel heap. 1066 * Fix up start of kernel heap.
1067 */ 1067 */
1068 vmmap = (vaddr_t)roundup(ekdata, 4*MEG); 1068 vmmap = (vaddr_t)roundup(ekdata, 4*MEG);
1069 /* Let's keep 1 page of redzone after the kernel */ 1069 /* Let's keep 1 page of redzone after the kernel */
1070 vmmap += PAGE_SIZE; 1070 vmmap += PAGE_SIZE;
1071 { 1071 {
1072 extern void main(void); 1072 extern void main(void);
1073 vaddr_t u0va; 1073 vaddr_t u0va;
1074 paddr_t pa; 1074 paddr_t pa;
1075 1075
1076 u0va = vmmap; 1076 u0va = vmmap;
1077 1077
1078 BDPRINTF(PDB_BOOT1, 1078 BDPRINTF(PDB_BOOT1,
1079 ("Inserting lwp0 USPACE into pmap_kernel() at %p\n", 1079 ("Inserting lwp0 USPACE into pmap_kernel() at %p\n",
1080 vmmap)); 1080 vmmap));
1081 1081
1082 while (vmmap < u0va + 2*USPACE) { 1082 while (vmmap < u0va + 2*USPACE) {
1083 int64_t data1; 1083 int64_t data1;
1084 1084
1085 if (!pmap_get_page(&pa)) 1085 if (!pmap_get_page(&pa))
1086 panic("pmap_bootstrap: no pages"); 1086 panic("pmap_bootstrap: no pages");
1087 prom_map_phys(pa, PAGE_SIZE, vmmap, -1); 1087 prom_map_phys(pa, PAGE_SIZE, vmmap, -1);
1088 data1 = TSB_DATA(0 /* global */, 1088 data1 = TSB_DATA(0 /* global */,
1089 PGSZ_8K, 1089 PGSZ_8K,
1090 pa, 1090 pa,
1091 1 /* priv */, 1091 1 /* priv */,
1092 1 /* Write */, 1092 1 /* Write */,
1093 1 /* Cacheable */, 1093 1 /* Cacheable */,
1094 FORCE_ALIAS /* ALIAS -- Disable D$ */, 1094 FORCE_ALIAS /* ALIAS -- Disable D$ */,
1095 1 /* valid */, 1095 1 /* valid */,
1096 0 /* IE */); 1096 0 /* IE */);
1097 pmap_enter_kpage(vmmap, data1); 1097 pmap_enter_kpage(vmmap, data1);
1098 vmmap += PAGE_SIZE; 1098 vmmap += PAGE_SIZE;
1099 } 1099 }
1100 BDPRINTF(PDB_BOOT1, 1100 BDPRINTF(PDB_BOOT1,
1101 ("Done inserting stack 0 into pmap_kernel()\n")); 1101 ("Done inserting stack 0 into pmap_kernel()\n"));
1102 1102
1103 /* Now map in and initialize our cpu_info structure */ 1103 /* Now map in and initialize our cpu_info structure */
1104#ifdef DIAGNOSTIC 1104#ifdef DIAGNOSTIC
1105 vmmap += PAGE_SIZE; /* redzone -- XXXX do we need one? */ 1105 vmmap += PAGE_SIZE; /* redzone -- XXXX do we need one? */
1106#endif 1106#endif
1107 if ((vmmap ^ INTSTACK) & VA_ALIAS_MASK) 1107 if ((vmmap ^ INTSTACK) & VA_ALIAS_MASK)
1108 vmmap += PAGE_SIZE; /* Matchup virtual color for D$ */ 1108 vmmap += PAGE_SIZE; /* Matchup virtual color for D$ */
1109 intstk = vmmap; 1109 intstk = vmmap;
1110 cpus = (struct cpu_info *)(intstk + CPUINFO_VA - INTSTACK); 1110 cpus = (struct cpu_info *)(intstk + CPUINFO_VA - INTSTACK);
1111 1111
1112 BDPRINTF(PDB_BOOT1, 1112 BDPRINTF(PDB_BOOT1,
1113 ("Inserting cpu_info into pmap_kernel() at %p\n", 1113 ("Inserting cpu_info into pmap_kernel() at %p\n",
1114 cpus)); 1114 cpus));
1115 /* Now map in all 8 pages of interrupt stack/cpu_info */ 1115 /* Now map in all 8 pages of interrupt stack/cpu_info */
1116 pa = cpu0paddr; 1116 pa = cpu0paddr;
1117 prom_map_phys(pa, 64*KB, vmmap, -1); 1117 prom_map_phys(pa, 64*KB, vmmap, -1);
1118 1118
1119 /* 1119 /*
1120 * Also map it in as the interrupt stack. 1120 * Also map it in as the interrupt stack.
1121 * This lets the PROM see this if needed. 1121 * This lets the PROM see this if needed.
1122 * 1122 *
1123 * XXXX locore.s does not flush these mappings 1123 * XXXX locore.s does not flush these mappings
1124 * before installing the locked TTE. 1124 * before installing the locked TTE.
1125 */ 1125 */
1126 prom_map_phys(pa, 64*KB, INTSTACK, -1); 1126 prom_map_phys(pa, 64*KB, INTSTACK, -1);
1127 for (i = 0; i < 8; i++) { 1127 for (i = 0; i < 8; i++) {
1128 int64_t data1; 1128 int64_t data1;
1129 1129
1130 data1 = TSB_DATA(0 /* global */, 1130 data1 = TSB_DATA(0 /* global */,
1131 PGSZ_8K, 1131 PGSZ_8K,
1132 pa, 1132 pa,
1133 1 /* priv */, 1133 1 /* priv */,
1134 1 /* Write */, 1134 1 /* Write */,
1135 1 /* Cacheable */, 1135 1 /* Cacheable */,
1136 FORCE_ALIAS /* ALIAS -- Disable D$ */, 1136 FORCE_ALIAS /* ALIAS -- Disable D$ */,
1137 1 /* valid */, 1137 1 /* valid */,
1138 0 /* IE */); 1138 0 /* IE */);
1139 pmap_enter_kpage(vmmap, data1); 1139 pmap_enter_kpage(vmmap, data1);
1140 vmmap += PAGE_SIZE; 1140 vmmap += PAGE_SIZE;
1141 pa += PAGE_SIZE; 1141 pa += PAGE_SIZE;
1142 } 1142 }
1143 BDPRINTF(PDB_BOOT1, ("Initializing cpu_info\n")); 1143 BDPRINTF(PDB_BOOT1, ("Initializing cpu_info\n"));
1144 1144
1145 /* Initialize our cpu_info structure */ 1145 /* Initialize our cpu_info structure */
1146 memset((void *)intstk, 0, 64 * KB); 1146 memset((void *)intstk, 0, 64 * KB);
1147 cpus->ci_self = cpus; 1147 cpus->ci_self = cpus;
1148 cpus->ci_next = NULL; 1148 cpus->ci_next = NULL;
1149 cpus->ci_curlwp = &lwp0; 1149 cpus->ci_curlwp = &lwp0;
1150 cpus->ci_flags = CPUF_PRIMARY; 1150 cpus->ci_flags = CPUF_PRIMARY;
1151 cpus->ci_cpuid = CPU_UPAID; 1151 cpus->ci_cpuid = CPU_UPAID;
1152 cpus->ci_fplwp = NULL; 1152 cpus->ci_fplwp = NULL;
1153 cpus->ci_eintstack = NULL; 1153 cpus->ci_eintstack = NULL;
1154 cpus->ci_spinup = main; /* Call main when we're running. */ 1154 cpus->ci_spinup = main; /* Call main when we're running. */
1155 cpus->ci_paddr = cpu0paddr; 1155 cpus->ci_paddr = cpu0paddr;
1156 cpus->ci_cpcb = (struct pcb *)u0va; 1156 cpus->ci_cpcb = (struct pcb *)u0va;
1157 cpus->ci_idepth = -1; 1157 cpus->ci_idepth = -1;
1158 memset(cpus->ci_intrpending, -1, sizeof(cpus->ci_intrpending)); 1158 memset(cpus->ci_intrpending, -1, sizeof(cpus->ci_intrpending));
1159 1159
1160 uvm_lwp_setuarea(&lwp0, u0va); 1160 uvm_lwp_setuarea(&lwp0, u0va);
1161 lwp0.l_md.md_tf = (struct trapframe64*)(u0va + USPACE 1161 lwp0.l_md.md_tf = (struct trapframe64*)(u0va + USPACE
1162 - sizeof(struct trapframe64)); 1162 - sizeof(struct trapframe64));
1163 1163
1164 cpu0paddr += 64 * KB; 1164 cpu0paddr += 64 * KB;
1165 1165
1166 CPUSET_CLEAR(cpus_active); 1166 CPUSET_CLEAR(cpus_active);
1167 CPUSET_ADD(cpus_active, 0); 1167 CPUSET_ADD(cpus_active, 0);
1168 1168
1169 cpu_pmap_prepare(cpus, true); 1169 cpu_pmap_prepare(cpus, true);
1170 cpu_pmap_init(cpus); 1170 cpu_pmap_init(cpus);
1171 1171
1172 /* The rest will be done at CPU attach time. */ 1172 /* The rest will be done at CPU attach time. */
1173 BDPRINTF(PDB_BOOT1, 1173 BDPRINTF(PDB_BOOT1,
1174 ("Done inserting cpu_info into pmap_kernel()\n")); 1174 ("Done inserting cpu_info into pmap_kernel()\n"));
1175 } 1175 }
1176 1176
1177 vmmap = (vaddr_t)reserve_dumppages((void *)(u_long)vmmap); 1177 vmmap = (vaddr_t)reserve_dumppages((void *)(u_long)vmmap);
1178 1178
1179 /* 1179 /*
1180 * Set up bounds of allocatable memory for vmstat et al. 1180 * Set up bounds of allocatable memory for vmstat et al.
1181 */ 1181 */
1182 avail_start = avail->start; 1182 avail_start = avail->start;
1183 for (mp = avail; mp->size; mp++) 1183 for (mp = avail; mp->size; mp++)
1184 avail_end = mp->start+mp->size; 1184 avail_end = mp->start+mp->size;
1185 1185
1186 BDPRINTF(PDB_BOOT1, ("Finished pmap_bootstrap()\n")); 1186 BDPRINTF(PDB_BOOT1, ("Finished pmap_bootstrap()\n"));
1187 1187
1188 BDPRINTF(PDB_BOOT, ("left kdata: %" PRId64 " @%" PRIx64 ".\n", 1188 BDPRINTF(PDB_BOOT, ("left kdata: %" PRId64 " @%" PRIx64 ".\n",
1189 kdata_mem_pool.size, kdata_mem_pool.start)); 1189 kdata_mem_pool.size, kdata_mem_pool.start));
1190} 1190}
1191 1191
1192/* 1192/*
1193 * Allocate TSBs for both mmus from the locked kernel data segment page. 1193 * Allocate TSBs for both mmus from the locked kernel data segment page.
1194 * This is run before the cpu itself is activated (or by the first cpu 1194 * This is run before the cpu itself is activated (or by the first cpu
1195 * itself) 1195 * itself)
1196 */ 1196 */
1197void 1197void
1198cpu_pmap_prepare(struct cpu_info *ci, bool initial) 1198cpu_pmap_prepare(struct cpu_info *ci, bool initial)
1199{ 1199{
1200 /* allocate our TSBs */ 1200 /* allocate our TSBs */
1201 ci->ci_tsb_dmmu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE); 1201 ci->ci_tsb_dmmu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE);
1202 ci->ci_tsb_immu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE); 1202 ci->ci_tsb_immu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE);
1203 memset(ci->ci_tsb_dmmu, 0, TSBSIZE); 1203 memset(ci->ci_tsb_dmmu, 0, TSBSIZE);
1204 memset(ci->ci_tsb_immu, 0, TSBSIZE); 1204 memset(ci->ci_tsb_immu, 0, TSBSIZE);
1205 if (!initial) { 1205 if (!initial) {
1206 KASSERT(ci != curcpu()); 1206 KASSERT(ci != curcpu());
1207 /* 1207 /*
1208 * Initially share ctxbusy with the boot cpu, the 1208 * Initially share ctxbusy with the boot cpu, the
1209 * cpu will replace it as soon as it runs (and can 1209 * cpu will replace it as soon as it runs (and can
1210 * probe the number of available contexts itself). 1210 * probe the number of available contexts itself).
1211 * Untill then only context 0 (aka kernel) will be 1211 * Untill then only context 0 (aka kernel) will be
1212 * referenced anyway. 1212 * referenced anyway.
1213 */ 1213 */
1214 ci->ci_numctx = curcpu()->ci_numctx; 1214 ci->ci_numctx = curcpu()->ci_numctx;
1215 ci->ci_ctxbusy = curcpu()->ci_ctxbusy; 1215 ci->ci_ctxbusy = curcpu()->ci_ctxbusy;
1216 } 1216 }
1217 1217
1218 BDPRINTF(PDB_BOOT1, ("cpu %d: TSB allocated at %p/%p size %08x\n", 1218 BDPRINTF(PDB_BOOT1, ("cpu %d: TSB allocated at %p/%p size %08x\n",
1219 ci->ci_index, ci->ci_tsb_dmmu, ci->ci_tsb_immu, TSBSIZE)); 1219 ci->ci_index, ci->ci_tsb_dmmu, ci->ci_tsb_immu, TSBSIZE));
1220} 1220}
1221 1221
1222/* 1222/*
1223 * Initialize the per CPU parts for the cpu running this code. 1223 * Initialize the per CPU parts for the cpu running this code.
1224 */ 1224 */
1225void 1225void
1226cpu_pmap_init(struct cpu_info *ci) 1226cpu_pmap_init(struct cpu_info *ci)
1227{ 1227{
1228 size_t ctxsize; 1228 size_t ctxsize;
1229 1229
1230 /* 1230 /*
1231 * We delay initialising ci_ctx_lock here as LOCKDEBUG isn't 1231 * We delay initialising ci_ctx_lock here as LOCKDEBUG isn't
1232 * running for cpu0 yet.. 1232 * running for cpu0 yet..
1233 */ 1233 */
1234 ci->ci_pmap_next_ctx = 1; 1234 ci->ci_pmap_next_ctx = 1;
1235#ifdef SUN4V 1235#ifdef SUN4V
1236#error find out if we have 16 or 13 bit context ids 1236#error find out if we have 16 or 13 bit context ids
1237#else 1237#else
1238 ci->ci_numctx = 0x2000; /* all SUN4U use 13 bit contexts */ 1238 ci->ci_numctx = 0x2000; /* all SUN4U use 13 bit contexts */
1239#endif 1239#endif
1240 ctxsize = sizeof(paddr_t)*ci->ci_numctx; 1240 ctxsize = sizeof(paddr_t)*ci->ci_numctx;
1241 ci->ci_ctxbusy = (paddr_t *)kdata_alloc(ctxsize, sizeof(uint64_t)); 1241 ci->ci_ctxbusy = (paddr_t *)kdata_alloc(ctxsize, sizeof(uint64_t));
1242 memset(ci->ci_ctxbusy, 0, ctxsize); 1242 memset(ci->ci_ctxbusy, 0, ctxsize);
1243 LIST_INIT(&ci->ci_pmap_ctxlist); 1243 LIST_INIT(&ci->ci_pmap_ctxlist);
1244 1244
1245 /* mark kernel context as busy */ 1245 /* mark kernel context as busy */
1246 ci->ci_ctxbusy[0] = pmap_kernel()->pm_physaddr; 1246 ci->ci_ctxbusy[0] = pmap_kernel()->pm_physaddr;
1247} 1247}
1248 1248
1249/* 1249/*
1250 * Initialize anything else for pmap handling. 1250 * Initialize anything else for pmap handling.
1251 * Called during vm_init(). 1251 * Called during vm_init().
1252 */ 1252 */
1253void 1253void
1254pmap_init(void) 1254pmap_init(void)
1255{ 1255{
1256 struct vm_page *pg; 1256 struct vm_page *pg;
1257 struct pglist pglist; 1257 struct pglist pglist;
1258 uint64_t data; 1258 uint64_t data;
1259 paddr_t pa; 1259 paddr_t pa;
1260 psize_t size; 1260 psize_t size;
1261 vaddr_t va; 1261 vaddr_t va;
1262 1262
1263 BDPRINTF(PDB_BOOT1, ("pmap_init()\n")); 1263 BDPRINTF(PDB_BOOT1, ("pmap_init()\n"));
1264 1264
1265 size = sizeof(struct pv_entry) * physmem; 1265 size = sizeof(struct pv_entry) * physmem;
1266 if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1, 1266 if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1,
1267 (paddr_t)PAGE_SIZE, (paddr_t)0, &pglist, 1, 0) != 0) 1267 (paddr_t)PAGE_SIZE, (paddr_t)0, &pglist, 1, 0) != 0)
1268 panic("pmap_init: no memory"); 1268 panic("pmap_init: no memory");
1269 1269
1270 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY); 1270 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY);
1271 if (va == 0) 1271 if (va == 0)
1272 panic("pmap_init: no memory"); 1272 panic("pmap_init: no memory");
1273 1273
1274 /* Map the pages */ 1274 /* Map the pages */
1275 TAILQ_FOREACH(pg, &pglist, pageq.queue) { 1275 TAILQ_FOREACH(pg, &pglist, pageq.queue) {
1276 pa = VM_PAGE_TO_PHYS(pg); 1276 pa = VM_PAGE_TO_PHYS(pg);
1277 pmap_zero_page(pa); 1277 pmap_zero_page(pa);
1278 data = TSB_DATA(0 /* global */, 1278 data = TSB_DATA(0 /* global */,
1279 PGSZ_8K, 1279 PGSZ_8K,
1280 pa, 1280 pa,
1281 1 /* priv */, 1281 1 /* priv */,
1282 1 /* Write */, 1282 1 /* Write */,
1283 1 /* Cacheable */, 1283 1 /* Cacheable */,
1284 FORCE_ALIAS /* ALIAS -- Disable D$ */, 1284 FORCE_ALIAS /* ALIAS -- Disable D$ */,
1285 1 /* valid */, 1285 1 /* valid */,
1286 0 /* IE */); 1286 0 /* IE */);
1287 pmap_enter_kpage(va, data); 1287 pmap_enter_kpage(va, data);
1288 va += PAGE_SIZE; 1288 va += PAGE_SIZE;
1289 } 1289 }
1290 1290
1291 /* 1291 /*
1292 * initialize the pmap pools. 1292 * initialize the pmap pools.
1293 */ 1293 */
1294 pool_cache_bootstrap(&pmap_cache, sizeof(struct pmap), 1294 pool_cache_bootstrap(&pmap_cache, sizeof(struct pmap),
1295 SPARC64_BLOCK_SIZE, 0, 0, "pmappl", NULL, IPL_NONE, NULL, NULL, 1295 SPARC64_BLOCK_SIZE, 0, 0, "pmappl", NULL, IPL_NONE, NULL, NULL,
1296 NULL); 1296 NULL);
1297 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0, 1297 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0,
1298 PR_LARGECACHE, "pv_entry", NULL, IPL_NONE, NULL, NULL, NULL); 1298 PR_LARGECACHE, "pv_entry", NULL, IPL_NONE, NULL, NULL, NULL);
1299 1299
1300 vm_first_phys = avail_start; 1300 vm_first_phys = avail_start;
1301 vm_num_phys = avail_end - avail_start; 1301 vm_num_phys = avail_end - avail_start;
1302 1302
1303 mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE); 1303 mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE);
1304#if defined(USE_LOCKSAFE_PSEG_GETSET) 1304#if defined(USE_LOCKSAFE_PSEG_GETSET)
1305 mutex_init(&pseg_lock, MUTEX_SPIN, IPL_VM); 1305 mutex_init(&pseg_lock, MUTEX_SPIN, IPL_VM);
1306#endif 1306#endif
1307 lock_available = true; 1307 lock_available = true;
1308} 1308}
1309 1309
1310/* 1310/*
1311 * How much virtual space is available to the kernel? 1311 * How much virtual space is available to the kernel?
1312 */ 1312 */
1313static vaddr_t kbreak; /* End of kernel VA */ 1313static vaddr_t kbreak; /* End of kernel VA */
1314void 1314void
1315pmap_virtual_space(vaddr_t *start, vaddr_t *end) 1315pmap_virtual_space(vaddr_t *start, vaddr_t *end)
1316{ 1316{
1317 1317
1318 /* 1318 /*
1319 * Reserve one segment for kernel virtual memory 1319 * Reserve one segment for kernel virtual memory
1320 */ 1320 */
1321 /* Reserve two pages for pmap_copy_page && /dev/mem */ 1321 /* Reserve two pages for pmap_copy_page && /dev/mem */
1322 *start = kbreak = (vaddr_t)(vmmap + 2*PAGE_SIZE); 1322 *start = kbreak = (vaddr_t)(vmmap + 2*PAGE_SIZE);
1323 *end = VM_MAX_KERNEL_ADDRESS; 1323 *end = VM_MAX_KERNEL_ADDRESS;
1324 BDPRINTF(PDB_BOOT1, ("pmap_virtual_space: %x-%x\n", *start, *end)); 1324 BDPRINTF(PDB_BOOT1, ("pmap_virtual_space: %x-%x\n", *start, *end));
1325} 1325}
1326 1326
1327/* 1327/*
1328 * Preallocate kernel page tables to a specified VA. 1328 * Preallocate kernel page tables to a specified VA.
1329 * This simply loops through the first TTE for each 1329 * This simply loops through the first TTE for each
1330 * page table from the beginning of the kernel pmap, 1330 * page table from the beginning of the kernel pmap,
1331 * reads the entry, and if the result is 1331 * reads the entry, and if the result is
1332 * zero (either invalid entry or no page table) it stores 1332 * zero (either invalid entry or no page table) it stores
1333 * a zero there, populating page tables in the process. 1333 * a zero there, populating page tables in the process.
1334 * This is not the most efficient technique but i don't 1334 * This is not the most efficient technique but i don't
1335 * expect it to be called that often. 1335 * expect it to be called that often.
1336 */ 1336 */
1337vaddr_t 1337vaddr_t
1338pmap_growkernel(vaddr_t maxkvaddr) 1338pmap_growkernel(vaddr_t maxkvaddr)
1339{ 1339{
1340 struct pmap *pm = pmap_kernel(); 1340 struct pmap *pm = pmap_kernel();
1341 paddr_t pa; 1341 paddr_t pa;
1342 1342
1343 if (maxkvaddr >= KERNEND) { 1343 if (maxkvaddr >= KERNEND) {
1344 printf("WARNING: cannot extend kernel pmap beyond %p to %p\n", 1344 printf("WARNING: cannot extend kernel pmap beyond %p to %p\n",
1345 (void *)KERNEND, (void *)maxkvaddr); 1345 (void *)KERNEND, (void *)maxkvaddr);
1346 return (kbreak); 1346 return (kbreak);
1347 } 1347 }
1348 DPRINTF(PDB_GROW, ("pmap_growkernel(%lx...%lx)\n", kbreak, maxkvaddr)); 1348 DPRINTF(PDB_GROW, ("pmap_growkernel(%lx...%lx)\n", kbreak, maxkvaddr));
1349 /* Align with the start of a page table */ 1349 /* Align with the start of a page table */
1350 for (kbreak &= (-1 << PDSHIFT); kbreak < maxkvaddr; 1350 for (kbreak &= (-1 << PDSHIFT); kbreak < maxkvaddr;
1351 kbreak += (1 << PDSHIFT)) { 1351 kbreak += (1 << PDSHIFT)) {
1352 if (pseg_get(pm, kbreak) & TLB_V) 1352 if (pseg_get(pm, kbreak) & TLB_V)
1353 continue; 1353 continue;
1354 1354
1355 pa = 0; 1355 pa = 0;
1356 while (pseg_set(pm, kbreak, 0, pa) & 1) { 1356 while (pseg_set(pm, kbreak, 0, pa) & 1) {
1357 DPRINTF(PDB_GROW, 1357 DPRINTF(PDB_GROW,
1358 ("pmap_growkernel: extending %lx\n", kbreak)); 1358 ("pmap_growkernel: extending %lx\n", kbreak));
1359 pa = 0; 1359 pa = 0;
1360 if (!pmap_get_page(&pa)) 1360 if (!pmap_get_page(&pa))
1361 panic("pmap_growkernel: no pages"); 1361 panic("pmap_growkernel: no pages");
1362 ENTER_STAT(ptpneeded); 1362 ENTER_STAT(ptpneeded);
1363 } 1363 }
1364 } 1364 }
1365 return (kbreak); 1365 return (kbreak);
1366} 1366}
1367 1367
1368/* 1368/*
1369 * Create and return a physical map. 1369 * Create and return a physical map.
1370 */ 1370 */
1371struct pmap * 1371struct pmap *
1372pmap_create(void) 1372pmap_create(void)
1373{ 1373{
1374 struct pmap *pm; 1374 struct pmap *pm;
1375 1375
1376 DPRINTF(PDB_CREATE, ("pmap_create()\n")); 1376 DPRINTF(PDB_CREATE, ("pmap_create()\n"));
1377 1377
1378 pm = pool_cache_get(&pmap_cache, PR_WAITOK); 1378 pm = pool_cache_get(&pmap_cache, PR_WAITOK);
1379 memset(pm, 0, sizeof *pm); 1379 memset(pm, 0, sizeof *pm);
1380 DPRINTF(PDB_CREATE, ("pmap_create(): created %p\n", pm)); 1380 DPRINTF(PDB_CREATE, ("pmap_create(): created %p\n", pm));
1381 1381
1382 mutex_init(&pm->pm_obj_lock, MUTEX_DEFAULT, IPL_NONE); 1382 pm->pm_refs = 1;
1383 uvm_obj_init(&pm->pm_obj, NULL, false, 1); 1383 TAILQ_INIT(&pm->pm_ptps);
1384 uvm_obj_setlock(&pm->pm_obj, &pm->pm_obj_lock); 
1385 
1386 if (pm != pmap_kernel()) { 1384 if (pm != pmap_kernel()) {
1387 while (!pmap_get_page(&pm->pm_physaddr)) { 1385 while (!pmap_get_page(&pm->pm_physaddr)) {
1388 uvm_wait("pmap_create"); 1386 uvm_wait("pmap_create");
1389 } 1387 }
1390 pm->pm_segs = (paddr_t *)(u_long)pm->pm_physaddr; 1388 pm->pm_segs = (paddr_t *)(u_long)pm->pm_physaddr;
1391 } 1389 }
1392 DPRINTF(PDB_CREATE, ("pmap_create(%p): ctx %d\n", pm, pmap_ctx(pm))); 1390 DPRINTF(PDB_CREATE, ("pmap_create(%p): ctx %d\n", pm, pmap_ctx(pm)));
1393 return pm; 1391 return pm;
1394} 1392}
1395 1393
1396/* 1394/*
1397 * Add a reference to the given pmap. 1395 * Add a reference to the given pmap.
1398 */ 1396 */
1399void 1397void
1400pmap_reference(struct pmap *pm) 1398pmap_reference(struct pmap *pm)
1401{ 1399{
1402 1400
1403 atomic_inc_uint(&pm->pm_refs); 1401 atomic_inc_uint(&pm->pm_refs);
1404} 1402}
1405 1403
1406/* 1404/*
1407 * Retire the given pmap from service. 1405 * Retire the given pmap from service.
1408 * Should only be called if the map contains no valid mappings. 1406 * Should only be called if the map contains no valid mappings.
1409 */ 1407 */
1410void 1408void
1411pmap_destroy(struct pmap *pm) 1409pmap_destroy(struct pmap *pm)
1412{ 1410{
1413#ifdef MULTIPROCESSOR 1411#ifdef MULTIPROCESSOR
1414 struct cpu_info *ci; 1412 struct cpu_info *ci;
1415 sparc64_cpuset_t pmap_cpus_active; 1413 sparc64_cpuset_t pmap_cpus_active;
1416#else 1414#else
1417#define pmap_cpus_active 0 1415#define pmap_cpus_active 0
1418#endif 1416#endif
1419 struct vm_page *pg, *nextpg; 1417 struct vm_page *pg;
1420 1418
1421 if ((int)atomic_dec_uint_nv(&pm->pm_refs) > 0) { 1419 if ((int)atomic_dec_uint_nv(&pm->pm_refs) > 0) {
1422 return; 1420 return;
1423 } 1421 }
1424 DPRINTF(PDB_DESTROY, ("pmap_destroy: freeing pmap %p\n", pm)); 1422 DPRINTF(PDB_DESTROY, ("pmap_destroy: freeing pmap %p\n", pm));
1425#ifdef MULTIPROCESSOR 1423#ifdef MULTIPROCESSOR
1426 CPUSET_CLEAR(pmap_cpus_active); 1424 CPUSET_CLEAR(pmap_cpus_active);
1427 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 1425 for (ci = cpus; ci != NULL; ci = ci->ci_next) {
1428 /* XXXMRG: Move the lock inside one or both tests? */ 1426 /* XXXMRG: Move the lock inside one or both tests? */
1429 mutex_enter(&ci->ci_ctx_lock); 1427 mutex_enter(&ci->ci_ctx_lock);
1430 if (CPUSET_HAS(cpus_active, ci->ci_index)) { 1428 if (CPUSET_HAS(cpus_active, ci->ci_index)) {
1431 if (pm->pm_ctx[ci->ci_index] > 0) { 1429 if (pm->pm_ctx[ci->ci_index] > 0) {
1432 CPUSET_ADD(pmap_cpus_active, ci->ci_index); 1430 CPUSET_ADD(pmap_cpus_active, ci->ci_index);
1433 ctx_free(pm, ci); 1431 ctx_free(pm, ci);
1434 } 1432 }
1435 } 1433 }
1436 mutex_exit(&ci->ci_ctx_lock); 1434 mutex_exit(&ci->ci_ctx_lock);
1437 } 1435 }
1438#else 1436#else
1439 if (pmap_ctx(pm)) { 1437 if (pmap_ctx(pm)) {
1440 mutex_enter(&curcpu()->ci_ctx_lock); 1438 mutex_enter(&curcpu()->ci_ctx_lock);
1441 ctx_free(pm, curcpu()); 1439 ctx_free(pm, curcpu());
1442 mutex_exit(&curcpu()->ci_ctx_lock); 1440 mutex_exit(&curcpu()->ci_ctx_lock);
1443 } 1441 }
1444#endif 1442#endif
1445 1443
1446 /* we could be a little smarter and leave pages zeroed */ 1444 /* we could be a little smarter and leave pages zeroed */
1447 for (pg = TAILQ_FIRST(&pm->pm_obj.memq); pg != NULL; pg = nextpg) { 1445 while ((pg = TAILQ_FIRST(&pm->pm_ptps)) != NULL) {
1448#ifdef DIAGNOSTIC 1446#ifdef DIAGNOSTIC
1449 struct vm_page_md *md = VM_PAGE_TO_MD(pg); 1447 struct vm_page_md *md = VM_PAGE_TO_MD(pg);
1450#endif 1448#endif
1451 1449
1452 KASSERT((pg->flags & PG_MARKER) == 0); 1450 TAILQ_REMOVE(&pm->pm_ptps, pg, pageq.queue);
1453 nextpg = TAILQ_NEXT(pg, listq.queue); 
1454 TAILQ_REMOVE(&pm->pm_obj.memq, pg, listq.queue); 
1455 KASSERT(md->mdpg_pvh.pv_pmap == NULL); 1451 KASSERT(md->mdpg_pvh.pv_pmap == NULL);
1456 dcache_flush_page_cpuset(VM_PAGE_TO_PHYS(pg), pmap_cpus_active); 1452 dcache_flush_page_cpuset(VM_PAGE_TO_PHYS(pg), pmap_cpus_active);
1457 uvm_pagefree(pg); 1453 uvm_pagefree(pg);
1458 } 1454 }
1459 pmap_free_page((paddr_t)(u_long)pm->pm_segs, pmap_cpus_active); 1455 pmap_free_page((paddr_t)(u_long)pm->pm_segs, pmap_cpus_active);
1460 1456
1461 uvm_obj_destroy(&pm->pm_obj, false); 
1462 mutex_destroy(&pm->pm_obj_lock); 
1463 pool_cache_put(&pmap_cache, pm); 1457 pool_cache_put(&pmap_cache, pm);
1464} 1458}
1465 1459
1466/* 1460/*
1467 * Copy the range specified by src_addr/len 1461 * Copy the range specified by src_addr/len
1468 * from the source map to the range dst_addr/len 1462 * from the source map to the range dst_addr/len
1469 * in the destination map. 1463 * in the destination map.
1470 * 1464 *
1471 * This routine is only advisory and need not do anything. 1465 * This routine is only advisory and need not do anything.
1472 */ 1466 */
1473void 1467void
1474pmap_copy(struct pmap *dst_pmap, struct pmap *src_pmap, vaddr_t dst_addr, vsize_t len, vaddr_t src_addr) 1468pmap_copy(struct pmap *dst_pmap, struct pmap *src_pmap, vaddr_t dst_addr, vsize_t len, vaddr_t src_addr)
1475{ 1469{
1476 1470
1477 DPRINTF(PDB_CREATE, ("pmap_copy(%p, %p, %p, %lx, %p)\n", 1471 DPRINTF(PDB_CREATE, ("pmap_copy(%p, %p, %p, %lx, %p)\n",
1478 dst_pmap, src_pmap, (void *)(u_long)dst_addr, 1472 dst_pmap, src_pmap, (void *)(u_long)dst_addr,
1479 (u_long)len, (void *)(u_long)src_addr)); 1473 (u_long)len, (void *)(u_long)src_addr));
1480} 1474}
1481 1475
1482/* 1476/*
1483 * Activate the address space for the specified process. If the 1477 * Activate the address space for the specified process. If the
1484 * process is the current process, load the new MMU context. 1478 * process is the current process, load the new MMU context.
1485 */ 1479 */
1486void 1480void
1487pmap_activate(struct lwp *l) 1481pmap_activate(struct lwp *l)
1488{ 1482{
1489 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; 1483 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
1490 1484
1491 if (pmap == pmap_kernel()) { 1485 if (pmap == pmap_kernel()) {
1492 return; 1486 return;
1493 } 1487 }
1494 1488
1495 /* 1489 /*
1496 * This is essentially the same thing that happens in cpu_switchto() 1490 * This is essentially the same thing that happens in cpu_switchto()
1497 * when the newly selected process is about to run, except that we 1491 * when the newly selected process is about to run, except that we
1498 * have to make sure to clean the register windows before we set 1492 * have to make sure to clean the register windows before we set
1499 * the new context. 1493 * the new context.
1500 */ 1494 */
1501 1495
1502 if (l != curlwp) { 1496 if (l != curlwp) {
1503 return; 1497 return;
1504 } 1498 }
1505 write_user_windows(); 1499 write_user_windows();
1506 pmap_activate_pmap(pmap); 1500 pmap_activate_pmap(pmap);
1507} 1501}
1508 1502
1509void 1503void
1510pmap_activate_pmap(struct pmap *pmap) 1504pmap_activate_pmap(struct pmap *pmap)
1511{ 1505{
1512 1506
1513 if (pmap_ctx(pmap) == 0) { 1507 if (pmap_ctx(pmap) == 0) {
1514 (void) ctx_alloc(pmap); 1508 (void) ctx_alloc(pmap);
1515 } 1509 }
1516 dmmu_set_secondary_context(pmap_ctx(pmap)); 1510 dmmu_set_secondary_context(pmap_ctx(pmap));
1517} 1511}
1518 1512
1519/* 1513/*
1520 * Deactivate the address space of the specified process. 1514 * Deactivate the address space of the specified process.
1521 */ 1515 */
1522void 1516void
1523pmap_deactivate(struct lwp *l) 1517pmap_deactivate(struct lwp *l)
1524{ 1518{
1525} 1519}
1526 1520
1527/* 1521/*
1528 * pmap_kenter_pa: [ INTERFACE ] 1522 * pmap_kenter_pa: [ INTERFACE ]
1529 * 1523 *
1530 * Enter a va -> pa mapping into the kernel pmap without any 1524 * Enter a va -> pa mapping into the kernel pmap without any
1531 * physical->virtual tracking. 1525 * physical->virtual tracking.
1532 * 1526 *
1533 * Note: no locking is necessary in this function. 1527 * Note: no locking is necessary in this function.
1534 */ 1528 */
1535void 1529void
1536pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 1530pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
1537{ 1531{
1538 pte_t tte; 1532 pte_t tte;
1539 paddr_t ptp; 1533 paddr_t ptp;
1540 struct pmap *pm = pmap_kernel(); 1534 struct pmap *pm = pmap_kernel();
1541 int i; 1535 int i;
1542 1536
1543 KASSERT(va < INTSTACK || va > EINTSTACK); 1537 KASSERT(va < INTSTACK || va > EINTSTACK);
1544 KASSERT(va < kdata || va > ekdata); 1538 KASSERT(va < kdata || va > ekdata);
1545 1539
1546 /* 1540 /*
1547 * Construct the TTE. 1541 * Construct the TTE.
1548 */ 1542 */
1549 1543
1550 ENTER_STAT(unmanaged); 1544 ENTER_STAT(unmanaged);
1551 if (pa & (PMAP_NVC|PMAP_NC)) { 1545 if (pa & (PMAP_NVC|PMAP_NC)) {
1552 ENTER_STAT(ci); 1546 ENTER_STAT(ci);
1553 } 1547 }
1554 1548
1555 tte.data = TSB_DATA(0, PGSZ_8K, pa, 1 /* Privileged */, 1549 tte.data = TSB_DATA(0, PGSZ_8K, pa, 1 /* Privileged */,
1556 (VM_PROT_WRITE & prot), 1550 (VM_PROT_WRITE & prot),
1557 !(pa & PMAP_NC), pa & (PMAP_NVC), 1, 0); 1551 !(pa & PMAP_NC), pa & (PMAP_NVC), 1, 0);
1558 /* We don't track mod/ref here. */ 1552 /* We don't track mod/ref here. */
1559 if (prot & VM_PROT_WRITE) 1553 if (prot & VM_PROT_WRITE)
1560 tte.data |= TLB_REAL_W|TLB_W; 1554 tte.data |= TLB_REAL_W|TLB_W;
1561 if (prot & VM_PROT_EXECUTE) 1555 if (prot & VM_PROT_EXECUTE)
1562 tte.data |= TLB_EXEC; 1556 tte.data |= TLB_EXEC;
1563 tte.data |= TLB_TSB_LOCK; /* wired */ 1557 tte.data |= TLB_TSB_LOCK; /* wired */
1564 ptp = 0; 1558 ptp = 0;
1565 1559
1566 retry: 1560 retry:
1567 i = pseg_set(pm, va, tte.data, ptp); 1561 i = pseg_set(pm, va, tte.data, ptp);
1568 if (i & 1) { 1562 if (i & 1) {
1569 KASSERT((i & 4) == 0); 1563 KASSERT((i & 4) == 0);
1570 ptp = 0; 1564 ptp = 0;
1571 if (!pmap_get_page(&ptp)) 1565 if (!pmap_get_page(&ptp))
1572 panic("pmap_kenter_pa: no pages"); 1566 panic("pmap_kenter_pa: no pages");
1573 ENTER_STAT(ptpneeded); 1567 ENTER_STAT(ptpneeded);
1574 goto retry; 1568 goto retry;
1575 } 1569 }
1576 if (ptp && i == 0) { 1570 if (ptp && i == 0) {
1577 /* We allocated a spare page but didn't use it. Free it. */ 1571 /* We allocated a spare page but didn't use it. Free it. */
1578 printf("pmap_kenter_pa: freeing unused page %llx\n", 1572 printf("pmap_kenter_pa: freeing unused page %llx\n",
1579 (long long)ptp); 1573 (long long)ptp);
1580 pmap_free_page_noflush(ptp); 1574 pmap_free_page_noflush(ptp);
1581 } 1575 }
1582#ifdef DEBUG 1576#ifdef DEBUG
1583 i = ptelookup_va(va); 1577 i = ptelookup_va(va);
1584 if (pmapdebug & PDB_ENTER) 1578 if (pmapdebug & PDB_ENTER)
1585 prom_printf("pmap_kenter_pa: va=%08x data=%08x:%08x " 1579 prom_printf("pmap_kenter_pa: va=%08x data=%08x:%08x "
1586 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32), 1580 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32),
1587 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]); 1581 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]);
1588 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) { 1582 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) {
1589 prom_printf("pmap_kenter_pa: evicting entry tag=%x:%08x " 1583 prom_printf("pmap_kenter_pa: evicting entry tag=%x:%08x "
1590 "data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1584 "data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1591 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag, 1585 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag,
1592 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data, 1586 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data,
1593 i, &curcpu()->ci_tsb_dmmu[i]); 1587 i, &curcpu()->ci_tsb_dmmu[i]);
1594 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1588 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1595 va, (int)(tte.data>>32), (int)tte.data, i, 1589 va, (int)(tte.data>>32), (int)tte.data, i,
1596 &curcpu()->ci_tsb_dmmu[i]); 1590 &curcpu()->ci_tsb_dmmu[i]);
1597 } 1591 }
1598#endif 1592#endif
1599} 1593}
1600 1594
1601/* 1595/*
1602 * pmap_kremove: [ INTERFACE ] 1596 * pmap_kremove: [ INTERFACE ]
1603 * 1597 *
1604 * Remove a mapping entered with pmap_kenter_pa() starting at va, 1598 * Remove a mapping entered with pmap_kenter_pa() starting at va,
1605 * for size bytes (assumed to be page rounded). 1599 * for size bytes (assumed to be page rounded).
1606 */ 1600 */
1607void 1601void
1608pmap_kremove(vaddr_t va, vsize_t size) 1602pmap_kremove(vaddr_t va, vsize_t size)
1609{ 1603{
1610 struct pmap *pm = pmap_kernel(); 1604 struct pmap *pm = pmap_kernel();
1611 int64_t data; 1605 int64_t data;
1612 paddr_t pa; 1606 paddr_t pa;
1613 int rv; 1607 int rv;
1614 bool flush = FALSE; 1608 bool flush = FALSE;
1615 1609
1616 KASSERT(va < INTSTACK || va > EINTSTACK); 1610 KASSERT(va < INTSTACK || va > EINTSTACK);
1617 KASSERT(va < kdata || va > ekdata); 1611 KASSERT(va < kdata || va > ekdata);
1618 1612
1619 DPRINTF(PDB_DEMAP, ("pmap_kremove: start 0x%lx size %lx\n", va, size)); 1613 DPRINTF(PDB_DEMAP, ("pmap_kremove: start 0x%lx size %lx\n", va, size));
1620 for (; size >= PAGE_SIZE; va += PAGE_SIZE, size -= PAGE_SIZE) { 1614 for (; size >= PAGE_SIZE; va += PAGE_SIZE, size -= PAGE_SIZE) {
1621 1615
1622#ifdef DIAGNOSTIC 1616#ifdef DIAGNOSTIC
1623 /* 1617 /*
1624 * Is this part of the permanent 4MB mapping? 1618 * Is this part of the permanent 4MB mapping?
1625 */ 1619 */
1626 if (va >= ktext && va < roundup(ekdata, 4*MEG)) 1620 if (va >= ktext && va < roundup(ekdata, 4*MEG))
1627 panic("pmap_kremove: va=%08x in locked TLB", (u_int)va); 1621 panic("pmap_kremove: va=%08x in locked TLB", (u_int)va);
1628#endif 1622#endif
1629 1623
1630 data = pseg_get(pm, va); 1624 data = pseg_get(pm, va);
1631 if ((data & TLB_V) == 0) { 1625 if ((data & TLB_V) == 0) {
1632 continue; 1626 continue;
1633 } 1627 }
1634 1628
1635 flush = TRUE; 1629 flush = TRUE;
1636 pa = data & TLB_PA_MASK; 1630 pa = data & TLB_PA_MASK;
1637 1631
1638 /* 1632 /*
1639 * We need to flip the valid bit and 1633 * We need to flip the valid bit and
1640 * clear the access statistics. 1634 * clear the access statistics.
1641 */ 1635 */
1642 1636
1643 rv = pseg_set(pm, va, 0, 0); 1637 rv = pseg_set(pm, va, 0, 0);
1644 if (rv & 1) 1638 if (rv & 1)
1645 panic("pmap_kremove: pseg_set needs spare, rv=%d\n", 1639 panic("pmap_kremove: pseg_set needs spare, rv=%d\n",
1646 rv); 1640 rv);
1647 DPRINTF(PDB_DEMAP, ("pmap_kremove: seg %x pdir %x pte %x\n", 1641 DPRINTF(PDB_DEMAP, ("pmap_kremove: seg %x pdir %x pte %x\n",
1648 (int)va_to_seg(va), (int)va_to_dir(va), 1642 (int)va_to_seg(va), (int)va_to_dir(va),
1649 (int)va_to_pte(va))); 1643 (int)va_to_pte(va)));
1650 REMOVE_STAT(removes); 1644 REMOVE_STAT(removes);
1651 1645
1652 tsb_invalidate(va, pm); 1646 tsb_invalidate(va, pm);
1653 REMOVE_STAT(tflushes); 1647 REMOVE_STAT(tflushes);
1654 1648
1655 /* 1649 /*
1656 * Here we assume nothing can get into the TLB 1650 * Here we assume nothing can get into the TLB
1657 * unless it has a PTE. 1651 * unless it has a PTE.
1658 */ 1652 */
1659 1653
1660 tlb_flush_pte(va, pm); 1654 tlb_flush_pte(va, pm);
1661 dcache_flush_page_all(pa); 1655 dcache_flush_page_all(pa);
1662 } 1656 }
1663 if (flush) 1657 if (flush)
1664 REMOVE_STAT(flushes); 1658 REMOVE_STAT(flushes);
1665} 1659}
1666 1660
1667/* 1661/*
1668 * Insert physical page at pa into the given pmap at virtual address va. 1662 * Insert physical page at pa into the given pmap at virtual address va.
1669 * Supports 64-bit pa so we can map I/O space. 1663 * Supports 64-bit pa so we can map I/O space.
1670 */ 1664 */
1671 1665
1672int 1666int
1673pmap_enter(struct pmap *pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 1667pmap_enter(struct pmap *pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
1674{ 1668{
1675 pte_t tte; 1669 pte_t tte;
1676 int64_t data; 1670 int64_t data;
1677 paddr_t opa = 0, ptp; /* XXX: gcc */ 1671 paddr_t opa = 0, ptp; /* XXX: gcc */
1678 pv_entry_t pvh, npv = NULL, freepv; 1672 pv_entry_t pvh, npv = NULL, freepv;
1679 struct vm_page *pg, *opg, *ptpg; 1673 struct vm_page *pg, *opg, *ptpg;
1680 int s, i, uncached = 0, error = 0; 1674 int s, i, uncached = 0, error = 0;
1681 int size = PGSZ_8K; /* PMAP_SZ_TO_TTE(pa); */ 1675 int size = PGSZ_8K; /* PMAP_SZ_TO_TTE(pa); */
1682 bool wired = (flags & PMAP_WIRED) != 0; 1676 bool wired = (flags & PMAP_WIRED) != 0;
1683 bool wasmapped = FALSE; 1677 bool wasmapped = FALSE;
1684 bool dopv = TRUE; 1678 bool dopv = TRUE;
1685 1679
1686 /* 1680 /*
1687 * Is this part of the permanent mappings? 1681 * Is this part of the permanent mappings?
1688 */ 1682 */
1689 KASSERT(pm != pmap_kernel() || va < INTSTACK || va > EINTSTACK); 1683 KASSERT(pm != pmap_kernel() || va < INTSTACK || va > EINTSTACK);
1690 KASSERT(pm != pmap_kernel() || va < kdata || va > ekdata); 1684 KASSERT(pm != pmap_kernel() || va < kdata || va > ekdata);
1691 1685
1692 /* Grab a spare PV. */ 1686 /* Grab a spare PV. */
1693 freepv = pool_cache_get(&pmap_pv_cache, PR_NOWAIT); 1687 freepv = pool_cache_get(&pmap_pv_cache, PR_NOWAIT);
1694 if (__predict_false(freepv == NULL)) { 1688 if (__predict_false(freepv == NULL)) {
1695 if (flags & PMAP_CANFAIL) 1689 if (flags & PMAP_CANFAIL)
1696 return (ENOMEM); 1690 return (ENOMEM);
1697 panic("pmap_enter: no pv entries available"); 1691 panic("pmap_enter: no pv entries available");
1698 } 1692 }
1699 freepv->pv_next = NULL; 1693 freepv->pv_next = NULL;
1700 1694
1701 /* 1695 /*
1702 * If a mapping at this address already exists, check if we're 1696 * If a mapping at this address already exists, check if we're
1703 * entering the same PA again. if it's different remove it. 1697 * entering the same PA again. if it's different remove it.
1704 */ 1698 */
1705 1699
1706 mutex_enter(&pmap_lock); 1700 mutex_enter(&pmap_lock);
1707 data = pseg_get(pm, va); 1701 data = pseg_get(pm, va);
1708 if (data & TLB_V) { 1702 if (data & TLB_V) {
1709 wasmapped = TRUE; 1703 wasmapped = TRUE;
1710 opa = data & TLB_PA_MASK; 1704 opa = data & TLB_PA_MASK;
1711 if (opa != pa) { 1705 if (opa != pa) {
1712 opg = PHYS_TO_VM_PAGE(opa); 1706 opg = PHYS_TO_VM_PAGE(opa);
1713 if (opg != NULL) { 1707 if (opg != NULL) {
1714 npv = pmap_remove_pv(pm, va, opg); 1708 npv = pmap_remove_pv(pm, va, opg);
1715 } 1709 }
1716 } 1710 }
1717 } 1711 }
1718 1712
1719 /* 1713 /*
1720 * Construct the TTE. 1714 * Construct the TTE.
1721 */ 1715 */
1722 pg = PHYS_TO_VM_PAGE(pa); 1716 pg = PHYS_TO_VM_PAGE(pa);
1723 if (pg) { 1717 if (pg) {
1724 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 1718 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
1725 1719
1726 pvh = &md->mdpg_pvh; 1720 pvh = &md->mdpg_pvh;
1727 uncached = (pvh->pv_va & (PV_ALIAS|PV_NVC)); 1721 uncached = (pvh->pv_va & (PV_ALIAS|PV_NVC));
1728#ifdef DIAGNOSTIC 1722#ifdef DIAGNOSTIC
1729 if ((flags & VM_PROT_ALL) & ~prot) 1723 if ((flags & VM_PROT_ALL) & ~prot)
1730 panic("pmap_enter: access_type exceeds prot"); 1724 panic("pmap_enter: access_type exceeds prot");
1731#endif 1725#endif
1732 /* 1726 /*
1733 * If we don't have the traphandler do it, 1727 * If we don't have the traphandler do it,
1734 * set the ref/mod bits now. 1728 * set the ref/mod bits now.
1735 */ 1729 */
1736 if (flags & VM_PROT_ALL) 1730 if (flags & VM_PROT_ALL)
1737 pvh->pv_va |= PV_REF; 1731 pvh->pv_va |= PV_REF;
1738 if (flags & VM_PROT_WRITE) 1732 if (flags & VM_PROT_WRITE)
1739 pvh->pv_va |= PV_MOD; 1733 pvh->pv_va |= PV_MOD;
1740 1734
1741 /* 1735 /*
1742 * make sure we have a pv entry ready if we need one. 1736 * make sure we have a pv entry ready if we need one.
1743 */ 1737 */
1744 if (pvh->pv_pmap == NULL || (wasmapped && opa == pa)) { 1738 if (pvh->pv_pmap == NULL || (wasmapped && opa == pa)) {
1745 if (npv != NULL) { 1739 if (npv != NULL) {
1746 /* free it */ 1740 /* free it */
1747 npv->pv_next = freepv; 1741 npv->pv_next = freepv;
1748 freepv = npv; 1742 freepv = npv;
1749 npv = NULL; 1743 npv = NULL;
1750 } 1744 }
1751 if (wasmapped && opa == pa) { 1745 if (wasmapped && opa == pa) {
1752 dopv = FALSE; 1746 dopv = FALSE;
1753 } 1747 }
1754 } else if (npv == NULL) { 1748 } else if (npv == NULL) {
1755 /* use the pre-allocated pv */ 1749 /* use the pre-allocated pv */
1756 npv = freepv; 1750 npv = freepv;
1757 freepv = freepv->pv_next; 1751 freepv = freepv->pv_next;
1758 } 1752 }
1759 ENTER_STAT(managed); 1753 ENTER_STAT(managed);
1760 } else { 1754 } else {
1761 ENTER_STAT(unmanaged); 1755 ENTER_STAT(unmanaged);
1762 dopv = FALSE; 1756 dopv = FALSE;
1763 if (npv != NULL) { 1757 if (npv != NULL) {
1764 /* free it */ 1758 /* free it */
1765 npv->pv_next = freepv; 1759 npv->pv_next = freepv;
1766 freepv = npv; 1760 freepv = npv;
1767 npv = NULL; 1761 npv = NULL;
1768 } 1762 }
1769 } 1763 }
1770 1764
1771#ifndef NO_VCACHE 1765#ifndef NO_VCACHE
1772 if (pa & PMAP_NVC) 1766 if (pa & PMAP_NVC)
1773#endif 1767#endif
1774 uncached = 1; 1768 uncached = 1;
1775 if (uncached) { 1769 if (uncached) {
1776 ENTER_STAT(ci); 1770 ENTER_STAT(ci);
1777 } 1771 }
1778 tte.data = TSB_DATA(0, size, pa, pm == pmap_kernel(), 1772 tte.data = TSB_DATA(0, size, pa, pm == pmap_kernel(),
1779 flags & VM_PROT_WRITE, !(pa & PMAP_NC), 1773 flags & VM_PROT_WRITE, !(pa & PMAP_NC),
1780 uncached, 1, pa & PMAP_LITTLE); 1774 uncached, 1, pa & PMAP_LITTLE);
1781#ifdef HWREF 1775#ifdef HWREF
1782 if (prot & VM_PROT_WRITE) 1776 if (prot & VM_PROT_WRITE)
1783 tte.data |= TLB_REAL_W; 1777 tte.data |= TLB_REAL_W;
1784 if (prot & VM_PROT_EXECUTE) 1778 if (prot & VM_PROT_EXECUTE)
1785 tte.data |= TLB_EXEC; 1779 tte.data |= TLB_EXEC;
1786#else 1780#else
1787 /* If it needs ref accounting do nothing. */ 1781 /* If it needs ref accounting do nothing. */
1788 if (!(flags & VM_PROT_READ)) { 1782 if (!(flags & VM_PROT_READ)) {
1789 mutex_exit(&pmap_lock); 1783 mutex_exit(&pmap_lock);
1790 goto out; 1784 goto out;
1791 } 1785 }
1792#endif 1786#endif
1793 if (flags & VM_PROT_EXECUTE) { 1787 if (flags & VM_PROT_EXECUTE) {
1794 if ((flags & (VM_PROT_READ|VM_PROT_WRITE)) == 0) 1788 if ((flags & (VM_PROT_READ|VM_PROT_WRITE)) == 0)
1795 tte.data |= TLB_EXEC_ONLY|TLB_EXEC; 1789 tte.data |= TLB_EXEC_ONLY|TLB_EXEC;
1796 else 1790 else
1797 tte.data |= TLB_EXEC; 1791 tte.data |= TLB_EXEC;
1798 } 1792 }
1799 if (wired) 1793 if (wired)
1800 tte.data |= TLB_TSB_LOCK; 1794 tte.data |= TLB_TSB_LOCK;
1801 ptp = 0; 1795 ptp = 0;
1802 1796
1803 retry: 1797 retry:
1804 i = pseg_set(pm, va, tte.data, ptp); 1798 i = pseg_set(pm, va, tte.data, ptp);
1805 if (i & 4) { 1799 if (i & 4) {
1806 /* ptp used as L3 */ 1800 /* ptp used as L3 */
1807 KASSERT(ptp != 0); 1801 KASSERT(ptp != 0);
1808 KASSERT((i & 3) == 0); 1802 KASSERT((i & 3) == 0);
1809 ptpg = PHYS_TO_VM_PAGE(ptp); 1803 ptpg = PHYS_TO_VM_PAGE(ptp);
1810 if (ptpg) { 1804 if (ptpg) {
1811 ptpg->offset = (uint64_t)va & (0xfffffLL << 23); 1805 ptpg->offset = (uint64_t)va & (0xfffffLL << 23);
1812 TAILQ_INSERT_TAIL(&pm->pm_obj.memq, ptpg, listq.queue); 1806 TAILQ_INSERT_TAIL(&pm->pm_ptps, ptpg, pageq.queue);
1813 } else { 1807 } else {
1814 KASSERT(pm == pmap_kernel()); 1808 KASSERT(pm == pmap_kernel());
1815 } 1809 }
1816 } 1810 }
1817 if (i & 2) { 1811 if (i & 2) {
1818 /* ptp used as L2 */ 1812 /* ptp used as L2 */
1819 KASSERT(ptp != 0); 1813 KASSERT(ptp != 0);
1820 KASSERT((i & 4) == 0); 1814 KASSERT((i & 4) == 0);
1821 ptpg = PHYS_TO_VM_PAGE(ptp); 1815 ptpg = PHYS_TO_VM_PAGE(ptp);
1822 if (ptpg) { 1816 if (ptpg) {
1823 ptpg->offset = (((uint64_t)va >> 43) & 0x3ffLL) << 13; 1817 ptpg->offset = (((uint64_t)va >> 43) & 0x3ffLL) << 13;
1824 TAILQ_INSERT_TAIL(&pm->pm_obj.memq, ptpg, listq.queue); 1818 TAILQ_INSERT_TAIL(&pm->pm_ptps, ptpg, pageq.queue);
1825 } else { 1819 } else {
1826 KASSERT(pm == pmap_kernel()); 1820 KASSERT(pm == pmap_kernel());
1827 } 1821 }
1828 } 1822 }
1829 if (i & 1) { 1823 if (i & 1) {
1830 KASSERT((i & 4) == 0); 1824 KASSERT((i & 4) == 0);
1831 ptp = 0; 1825 ptp = 0;
1832 if (!pmap_get_page(&ptp)) { 1826 if (!pmap_get_page(&ptp)) {
1833 mutex_exit(&pmap_lock); 1827 mutex_exit(&pmap_lock);
1834 if (flags & PMAP_CANFAIL) { 1828 if (flags & PMAP_CANFAIL) {
1835 if (npv != NULL) { 1829 if (npv != NULL) {
1836 /* free it */ 1830 /* free it */
1837 npv->pv_next = freepv; 1831 npv->pv_next = freepv;
1838 freepv = npv; 1832 freepv = npv;
1839 } 1833 }
1840 error = ENOMEM; 1834 error = ENOMEM;
1841 goto out; 1835 goto out;
1842 } else { 1836 } else {
1843 panic("pmap_enter: no pages"); 1837 panic("pmap_enter: no pages");
1844 } 1838 }
1845 } 1839 }
1846 ENTER_STAT(ptpneeded); 1840 ENTER_STAT(ptpneeded);
1847 goto retry; 1841 goto retry;
1848 } 1842 }
1849 if (ptp && i == 0) { 1843 if (ptp && i == 0) {
1850 /* We allocated a spare page but didn't use it. Free it. */ 1844 /* We allocated a spare page but didn't use it. Free it. */
1851 printf("pmap_enter: freeing unused page %llx\n", 1845 printf("pmap_enter: freeing unused page %llx\n",
1852 (long long)ptp); 1846 (long long)ptp);
1853 pmap_free_page_noflush(ptp); 1847 pmap_free_page_noflush(ptp);
1854 } 1848 }
1855 if (dopv) { 1849 if (dopv) {
1856 pmap_enter_pv(pm, va, pa, pg, npv); 1850 pmap_enter_pv(pm, va, pa, pg, npv);
1857 } 1851 }
1858 1852
1859 mutex_exit(&pmap_lock); 1853 mutex_exit(&pmap_lock);
1860#ifdef DEBUG 1854#ifdef DEBUG
1861 i = ptelookup_va(va); 1855 i = ptelookup_va(va);
1862 if (pmapdebug & PDB_ENTER) 1856 if (pmapdebug & PDB_ENTER)
1863 prom_printf("pmap_enter: va=%08x data=%08x:%08x " 1857 prom_printf("pmap_enter: va=%08x data=%08x:%08x "
1864 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32), 1858 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32),
1865 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]); 1859 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]);
1866 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) { 1860 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) {
1867 prom_printf("pmap_enter: evicting entry tag=%x:%08x " 1861 prom_printf("pmap_enter: evicting entry tag=%x:%08x "
1868 "data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1862 "data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1869 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag, 1863 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag,
1870 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data, i, 1864 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data, i,
1871 &curcpu()->ci_tsb_dmmu[i]); 1865 &curcpu()->ci_tsb_dmmu[i]);
1872 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1866 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1873 va, (int)(tte.data>>32), (int)tte.data, i, 1867 va, (int)(tte.data>>32), (int)tte.data, i,
1874 &curcpu()->ci_tsb_dmmu[i]); 1868 &curcpu()->ci_tsb_dmmu[i]);
1875 } 1869 }
1876#endif 1870#endif
1877 1871
1878 if (flags & (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)) { 1872 if (flags & (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)) {
1879 1873
1880 /* 1874 /*
1881 * preload the TSB with the new entry, 1875 * preload the TSB with the new entry,
1882 * since we're going to need it immediately anyway. 1876 * since we're going to need it immediately anyway.
1883 */ 1877 */
1884 1878
1885 KASSERT(pmap_ctx(pm)>=0); 1879 KASSERT(pmap_ctx(pm)>=0);
1886 i = ptelookup_va(va); 1880 i = ptelookup_va(va);
1887 tte.tag = TSB_TAG(0, pmap_ctx(pm), va); 1881 tte.tag = TSB_TAG(0, pmap_ctx(pm), va);
1888 s = splhigh(); 1882 s = splhigh();
1889 if (wasmapped && pmap_is_on_mmu(pm)) { 1883 if (wasmapped && pmap_is_on_mmu(pm)) {
1890 tsb_invalidate(va, pm); 1884 tsb_invalidate(va, pm);
1891 } 1885 }
1892 if (flags & (VM_PROT_READ | VM_PROT_WRITE)) { 1886 if (flags & (VM_PROT_READ | VM_PROT_WRITE)) {
1893 curcpu()->ci_tsb_dmmu[i].tag = tte.tag; 1887 curcpu()->ci_tsb_dmmu[i].tag = tte.tag;
1894 __asm volatile("" : : : "memory"); 1888 __asm volatile("" : : : "memory");
1895 curcpu()->ci_tsb_dmmu[i].data = tte.data; 1889 curcpu()->ci_tsb_dmmu[i].data = tte.data;
1896 } 1890 }
1897 if (flags & VM_PROT_EXECUTE) { 1891 if (flags & VM_PROT_EXECUTE) {
1898 curcpu()->ci_tsb_immu[i].tag = tte.tag; 1892 curcpu()->ci_tsb_immu[i].tag = tte.tag;
1899 __asm volatile("" : : : "memory"); 1893 __asm volatile("" : : : "memory");
1900 curcpu()->ci_tsb_immu[i].data = tte.data; 1894 curcpu()->ci_tsb_immu[i].data = tte.data;
1901 } 1895 }
1902 1896
1903 /* 1897 /*
1904 * it's only necessary to flush the TLB if this page was 1898 * it's only necessary to flush the TLB if this page was
1905 * previously mapped, but for some reason it's a lot faster 1899 * previously mapped, but for some reason it's a lot faster
1906 * for the fork+exit microbenchmark if we always do it. 1900 * for the fork+exit microbenchmark if we always do it.
1907 */ 1901 */
1908 1902
1909 KASSERT(pmap_ctx(pm)>=0); 1903 KASSERT(pmap_ctx(pm)>=0);
1910#ifdef MULTIPROCESSOR 1904#ifdef MULTIPROCESSOR
1911 if (wasmapped && pmap_is_on_mmu(pm)) 1905 if (wasmapped && pmap_is_on_mmu(pm))
1912 tlb_flush_pte(va, pm); 1906 tlb_flush_pte(va, pm);
1913 else 1907 else
1914 sp_tlb_flush_pte(va, pmap_ctx(pm)); 1908 sp_tlb_flush_pte(va, pmap_ctx(pm));
1915#else 1909#else
1916 tlb_flush_pte(va, pm); 1910 tlb_flush_pte(va, pm);
1917#endif 1911#endif
1918 splx(s); 1912 splx(s);
1919 } else if (wasmapped && pmap_is_on_mmu(pm)) { 1913 } else if (wasmapped && pmap_is_on_mmu(pm)) {
1920 /* Force reload -- protections may be changed */ 1914 /* Force reload -- protections may be changed */
1921 KASSERT(pmap_ctx(pm)>=0); 1915 KASSERT(pmap_ctx(pm)>=0);
1922 tsb_invalidate(va, pm); 1916 tsb_invalidate(va, pm);
1923 tlb_flush_pte(va, pm); 1917 tlb_flush_pte(va, pm);
1924 } 1918 }
1925 1919
1926 /* We will let the fast mmu miss interrupt load the new translation */ 1920 /* We will let the fast mmu miss interrupt load the new translation */
1927 pv_check(); 1921 pv_check();
1928 out: 1922 out:
1929 /* Catch up on deferred frees. */ 1923 /* Catch up on deferred frees. */
1930 for (; freepv != NULL; freepv = npv) { 1924 for (; freepv != NULL; freepv = npv) {
1931 npv = freepv->pv_next; 1925 npv = freepv->pv_next;
1932 pool_cache_put(&pmap_pv_cache, freepv); 1926 pool_cache_put(&pmap_pv_cache, freepv);
1933 } 1927 }
1934 return error; 1928 return error;
1935} 1929}
1936 1930
1937void 1931void
1938pmap_remove_all(struct pmap *pm) 1932pmap_remove_all(struct pmap *pm)
1939{ 1933{
1940#ifdef MULTIPROCESSOR 1934#ifdef MULTIPROCESSOR
1941 struct cpu_info *ci; 1935 struct cpu_info *ci;
1942 sparc64_cpuset_t pmap_cpus_active; 1936 sparc64_cpuset_t pmap_cpus_active;
1943#endif 1937#endif
1944 1938
1945 if (pm == pmap_kernel()) { 1939 if (pm == pmap_kernel()) {
1946 return; 1940 return;
1947 } 1941 }
1948 write_user_windows(); 1942 write_user_windows();
1949 pm->pm_refs = 0; 1943 pm->pm_refs = 0;
1950 1944
1951 /* 1945 /*
1952 * XXXMRG: pmap_destroy() does exactly the same dance here. 1946 * XXXMRG: pmap_destroy() does exactly the same dance here.
1953 * surely one of them isn't necessary? 1947 * surely one of them isn't necessary?
1954 */ 1948 */
1955#ifdef MULTIPROCESSOR 1949#ifdef MULTIPROCESSOR
1956 CPUSET_CLEAR(pmap_cpus_active); 1950 CPUSET_CLEAR(pmap_cpus_active);
1957 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 1951 for (ci = cpus; ci != NULL; ci = ci->ci_next) {
1958 /* XXXMRG: Move the lock inside one or both tests? */ 1952 /* XXXMRG: Move the lock inside one or both tests? */
1959 mutex_enter(&ci->ci_ctx_lock); 1953 mutex_enter(&ci->ci_ctx_lock);
1960 if (CPUSET_HAS(cpus_active, ci->ci_index)) { 1954 if (CPUSET_HAS(cpus_active, ci->ci_index)) {
1961 if (pm->pm_ctx[ci->ci_index] > 0) { 1955 if (pm->pm_ctx[ci->ci_index] > 0) {
1962 CPUSET_ADD(pmap_cpus_active, ci->ci_index); 1956 CPUSET_ADD(pmap_cpus_active, ci->ci_index);
1963 ctx_free(pm, ci); 1957 ctx_free(pm, ci);
1964 } 1958 }
1965 } 1959 }
1966 mutex_exit(&ci->ci_ctx_lock); 1960 mutex_exit(&ci->ci_ctx_lock);
1967 } 1961 }
1968#else 1962#else
1969 if (pmap_ctx(pm)) { 1963 if (pmap_ctx(pm)) {
1970 mutex_enter(&curcpu()->ci_ctx_lock); 1964 mutex_enter(&curcpu()->ci_ctx_lock);
1971 ctx_free(pm, curcpu()); 1965 ctx_free(pm, curcpu());
1972 mutex_exit(&curcpu()->ci_ctx_lock); 1966 mutex_exit(&curcpu()->ci_ctx_lock);
1973 } 1967 }
1974#endif 1968#endif
1975 1969
1976 REMOVE_STAT(flushes); 1970 REMOVE_STAT(flushes);
1977 /* 1971 /*
1978 * XXXMRG: couldn't we do something less severe here, and 1972 * XXXMRG: couldn't we do something less severe here, and
1979 * only flush the right context on each CPU? 1973 * only flush the right context on each CPU?
1980 */ 1974 */
1981 blast_dcache(); 1975 blast_dcache();
1982} 1976}
1983 1977
1984/* 1978/*
1985 * Remove the given range of mapping entries. 1979 * Remove the given range of mapping entries.
1986 */ 1980 */
1987void 1981void
1988pmap_remove(struct pmap *pm, vaddr_t va, vaddr_t endva) 1982pmap_remove(struct pmap *pm, vaddr_t va, vaddr_t endva)
1989{ 1983{
1990 int64_t data; 1984 int64_t data;
1991 paddr_t pa; 1985 paddr_t pa;
1992 struct vm_page *pg; 1986 struct vm_page *pg;
1993 pv_entry_t pv, freepv = NULL; 1987 pv_entry_t pv, freepv = NULL;
1994 int rv; 1988 int rv;
1995 bool flush = FALSE; 1989 bool flush = FALSE;
1996 1990
1997 /* 1991 /*
1998 * In here we should check each pseg and if there are no more entries, 1992 * In here we should check each pseg and if there are no more entries,
1999 * free it. It's just that linear scans of 8K pages gets expensive. 1993 * free it. It's just that linear scans of 8K pages gets expensive.
2000 */ 1994 */
2001 1995
2002 KASSERT(pm != pmap_kernel() || endva < INTSTACK || va > EINTSTACK); 1996 KASSERT(pm != pmap_kernel() || endva < INTSTACK || va > EINTSTACK);
2003 KASSERT(pm != pmap_kernel() || endva < kdata || va > ekdata); 1997 KASSERT(pm != pmap_kernel() || endva < kdata || va > ekdata);
2004 1998
2005 mutex_enter(&pmap_lock); 1999 mutex_enter(&pmap_lock);
2006 DPRINTF(PDB_REMOVE, ("pmap_remove(pm=%p, va=%p, endva=%p):", pm, 2000 DPRINTF(PDB_REMOVE, ("pmap_remove(pm=%p, va=%p, endva=%p):", pm,
2007 (void *)(u_long)va, (void *)(u_long)endva)); 2001 (void *)(u_long)va, (void *)(u_long)endva));
2008 REMOVE_STAT(calls); 2002 REMOVE_STAT(calls);
2009 2003
2010 /* Now do the real work */ 2004 /* Now do the real work */
2011 for (; va < endva; va += PAGE_SIZE) { 2005 for (; va < endva; va += PAGE_SIZE) {
2012#ifdef DIAGNOSTIC 2006#ifdef DIAGNOSTIC
2013 /* 2007 /*
2014 * Is this part of the permanent 4MB mapping? 2008 * Is this part of the permanent 4MB mapping?
2015 */ 2009 */
2016 if (pm == pmap_kernel() && va >= ktext && 2010 if (pm == pmap_kernel() && va >= ktext &&
2017 va < roundup(ekdata, 4*MEG)) 2011 va < roundup(ekdata, 4*MEG))
2018 panic("pmap_remove: va=%08llx in locked TLB", 2012 panic("pmap_remove: va=%08llx in locked TLB",
2019 (long long)va); 2013 (long long)va);
2020#endif 2014#endif
2021 2015
2022 data = pseg_get(pm, va); 2016 data = pseg_get(pm, va);
2023 if ((data & TLB_V) == 0) { 2017 if ((data & TLB_V) == 0) {
2024 continue; 2018 continue;
2025 } 2019 }
2026 2020
2027 flush = TRUE; 2021 flush = TRUE;
2028 /* First remove the pv entry, if there is one */ 2022 /* First remove the pv entry, if there is one */
2029 pa = data & TLB_PA_MASK; 2023 pa = data & TLB_PA_MASK;
2030 pg = PHYS_TO_VM_PAGE(pa); 2024 pg = PHYS_TO_VM_PAGE(pa);
2031 if (pg) { 2025 if (pg) {
2032 pv = pmap_remove_pv(pm, va, pg); 2026 pv = pmap_remove_pv(pm, va, pg);
2033 if (pv != NULL) { 2027 if (pv != NULL) {
2034 /* free it */ 2028 /* free it */
2035 pv->pv_next = freepv; 2029 pv->pv_next = freepv;
2036 freepv = pv; 2030 freepv = pv;
2037 } 2031 }
2038 } 2032 }
2039 2033
2040 /* 2034 /*
2041 * We need to flip the valid bit and 2035 * We need to flip the valid bit and
2042 * clear the access statistics. 2036 * clear the access statistics.
2043 */ 2037 */
2044 2038
2045 rv = pseg_set(pm, va, 0, 0); 2039 rv = pseg_set(pm, va, 0, 0);
2046 if (rv & 1) 2040 if (rv & 1)
2047 panic("pmap_remove: pseg_set needed spare, rv=%d!\n", 2041 panic("pmap_remove: pseg_set needed spare, rv=%d!\n",
2048 rv); 2042 rv);
2049 2043
2050 DPRINTF(PDB_REMOVE, (" clearing seg %x pte %x\n", 2044 DPRINTF(PDB_REMOVE, (" clearing seg %x pte %x\n",
2051 (int)va_to_seg(va), (int)va_to_pte(va))); 2045 (int)va_to_seg(va), (int)va_to_pte(va)));
2052 REMOVE_STAT(removes); 2046 REMOVE_STAT(removes);
2053 2047
2054 if (pm != pmap_kernel() && !pmap_has_ctx(pm)) 2048 if (pm != pmap_kernel() && !pmap_has_ctx(pm))
2055 continue; 2049 continue;
2056 2050
2057 /* 2051 /*
2058 * if the pmap is being torn down, don't bother flushing, 2052 * if the pmap is being torn down, don't bother flushing,
2059 * we already have done so. 2053 * we already have done so.
2060 */ 2054 */
2061 2055
2062 if (!pm->pm_refs) 2056 if (!pm->pm_refs)
2063 continue; 2057 continue;
2064 2058
2065 /* 2059 /*
2066 * Here we assume nothing can get into the TLB 2060 * Here we assume nothing can get into the TLB
2067 * unless it has a PTE. 2061 * unless it has a PTE.
2068 */ 2062 */
2069 2063
2070 KASSERT(pmap_ctx(pm)>=0); 2064 KASSERT(pmap_ctx(pm)>=0);
2071 tsb_invalidate(va, pm); 2065 tsb_invalidate(va, pm);
2072 REMOVE_STAT(tflushes); 2066 REMOVE_STAT(tflushes);
2073 tlb_flush_pte(va, pm); 2067 tlb_flush_pte(va, pm);
2074 dcache_flush_page_all(pa); 2068 dcache_flush_page_all(pa);
2075 } 2069 }
2076 if (flush && pm->pm_refs) 2070 if (flush && pm->pm_refs)
2077 REMOVE_STAT(flushes); 2071 REMOVE_STAT(flushes);
2078 DPRINTF(PDB_REMOVE, ("\n")); 2072 DPRINTF(PDB_REMOVE, ("\n"));
2079 pv_check(); 2073 pv_check();
2080 mutex_exit(&pmap_lock); 2074 mutex_exit(&pmap_lock);
2081 2075
2082 /* Catch up on deferred frees. */ 2076 /* Catch up on deferred frees. */
2083 for (; freepv != NULL; freepv = pv) { 2077 for (; freepv != NULL; freepv = pv) {
2084 pv = freepv->pv_next; 2078 pv = freepv->pv_next;
2085 pool_cache_put(&pmap_pv_cache, freepv); 2079 pool_cache_put(&pmap_pv_cache, freepv);
2086 } 2080 }
2087} 2081}
2088 2082
2089/* 2083/*
2090 * Change the protection on the specified range of this pmap. 2084 * Change the protection on the specified range of this pmap.
2091 */ 2085 */
2092void 2086void
2093pmap_protect(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 2087pmap_protect(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
2094{ 2088{
2095 paddr_t pa; 2089 paddr_t pa;
2096 int64_t data; 2090 int64_t data;
2097 struct vm_page *pg; 2091 struct vm_page *pg;
2098 pv_entry_t pv; 2092 pv_entry_t pv;
2099 int rv; 2093 int rv;
2100 2094
2101 KASSERT(pm != pmap_kernel() || eva < INTSTACK || sva > EINTSTACK); 2095 KASSERT(pm != pmap_kernel() || eva < INTSTACK || sva > EINTSTACK);
2102 KASSERT(pm != pmap_kernel() || eva < kdata || sva > ekdata); 2096 KASSERT(pm != pmap_kernel() || eva < kdata || sva > ekdata);
2103 2097
2104 if (prot == VM_PROT_NONE) { 2098 if (prot == VM_PROT_NONE) {
2105 pmap_remove(pm, sva, eva); 2099 pmap_remove(pm, sva, eva);
2106 return; 2100 return;
2107 } 2101 }
2108 2102
2109 sva = trunc_page(sva); 2103 sva = trunc_page(sva);
2110 for (; sva < eva; sva += PAGE_SIZE) { 2104 for (; sva < eva; sva += PAGE_SIZE) {
2111#ifdef DEBUG 2105#ifdef DEBUG
2112 /* 2106 /*
2113 * Is this part of the permanent 4MB mapping? 2107 * Is this part of the permanent 4MB mapping?
2114 */ 2108 */
2115 if (pm == pmap_kernel() && sva >= ktext && 2109 if (pm == pmap_kernel() && sva >= ktext &&
2116 sva < roundup(ekdata, 4 * MEG)) { 2110 sva < roundup(ekdata, 4 * MEG)) {
2117 prom_printf("pmap_protect: va=%08x in locked TLB\n", 2111 prom_printf("pmap_protect: va=%08x in locked TLB\n",
2118 sva); 2112 sva);
2119 prom_abort(); 2113 prom_abort();
2120 return; 2114 return;
2121 } 2115 }
2122#endif 2116#endif
2123 DPRINTF(PDB_CHANGEPROT, ("pmap_protect: va %p\n", 2117 DPRINTF(PDB_CHANGEPROT, ("pmap_protect: va %p\n",
2124 (void *)(u_long)sva)); 2118 (void *)(u_long)sva));
2125 data = pseg_get(pm, sva); 2119 data = pseg_get(pm, sva);
2126 if ((data & TLB_V) == 0) { 2120 if ((data & TLB_V) == 0) {
2127 continue; 2121 continue;
2128 } 2122 }
2129 2123
2130 pa = data & TLB_PA_MASK; 2124 pa = data & TLB_PA_MASK;
2131 DPRINTF(PDB_CHANGEPROT|PDB_REF, 2125 DPRINTF(PDB_CHANGEPROT|PDB_REF,
2132 ("pmap_protect: va=%08x data=%08llx " 2126 ("pmap_protect: va=%08x data=%08llx "
2133 "seg=%08x pte=%08x\n", 2127 "seg=%08x pte=%08x\n",
2134 (u_int)sva, (long long)pa, (int)va_to_seg(sva), 2128 (u_int)sva, (long long)pa, (int)va_to_seg(sva),
2135 (int)va_to_pte(sva))); 2129 (int)va_to_pte(sva)));
2136 2130
2137 pg = PHYS_TO_VM_PAGE(pa); 2131 pg = PHYS_TO_VM_PAGE(pa);
2138 if (pg) { 2132 if (pg) {
2139 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2133 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2140 2134
2141 /* Save REF/MOD info */ 2135 /* Save REF/MOD info */
2142 pv = &md->mdpg_pvh; 2136 pv = &md->mdpg_pvh;
2143 if (data & TLB_ACCESS) 2137 if (data & TLB_ACCESS)
2144 pv->pv_va |= PV_REF; 2138 pv->pv_va |= PV_REF;
2145 if (data & TLB_MODIFY) 2139 if (data & TLB_MODIFY)
2146 pv->pv_va |= PV_MOD; 2140 pv->pv_va |= PV_MOD;
2147 } 2141 }
2148 2142
2149 /* Just do the pmap and TSB, not the pv_list */ 2143 /* Just do the pmap and TSB, not the pv_list */
2150 if ((prot & VM_PROT_WRITE) == 0) 2144 if ((prot & VM_PROT_WRITE) == 0)
2151 data &= ~(TLB_W|TLB_REAL_W); 2145 data &= ~(TLB_W|TLB_REAL_W);
2152 if ((prot & VM_PROT_EXECUTE) == 0) 2146 if ((prot & VM_PROT_EXECUTE) == 0)
2153 data &= ~(TLB_EXEC); 2147 data &= ~(TLB_EXEC);
2154 2148
2155 rv = pseg_set(pm, sva, data, 0); 2149 rv = pseg_set(pm, sva, data, 0);
2156 if (rv & 1) 2150 if (rv & 1)
2157 panic("pmap_protect: pseg_set needs spare! rv=%d\n", 2151 panic("pmap_protect: pseg_set needs spare! rv=%d\n",
2158 rv); 2152 rv);
2159 2153
2160 if (pm != pmap_kernel() && !pmap_has_ctx(pm)) 2154 if (pm != pmap_kernel() && !pmap_has_ctx(pm))
2161 continue; 2155 continue;
2162 2156
2163 KASSERT(pmap_ctx(pm)>=0); 2157 KASSERT(pmap_ctx(pm)>=0);
2164 tsb_invalidate(sva, pm); 2158 tsb_invalidate(sva, pm);
2165 tlb_flush_pte(sva, pm); 2159 tlb_flush_pte(sva, pm);
2166 } 2160 }
2167 pv_check(); 2161 pv_check();
2168} 2162}
2169 2163
2170/* 2164/*
2171 * Extract the physical page address associated 2165 * Extract the physical page address associated
2172 * with the given map/virtual_address pair. 2166 * with the given map/virtual_address pair.
2173 */ 2167 */
2174bool 2168bool
2175pmap_extract(struct pmap *pm, vaddr_t va, paddr_t *pap) 2169pmap_extract(struct pmap *pm, vaddr_t va, paddr_t *pap)
2176{ 2170{
2177 paddr_t pa; 2171 paddr_t pa;
2178 int64_t data = 0; 2172 int64_t data = 0;
2179 2173
2180 if (pm == pmap_kernel() && va >= kdata && va < roundup(ekdata, 4*MEG)) { 2174 if (pm == pmap_kernel() && va >= kdata && va < roundup(ekdata, 4*MEG)) {
2181 /* Need to deal w/locked TLB entry specially. */ 2175 /* Need to deal w/locked TLB entry specially. */
2182 pa = pmap_kextract(va); 2176 pa = pmap_kextract(va);
2183 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n", 2177 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
2184 (u_long)va, (unsigned long long)pa)); 2178 (u_long)va, (unsigned long long)pa));
2185 if (pap != NULL) 2179 if (pap != NULL)
2186 *pap = pa; 2180 *pap = pa;
2187 return TRUE; 2181 return TRUE;
2188 } else if (pm == pmap_kernel() && va >= ktext && va < ektext) { 2182 } else if (pm == pmap_kernel() && va >= ktext && va < ektext) {
2189 /* Need to deal w/locked TLB entry specially. */ 2183 /* Need to deal w/locked TLB entry specially. */
2190 pa = pmap_kextract(va); 2184 pa = pmap_kextract(va);
2191 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n", 2185 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
2192 (u_long)va, (unsigned long long)pa)); 2186 (u_long)va, (unsigned long long)pa));
2193 if (pap != NULL) 2187 if (pap != NULL)
2194 *pap = pa; 2188 *pap = pa;
2195 return TRUE; 2189 return TRUE;
2196 } else if (pm == pmap_kernel() && va >= INTSTACK && va < (INTSTACK + 64*KB)) { 2190 } else if (pm == pmap_kernel() && va >= INTSTACK && va < (INTSTACK + 64*KB)) {
2197 pa = (paddr_t)(curcpu()->ci_paddr - INTSTACK + va); 2191 pa = (paddr_t)(curcpu()->ci_paddr - INTSTACK + va);
2198 DPRINTF(PDB_EXTRACT, ("pmap_extract (intstack): va=%lx pa=%llx\n", 2192 DPRINTF(PDB_EXTRACT, ("pmap_extract (intstack): va=%lx pa=%llx\n",
2199 (u_long)va, (unsigned long long)pa)); 2193 (u_long)va, (unsigned long long)pa));
2200 if (pap != NULL) 2194 if (pap != NULL)
2201 *pap = pa; 2195 *pap = pa;
2202 return TRUE; 2196 return TRUE;
2203 } else { 2197 } else {
2204 data = pseg_get(pm, va); 2198 data = pseg_get(pm, va);
2205 pa = data & TLB_PA_MASK; 2199 pa = data & TLB_PA_MASK;
2206#ifdef DEBUG 2200#ifdef DEBUG
2207 if (pmapdebug & PDB_EXTRACT) { 2201 if (pmapdebug & PDB_EXTRACT) {
2208 paddr_t npa = ldxa((vaddr_t)&pm->pm_segs[va_to_seg(va)], 2202 paddr_t npa = ldxa((vaddr_t)&pm->pm_segs[va_to_seg(va)],
2209 ASI_PHYS_CACHED); 2203 ASI_PHYS_CACHED);
2210 printf("pmap_extract: va=%p segs[%ld]=%llx", 2204 printf("pmap_extract: va=%p segs[%ld]=%llx",
2211 (void *)(u_long)va, (long)va_to_seg(va), 2205 (void *)(u_long)va, (long)va_to_seg(va),
2212 (unsigned long long)npa); 2206 (unsigned long long)npa);
2213 if (npa) { 2207 if (npa) {
2214 npa = (paddr_t) 2208 npa = (paddr_t)
2215 ldxa((vaddr_t)&((paddr_t *)(u_long)npa) 2209 ldxa((vaddr_t)&((paddr_t *)(u_long)npa)
2216 [va_to_dir(va)], 2210 [va_to_dir(va)],
2217 ASI_PHYS_CACHED); 2211 ASI_PHYS_CACHED);
2218 printf(" segs[%ld][%ld]=%lx", 2212 printf(" segs[%ld][%ld]=%lx",
2219 (long)va_to_seg(va), 2213 (long)va_to_seg(va),
2220 (long)va_to_dir(va), (long)npa); 2214 (long)va_to_dir(va), (long)npa);
2221 } 2215 }
2222 if (npa) { 2216 if (npa) {
2223 npa = (paddr_t) 2217 npa = (paddr_t)
2224 ldxa((vaddr_t)&((paddr_t *)(u_long)npa) 2218 ldxa((vaddr_t)&((paddr_t *)(u_long)npa)
2225 [va_to_pte(va)], 2219 [va_to_pte(va)],
2226 ASI_PHYS_CACHED); 2220 ASI_PHYS_CACHED);
2227 printf(" segs[%ld][%ld][%ld]=%lx", 2221 printf(" segs[%ld][%ld][%ld]=%lx",
2228 (long)va_to_seg(va), 2222 (long)va_to_seg(va),
2229 (long)va_to_dir(va), 2223 (long)va_to_dir(va),
2230 (long)va_to_pte(va), (long)npa); 2224 (long)va_to_pte(va), (long)npa);
2231 } 2225 }
2232 printf(" pseg_get: %lx\n", (long)pa); 2226 printf(" pseg_get: %lx\n", (long)pa);
2233 } 2227 }
2234#endif 2228#endif
2235 } 2229 }
2236 if ((data & TLB_V) == 0) 2230 if ((data & TLB_V) == 0)
2237 return (FALSE); 2231 return (FALSE);
2238 if (pap != NULL) 2232 if (pap != NULL)
2239 *pap = pa + (va & PGOFSET); 2233 *pap = pa + (va & PGOFSET);
2240 return (TRUE); 2234 return (TRUE);
2241} 2235}
2242 2236
2243/* 2237/*
2244 * Change protection on a kernel address. 2238 * Change protection on a kernel address.
2245 * This should only be called from MD code. 2239 * This should only be called from MD code.
2246 */ 2240 */
2247void 2241void
2248pmap_kprotect(vaddr_t va, vm_prot_t prot) 2242pmap_kprotect(vaddr_t va, vm_prot_t prot)
2249{ 2243{
2250 struct pmap *pm = pmap_kernel(); 2244 struct pmap *pm = pmap_kernel();
2251 int64_t data; 2245 int64_t data;
2252 int rv; 2246 int rv;
2253 2247
2254 data = pseg_get(pm, va); 2248 data = pseg_get(pm, va);
2255 KASSERT(data & TLB_V); 2249 KASSERT(data & TLB_V);
2256 if (prot & VM_PROT_WRITE) { 2250 if (prot & VM_PROT_WRITE) {
2257 data |= (TLB_W|TLB_REAL_W); 2251 data |= (TLB_W|TLB_REAL_W);
2258 } else { 2252 } else {
2259 data &= ~(TLB_W|TLB_REAL_W); 2253 data &= ~(TLB_W|TLB_REAL_W);
2260 } 2254 }
2261 rv = pseg_set(pm, va, data, 0); 2255 rv = pseg_set(pm, va, data, 0);
2262 if (rv & 1) 2256 if (rv & 1)
2263 panic("pmap_kprotect: pseg_set needs spare! rv=%d", rv); 2257 panic("pmap_kprotect: pseg_set needs spare! rv=%d", rv);
2264 KASSERT(pmap_ctx(pm)>=0); 2258 KASSERT(pmap_ctx(pm)>=0);
2265 tsb_invalidate(va, pm); 2259 tsb_invalidate(va, pm);
2266 tlb_flush_pte(va, pm); 2260 tlb_flush_pte(va, pm);
2267} 2261}
2268 2262
2269/* 2263/*
2270 * Return the number bytes that pmap_dumpmmu() will dump. 2264 * Return the number bytes that pmap_dumpmmu() will dump.
2271 */ 2265 */
2272int 2266int
2273pmap_dumpsize(void) 2267pmap_dumpsize(void)
2274{ 2268{
2275 int sz; 2269 int sz;
2276 2270
2277 sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); 2271 sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
2278 sz += kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg); 2272 sz += kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg);
2279 sz += phys_installed_size * sizeof(phys_ram_seg_t); 2273 sz += phys_installed_size * sizeof(phys_ram_seg_t);
2280 2274
2281 return btodb(sz + DEV_BSIZE - 1); 2275 return btodb(sz + DEV_BSIZE - 1);
2282} 2276}
2283 2277
2284/* 2278/*
2285 * Write the mmu contents to the dump device. 2279 * Write the mmu contents to the dump device.
2286 * This gets appended to the end of a crash dump since 2280 * This gets appended to the end of a crash dump since
2287 * there is no in-core copy of kernel memory mappings on a 4/4c machine. 2281 * there is no in-core copy of kernel memory mappings on a 4/4c machine.
2288 * 2282 *
2289 * Write the core dump headers and MD data to the dump device. 2283 * Write the core dump headers and MD data to the dump device.
2290 * We dump the following items: 2284 * We dump the following items:
2291 * 2285 *
2292 * kcore_seg_t MI header defined in <sys/kcore.h>) 2286 * kcore_seg_t MI header defined in <sys/kcore.h>)
2293 * cpu_kcore_hdr_t MD header defined in <machine/kcore.h>) 2287 * cpu_kcore_hdr_t MD header defined in <machine/kcore.h>)
2294 * phys_ram_seg_t[phys_installed_size] physical memory segments 2288 * phys_ram_seg_t[phys_installed_size] physical memory segments
2295 */ 2289 */
2296int 2290int
2297pmap_dumpmmu(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t blkno) 2291pmap_dumpmmu(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t blkno)
2298{ 2292{
2299 kcore_seg_t *kseg; 2293 kcore_seg_t *kseg;
2300 cpu_kcore_hdr_t *kcpu; 2294 cpu_kcore_hdr_t *kcpu;
2301 phys_ram_seg_t memseg; 2295 phys_ram_seg_t memseg;
2302 struct cpu_kcore_4mbseg ktlb; 2296 struct cpu_kcore_4mbseg ktlb;
2303 int error = 0; 2297 int error = 0;
2304 int i; 2298 int i;
2305 int buffer[dbtob(1) / sizeof(int)]; 2299 int buffer[dbtob(1) / sizeof(int)];
2306 int *bp, *ep; 2300 int *bp, *ep;
2307 2301
2308#define EXPEDITE(p,n) do { \ 2302#define EXPEDITE(p,n) do { \
2309 int *sp = (void *)(p); \ 2303 int *sp = (void *)(p); \
2310 int sz = (n); \ 2304 int sz = (n); \
2311 while (sz > 0) { \ 2305 while (sz > 0) { \
2312 *bp++ = *sp++; \ 2306 *bp++ = *sp++; \
2313 if (bp >= ep) { \ 2307 if (bp >= ep) { \
2314 error = (*dump)(dumpdev, blkno, \ 2308 error = (*dump)(dumpdev, blkno, \
2315 (void *)buffer, dbtob(1)); \ 2309 (void *)buffer, dbtob(1)); \
2316 if (error != 0) \ 2310 if (error != 0) \
2317 return (error); \ 2311 return (error); \
2318 ++blkno; \ 2312 ++blkno; \
2319 bp = buffer; \ 2313 bp = buffer; \
2320 } \ 2314 } \
2321 sz -= 4; \ 2315 sz -= 4; \
2322 } \ 2316 } \
2323} while (0) 2317} while (0)
2324 2318
2325 /* Setup bookkeeping pointers */ 2319 /* Setup bookkeeping pointers */
2326 bp = buffer; 2320 bp = buffer;
2327 ep = &buffer[sizeof(buffer) / sizeof(buffer[0])]; 2321 ep = &buffer[sizeof(buffer) / sizeof(buffer[0])];
2328 2322
2329 /* Fill in MI segment header */ 2323 /* Fill in MI segment header */
2330 kseg = (kcore_seg_t *)bp; 2324 kseg = (kcore_seg_t *)bp;
2331 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 2325 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
2332 kseg->c_size = dbtob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t)); 2326 kseg->c_size = dbtob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t));
2333 2327
2334 /* Fill in MD segment header (interpreted by MD part of libkvm) */ 2328 /* Fill in MD segment header (interpreted by MD part of libkvm) */
2335 kcpu = (cpu_kcore_hdr_t *)((long)bp + ALIGN(sizeof(kcore_seg_t))); 2329 kcpu = (cpu_kcore_hdr_t *)((long)bp + ALIGN(sizeof(kcore_seg_t)));
2336 kcpu->cputype = cputyp; 2330 kcpu->cputype = cputyp;
2337 kcpu->kernbase = (uint64_t)KERNBASE; 2331 kcpu->kernbase = (uint64_t)KERNBASE;
2338 kcpu->cpubase = (uint64_t)CPUINFO_VA; 2332 kcpu->cpubase = (uint64_t)CPUINFO_VA;
2339 2333
2340 /* Describe the locked text segment */ 2334 /* Describe the locked text segment */
2341 kcpu->ktextbase = (uint64_t)ktext; 2335 kcpu->ktextbase = (uint64_t)ktext;
2342 kcpu->ktextp = (uint64_t)ktextp; 2336 kcpu->ktextp = (uint64_t)ktextp;
2343 kcpu->ktextsz = (uint64_t)ektext - ktext; 2337 kcpu->ktextsz = (uint64_t)ektext - ktext;
2344 if (kcpu->ktextsz > 4*MEG) 2338 if (kcpu->ktextsz > 4*MEG)
2345 kcpu->ktextsz = 0; /* old version can not work */ 2339 kcpu->ktextsz = 0; /* old version can not work */
2346 2340
2347 /* Describe locked data segment */ 2341 /* Describe locked data segment */
2348 kcpu->kdatabase = (uint64_t)kdata; 2342 kcpu->kdatabase = (uint64_t)kdata;
2349 kcpu->kdatap = (uint64_t)kdatap; 2343 kcpu->kdatap = (uint64_t)kdatap;
2350 kcpu->kdatasz = (uint64_t)ekdatap - kdatap; 2344 kcpu->kdatasz = (uint64_t)ekdatap - kdatap;
2351 2345
2352 /* new version of locked segments description */ 2346 /* new version of locked segments description */
2353 kcpu->newmagic = SPARC64_KCORE_NEWMAGIC; 2347 kcpu->newmagic = SPARC64_KCORE_NEWMAGIC;
2354 kcpu->num4mbsegs = kernel_tlb_slots; 2348 kcpu->num4mbsegs = kernel_tlb_slots;
2355 kcpu->off4mbsegs = ALIGN(sizeof(cpu_kcore_hdr_t)); 2349 kcpu->off4mbsegs = ALIGN(sizeof(cpu_kcore_hdr_t));
2356 2350
2357 /* description of per-cpu mappings */ 2351 /* description of per-cpu mappings */
2358 kcpu->numcpuinfos = sparc_ncpus; 2352 kcpu->numcpuinfos = sparc_ncpus;
2359 kcpu->percpusz = 64 * 1024; /* used to be 128k for some time */ 2353 kcpu->percpusz = 64 * 1024; /* used to be 128k for some time */
2360 kcpu->thiscpu = cpu_number(); /* which cpu is doing this dump */ 2354 kcpu->thiscpu = cpu_number(); /* which cpu is doing this dump */
2361 kcpu->cpusp = cpu0paddr - 64 * 1024 * sparc_ncpus; 2355 kcpu->cpusp = cpu0paddr - 64 * 1024 * sparc_ncpus;
2362 2356
2363 /* Now the memsegs */ 2357 /* Now the memsegs */
2364 kcpu->nmemseg = phys_installed_size; 2358 kcpu->nmemseg = phys_installed_size;
2365 kcpu->memsegoffset = kcpu->off4mbsegs 2359 kcpu->memsegoffset = kcpu->off4mbsegs
2366 + kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg); 2360 + kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg);
2367 2361
2368 /* Now we need to point this at our kernel pmap. */ 2362 /* Now we need to point this at our kernel pmap. */
2369 kcpu->nsegmap = STSZ; 2363 kcpu->nsegmap = STSZ;
2370 kcpu->segmapoffset = (uint64_t)pmap_kernel()->pm_physaddr; 2364 kcpu->segmapoffset = (uint64_t)pmap_kernel()->pm_physaddr;
2371 2365
2372 /* Note: we have assumed everything fits in buffer[] so far... */ 2366 /* Note: we have assumed everything fits in buffer[] so far... */
2373 bp = (int *)((long)kcpu + ALIGN(sizeof(cpu_kcore_hdr_t))); 2367 bp = (int *)((long)kcpu + ALIGN(sizeof(cpu_kcore_hdr_t)));
2374 2368
2375 /* write locked kernel 4MB TLBs */ 2369 /* write locked kernel 4MB TLBs */
2376 for (i = 0; i < kernel_tlb_slots; i++) { 2370 for (i = 0; i < kernel_tlb_slots; i++) {
2377 ktlb.va = kernel_tlbs[i].te_va; 2371 ktlb.va = kernel_tlbs[i].te_va;
2378 ktlb.pa = kernel_tlbs[i].te_pa; 2372 ktlb.pa = kernel_tlbs[i].te_pa;
2379 EXPEDITE(&ktlb, sizeof(ktlb)); 2373 EXPEDITE(&ktlb, sizeof(ktlb));
2380 } 2374 }
2381 2375
2382 /* write memsegs */ 2376 /* write memsegs */
2383 for (i = 0; i < phys_installed_size; i++) { 2377 for (i = 0; i < phys_installed_size; i++) {
2384 memseg.start = phys_installed[i].start; 2378 memseg.start = phys_installed[i].start;
2385 memseg.size = phys_installed[i].size; 2379 memseg.size = phys_installed[i].size;
2386 EXPEDITE(&memseg, sizeof(phys_ram_seg_t)); 2380 EXPEDITE(&memseg, sizeof(phys_ram_seg_t));
2387 } 2381 }
2388 2382
2389 if (bp != buffer) 2383 if (bp != buffer)
2390 error = (*dump)(dumpdev, blkno++, (void *)buffer, dbtob(1)); 2384 error = (*dump)(dumpdev, blkno++, (void *)buffer, dbtob(1));
2391 2385
2392 return (error); 2386 return (error);
2393} 2387}
2394 2388
2395/* 2389/*
2396 * Determine (non)existence of physical page 2390 * Determine (non)existence of physical page
2397 */ 2391 */
2398int 2392int
2399pmap_pa_exists(paddr_t pa) 2393pmap_pa_exists(paddr_t pa)
2400{ 2394{
2401 int i; 2395 int i;
2402 2396
2403 /* Just go through physical memory list & see if we're there */ 2397 /* Just go through physical memory list & see if we're there */
2404 for (i = 0; i < phys_installed_size; i++) { 2398 for (i = 0; i < phys_installed_size; i++) {
2405 if ((phys_installed[i].start <= pa) && 2399 if ((phys_installed[i].start <= pa) &&
2406 (phys_installed[i].start + 2400 (phys_installed[i].start +
2407 phys_installed[i].size >= pa)) 2401 phys_installed[i].size >= pa))
2408 return 1; 2402 return 1;
2409 } 2403 }
2410 return 0; 2404 return 0;
2411} 2405}
2412 2406
2413/* 2407/*
2414 * Lookup the appropriate TSB entry. 2408 * Lookup the appropriate TSB entry.
2415 * 2409 *
2416 * Here is the full official pseudo code: 2410 * Here is the full official pseudo code:
2417 * 2411 *
2418 */ 2412 */
2419 2413
2420#ifdef NOTYET 2414#ifdef NOTYET
2421int64 GenerateTSBPointer( 2415int64 GenerateTSBPointer(
2422 int64 va, /* Missing VA */ 2416 int64 va, /* Missing VA */
2423 PointerType type, /* 8K_POINTER or 16K_POINTER */ 2417 PointerType type, /* 8K_POINTER or 16K_POINTER */
2424 int64 TSBBase, /* TSB Register[63:13] << 13 */ 2418 int64 TSBBase, /* TSB Register[63:13] << 13 */
2425 Boolean split, /* TSB Register[12] */ 2419 Boolean split, /* TSB Register[12] */
2426 int TSBSize) /* TSB Register[2:0] */ 2420 int TSBSize) /* TSB Register[2:0] */
2427{ 2421{
2428 int64 vaPortion; 2422 int64 vaPortion;
2429 int64 TSBBaseMask; 2423 int64 TSBBaseMask;
2430 int64 splitMask; 2424 int64 splitMask;
2431 2425
2432 /* TSBBaseMask marks the bits from TSB Base Reg */ 2426 /* TSBBaseMask marks the bits from TSB Base Reg */
2433 TSBBaseMask = 0xffffffffffffe000 << 2427 TSBBaseMask = 0xffffffffffffe000 <<
2434 (split? (TSBsize + 1) : TSBsize); 2428 (split? (TSBsize + 1) : TSBsize);
2435 2429
2436 /* Shift va towards lsb appropriately and */ 2430 /* Shift va towards lsb appropriately and */
2437 /* zero out the original va page offset */ 2431 /* zero out the original va page offset */
2438 vaPortion = (va >> ((type == 8K_POINTER)? 9: 12)) & 2432 vaPortion = (va >> ((type == 8K_POINTER)? 9: 12)) &
2439 0xfffffffffffffff0; 2433 0xfffffffffffffff0;
2440 2434
2441 if (split) { 2435 if (split) {
2442 /* There's only one bit in question for split */ 2436 /* There's only one bit in question for split */
2443 splitMask = 1 << (13 + TSBsize); 2437 splitMask = 1 << (13 + TSBsize);
2444 if (type == 8K_POINTER) 2438 if (type == 8K_POINTER)
2445 /* Make sure we're in the lower half */ 2439 /* Make sure we're in the lower half */
2446 vaPortion &= ~splitMask; 2440 vaPortion &= ~splitMask;
2447 else 2441 else
2448 /* Make sure we're in the upper half */ 2442 /* Make sure we're in the upper half */
2449 vaPortion |= splitMask; 2443 vaPortion |= splitMask;
2450 } 2444 }
2451 return (TSBBase & TSBBaseMask) | (vaPortion & ~TSBBaseMask); 2445 return (TSBBase & TSBBaseMask) | (vaPortion & ~TSBBaseMask);
2452} 2446}
2453#endif 2447#endif
2454/* 2448/*
2455 * Of course, since we are not using a split TSB or variable page sizes, 2449 * Of course, since we are not using a split TSB or variable page sizes,
2456 * we can optimize this a bit. 2450 * we can optimize this a bit.
2457 * 2451 *
2458 * The following only works for a unified 8K TSB. It will find the slot 2452 * The following only works for a unified 8K TSB. It will find the slot
2459 * for that particular va and return it. IT MAY BE FOR ANOTHER MAPPING! 2453 * for that particular va and return it. IT MAY BE FOR ANOTHER MAPPING!
2460 */ 2454 */
2461int 2455int
2462ptelookup_va(vaddr_t va) 2456ptelookup_va(vaddr_t va)
2463{ 2457{
2464 long tsbptr; 2458 long tsbptr;
2465#define TSBBASEMASK (0xffffffffffffe000LL << tsbsize) 2459#define TSBBASEMASK (0xffffffffffffe000LL << tsbsize)
2466 2460
2467 tsbptr = (((va >> 9) & 0xfffffffffffffff0LL) & ~TSBBASEMASK); 2461 tsbptr = (((va >> 9) & 0xfffffffffffffff0LL) & ~TSBBASEMASK);
2468 return (tsbptr / sizeof(pte_t)); 2462 return (tsbptr / sizeof(pte_t));
2469} 2463}
2470 2464
2471/* 2465/*
2472 * Do whatever is needed to sync the MOD/REF flags 2466 * Do whatever is needed to sync the MOD/REF flags
2473 */ 2467 */
2474 2468
2475bool 2469bool
2476pmap_clear_modify(struct vm_page *pg) 2470pmap_clear_modify(struct vm_page *pg)
2477{ 2471{
2478 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2472 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2479 pv_entry_t pv; 2473 pv_entry_t pv;
2480 int rv; 2474 int rv;
2481 int changed = 0; 2475 int changed = 0;
2482#ifdef DEBUG 2476#ifdef DEBUG
2483 int modified = 0; 2477 int modified = 0;
2484 2478
2485 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_modify(%p)\n", pg)); 2479 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_modify(%p)\n", pg));
2486 2480
2487 modified = pmap_is_modified(pg); 2481 modified = pmap_is_modified(pg);
2488#endif 2482#endif
2489 mutex_enter(&pmap_lock); 2483 mutex_enter(&pmap_lock);
2490 /* Clear all mappings */ 2484 /* Clear all mappings */
2491 pv = &md->mdpg_pvh; 2485 pv = &md->mdpg_pvh;
2492#ifdef DEBUG 2486#ifdef DEBUG
2493 if (pv->pv_va & PV_MOD) 2487 if (pv->pv_va & PV_MOD)
2494 pv->pv_va |= PV_WE; /* Remember this was modified */ 2488 pv->pv_va |= PV_WE; /* Remember this was modified */
2495#endif 2489#endif
2496 if (pv->pv_va & PV_MOD) { 2490 if (pv->pv_va & PV_MOD) {
2497 changed |= 1; 2491 changed |= 1;
2498 pv->pv_va &= ~PV_MOD; 2492 pv->pv_va &= ~PV_MOD;
2499 } 2493 }
2500#ifdef DEBUG 2494#ifdef DEBUG
2501 if (pv->pv_next && !pv->pv_pmap) { 2495 if (pv->pv_next && !pv->pv_pmap) {
2502 printf("pmap_clear_modify: npv but no pmap for pv %p\n", pv); 2496 printf("pmap_clear_modify: npv but no pmap for pv %p\n", pv);
2503 Debugger(); 2497 Debugger();
2504 } 2498 }
2505#endif 2499#endif
2506 if (pv->pv_pmap != NULL) { 2500 if (pv->pv_pmap != NULL) {
2507 for (; pv; pv = pv->pv_next) { 2501 for (; pv; pv = pv->pv_next) {
2508 int64_t data; 2502 int64_t data;
2509 struct pmap *pmap = pv->pv_pmap; 2503 struct pmap *pmap = pv->pv_pmap;
2510 vaddr_t va = pv->pv_va & PV_VAMASK; 2504 vaddr_t va = pv->pv_va & PV_VAMASK;
2511 2505
2512 /* First clear the mod bit in the PTE and make it R/O */ 2506 /* First clear the mod bit in the PTE and make it R/O */
2513 data = pseg_get(pmap, va); 2507 data = pseg_get(pmap, va);
2514 KASSERT(data & TLB_V); 2508 KASSERT(data & TLB_V);
2515 /* Need to both clear the modify and write bits */ 2509 /* Need to both clear the modify and write bits */
2516 if (data & TLB_MODIFY) 2510 if (data & TLB_MODIFY)
2517 changed |= 1; 2511 changed |= 1;
2518#ifdef HWREF 2512#ifdef HWREF
2519 data &= ~(TLB_MODIFY|TLB_W); 2513 data &= ~(TLB_MODIFY|TLB_W);
2520#else 2514#else
2521 data &= ~(TLB_MODIFY|TLB_W|TLB_REAL_W); 2515 data &= ~(TLB_MODIFY|TLB_W|TLB_REAL_W);
2522#endif 2516#endif
2523 rv = pseg_set(pmap, va, data, 0); 2517 rv = pseg_set(pmap, va, data, 0);
2524 if (rv & 1) 2518 if (rv & 1)
2525 printf("pmap_clear_modify: pseg_set needs" 2519 printf("pmap_clear_modify: pseg_set needs"
2526 " spare! rv=%d\n", rv); 2520 " spare! rv=%d\n", rv);
2527 if (pmap_is_on_mmu(pmap)) { 2521 if (pmap_is_on_mmu(pmap)) {
2528 KASSERT(pmap_ctx(pmap)>=0); 2522 KASSERT(pmap_ctx(pmap)>=0);
2529 tsb_invalidate(va, pmap); 2523 tsb_invalidate(va, pmap);
2530 tlb_flush_pte(va, pmap); 2524 tlb_flush_pte(va, pmap);
2531 } 2525 }
2532 /* Then clear the mod bit in the pv */ 2526 /* Then clear the mod bit in the pv */
2533 if (pv->pv_va & PV_MOD) { 2527 if (pv->pv_va & PV_MOD) {
2534 changed |= 1; 2528 changed |= 1;
2535 pv->pv_va &= ~PV_MOD; 2529 pv->pv_va &= ~PV_MOD;
2536 } 2530 }
2537 } 2531 }
2538 } 2532 }
2539 pv_check(); 2533 pv_check();
2540 mutex_exit(&pmap_lock); 2534 mutex_exit(&pmap_lock);
2541#ifdef DEBUG 2535#ifdef DEBUG
2542 if (pmap_is_modified(pg)) { 2536 if (pmap_is_modified(pg)) {
2543 printf("pmap_clear_modify(): %p still modified!\n", pg); 2537 printf("pmap_clear_modify(): %p still modified!\n", pg);
2544 Debugger(); 2538 Debugger();
2545 } 2539 }
2546 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_modify: pg %p %s\n", pg, 2540 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_modify: pg %p %s\n", pg,
2547 (changed ? "was modified" : "was not modified"))); 2541 (changed ? "was modified" : "was not modified")));
2548 if (modified != changed) { 2542 if (modified != changed) {
2549 printf("pmap_clear_modify: modified %d changed %d\n", 2543 printf("pmap_clear_modify: modified %d changed %d\n",
2550 modified, changed); 2544 modified, changed);
2551 Debugger(); 2545 Debugger();
2552 } else return (modified); 2546 } else return (modified);
2553#endif 2547#endif
2554 return (changed); 2548 return (changed);
2555} 2549}
2556 2550
2557bool 2551bool
2558pmap_clear_reference(struct vm_page *pg) 2552pmap_clear_reference(struct vm_page *pg)
2559{ 2553{
2560 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2554 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2561 pv_entry_t pv; 2555 pv_entry_t pv;
2562 int rv; 2556 int rv;
2563 int changed = 0; 2557 int changed = 0;
2564#ifdef DEBUG 2558#ifdef DEBUG
2565 int referenced = 0; 2559 int referenced = 0;
2566#endif 2560#endif
2567 2561
2568 mutex_enter(&pmap_lock); 2562 mutex_enter(&pmap_lock);
2569#ifdef DEBUG 2563#ifdef DEBUG
2570 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_reference(%p)\n", pg)); 2564 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_reference(%p)\n", pg));
2571 referenced = pmap_is_referenced_locked(pg); 2565 referenced = pmap_is_referenced_locked(pg);
2572#endif 2566#endif
2573 /* Clear all references */ 2567 /* Clear all references */
2574 pv = &md->mdpg_pvh; 2568 pv = &md->mdpg_pvh;
2575 if (pv->pv_va & PV_REF) { 2569 if (pv->pv_va & PV_REF) {
2576 changed |= 1; 2570 changed |= 1;
2577 pv->pv_va &= ~PV_REF; 2571 pv->pv_va &= ~PV_REF;
2578 } 2572 }
2579#ifdef DEBUG 2573#ifdef DEBUG
2580 if (pv->pv_next && !pv->pv_pmap) { 2574 if (pv->pv_next && !pv->pv_pmap) {
2581 printf("pmap_clear_reference: npv but no pmap for pv %p\n", pv); 2575 printf("pmap_clear_reference: npv but no pmap for pv %p\n", pv);
2582 Debugger(); 2576 Debugger();
2583 } 2577 }
2584#endif 2578#endif
2585 if (pv->pv_pmap != NULL) { 2579 if (pv->pv_pmap != NULL) {
2586 for (; pv; pv = pv->pv_next) { 2580 for (; pv; pv = pv->pv_next) {
2587 int64_t data; 2581 int64_t data;
2588 struct pmap *pmap = pv->pv_pmap; 2582 struct pmap *pmap = pv->pv_pmap;
2589 vaddr_t va = pv->pv_va & PV_VAMASK; 2583 vaddr_t va = pv->pv_va & PV_VAMASK;
2590 2584
2591 data = pseg_get(pmap, va); 2585 data = pseg_get(pmap, va);
2592 KASSERT(data & TLB_V); 2586 KASSERT(data & TLB_V);
2593 DPRINTF(PDB_CHANGEPROT, 2587 DPRINTF(PDB_CHANGEPROT,
2594 ("clearing ref pm:%p va:%p ctx:%lx data:%llx\n", 2588 ("clearing ref pm:%p va:%p ctx:%lx data:%llx\n",
2595 pmap, (void *)(u_long)va, 2589 pmap, (void *)(u_long)va,
2596 (u_long)pmap_ctx(pmap), 2590 (u_long)pmap_ctx(pmap),
2597 (long long)data)); 2591 (long long)data));
2598#ifdef HWREF 2592#ifdef HWREF
2599 if (data & TLB_ACCESS) { 2593 if (data & TLB_ACCESS) {
2600 changed |= 1; 2594 changed |= 1;
2601 data &= ~TLB_ACCESS; 2595 data &= ~TLB_ACCESS;
2602 } 2596 }
2603#else 2597#else
2604 if (data < 0) 2598 if (data < 0)
2605 changed |= 1; 2599 changed |= 1;
2606 data = 0; 2600 data = 0;
2607#endif 2601#endif
2608 rv = pseg_set(pmap, va, data, 0); 2602 rv = pseg_set(pmap, va, data, 0);
2609 if (rv & 1) 2603 if (rv & 1)
2610 panic("pmap_clear_reference: pseg_set needs" 2604 panic("pmap_clear_reference: pseg_set needs"
2611 " spare! rv=%d\n", rv); 2605 " spare! rv=%d\n", rv);
2612 if (pmap_is_on_mmu(pmap)) { 2606 if (pmap_is_on_mmu(pmap)) {
2613 KASSERT(pmap_ctx(pmap)>=0); 2607 KASSERT(pmap_ctx(pmap)>=0);
2614 tsb_invalidate(va, pmap); 2608 tsb_invalidate(va, pmap);
2615 tlb_flush_pte(va, pmap); 2609 tlb_flush_pte(va, pmap);
2616 } 2610 }
2617 if (pv->pv_va & PV_REF) { 2611 if (pv->pv_va & PV_REF) {
2618 changed |= 1; 2612 changed |= 1;
2619 pv->pv_va &= ~PV_REF; 2613 pv->pv_va &= ~PV_REF;
2620 } 2614 }
2621 } 2615 }
2622 } 2616 }
2623 dcache_flush_page_all(VM_PAGE_TO_PHYS(pg)); 2617 dcache_flush_page_all(VM_PAGE_TO_PHYS(pg));
2624 pv_check(); 2618 pv_check();
2625#ifdef DEBUG 2619#ifdef DEBUG
2626 if (pmap_is_referenced_locked(pg)) { 2620 if (pmap_is_referenced_locked(pg)) {
2627 pv = &md->mdpg_pvh; 2621 pv = &md->mdpg_pvh;
2628 printf("pmap_clear_reference(): %p still referenced " 2622 printf("pmap_clear_reference(): %p still referenced "
2629 "(pmap = %p, ctx = %d)\n", pg, pv->pv_pmap, 2623 "(pmap = %p, ctx = %d)\n", pg, pv->pv_pmap,
2630 pv->pv_pmap ? pmap_ctx(pv->pv_pmap) : 0); 2624 pv->pv_pmap ? pmap_ctx(pv->pv_pmap) : 0);
2631 Debugger(); 2625 Debugger();
2632 } 2626 }
2633 DPRINTF(PDB_CHANGEPROT|PDB_REF, 2627 DPRINTF(PDB_CHANGEPROT|PDB_REF,
2634 ("pmap_clear_reference: pg %p %s\n", pg, 2628 ("pmap_clear_reference: pg %p %s\n", pg,
2635 (changed ? "was referenced" : "was not referenced"))); 2629 (changed ? "was referenced" : "was not referenced")));
2636 if (referenced != changed) { 2630 if (referenced != changed) {
2637 printf("pmap_clear_reference: referenced %d changed %d\n", 2631 printf("pmap_clear_reference: referenced %d changed %d\n",
2638 referenced, changed); 2632 referenced, changed);
2639 Debugger(); 2633 Debugger();
2640 } else { 2634 } else {
2641 mutex_exit(&pmap_lock); 2635 mutex_exit(&pmap_lock);
2642 return (referenced); 2636 return (referenced);
2643 } 2637 }
2644#endif 2638#endif
2645 mutex_exit(&pmap_lock); 2639 mutex_exit(&pmap_lock);
2646 return (changed); 2640 return (changed);
2647} 2641}
2648 2642
2649bool 2643bool
2650pmap_is_modified(struct vm_page *pg) 2644pmap_is_modified(struct vm_page *pg)
2651{ 2645{
2652 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2646 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2653 pv_entry_t pv, npv; 2647 pv_entry_t pv, npv;
2654 bool res = false; 2648 bool res = false;
2655 2649
2656 /* Check if any mapping has been modified */ 2650 /* Check if any mapping has been modified */
2657 pv = &md->mdpg_pvh; 2651 pv = &md->mdpg_pvh;
2658 if (pv->pv_va & PV_MOD) 2652 if (pv->pv_va & PV_MOD)
2659 res = true; 2653 res = true;
2660#ifdef HWREF 2654#ifdef HWREF
2661#ifdef DEBUG 2655#ifdef DEBUG
2662 if (pv->pv_next && !pv->pv_pmap) { 2656 if (pv->pv_next && !pv->pv_pmap) {
2663 printf("pmap_is_modified: npv but no pmap for pv %p\n", pv); 2657 printf("pmap_is_modified: npv but no pmap for pv %p\n", pv);
2664 Debugger(); 2658 Debugger();
2665 } 2659 }
2666#endif 2660#endif
2667 if (!res && pv->pv_pmap != NULL) { 2661 if (!res && pv->pv_pmap != NULL) {
2668 mutex_enter(&pmap_lock); 2662 mutex_enter(&pmap_lock);
2669 for (npv = pv; !res && npv && npv->pv_pmap; 2663 for (npv = pv; !res && npv && npv->pv_pmap;
2670 npv = npv->pv_next) { 2664 npv = npv->pv_next) {
2671 int64_t data; 2665 int64_t data;
2672 2666
2673 data = pseg_get(npv->pv_pmap, npv->pv_va & PV_VAMASK); 2667 data = pseg_get(npv->pv_pmap, npv->pv_va & PV_VAMASK);
2674 KASSERT(data & TLB_V); 2668 KASSERT(data & TLB_V);
2675 if (data & TLB_MODIFY) 2669 if (data & TLB_MODIFY)
2676 res = true; 2670 res = true;
2677 2671
2678 /* Migrate modify info to head pv */ 2672 /* Migrate modify info to head pv */
2679 if (npv->pv_va & PV_MOD) { 2673 if (npv->pv_va & PV_MOD) {
2680 res = true; 2674 res = true;
2681 npv->pv_va &= ~PV_MOD; 2675 npv->pv_va &= ~PV_MOD;
2682 } 2676 }
2683 } 2677 }
2684 /* Save modify info */ 2678 /* Save modify info */
2685 if (res) 2679 if (res)
2686 pv->pv_va |= PV_MOD; 2680 pv->pv_va |= PV_MOD;
2687#ifdef DEBUG 2681#ifdef DEBUG
2688 if (res) 2682 if (res)
2689 pv->pv_va |= PV_WE; 2683 pv->pv_va |= PV_WE;
2690#endif 2684#endif
2691 mutex_exit(&pmap_lock); 2685 mutex_exit(&pmap_lock);
2692 } 2686 }
2693#endif 2687#endif
2694 2688
2695 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_is_modified(%p) = %d\n", pg, 2689 DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_is_modified(%p) = %d\n", pg,
2696 res)); 2690 res));
2697 pv_check(); 2691 pv_check();
2698 return res; 2692 return res;
2699} 2693}
2700 2694
2701/* 2695/*
2702 * Variant of pmap_is_reference() where caller already holds pmap_lock 2696 * Variant of pmap_is_reference() where caller already holds pmap_lock
2703 */ 2697 */
2704static bool 2698static bool
2705pmap_is_referenced_locked(struct vm_page *pg) 2699pmap_is_referenced_locked(struct vm_page *pg)
2706{ 2700{
2707 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2701 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2708 pv_entry_t pv, npv; 2702 pv_entry_t pv, npv;
2709 bool res = false; 2703 bool res = false;
2710 2704
2711 KASSERT(mutex_owned(&pmap_lock)); 2705 KASSERT(mutex_owned(&pmap_lock));
2712 2706
2713 /* Check if any mapping has been referenced */ 2707 /* Check if any mapping has been referenced */
2714 pv = &md->mdpg_pvh; 2708 pv = &md->mdpg_pvh;
2715 if (pv->pv_va & PV_REF) 2709 if (pv->pv_va & PV_REF)
2716 return true; 2710 return true;
2717 2711
2718#ifdef HWREF 2712#ifdef HWREF
2719#ifdef DEBUG 2713#ifdef DEBUG
2720 if (pv->pv_next && !pv->pv_pmap) { 2714 if (pv->pv_next && !pv->pv_pmap) {
2721 printf("pmap_is_referenced: npv but no pmap for pv %p\n", pv); 2715 printf("pmap_is_referenced: npv but no pmap for pv %p\n", pv);
2722 Debugger(); 2716 Debugger();
2723 } 2717 }
2724#endif 2718#endif
2725 if (pv->pv_pmap == NULL) 2719 if (pv->pv_pmap == NULL)
2726 return false; 2720 return false;
2727 2721
2728 for (npv = pv; npv; npv = npv->pv_next) { 2722 for (npv = pv; npv; npv = npv->pv_next) {
2729 int64_t data; 2723 int64_t data;
2730 2724
2731 data = pseg_get(npv->pv_pmap, npv->pv_va & PV_VAMASK); 2725 data = pseg_get(npv->pv_pmap, npv->pv_va & PV_VAMASK);
2732 KASSERT(data & TLB_V); 2726 KASSERT(data & TLB_V);
2733 if (data & TLB_ACCESS) 2727 if (data & TLB_ACCESS)
2734 res = true; 2728 res = true;
2735 2729
2736 /* Migrate ref info to head pv */ 2730 /* Migrate ref info to head pv */
2737 if (npv->pv_va & PV_REF) { 2731 if (npv->pv_va & PV_REF) {
2738 res = true; 2732 res = true;
2739 npv->pv_va &= ~PV_REF; 2733 npv->pv_va &= ~PV_REF;
2740 } 2734 }
2741 } 2735 }
2742 /* Save ref info */ 2736 /* Save ref info */
2743 if (res) 2737 if (res)
2744 pv->pv_va |= PV_REF; 2738 pv->pv_va |= PV_REF;
2745#endif 2739#endif
2746 2740
2747 DPRINTF(PDB_CHANGEPROT|PDB_REF, 2741 DPRINTF(PDB_CHANGEPROT|PDB_REF,
2748 ("pmap_is_referenced(%p) = %d\n", pg, res)); 2742 ("pmap_is_referenced(%p) = %d\n", pg, res));
2749 pv_check(); 2743 pv_check();
2750 return res; 2744 return res;
2751} 2745}
2752 2746
2753bool 2747bool
2754pmap_is_referenced(struct vm_page *pg) 2748pmap_is_referenced(struct vm_page *pg)
2755{ 2749{
2756 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2750 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2757 pv_entry_t pv; 2751 pv_entry_t pv;
2758 bool res = false; 2752 bool res = false;
2759 2753
2760 /* Check if any mapping has been referenced */ 2754 /* Check if any mapping has been referenced */
2761 pv = &md->mdpg_pvh; 2755 pv = &md->mdpg_pvh;
2762 if (pv->pv_va & PV_REF) 2756 if (pv->pv_va & PV_REF)
2763 return true; 2757 return true;
2764 2758
2765#ifdef HWREF 2759#ifdef HWREF
2766#ifdef DEBUG 2760#ifdef DEBUG
2767 if (pv->pv_next && !pv->pv_pmap) { 2761 if (pv->pv_next && !pv->pv_pmap) {
2768 printf("pmap_is_referenced: npv but no pmap for pv %p\n", pv); 2762 printf("pmap_is_referenced: npv but no pmap for pv %p\n", pv);
2769 Debugger(); 2763 Debugger();
2770 } 2764 }
2771#endif 2765#endif
2772 if (pv->pv_pmap != NULL) { 2766 if (pv->pv_pmap != NULL) {
2773 mutex_enter(&pmap_lock); 2767 mutex_enter(&pmap_lock);
2774 res = pmap_is_referenced_locked(pg); 2768 res = pmap_is_referenced_locked(pg);
2775 mutex_exit(&pmap_lock); 2769 mutex_exit(&pmap_lock);
2776 } 2770 }
2777#endif 2771#endif
2778 2772
2779 DPRINTF(PDB_CHANGEPROT|PDB_REF, 2773 DPRINTF(PDB_CHANGEPROT|PDB_REF,
2780 ("pmap_is_referenced(%p) = %d\n", pg, res)); 2774 ("pmap_is_referenced(%p) = %d\n", pg, res));
2781 pv_check(); 2775 pv_check();
2782 return res; 2776 return res;
2783} 2777}
2784 2778
2785 2779
2786 2780
2787/* 2781/*
2788 * Routine: pmap_unwire 2782 * Routine: pmap_unwire
2789 * Function: Clear the wired attribute for a map/virtual-address 2783 * Function: Clear the wired attribute for a map/virtual-address
2790 * pair. 2784 * pair.
2791 * In/out conditions: 2785 * In/out conditions:
2792 * The mapping must already exist in the pmap. 2786 * The mapping must already exist in the pmap.
2793 */ 2787 */
2794void 2788void
2795pmap_unwire(pmap_t pmap, vaddr_t va) 2789pmap_unwire(pmap_t pmap, vaddr_t va)
2796{ 2790{
2797 int64_t data; 2791 int64_t data;
2798 int rv; 2792 int rv;
2799 2793
2800 DPRINTF(PDB_MMU_STEAL, ("pmap_unwire(%p, %lx)\n", pmap, va)); 2794 DPRINTF(PDB_MMU_STEAL, ("pmap_unwire(%p, %lx)\n", pmap, va));
2801 2795
2802#ifdef DEBUG 2796#ifdef DEBUG
2803 /* 2797 /*
2804 * Is this part of the permanent 4MB mapping? 2798 * Is this part of the permanent 4MB mapping?
2805 */ 2799 */
2806 if (pmap == pmap_kernel() && va >= ktext && 2800 if (pmap == pmap_kernel() && va >= ktext &&
2807 va < roundup(ekdata, 4*MEG)) { 2801 va < roundup(ekdata, 4*MEG)) {
2808 prom_printf("pmap_unwire: va=%08x in locked TLB\n", va); 2802 prom_printf("pmap_unwire: va=%08x in locked TLB\n", va);
2809 prom_abort(); 2803 prom_abort();
2810 return; 2804 return;
2811 } 2805 }
2812#endif 2806#endif
2813 data = pseg_get(pmap, va & PV_VAMASK); 2807 data = pseg_get(pmap, va & PV_VAMASK);
2814 KASSERT(data & TLB_V); 2808 KASSERT(data & TLB_V);
2815 data &= ~TLB_TSB_LOCK; 2809 data &= ~TLB_TSB_LOCK;
2816 rv = pseg_set(pmap, va & PV_VAMASK, data, 0); 2810 rv = pseg_set(pmap, va & PV_VAMASK, data, 0);
2817 if (rv & 1) 2811 if (rv & 1)
2818 panic("pmap_unwire: pseg_set needs spare! rv=%d\n", rv); 2812 panic("pmap_unwire: pseg_set needs spare! rv=%d\n", rv);
2819 pv_check(); 2813 pv_check();
2820} 2814}
2821 2815
2822/* 2816/*
2823 * Lower the protection on the specified physical page. 2817 * Lower the protection on the specified physical page.