Tue Nov 2 13:09:29 2010 UTC ()
Oops, fix build !DIAGNOSTICS again.


(uebayasi)
diff -r1.267 -r1.268 src/sys/arch/sparc64/sparc64/pmap.c

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

--- src/sys/arch/sparc64/sparc64/pmap.c 2010/11/02 12:21:07 1.267
+++ src/sys/arch/sparc64/sparc64/pmap.c 2010/11/02 13:09:29 1.268
@@ -1,2448 +1,2450 @@ @@ -1,2448 +1,2450 @@
1/* $NetBSD: pmap.c,v 1.267 2010/11/02 12:21:07 uebayasi Exp $ */ 1/* $NetBSD: pmap.c,v 1.268 2010/11/02 13:09:29 uebayasi 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.267 2010/11/02 12:21:07 uebayasi Exp $"); 29__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.268 2010/11/02 13:09:29 uebayasi 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 VM_PAGE_TO_MD(pg) (&(pg)->mdpage) 76#define VM_PAGE_TO_MD(pg) (&(pg)->mdpage)
77 77
78#define MEG (1<<20) /* 1MB */ 78#define MEG (1<<20) /* 1MB */
79#define KB (1<<10) /* 1KB */ 79#define KB (1<<10) /* 1KB */
80 80
81paddr_t cpu0paddr; /* contigious phys memory preallocated for cpus */ 81paddr_t cpu0paddr; /* contigious phys memory preallocated for cpus */
82 82
83/* These routines are in assembly to allow access thru physical mappings */ 83/* These routines are in assembly to allow access thru physical mappings */
84extern int64_t pseg_get_real(struct pmap *, vaddr_t); 84extern int64_t pseg_get_real(struct pmap *, vaddr_t);
85extern int pseg_set_real(struct pmap *, vaddr_t, int64_t, paddr_t); 85extern int pseg_set_real(struct pmap *, vaddr_t, int64_t, paddr_t);
86 86
87/* 87/*
88 * Diatribe on ref/mod counting: 88 * Diatribe on ref/mod counting:
89 * 89 *
90 * First of all, ref/mod info must be non-volatile. Hence we need to keep it 90 * First of all, ref/mod info must be non-volatile. Hence we need to keep it
91 * in the pv_entry structure for each page. (We could bypass this for the 91 * in the pv_entry structure for each page. (We could bypass this for the
92 * vm_page, but that's a long story....) 92 * vm_page, but that's a long story....)
93 * 93 *
94 * This architecture has nice, fast traps with lots of space for software bits 94 * This architecture has nice, fast traps with lots of space for software bits
95 * in the TTE. To accelerate ref/mod counts we make use of these features. 95 * in the TTE. To accelerate ref/mod counts we make use of these features.
96 * 96 *
97 * When we map a page initially, we place a TTE in the page table. It's 97 * When we map a page initially, we place a TTE in the page table. It's
98 * inserted with the TLB_W and TLB_ACCESS bits cleared. If a page is really 98 * inserted with the TLB_W and TLB_ACCESS bits cleared. If a page is really
99 * writable we set the TLB_REAL_W bit for the trap handler. 99 * writable we set the TLB_REAL_W bit for the trap handler.
100 * 100 *
101 * Whenever we take a TLB miss trap, the trap handler will set the TLB_ACCESS 101 * Whenever we take a TLB miss trap, the trap handler will set the TLB_ACCESS
102 * bit in the approprate TTE in the page table. Whenever we take a protection 102 * bit in the approprate TTE in the page table. Whenever we take a protection
103 * fault, if the TLB_REAL_W bit is set then we flip both the TLB_W and TLB_MOD 103 * fault, if the TLB_REAL_W bit is set then we flip both the TLB_W and TLB_MOD
104 * bits to enable writing and mark the page as modified. 104 * bits to enable writing and mark the page as modified.
105 * 105 *
106 * This means that we may have ref/mod information all over the place. The 106 * This means that we may have ref/mod information all over the place. The
107 * pmap routines must traverse the page tables of all pmaps with a given page 107 * pmap routines must traverse the page tables of all pmaps with a given page
108 * and collect/clear all the ref/mod information and copy it into the pv_entry. 108 * and collect/clear all the ref/mod information and copy it into the pv_entry.
109 */ 109 */
110 110
111#ifdef NO_VCACHE 111#ifdef NO_VCACHE
112#define FORCE_ALIAS 1 112#define FORCE_ALIAS 1
113#else 113#else
114#define FORCE_ALIAS 0 114#define FORCE_ALIAS 0
115#endif 115#endif
116 116
117#define PV_ALIAS 0x1LL 117#define PV_ALIAS 0x1LL
118#define PV_REF 0x2LL 118#define PV_REF 0x2LL
119#define PV_MOD 0x4LL 119#define PV_MOD 0x4LL
120#define PV_NVC 0x8LL 120#define PV_NVC 0x8LL
121#define PV_NC 0x10LL 121#define PV_NC 0x10LL
122#define PV_WE 0x20LL /* Debug -- this page was writable somtime */ 122#define PV_WE 0x20LL /* Debug -- this page was writable somtime */
123#define PV_MASK (0x03fLL) 123#define PV_MASK (0x03fLL)
124#define PV_VAMASK (~(PAGE_SIZE - 1)) 124#define PV_VAMASK (~(PAGE_SIZE - 1))
125#define PV_MATCH(pv,va) (!(((pv)->pv_va ^ (va)) & PV_VAMASK)) 125#define PV_MATCH(pv,va) (!(((pv)->pv_va ^ (va)) & PV_VAMASK))
126#define PV_SETVA(pv,va) ((pv)->pv_va = (((va) & PV_VAMASK) | \ 126#define PV_SETVA(pv,va) ((pv)->pv_va = (((va) & PV_VAMASK) | \
127 (((pv)->pv_va) & PV_MASK))) 127 (((pv)->pv_va) & PV_MASK)))
128 128
129struct pool_cache pmap_cache; 129struct pool_cache pmap_cache;
130struct pool_cache pmap_pv_cache; 130struct pool_cache pmap_pv_cache;
131 131
132pv_entry_t pmap_remove_pv(struct pmap *, vaddr_t, struct vm_page *); 132pv_entry_t pmap_remove_pv(struct pmap *, vaddr_t, struct vm_page *);
133void pmap_enter_pv(struct pmap *, vaddr_t, paddr_t, struct vm_page *, 133void pmap_enter_pv(struct pmap *, vaddr_t, paddr_t, struct vm_page *,
134 pv_entry_t); 134 pv_entry_t);
135void pmap_page_cache(struct pmap *, paddr_t, int); 135void pmap_page_cache(struct pmap *, paddr_t, int);
136 136
137/* 137/*
138 * First and last managed physical addresses. 138 * First and last managed physical addresses.
139 * XXX only used for dumping the system. 139 * XXX only used for dumping the system.
140 */ 140 */
141paddr_t vm_first_phys, vm_num_phys; 141paddr_t vm_first_phys, vm_num_phys;
142 142
143/* 143/*
144 * Here's the CPU TSB stuff. It's allocated in pmap_bootstrap. 144 * Here's the CPU TSB stuff. It's allocated in pmap_bootstrap.
145 */ 145 */
146int tsbsize; /* tsbents = 512 * 2^^tsbsize */ 146int tsbsize; /* tsbents = 512 * 2^^tsbsize */
147#define TSBENTS (512<<tsbsize) 147#define TSBENTS (512<<tsbsize)
148#define TSBSIZE (TSBENTS * 16) 148#define TSBSIZE (TSBENTS * 16)
149 149
150static struct pmap kernel_pmap_; 150static struct pmap kernel_pmap_;
151struct pmap *const kernel_pmap_ptr = &kernel_pmap_; 151struct pmap *const kernel_pmap_ptr = &kernel_pmap_;
152 152
153static int ctx_alloc(struct pmap *); 153static int ctx_alloc(struct pmap *);
154static bool pmap_is_referenced_locked(struct vm_page *); 154static bool pmap_is_referenced_locked(struct vm_page *);
155 155
156static void ctx_free(struct pmap *, struct cpu_info *); 156static void ctx_free(struct pmap *, struct cpu_info *);
157 157
158/* 158/*
159 * Check if any MMU has a non-zero context 159 * Check if any MMU has a non-zero context
160 */ 160 */
161static inline bool 161static inline bool
162pmap_has_ctx(struct pmap *p) 162pmap_has_ctx(struct pmap *p)
163{ 163{
164 int i; 164 int i;
165 165
166 /* any context on any cpu? */ 166 /* any context on any cpu? */
167 for (i = 0; i < sparc_ncpus; i++) 167 for (i = 0; i < sparc_ncpus; i++)
168 if (p->pm_ctx[i] > 0) 168 if (p->pm_ctx[i] > 0)
169 return true; 169 return true;
170 170
171 return false;  171 return false;
172} 172}
173 173
174#ifdef MULTIPROCESSOR 174#ifdef MULTIPROCESSOR
175#define pmap_ctx(PM) ((PM)->pm_ctx[cpu_number()]) 175#define pmap_ctx(PM) ((PM)->pm_ctx[cpu_number()])
176#else 176#else
177#define pmap_ctx(PM) ((PM)->pm_ctx[0]) 177#define pmap_ctx(PM) ((PM)->pm_ctx[0])
178#endif 178#endif
179 179
180/* 180/*
181 * Check if this pmap has a live mapping on some MMU. 181 * Check if this pmap has a live mapping on some MMU.
182 */ 182 */
183static inline bool 183static inline bool
184pmap_is_on_mmu(struct pmap *p) 184pmap_is_on_mmu(struct pmap *p)
185{ 185{
186 /* The kernel pmap is always on all MMUs */ 186 /* The kernel pmap is always on all MMUs */
187 if (p == pmap_kernel()) 187 if (p == pmap_kernel())
188 return true; 188 return true;
189 189
190 return pmap_has_ctx(p); 190 return pmap_has_ctx(p);
191} 191}
192 192
193/* 193/*
194 * Virtual and physical addresses of the start and end of kernel text 194 * Virtual and physical addresses of the start and end of kernel text
195 * and data segments. 195 * and data segments.
196 */ 196 */
197vaddr_t ktext; 197vaddr_t ktext;
198paddr_t ktextp; 198paddr_t ktextp;
199vaddr_t ektext; 199vaddr_t ektext;
200paddr_t ektextp; 200paddr_t ektextp;
201vaddr_t kdata; 201vaddr_t kdata;
202paddr_t kdatap; 202paddr_t kdatap;
203vaddr_t ekdata; 203vaddr_t ekdata;
204paddr_t ekdatap; 204paddr_t ekdatap;
205 205
206/* 206/*
207 * Kernel 4MB pages. 207 * Kernel 4MB pages.
208 */ 208 */
209extern struct tlb_entry *kernel_tlbs; 209extern struct tlb_entry *kernel_tlbs;
210extern int kernel_tlb_slots; 210extern int kernel_tlb_slots;
211 211
212static int npgs; 212static int npgs;
213 213
214vaddr_t vmmap; /* one reserved MI vpage for /dev/mem */ 214vaddr_t vmmap; /* one reserved MI vpage for /dev/mem */
215 215
216int phys_installed_size; /* Installed physical memory */ 216int phys_installed_size; /* Installed physical memory */
217struct mem_region *phys_installed; 217struct mem_region *phys_installed;
218 218
219paddr_t avail_start, avail_end; /* These are used by ps & family */ 219paddr_t avail_start, avail_end; /* These are used by ps & family */
220 220
221static int ptelookup_va(vaddr_t va); 221static int ptelookup_va(vaddr_t va);
222 222
223static inline void 223static inline void
224clrx(void *addr) 224clrx(void *addr)
225{ 225{
226 __asm volatile("clrx [%0]" : : "r" (addr) : "memory"); 226 __asm volatile("clrx [%0]" : : "r" (addr) : "memory");
227} 227}
228 228
229static void 229static void
230tsb_invalidate(vaddr_t va, pmap_t pm) 230tsb_invalidate(vaddr_t va, pmap_t pm)
231{ 231{
232 struct cpu_info *ci; 232 struct cpu_info *ci;
233 int ctx; 233 int ctx;
234 bool kpm = (pm == pmap_kernel()); 234 bool kpm = (pm == pmap_kernel());
235 int i; 235 int i;
236 int64_t tag; 236 int64_t tag;
237 237
238 i = ptelookup_va(va); 238 i = ptelookup_va(va);
239#ifdef MULTIPROCESSOR 239#ifdef MULTIPROCESSOR
240 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 240 for (ci = cpus; ci != NULL; ci = ci->ci_next) {
241 if (!CPUSET_HAS(cpus_active, ci->ci_index)) 241 if (!CPUSET_HAS(cpus_active, ci->ci_index))
242 continue; 242 continue;
243#else 243#else
244 ci = curcpu(); 244 ci = curcpu();
245#endif 245#endif
246 ctx = pm->pm_ctx[ci->ci_index]; 246 ctx = pm->pm_ctx[ci->ci_index];
247 if (kpm || ctx > 0) { 247 if (kpm || ctx > 0) {
248 tag = TSB_TAG(0, ctx, va); 248 tag = TSB_TAG(0, ctx, va);
249 if (ci->ci_tsb_dmmu[i].tag == tag) { 249 if (ci->ci_tsb_dmmu[i].tag == tag) {
250 clrx(&ci->ci_tsb_dmmu[i].data); 250 clrx(&ci->ci_tsb_dmmu[i].data);
251 } 251 }
252 if (ci->ci_tsb_immu[i].tag == tag) { 252 if (ci->ci_tsb_immu[i].tag == tag) {
253 clrx(&ci->ci_tsb_immu[i].data); 253 clrx(&ci->ci_tsb_immu[i].data);
254 } 254 }
255 } 255 }
256#ifdef MULTIPROCESSOR 256#ifdef MULTIPROCESSOR
257 } 257 }
258#endif 258#endif
259} 259}
260 260
261struct prom_map *prom_map; 261struct prom_map *prom_map;
262int prom_map_size; 262int prom_map_size;
263 263
264#ifdef DEBUG 264#ifdef DEBUG
265struct { 265struct {
266 int kernel; /* entering kernel mapping */ 266 int kernel; /* entering kernel mapping */
267 int user; /* entering user mapping */ 267 int user; /* entering user mapping */
268 int ptpneeded; /* needed to allocate a PT page */ 268 int ptpneeded; /* needed to allocate a PT page */
269 int pwchange; /* no mapping change, just wiring or protection */ 269 int pwchange; /* no mapping change, just wiring or protection */
270 int wchange; /* no mapping change, just wiring */ 270 int wchange; /* no mapping change, just wiring */
271 int mchange; /* was mapped but mapping to different page */ 271 int mchange; /* was mapped but mapping to different page */
272 int managed; /* a managed page */ 272 int managed; /* a managed page */
273 int firstpv; /* first mapping for this PA */ 273 int firstpv; /* first mapping for this PA */
274 int secondpv; /* second mapping for this PA */ 274 int secondpv; /* second mapping for this PA */
275 int ci; /* cache inhibited */ 275 int ci; /* cache inhibited */
276 int unmanaged; /* not a managed page */ 276 int unmanaged; /* not a managed page */
277 int flushes; /* cache flushes */ 277 int flushes; /* cache flushes */
278 int cachehit; /* new entry forced valid entry out */ 278 int cachehit; /* new entry forced valid entry out */
279} enter_stats; 279} enter_stats;
280struct { 280struct {
281 int calls; 281 int calls;
282 int removes; 282 int removes;
283 int flushes; 283 int flushes;
284 int tflushes; /* TLB flushes */ 284 int tflushes; /* TLB flushes */
285 int pidflushes; /* HW pid stolen */ 285 int pidflushes; /* HW pid stolen */
286 int pvfirst; 286 int pvfirst;
287 int pvsearch; 287 int pvsearch;
288} remove_stats; 288} remove_stats;
289#define ENTER_STAT(x) do { enter_stats.x ++; } while (0) 289#define ENTER_STAT(x) do { enter_stats.x ++; } while (0)
290#define REMOVE_STAT(x) do { remove_stats.x ++; } while (0) 290#define REMOVE_STAT(x) do { remove_stats.x ++; } while (0)
291 291
292#define PDB_CREATE 0x000001 292#define PDB_CREATE 0x000001
293#define PDB_DESTROY 0x000002 293#define PDB_DESTROY 0x000002
294#define PDB_REMOVE 0x000004 294#define PDB_REMOVE 0x000004
295#define PDB_CHANGEPROT 0x000008 295#define PDB_CHANGEPROT 0x000008
296#define PDB_ENTER 0x000010 296#define PDB_ENTER 0x000010
297#define PDB_DEMAP 0x000020 297#define PDB_DEMAP 0x000020
298#define PDB_REF 0x000040 298#define PDB_REF 0x000040
299#define PDB_COPY 0x000080 299#define PDB_COPY 0x000080
300#define PDB_MMU_ALLOC 0x000100 300#define PDB_MMU_ALLOC 0x000100
301#define PDB_MMU_STEAL 0x000200 301#define PDB_MMU_STEAL 0x000200
302#define PDB_CTX_ALLOC 0x000400 302#define PDB_CTX_ALLOC 0x000400
303#define PDB_CTX_STEAL 0x000800 303#define PDB_CTX_STEAL 0x000800
304#define PDB_MMUREG_ALLOC 0x001000 304#define PDB_MMUREG_ALLOC 0x001000
305#define PDB_MMUREG_STEAL 0x002000 305#define PDB_MMUREG_STEAL 0x002000
306#define PDB_CACHESTUFF 0x004000 306#define PDB_CACHESTUFF 0x004000
307#define PDB_ALIAS 0x008000 307#define PDB_ALIAS 0x008000
308#define PDB_EXTRACT 0x010000 308#define PDB_EXTRACT 0x010000
309#define PDB_BOOT 0x020000 309#define PDB_BOOT 0x020000
310#define PDB_BOOT1 0x040000 310#define PDB_BOOT1 0x040000
311#define PDB_GROW 0x080000 311#define PDB_GROW 0x080000
312#define PDB_CTX_FLUSHALL 0x100000 312#define PDB_CTX_FLUSHALL 0x100000
313int pmapdebug = 0; 313int pmapdebug = 0;
314/* Number of H/W pages stolen for page tables */ 314/* Number of H/W pages stolen for page tables */
315int pmap_pages_stolen = 0; 315int pmap_pages_stolen = 0;
316 316
317#define BDPRINTF(n, f) if (pmapdebug & (n)) prom_printf f 317#define BDPRINTF(n, f) if (pmapdebug & (n)) prom_printf f
318#define DPRINTF(n, f) if (pmapdebug & (n)) printf f 318#define DPRINTF(n, f) if (pmapdebug & (n)) printf f
319#else 319#else
320#define ENTER_STAT(x) do { /* nothing */ } while (0) 320#define ENTER_STAT(x) do { /* nothing */ } while (0)
321#define REMOVE_STAT(x) do { /* nothing */ } while (0) 321#define REMOVE_STAT(x) do { /* nothing */ } while (0)
322#define BDPRINTF(n, f) 322#define BDPRINTF(n, f)
323#define DPRINTF(n, f) 323#define DPRINTF(n, f)
324#endif 324#endif
325 325
326#define pv_check() 326#define pv_check()
327 327
328static int pmap_get_page(paddr_t *); 328static int pmap_get_page(paddr_t *);
329static void pmap_free_page(paddr_t, sparc64_cpuset_t); 329static void pmap_free_page(paddr_t, sparc64_cpuset_t);
330static void pmap_free_page_noflush(paddr_t); 330static void pmap_free_page_noflush(paddr_t);
331 331
332/* 332/*
333 * Global pmap locks. 333 * Global pmap locks.
334 */ 334 */
335static kmutex_t pmap_lock; 335static kmutex_t pmap_lock;
336static bool lock_available = false; 336static bool lock_available = false;
337 337
338/* 338/*
339 * Support for big page sizes. This maps the page size to the 339 * Support for big page sizes. This maps the page size to the
340 * page bits. That is: these are the bits between 8K pages and 340 * page bits. That is: these are the bits between 8K pages and
341 * larger page sizes that cause aliasing. 341 * larger page sizes that cause aliasing.
342 */ 342 */
343#define PSMAP_ENTRY(MASK, CODE) { .mask = MASK, .code = CODE } 343#define PSMAP_ENTRY(MASK, CODE) { .mask = MASK, .code = CODE }
344struct page_size_map page_size_map[] = { 344struct page_size_map page_size_map[] = {
345#ifdef DEBUG 345#ifdef DEBUG
346 PSMAP_ENTRY(0, PGSZ_8K & 0), /* Disable large pages */ 346 PSMAP_ENTRY(0, PGSZ_8K & 0), /* Disable large pages */
347#endif 347#endif
348 PSMAP_ENTRY((4 * 1024 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_4M), 348 PSMAP_ENTRY((4 * 1024 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_4M),
349 PSMAP_ENTRY((512 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_512K), 349 PSMAP_ENTRY((512 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_512K),
350 PSMAP_ENTRY((64 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_64K), 350 PSMAP_ENTRY((64 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_64K),
351 PSMAP_ENTRY((8 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_8K), 351 PSMAP_ENTRY((8 * 1024 - 1) & ~(8 * 1024 - 1), PGSZ_8K),
352 PSMAP_ENTRY(0, 0), 352 PSMAP_ENTRY(0, 0),
353}; 353};
354 354
355/* 355/*
356 * This probably shouldn't be necessary, but it stops USIII machines from 356 * This probably shouldn't be necessary, but it stops USIII machines from
357 * breaking in general, and not just for MULTIPROCESSOR. 357 * breaking in general, and not just for MULTIPROCESSOR.
358 */ 358 */
359#define USE_LOCKSAFE_PSEG_GETSET 359#define USE_LOCKSAFE_PSEG_GETSET
360#if defined(USE_LOCKSAFE_PSEG_GETSET) 360#if defined(USE_LOCKSAFE_PSEG_GETSET)
361 361
362static kmutex_t pseg_lock; 362static kmutex_t pseg_lock;
363 363
364static __inline__ int64_t 364static __inline__ int64_t
365pseg_get_locksafe(struct pmap *pm, vaddr_t va) 365pseg_get_locksafe(struct pmap *pm, vaddr_t va)
366{ 366{
367 int64_t rv; 367 int64_t rv;
368 bool took_lock = lock_available /*&& pm == pmap_kernel()*/; 368 bool took_lock = lock_available /*&& pm == pmap_kernel()*/;
369 369
370 if (__predict_true(took_lock)) 370 if (__predict_true(took_lock))
371 mutex_enter(&pseg_lock); 371 mutex_enter(&pseg_lock);
372 rv = pseg_get_real(pm, va); 372 rv = pseg_get_real(pm, va);
373 if (__predict_true(took_lock)) 373 if (__predict_true(took_lock))
374 mutex_exit(&pseg_lock); 374 mutex_exit(&pseg_lock);
375 return rv; 375 return rv;
376} 376}
377 377
378static __inline__ int 378static __inline__ int
379pseg_set_locksafe(struct pmap *pm, vaddr_t va, int64_t data, paddr_t ptp) 379pseg_set_locksafe(struct pmap *pm, vaddr_t va, int64_t data, paddr_t ptp)
380{ 380{
381 int rv; 381 int rv;
382 bool took_lock = lock_available /*&& pm == pmap_kernel()*/; 382 bool took_lock = lock_available /*&& pm == pmap_kernel()*/;
383 383
384 if (__predict_true(took_lock)) 384 if (__predict_true(took_lock))
385 mutex_enter(&pseg_lock); 385 mutex_enter(&pseg_lock);
386 rv = pseg_set_real(pm, va, data, ptp); 386 rv = pseg_set_real(pm, va, data, ptp);
387 if (__predict_true(took_lock)) 387 if (__predict_true(took_lock))
388 mutex_exit(&pseg_lock); 388 mutex_exit(&pseg_lock);
389 return rv; 389 return rv;
390} 390}
391 391
392#define pseg_get(pm, va) pseg_get_locksafe(pm, va) 392#define pseg_get(pm, va) pseg_get_locksafe(pm, va)
393#define pseg_set(pm, va, data, ptp) pseg_set_locksafe(pm, va, data, ptp) 393#define pseg_set(pm, va, data, ptp) pseg_set_locksafe(pm, va, data, ptp)
394 394
395#else /* USE_LOCKSAFE_PSEG_GETSET */ 395#else /* USE_LOCKSAFE_PSEG_GETSET */
396 396
397#define pseg_get(pm, va) pseg_get_real(pm, va) 397#define pseg_get(pm, va) pseg_get_real(pm, va)
398#define pseg_set(pm, va, data, ptp) pseg_set_real(pm, va, data, ptp) 398#define pseg_set(pm, va, data, ptp) pseg_set_real(pm, va, data, ptp)
399 399
400#endif /* USE_LOCKSAFE_PSEG_GETSET */ 400#endif /* USE_LOCKSAFE_PSEG_GETSET */
401 401
402/* 402/*
403 * Enter a TTE into the kernel pmap only. Don't do anything else. 403 * Enter a TTE into the kernel pmap only. Don't do anything else.
404 * 404 *
405 * Use only during bootstrapping since it does no locking and 405 * Use only during bootstrapping since it does no locking and
406 * can lose ref/mod info!!!! 406 * can lose ref/mod info!!!!
407 * 407 *
408 */ 408 */
409static void pmap_enter_kpage(vaddr_t va, int64_t data) 409static void pmap_enter_kpage(vaddr_t va, int64_t data)
410{ 410{
411 paddr_t newp; 411 paddr_t newp;
412 412
413 newp = 0UL; 413 newp = 0UL;
414 while (pseg_set(pmap_kernel(), va, data, newp) & 1) { 414 while (pseg_set(pmap_kernel(), va, data, newp) & 1) {
415 if (!pmap_get_page(&newp)) { 415 if (!pmap_get_page(&newp)) {
416 prom_printf("pmap_enter_kpage: out of pages\n"); 416 prom_printf("pmap_enter_kpage: out of pages\n");
417 panic("pmap_enter_kpage"); 417 panic("pmap_enter_kpage");
418 } 418 }
419 419
420 ENTER_STAT(ptpneeded); 420 ENTER_STAT(ptpneeded);
421 BDPRINTF(PDB_BOOT1, 421 BDPRINTF(PDB_BOOT1,
422 ("pseg_set: pm=%p va=%p data=%lx newp %lx\n", 422 ("pseg_set: pm=%p va=%p data=%lx newp %lx\n",
423 pmap_kernel(), va, (long)data, (long)newp)); 423 pmap_kernel(), va, (long)data, (long)newp));
424#ifdef DEBUG 424#ifdef DEBUG
425 if (pmapdebug & PDB_BOOT1) 425 if (pmapdebug & PDB_BOOT1)
426 {int i; for (i=0; i<140000000; i++) ;} 426 {int i; for (i=0; i<140000000; i++) ;}
427#endif 427#endif
428 } 428 }
429} 429}
430 430
431/* 431/*
432 * Check the bootargs to see if we need to enable bootdebug. 432 * Check the bootargs to see if we need to enable bootdebug.
433 */ 433 */
434#ifdef DEBUG 434#ifdef DEBUG
435static void pmap_bootdebug(void) 435static void pmap_bootdebug(void)
436{ 436{
437 const char *cp = prom_getbootargs(); 437 const char *cp = prom_getbootargs();
438 438
439 for (;;) 439 for (;;)
440 switch (*++cp) { 440 switch (*++cp) {
441 case '\0': 441 case '\0':
442 return; 442 return;
443 case 'V': 443 case 'V':
444 pmapdebug |= PDB_BOOT|PDB_BOOT1; 444 pmapdebug |= PDB_BOOT|PDB_BOOT1;
445 break; 445 break;
446 case 'D': 446 case 'D':
447 pmapdebug |= PDB_BOOT1; 447 pmapdebug |= PDB_BOOT1;
448 break; 448 break;
449 } 449 }
450} 450}
451#endif 451#endif
452 452
453 453
454/* 454/*
455 * Calculate the correct number of page colors to use. This should be the 455 * Calculate the correct number of page colors to use. This should be the
456 * size of the E$/PAGE_SIZE. However, different CPUs can have different sized 456 * size of the E$/PAGE_SIZE. However, different CPUs can have different sized
457 * E$, so we need to take the GCM of the E$ size. 457 * E$, so we need to take the GCM of the E$ size.
458 */ 458 */
459static int pmap_calculate_colors(void) 459static int pmap_calculate_colors(void)
460{ 460{
461 int node; 461 int node;
462 int size, assoc, color, maxcolor = 1; 462 int size, assoc, color, maxcolor = 1;
463 463
464 for (node = prom_firstchild(prom_findroot()); node != 0; 464 for (node = prom_firstchild(prom_findroot()); node != 0;
465 node = prom_nextsibling(node)) { 465 node = prom_nextsibling(node)) {
466 char *name = prom_getpropstring(node, "device_type"); 466 char *name = prom_getpropstring(node, "device_type");
467 if (strcmp("cpu", name) != 0) 467 if (strcmp("cpu", name) != 0)
468 continue; 468 continue;
469 469
470 /* Found a CPU, get the E$ info. */ 470 /* Found a CPU, get the E$ info. */
471 size = prom_getpropint(node, "ecache-size", -1); 471 size = prom_getpropint(node, "ecache-size", -1);
472 if (size == -1) { 472 if (size == -1) {
473 prom_printf("pmap_calculate_colors: node %x has " 473 prom_printf("pmap_calculate_colors: node %x has "
474 "no ecache-size\n", node); 474 "no ecache-size\n", node);
475 /* If we can't get the E$ size, skip the node */ 475 /* If we can't get the E$ size, skip the node */
476 continue; 476 continue;
477 } 477 }
478 478
479 assoc = prom_getpropint(node, "ecache-associativity", 1); 479 assoc = prom_getpropint(node, "ecache-associativity", 1);
480 color = size/assoc/PAGE_SIZE; 480 color = size/assoc/PAGE_SIZE;
481 if (color > maxcolor) 481 if (color > maxcolor)
482 maxcolor = color; 482 maxcolor = color;
483 } 483 }
484 return (maxcolor); 484 return (maxcolor);
485} 485}
486 486
487static void pmap_alloc_bootargs(void) 487static void pmap_alloc_bootargs(void)
488{ 488{
489 char *v; 489 char *v;
490 490
491 v = OF_claim(NULL, 2*PAGE_SIZE, PAGE_SIZE); 491 v = OF_claim(NULL, 2*PAGE_SIZE, PAGE_SIZE);
492 if ((v == NULL) || (v == (void*)-1)) 492 if ((v == NULL) || (v == (void*)-1))
493 panic("Can't claim two pages of memory."); 493 panic("Can't claim two pages of memory.");
494 494
495 memset(v, 0, 2*PAGE_SIZE); 495 memset(v, 0, 2*PAGE_SIZE);
496 496
497 cpu_args = (struct cpu_bootargs*)v; 497 cpu_args = (struct cpu_bootargs*)v;
498} 498}
499 499
500#if defined(MULTIPROCESSOR) 500#if defined(MULTIPROCESSOR)
501static void pmap_mp_init(void); 501static void pmap_mp_init(void);
502 502
503static void 503static void
504pmap_mp_init(void) 504pmap_mp_init(void)
505{ 505{
506 pte_t *tp; 506 pte_t *tp;
507 char *v; 507 char *v;
508 int i; 508 int i;
509 509
510 extern void cpu_mp_startup(void); 510 extern void cpu_mp_startup(void);
511 511
512 if ((v = OF_claim(NULL, PAGE_SIZE, PAGE_SIZE)) == NULL) { 512 if ((v = OF_claim(NULL, PAGE_SIZE, PAGE_SIZE)) == NULL) {
513 panic("pmap_mp_init: Cannot claim a page."); 513 panic("pmap_mp_init: Cannot claim a page.");
514 } 514 }
515 515
516 memcpy(v, mp_tramp_code, mp_tramp_code_len); 516 memcpy(v, mp_tramp_code, mp_tramp_code_len);
517 *(u_long *)(v + mp_tramp_tlb_slots) = kernel_tlb_slots; 517 *(u_long *)(v + mp_tramp_tlb_slots) = kernel_tlb_slots;
518 *(u_long *)(v + mp_tramp_func) = (u_long)cpu_mp_startup; 518 *(u_long *)(v + mp_tramp_func) = (u_long)cpu_mp_startup;
519 *(u_long *)(v + mp_tramp_ci) = (u_long)cpu_args; 519 *(u_long *)(v + mp_tramp_ci) = (u_long)cpu_args;
520 tp = (pte_t *)(v + mp_tramp_code_len); 520 tp = (pte_t *)(v + mp_tramp_code_len);
521 for (i = 0; i < kernel_tlb_slots; i++) { 521 for (i = 0; i < kernel_tlb_slots; i++) {
522 tp[i].tag = kernel_tlbs[i].te_va; 522 tp[i].tag = kernel_tlbs[i].te_va;
523 tp[i].data = TSB_DATA(0, /* g */ 523 tp[i].data = TSB_DATA(0, /* g */
524 PGSZ_4M, /* sz */ 524 PGSZ_4M, /* sz */
525 kernel_tlbs[i].te_pa, /* pa */ 525 kernel_tlbs[i].te_pa, /* pa */
526 1, /* priv */ 526 1, /* priv */
527 1, /* write */ 527 1, /* write */
528 1, /* cache */ 528 1, /* cache */
529 1, /* aliased */ 529 1, /* aliased */
530 1, /* valid */ 530 1, /* valid */
531 0 /* ie */); 531 0 /* ie */);
532 tp[i].data |= TLB_L | TLB_CV; 532 tp[i].data |= TLB_L | TLB_CV;
533 DPRINTF(PDB_BOOT1, ("xtlb[%d]: Tag: %" PRIx64 " Data: %" 533 DPRINTF(PDB_BOOT1, ("xtlb[%d]: Tag: %" PRIx64 " Data: %"
534 PRIx64 "\n", i, tp[i].tag, tp[i].data)); 534 PRIx64 "\n", i, tp[i].tag, tp[i].data));
535 } 535 }
536 536
537 for (i = 0; i < PAGE_SIZE; i += sizeof(long)) 537 for (i = 0; i < PAGE_SIZE; i += sizeof(long))
538 flush(v + i); 538 flush(v + i);
539 539
540 cpu_spinup_trampoline = (vaddr_t)v; 540 cpu_spinup_trampoline = (vaddr_t)v;
541} 541}
542#else 542#else
543#define pmap_mp_init() ((void)0) 543#define pmap_mp_init() ((void)0)
544#endif 544#endif
545 545
546paddr_t pmap_kextract(vaddr_t va); 546paddr_t pmap_kextract(vaddr_t va);
547 547
548paddr_t 548paddr_t
549pmap_kextract(vaddr_t va) 549pmap_kextract(vaddr_t va)
550{ 550{
551 int i; 551 int i;
552 paddr_t paddr = (paddr_t)-1; 552 paddr_t paddr = (paddr_t)-1;
553 553
554 for (i = 0; i < kernel_tlb_slots; i++) { 554 for (i = 0; i < kernel_tlb_slots; i++) {
555 if ((va & ~PAGE_MASK_4M) == kernel_tlbs[i].te_va) { 555 if ((va & ~PAGE_MASK_4M) == kernel_tlbs[i].te_va) {
556 paddr = kernel_tlbs[i].te_pa + 556 paddr = kernel_tlbs[i].te_pa +
557 (paddr_t)(va & PAGE_MASK_4M); 557 (paddr_t)(va & PAGE_MASK_4M);
558 break; 558 break;
559 } 559 }
560 } 560 }
561 561
562 if (i == kernel_tlb_slots) { 562 if (i == kernel_tlb_slots) {
563 panic("pmap_kextract: Address %p is not from kernel space.\n" 563 panic("pmap_kextract: Address %p is not from kernel space.\n"
564 "Data segment is too small?\n", (void*)va); 564 "Data segment is too small?\n", (void*)va);
565 } 565 }
566 566
567 return (paddr); 567 return (paddr);
568} 568}
569 569
570/* 570/*
571 * Bootstrap kernel allocator, allocates from unused space in 4MB kernel 571 * Bootstrap kernel allocator, allocates from unused space in 4MB kernel
572 * data segment meaning that 572 * data segment meaning that
573 * 573 *
574 * - Access to allocated memory will never generate a trap 574 * - Access to allocated memory will never generate a trap
575 * - Allocated chunks are never reclaimed or freed 575 * - Allocated chunks are never reclaimed or freed
576 * - Allocation calls do not change PROM memlists 576 * - Allocation calls do not change PROM memlists
577 */ 577 */
578static struct mem_region kdata_mem_pool; 578static struct mem_region kdata_mem_pool;
579 579
580static void 580static void
581kdata_alloc_init(vaddr_t va_start, vaddr_t va_end) 581kdata_alloc_init(vaddr_t va_start, vaddr_t va_end)
582{ 582{
583 vsize_t va_size = va_end - va_start; 583 vsize_t va_size = va_end - va_start;
584 584
585 kdata_mem_pool.start = va_start; 585 kdata_mem_pool.start = va_start;
586 kdata_mem_pool.size = va_size; 586 kdata_mem_pool.size = va_size;
587 587
588 BDPRINTF(PDB_BOOT, ("kdata_alloc_init(): %d bytes @%p.\n", va_size, 588 BDPRINTF(PDB_BOOT, ("kdata_alloc_init(): %d bytes @%p.\n", va_size,
589 va_start)); 589 va_start));
590} 590}
591 591
592static vaddr_t 592static vaddr_t
593kdata_alloc(vsize_t size, vsize_t align) 593kdata_alloc(vsize_t size, vsize_t align)
594{ 594{
595 vaddr_t va; 595 vaddr_t va;
596 vsize_t asize; 596 vsize_t asize;
597 597
598 asize = roundup(kdata_mem_pool.start, align) - kdata_mem_pool.start; 598 asize = roundup(kdata_mem_pool.start, align) - kdata_mem_pool.start;
599 599
600 kdata_mem_pool.start += asize; 600 kdata_mem_pool.start += asize;
601 kdata_mem_pool.size -= asize; 601 kdata_mem_pool.size -= asize;
602 602
603 if (kdata_mem_pool.size < size) { 603 if (kdata_mem_pool.size < size) {
604 panic("kdata_alloc(): Data segment is too small.\n"); 604 panic("kdata_alloc(): Data segment is too small.\n");
605 } 605 }
606 606
607 va = kdata_mem_pool.start; 607 va = kdata_mem_pool.start;
608 kdata_mem_pool.start += size; 608 kdata_mem_pool.start += size;
609 kdata_mem_pool.size -= size; 609 kdata_mem_pool.size -= size;
610 610
611 BDPRINTF(PDB_BOOT, ("kdata_alloc(): Allocated %d@%p, %d free.\n", 611 BDPRINTF(PDB_BOOT, ("kdata_alloc(): Allocated %d@%p, %d free.\n",
612 size, (void*)va, kdata_mem_pool.size)); 612 size, (void*)va, kdata_mem_pool.size));
613 613
614 return (va); 614 return (va);
615} 615}
616 616
617/* 617/*
618 * Unified routine for reading PROM properties. 618 * Unified routine for reading PROM properties.
619 */ 619 */
620static void 620static void
621pmap_read_memlist(const char *device, const char *property, void **ml, 621pmap_read_memlist(const char *device, const char *property, void **ml,
622 int *ml_size, vaddr_t (* ml_alloc)(vsize_t, vsize_t)) 622 int *ml_size, vaddr_t (* ml_alloc)(vsize_t, vsize_t))
623{ 623{
624 void *va; 624 void *va;
625 int size, handle; 625 int size, handle;
626 626
627 if ( (handle = prom_finddevice(device)) == 0) { 627 if ( (handle = prom_finddevice(device)) == 0) {
628 prom_printf("pmap_read_memlist(): No %s device found.\n", 628 prom_printf("pmap_read_memlist(): No %s device found.\n",
629 device); 629 device);
630 prom_halt(); 630 prom_halt();
631 } 631 }
632 if ( (size = OF_getproplen(handle, property)) < 0) { 632 if ( (size = OF_getproplen(handle, property)) < 0) {
633 prom_printf("pmap_read_memlist(): %s/%s has no length.\n", 633 prom_printf("pmap_read_memlist(): %s/%s has no length.\n",
634 device, property); 634 device, property);
635 prom_halt(); 635 prom_halt();
636 } 636 }
637 if ( (va = (void*)(* ml_alloc)(size, sizeof(uint64_t))) == NULL) { 637 if ( (va = (void*)(* ml_alloc)(size, sizeof(uint64_t))) == NULL) {
638 prom_printf("pmap_read_memlist(): Cannot allocate memlist.\n"); 638 prom_printf("pmap_read_memlist(): Cannot allocate memlist.\n");
639 prom_halt(); 639 prom_halt();
640 } 640 }
641 if (OF_getprop(handle, property, va, size) <= 0) { 641 if (OF_getprop(handle, property, va, size) <= 0) {
642 prom_printf("pmap_read_memlist(): Cannot read %s/%s.\n", 642 prom_printf("pmap_read_memlist(): Cannot read %s/%s.\n",
643 device, property); 643 device, property);
644 prom_halt(); 644 prom_halt();
645 } 645 }
646 646
647 *ml = va; 647 *ml = va;
648 *ml_size = size; 648 *ml_size = size;
649} 649}
650 650
651/* 651/*
652 * This is called during bootstrap, before the system is really initialized. 652 * This is called during bootstrap, before the system is really initialized.
653 * 653 *
654 * It's called with the start and end virtual addresses of the kernel. We 654 * It's called with the start and end virtual addresses of the kernel. We
655 * bootstrap the pmap allocator now. We will allocate the basic structures we 655 * bootstrap the pmap allocator now. We will allocate the basic structures we
656 * need to bootstrap the VM system here: the page frame tables, the TSB, and 656 * need to bootstrap the VM system here: the page frame tables, the TSB, and
657 * the free memory lists. 657 * the free memory lists.
658 * 658 *
659 * Now all this is becoming a bit obsolete. maxctx is still important, but by 659 * Now all this is becoming a bit obsolete. maxctx is still important, but by
660 * separating the kernel text and data segments we really would need to 660 * separating the kernel text and data segments we really would need to
661 * provide the start and end of each segment. But we can't. The rodata 661 * provide the start and end of each segment. But we can't. The rodata
662 * segment is attached to the end of the kernel segment and has nothing to 662 * segment is attached to the end of the kernel segment and has nothing to
663 * delimit its end. We could still pass in the beginning of the kernel and 663 * delimit its end. We could still pass in the beginning of the kernel and
664 * the beginning and end of the data segment but we could also just as easily 664 * the beginning and end of the data segment but we could also just as easily
665 * calculate that all in here. 665 * calculate that all in here.
666 * 666 *
667 * To handle the kernel text, we need to do a reverse mapping of the start of 667 * To handle the kernel text, we need to do a reverse mapping of the start of
668 * the kernel, then traverse the free memory lists to find out how big it is. 668 * the kernel, then traverse the free memory lists to find out how big it is.
669 */ 669 */
670 670
671void 671void
672pmap_bootstrap(u_long kernelstart, u_long kernelend) 672pmap_bootstrap(u_long kernelstart, u_long kernelend)
673{ 673{
674 extern char etext[], data_start[]; /* start of data segment */ 674 extern char etext[], data_start[]; /* start of data segment */
675 extern int msgbufmapped; 675 extern int msgbufmapped;
676 struct mem_region *mp, *mp1, *avail, *orig; 676 struct mem_region *mp, *mp1, *avail, *orig;
677 int i, j, pcnt, msgbufsiz; 677 int i, j, pcnt, msgbufsiz;
678 size_t s, sz; 678 size_t s, sz;
679 int64_t data; 679 int64_t data;
680 vaddr_t va, intstk; 680 vaddr_t va, intstk;
681 uint64_t phys_msgbuf; 681 uint64_t phys_msgbuf;
682 paddr_t newp = 0; 682 paddr_t newp = 0;
683 683
684 void *prom_memlist; 684 void *prom_memlist;
685 int prom_memlist_size; 685 int prom_memlist_size;
686 686
687 BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\n")); 687 BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\n"));
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_spinup = main; /* Call main when we're running. */ 1153 cpus->ci_spinup = main; /* Call main when we're running. */
1154 cpus->ci_paddr = cpu0paddr; 1154 cpus->ci_paddr = cpu0paddr;
1155 cpus->ci_cpcb = (struct pcb *)u0va; 1155 cpus->ci_cpcb = (struct pcb *)u0va;
1156 cpus->ci_idepth = -1; 1156 cpus->ci_idepth = -1;
1157 memset(cpus->ci_intrpending, -1, sizeof(cpus->ci_intrpending)); 1157 memset(cpus->ci_intrpending, -1, sizeof(cpus->ci_intrpending));
1158 1158
1159 uvm_lwp_setuarea(&lwp0, u0va); 1159 uvm_lwp_setuarea(&lwp0, u0va);
1160 lwp0.l_md.md_tf = (struct trapframe64*)(u0va + USPACE 1160 lwp0.l_md.md_tf = (struct trapframe64*)(u0va + USPACE
1161 - sizeof(struct trapframe64)); 1161 - sizeof(struct trapframe64));
1162 1162
1163 cpu0paddr += 64 * KB; 1163 cpu0paddr += 64 * KB;
1164 1164
1165 CPUSET_CLEAR(cpus_active); 1165 CPUSET_CLEAR(cpus_active);
1166 CPUSET_ADD(cpus_active, 0); 1166 CPUSET_ADD(cpus_active, 0);
1167 1167
1168 cpu_pmap_prepare(cpus, true); 1168 cpu_pmap_prepare(cpus, true);
1169 cpu_pmap_init(cpus); 1169 cpu_pmap_init(cpus);
1170 1170
1171 /* The rest will be done at CPU attach time. */ 1171 /* The rest will be done at CPU attach time. */
1172 BDPRINTF(PDB_BOOT1, 1172 BDPRINTF(PDB_BOOT1,
1173 ("Done inserting cpu_info into pmap_kernel()\n")); 1173 ("Done inserting cpu_info into pmap_kernel()\n"));
1174 } 1174 }
1175 1175
1176 vmmap = (vaddr_t)reserve_dumppages((void *)(u_long)vmmap); 1176 vmmap = (vaddr_t)reserve_dumppages((void *)(u_long)vmmap);
1177 1177
1178 /* 1178 /*
1179 * Set up bounds of allocatable memory for vmstat et al. 1179 * Set up bounds of allocatable memory for vmstat et al.
1180 */ 1180 */
1181 avail_start = avail->start; 1181 avail_start = avail->start;
1182 for (mp = avail; mp->size; mp++) 1182 for (mp = avail; mp->size; mp++)
1183 avail_end = mp->start+mp->size; 1183 avail_end = mp->start+mp->size;
1184 1184
1185 BDPRINTF(PDB_BOOT1, ("Finished pmap_bootstrap()\n")); 1185 BDPRINTF(PDB_BOOT1, ("Finished pmap_bootstrap()\n"));
1186 1186
1187 BDPRINTF(PDB_BOOT, ("left kdata: %" PRId64 " @%" PRIx64 ".\n", 1187 BDPRINTF(PDB_BOOT, ("left kdata: %" PRId64 " @%" PRIx64 ".\n",
1188 kdata_mem_pool.size, kdata_mem_pool.start)); 1188 kdata_mem_pool.size, kdata_mem_pool.start));
1189} 1189}
1190 1190
1191/* 1191/*
1192 * Allocate TSBs for both mmus from the locked kernel data segment page. 1192 * Allocate TSBs for both mmus from the locked kernel data segment page.
1193 * This is run before the cpu itself is activated (or by the first cpu 1193 * This is run before the cpu itself is activated (or by the first cpu
1194 * itself) 1194 * itself)
1195 */ 1195 */
1196void 1196void
1197cpu_pmap_prepare(struct cpu_info *ci, bool initial) 1197cpu_pmap_prepare(struct cpu_info *ci, bool initial)
1198{ 1198{
1199 /* allocate our TSBs */ 1199 /* allocate our TSBs */
1200 ci->ci_tsb_dmmu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE); 1200 ci->ci_tsb_dmmu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE);
1201 ci->ci_tsb_immu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE); 1201 ci->ci_tsb_immu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE);
1202 memset(ci->ci_tsb_dmmu, 0, TSBSIZE); 1202 memset(ci->ci_tsb_dmmu, 0, TSBSIZE);
1203 memset(ci->ci_tsb_immu, 0, TSBSIZE); 1203 memset(ci->ci_tsb_immu, 0, TSBSIZE);
1204 if (!initial) { 1204 if (!initial) {
1205 KASSERT(ci != curcpu()); 1205 KASSERT(ci != curcpu());
1206 /* 1206 /*
1207 * Initially share ctxbusy with the boot cpu, the 1207 * Initially share ctxbusy with the boot cpu, the
1208 * cpu will replace it as soon as it runs (and can 1208 * cpu will replace it as soon as it runs (and can
1209 * probe the number of available contexts itself). 1209 * probe the number of available contexts itself).
1210 * Untill then only context 0 (aka kernel) will be 1210 * Untill then only context 0 (aka kernel) will be
1211 * referenced anyway. 1211 * referenced anyway.
1212 */ 1212 */
1213 ci->ci_numctx = curcpu()->ci_numctx; 1213 ci->ci_numctx = curcpu()->ci_numctx;
1214 ci->ci_ctxbusy = curcpu()->ci_ctxbusy; 1214 ci->ci_ctxbusy = curcpu()->ci_ctxbusy;
1215 } 1215 }
1216 1216
1217 BDPRINTF(PDB_BOOT1, ("cpu %d: TSB allocated at %p/%p size %08x\n", 1217 BDPRINTF(PDB_BOOT1, ("cpu %d: TSB allocated at %p/%p size %08x\n",
1218 ci->ci_index, ci->ci_tsb_dmmu, ci->ci_tsb_immu, TSBSIZE)); 1218 ci->ci_index, ci->ci_tsb_dmmu, ci->ci_tsb_immu, TSBSIZE));
1219} 1219}
1220 1220
1221/* 1221/*
1222 * Initialize the per CPU parts for the cpu running this code. 1222 * Initialize the per CPU parts for the cpu running this code.
1223 */ 1223 */
1224void 1224void
1225cpu_pmap_init(struct cpu_info *ci) 1225cpu_pmap_init(struct cpu_info *ci)
1226{ 1226{
1227 size_t ctxsize; 1227 size_t ctxsize;
1228 1228
1229 /* 1229 /*
1230 * We delay initialising ci_ctx_lock here as LOCKDEBUG isn't 1230 * We delay initialising ci_ctx_lock here as LOCKDEBUG isn't
1231 * running for cpu0 yet.. 1231 * running for cpu0 yet..
1232 */ 1232 */
1233 ci->ci_pmap_next_ctx = 1; 1233 ci->ci_pmap_next_ctx = 1;
1234#ifdef SUN4V 1234#ifdef SUN4V
1235#error find out if we have 16 or 13 bit context ids 1235#error find out if we have 16 or 13 bit context ids
1236#else 1236#else
1237 ci->ci_numctx = 0x2000; /* all SUN4U use 13 bit contexts */ 1237 ci->ci_numctx = 0x2000; /* all SUN4U use 13 bit contexts */
1238#endif 1238#endif
1239 ctxsize = sizeof(paddr_t)*ci->ci_numctx; 1239 ctxsize = sizeof(paddr_t)*ci->ci_numctx;
1240 ci->ci_ctxbusy = (paddr_t *)kdata_alloc(ctxsize, sizeof(uint64_t)); 1240 ci->ci_ctxbusy = (paddr_t *)kdata_alloc(ctxsize, sizeof(uint64_t));
1241 memset(ci->ci_ctxbusy, 0, ctxsize); 1241 memset(ci->ci_ctxbusy, 0, ctxsize);
1242 LIST_INIT(&ci->ci_pmap_ctxlist); 1242 LIST_INIT(&ci->ci_pmap_ctxlist);
1243 1243
1244 /* mark kernel context as busy */ 1244 /* mark kernel context as busy */
1245 ci->ci_ctxbusy[0] = pmap_kernel()->pm_physaddr; 1245 ci->ci_ctxbusy[0] = pmap_kernel()->pm_physaddr;
1246} 1246}
1247 1247
1248/* 1248/*
1249 * Initialize anything else for pmap handling. 1249 * Initialize anything else for pmap handling.
1250 * Called during vm_init(). 1250 * Called during vm_init().
1251 */ 1251 */
1252void 1252void
1253pmap_init(void) 1253pmap_init(void)
1254{ 1254{
1255 struct vm_page *pg; 1255 struct vm_page *pg;
1256 struct pglist pglist; 1256 struct pglist pglist;
1257 uint64_t data; 1257 uint64_t data;
1258 paddr_t pa; 1258 paddr_t pa;
1259 psize_t size; 1259 psize_t size;
1260 vaddr_t va; 1260 vaddr_t va;
1261 1261
1262 BDPRINTF(PDB_BOOT1, ("pmap_init()\n")); 1262 BDPRINTF(PDB_BOOT1, ("pmap_init()\n"));
1263 1263
1264 size = sizeof(struct pv_entry) * physmem; 1264 size = sizeof(struct pv_entry) * physmem;
1265 if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1, 1265 if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1,
1266 (paddr_t)PAGE_SIZE, (paddr_t)0, &pglist, 1, 0) != 0) 1266 (paddr_t)PAGE_SIZE, (paddr_t)0, &pglist, 1, 0) != 0)
1267 panic("pmap_init: no memory"); 1267 panic("pmap_init: no memory");
1268 1268
1269 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY); 1269 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY);
1270 if (va == 0) 1270 if (va == 0)
1271 panic("pmap_init: no memory"); 1271 panic("pmap_init: no memory");
1272 1272
1273 /* Map the pages */ 1273 /* Map the pages */
1274 TAILQ_FOREACH(pg, &pglist, pageq.queue) { 1274 TAILQ_FOREACH(pg, &pglist, pageq.queue) {
1275 pa = VM_PAGE_TO_PHYS(pg); 1275 pa = VM_PAGE_TO_PHYS(pg);
1276 pmap_zero_page(pa); 1276 pmap_zero_page(pa);
1277 data = TSB_DATA(0 /* global */, 1277 data = TSB_DATA(0 /* global */,
1278 PGSZ_8K, 1278 PGSZ_8K,
1279 pa, 1279 pa,
1280 1 /* priv */, 1280 1 /* priv */,
1281 1 /* Write */, 1281 1 /* Write */,
1282 1 /* Cacheable */, 1282 1 /* Cacheable */,
1283 FORCE_ALIAS /* ALIAS -- Disable D$ */, 1283 FORCE_ALIAS /* ALIAS -- Disable D$ */,
1284 1 /* valid */, 1284 1 /* valid */,
1285 0 /* IE */); 1285 0 /* IE */);
1286 pmap_enter_kpage(va, data); 1286 pmap_enter_kpage(va, data);
1287 va += PAGE_SIZE; 1287 va += PAGE_SIZE;
1288 } 1288 }
1289 1289
1290 /* 1290 /*
1291 * initialize the pmap pools. 1291 * initialize the pmap pools.
1292 */ 1292 */
1293 pool_cache_bootstrap(&pmap_cache, sizeof(struct pmap), BLOCK_SIZE, 0, 1293 pool_cache_bootstrap(&pmap_cache, sizeof(struct pmap), BLOCK_SIZE, 0,
1294 0, "pmappl", NULL, IPL_NONE, NULL, NULL, NULL); 1294 0, "pmappl", NULL, IPL_NONE, NULL, NULL, NULL);
1295 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0, 1295 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0,
1296 PR_LARGECACHE, "pv_entry", NULL, IPL_NONE, NULL, NULL, NULL); 1296 PR_LARGECACHE, "pv_entry", NULL, IPL_NONE, NULL, NULL, NULL);
1297 1297
1298 vm_first_phys = avail_start; 1298 vm_first_phys = avail_start;
1299 vm_num_phys = avail_end - avail_start; 1299 vm_num_phys = avail_end - avail_start;
1300 1300
1301 mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE); 1301 mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE);
1302#if defined(USE_LOCKSAFE_PSEG_GETSET) 1302#if defined(USE_LOCKSAFE_PSEG_GETSET)
1303 mutex_init(&pseg_lock, MUTEX_SPIN, IPL_VM); 1303 mutex_init(&pseg_lock, MUTEX_SPIN, IPL_VM);
1304#endif 1304#endif
1305 lock_available = true; 1305 lock_available = true;
1306} 1306}
1307 1307
1308/* 1308/*
1309 * How much virtual space is available to the kernel? 1309 * How much virtual space is available to the kernel?
1310 */ 1310 */
1311static vaddr_t kbreak; /* End of kernel VA */ 1311static vaddr_t kbreak; /* End of kernel VA */
1312void 1312void
1313pmap_virtual_space(vaddr_t *start, vaddr_t *end) 1313pmap_virtual_space(vaddr_t *start, vaddr_t *end)
1314{ 1314{
1315 1315
1316 /* 1316 /*
1317 * Reserve one segment for kernel virtual memory 1317 * Reserve one segment for kernel virtual memory
1318 */ 1318 */
1319 /* Reserve two pages for pmap_copy_page && /dev/mem */ 1319 /* Reserve two pages for pmap_copy_page && /dev/mem */
1320 *start = kbreak = (vaddr_t)(vmmap + 2*PAGE_SIZE); 1320 *start = kbreak = (vaddr_t)(vmmap + 2*PAGE_SIZE);
1321 *end = VM_MAX_KERNEL_ADDRESS; 1321 *end = VM_MAX_KERNEL_ADDRESS;
1322 BDPRINTF(PDB_BOOT1, ("pmap_virtual_space: %x-%x\n", *start, *end)); 1322 BDPRINTF(PDB_BOOT1, ("pmap_virtual_space: %x-%x\n", *start, *end));
1323} 1323}
1324 1324
1325/* 1325/*
1326 * Preallocate kernel page tables to a specified VA. 1326 * Preallocate kernel page tables to a specified VA.
1327 * This simply loops through the first TTE for each 1327 * This simply loops through the first TTE for each
1328 * page table from the beginning of the kernel pmap, 1328 * page table from the beginning of the kernel pmap,
1329 * reads the entry, and if the result is 1329 * reads the entry, and if the result is
1330 * zero (either invalid entry or no page table) it stores 1330 * zero (either invalid entry or no page table) it stores
1331 * a zero there, populating page tables in the process. 1331 * a zero there, populating page tables in the process.
1332 * This is not the most efficient technique but i don't 1332 * This is not the most efficient technique but i don't
1333 * expect it to be called that often. 1333 * expect it to be called that often.
1334 */ 1334 */
1335vaddr_t 1335vaddr_t
1336pmap_growkernel(vaddr_t maxkvaddr) 1336pmap_growkernel(vaddr_t maxkvaddr)
1337{ 1337{
1338 struct pmap *pm = pmap_kernel(); 1338 struct pmap *pm = pmap_kernel();
1339 paddr_t pa; 1339 paddr_t pa;
1340 bool took_lock; 1340 bool took_lock;
1341 1341
1342 if (maxkvaddr >= KERNEND) { 1342 if (maxkvaddr >= KERNEND) {
1343 printf("WARNING: cannot extend kernel pmap beyond %p to %p\n", 1343 printf("WARNING: cannot extend kernel pmap beyond %p to %p\n",
1344 (void *)KERNEND, (void *)maxkvaddr); 1344 (void *)KERNEND, (void *)maxkvaddr);
1345 return (kbreak); 1345 return (kbreak);
1346 } 1346 }
1347 took_lock = lock_available; 1347 took_lock = lock_available;
1348 if (__predict_true(took_lock)) 1348 if (__predict_true(took_lock))
1349 mutex_enter(&pmap_lock); 1349 mutex_enter(&pmap_lock);
1350 DPRINTF(PDB_GROW, ("pmap_growkernel(%lx...%lx)\n", kbreak, maxkvaddr)); 1350 DPRINTF(PDB_GROW, ("pmap_growkernel(%lx...%lx)\n", kbreak, maxkvaddr));
1351 /* Align with the start of a page table */ 1351 /* Align with the start of a page table */
1352 for (kbreak &= (-1 << PDSHIFT); kbreak < maxkvaddr; 1352 for (kbreak &= (-1 << PDSHIFT); kbreak < maxkvaddr;
1353 kbreak += (1 << PDSHIFT)) { 1353 kbreak += (1 << PDSHIFT)) {
1354 if (pseg_get(pm, kbreak) & TLB_V) 1354 if (pseg_get(pm, kbreak) & TLB_V)
1355 continue; 1355 continue;
1356 1356
1357 pa = 0; 1357 pa = 0;
1358 while (pseg_set(pm, kbreak, 0, pa) & 1) { 1358 while (pseg_set(pm, kbreak, 0, pa) & 1) {
1359 DPRINTF(PDB_GROW, 1359 DPRINTF(PDB_GROW,
1360 ("pmap_growkernel: extending %lx\n", kbreak)); 1360 ("pmap_growkernel: extending %lx\n", kbreak));
1361 pa = 0; 1361 pa = 0;
1362 if (!pmap_get_page(&pa)) 1362 if (!pmap_get_page(&pa))
1363 panic("pmap_growkernel: no pages"); 1363 panic("pmap_growkernel: no pages");
1364 ENTER_STAT(ptpneeded); 1364 ENTER_STAT(ptpneeded);
1365 } 1365 }
1366 } 1366 }
1367 if (__predict_true(took_lock)) 1367 if (__predict_true(took_lock))
1368 mutex_exit(&pmap_lock); 1368 mutex_exit(&pmap_lock);
1369 return (kbreak); 1369 return (kbreak);
1370} 1370}
1371 1371
1372/* 1372/*
1373 * Create and return a physical map. 1373 * Create and return a physical map.
1374 */ 1374 */
1375struct pmap * 1375struct pmap *
1376pmap_create(void) 1376pmap_create(void)
1377{ 1377{
1378 struct pmap *pm; 1378 struct pmap *pm;
1379 1379
1380 DPRINTF(PDB_CREATE, ("pmap_create()\n")); 1380 DPRINTF(PDB_CREATE, ("pmap_create()\n"));
1381 1381
1382 pm = pool_cache_get(&pmap_cache, PR_WAITOK); 1382 pm = pool_cache_get(&pmap_cache, PR_WAITOK);
1383 memset(pm, 0, sizeof *pm); 1383 memset(pm, 0, sizeof *pm);
1384 DPRINTF(PDB_CREATE, ("pmap_create(): created %p\n", pm)); 1384 DPRINTF(PDB_CREATE, ("pmap_create(): created %p\n", pm));
1385 1385
1386 UVM_OBJ_INIT(&pm->pm_obj, NULL, 1); 1386 UVM_OBJ_INIT(&pm->pm_obj, NULL, 1);
1387 if (pm != pmap_kernel()) { 1387 if (pm != pmap_kernel()) {
1388 while (!pmap_get_page(&pm->pm_physaddr)) { 1388 while (!pmap_get_page(&pm->pm_physaddr)) {
1389 uvm_wait("pmap_create"); 1389 uvm_wait("pmap_create");
1390 } 1390 }
1391 pm->pm_segs = (paddr_t *)(u_long)pm->pm_physaddr; 1391 pm->pm_segs = (paddr_t *)(u_long)pm->pm_physaddr;
1392 } 1392 }
1393 DPRINTF(PDB_CREATE, ("pmap_create(%p): ctx %d\n", pm, pmap_ctx(pm))); 1393 DPRINTF(PDB_CREATE, ("pmap_create(%p): ctx %d\n", pm, pmap_ctx(pm)));
1394 return pm; 1394 return pm;
1395} 1395}
1396 1396
1397/* 1397/*
1398 * Add a reference to the given pmap. 1398 * Add a reference to the given pmap.
1399 */ 1399 */
1400void 1400void
1401pmap_reference(struct pmap *pm) 1401pmap_reference(struct pmap *pm)
1402{ 1402{
1403 1403
1404 atomic_inc_uint(&pm->pm_refs); 1404 atomic_inc_uint(&pm->pm_refs);
1405} 1405}
1406 1406
1407/* 1407/*
1408 * Retire the given pmap from service. 1408 * Retire the given pmap from service.
1409 * Should only be called if the map contains no valid mappings. 1409 * Should only be called if the map contains no valid mappings.
1410 */ 1410 */
1411void 1411void
1412pmap_destroy(struct pmap *pm) 1412pmap_destroy(struct pmap *pm)
1413{ 1413{
1414#ifdef MULTIPROCESSOR 1414#ifdef MULTIPROCESSOR
1415 struct cpu_info *ci; 1415 struct cpu_info *ci;
1416 sparc64_cpuset_t pmap_cpus_active; 1416 sparc64_cpuset_t pmap_cpus_active;
1417#else 1417#else
1418#define pmap_cpus_active 0 1418#define pmap_cpus_active 0
1419#endif 1419#endif
1420 struct vm_page *pg, *nextpg; 1420 struct vm_page *pg, *nextpg;
1421 1421
1422 if ((int)atomic_dec_uint_nv(&pm->pm_refs) > 0) { 1422 if ((int)atomic_dec_uint_nv(&pm->pm_refs) > 0) {
1423 return; 1423 return;
1424 } 1424 }
1425 DPRINTF(PDB_DESTROY, ("pmap_destroy: freeing pmap %p\n", pm)); 1425 DPRINTF(PDB_DESTROY, ("pmap_destroy: freeing pmap %p\n", pm));
1426#ifdef MULTIPROCESSOR 1426#ifdef MULTIPROCESSOR
1427 CPUSET_CLEAR(pmap_cpus_active); 1427 CPUSET_CLEAR(pmap_cpus_active);
1428 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 1428 for (ci = cpus; ci != NULL; ci = ci->ci_next) {
1429 /* XXXMRG: Move the lock inside one or both tests? */ 1429 /* XXXMRG: Move the lock inside one or both tests? */
1430 mutex_enter(&ci->ci_ctx_lock); 1430 mutex_enter(&ci->ci_ctx_lock);
1431 if (CPUSET_HAS(cpus_active, ci->ci_index)) { 1431 if (CPUSET_HAS(cpus_active, ci->ci_index)) {
1432 if (pm->pm_ctx[ci->ci_index] > 0) { 1432 if (pm->pm_ctx[ci->ci_index] > 0) {
1433 CPUSET_ADD(pmap_cpus_active, ci->ci_index); 1433 CPUSET_ADD(pmap_cpus_active, ci->ci_index);
1434 ctx_free(pm, ci); 1434 ctx_free(pm, ci);
1435 } 1435 }
1436 } 1436 }
1437 mutex_exit(&ci->ci_ctx_lock); 1437 mutex_exit(&ci->ci_ctx_lock);
1438 } 1438 }
1439#else 1439#else
1440 if (pmap_ctx(pm)) { 1440 if (pmap_ctx(pm)) {
1441 mutex_enter(&curcpu()->ci_ctx_lock); 1441 mutex_enter(&curcpu()->ci_ctx_lock);
1442 ctx_free(pm, curcpu()); 1442 ctx_free(pm, curcpu());
1443 mutex_exit(&curcpu()->ci_ctx_lock); 1443 mutex_exit(&curcpu()->ci_ctx_lock);
1444 } 1444 }
1445#endif 1445#endif
1446 1446
1447 /* we could be a little smarter and leave pages zeroed */ 1447 /* we could be a little smarter and leave pages zeroed */
1448 for (pg = TAILQ_FIRST(&pm->pm_obj.memq); pg != NULL; pg = nextpg) { 1448 for (pg = TAILQ_FIRST(&pm->pm_obj.memq); pg != NULL; pg = nextpg) {
 1449#ifdef DIAGNOSTIC
1449 struct vm_page_md *md = VM_PAGE_TO_MD(pg); 1450 struct vm_page_md *md = VM_PAGE_TO_MD(pg);
 1451#endif
1450 1452
1451 KASSERT((pg->flags & PG_MARKER) == 0); 1453 KASSERT((pg->flags & PG_MARKER) == 0);
1452 nextpg = TAILQ_NEXT(pg, listq.queue); 1454 nextpg = TAILQ_NEXT(pg, listq.queue);
1453 TAILQ_REMOVE(&pm->pm_obj.memq, pg, listq.queue); 1455 TAILQ_REMOVE(&pm->pm_obj.memq, pg, listq.queue);
1454 KASSERT(md->mdpg_pvh.pv_pmap == NULL); 1456 KASSERT(md->mdpg_pvh.pv_pmap == NULL);
1455 dcache_flush_page_cpuset(VM_PAGE_TO_PHYS(pg), pmap_cpus_active); 1457 dcache_flush_page_cpuset(VM_PAGE_TO_PHYS(pg), pmap_cpus_active);
1456 uvm_pagefree(pg); 1458 uvm_pagefree(pg);
1457 } 1459 }
1458 pmap_free_page((paddr_t)(u_long)pm->pm_segs, pmap_cpus_active); 1460 pmap_free_page((paddr_t)(u_long)pm->pm_segs, pmap_cpus_active);
1459 UVM_OBJ_DESTROY(&pm->pm_obj); 1461 UVM_OBJ_DESTROY(&pm->pm_obj);
1460 pool_cache_put(&pmap_cache, pm); 1462 pool_cache_put(&pmap_cache, pm);
1461} 1463}
1462 1464
1463/* 1465/*
1464 * Copy the range specified by src_addr/len 1466 * Copy the range specified by src_addr/len
1465 * from the source map to the range dst_addr/len 1467 * from the source map to the range dst_addr/len
1466 * in the destination map. 1468 * in the destination map.
1467 * 1469 *
1468 * This routine is only advisory and need not do anything. 1470 * This routine is only advisory and need not do anything.
1469 */ 1471 */
1470void 1472void
1471pmap_copy(struct pmap *dst_pmap, struct pmap *src_pmap, vaddr_t dst_addr, vsize_t len, vaddr_t src_addr) 1473pmap_copy(struct pmap *dst_pmap, struct pmap *src_pmap, vaddr_t dst_addr, vsize_t len, vaddr_t src_addr)
1472{ 1474{
1473 1475
1474 DPRINTF(PDB_CREATE, ("pmap_copy(%p, %p, %p, %lx, %p)\n", 1476 DPRINTF(PDB_CREATE, ("pmap_copy(%p, %p, %p, %lx, %p)\n",
1475 dst_pmap, src_pmap, (void *)(u_long)dst_addr, 1477 dst_pmap, src_pmap, (void *)(u_long)dst_addr,
1476 (u_long)len, (void *)(u_long)src_addr)); 1478 (u_long)len, (void *)(u_long)src_addr));
1477} 1479}
1478 1480
1479/* 1481/*
1480 * Activate the address space for the specified process. If the 1482 * Activate the address space for the specified process. If the
1481 * process is the current process, load the new MMU context. 1483 * process is the current process, load the new MMU context.
1482 */ 1484 */
1483void 1485void
1484pmap_activate(struct lwp *l) 1486pmap_activate(struct lwp *l)
1485{ 1487{
1486 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; 1488 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
1487 1489
1488 if (pmap == pmap_kernel()) { 1490 if (pmap == pmap_kernel()) {
1489 return; 1491 return;
1490 } 1492 }
1491 1493
1492 /* 1494 /*
1493 * This is essentially the same thing that happens in cpu_switchto() 1495 * This is essentially the same thing that happens in cpu_switchto()
1494 * when the newly selected process is about to run, except that we 1496 * when the newly selected process is about to run, except that we
1495 * have to make sure to clean the register windows before we set 1497 * have to make sure to clean the register windows before we set
1496 * the new context. 1498 * the new context.
1497 */ 1499 */
1498 1500
1499 if (l != curlwp) { 1501 if (l != curlwp) {
1500 return; 1502 return;
1501 } 1503 }
1502 write_user_windows(); 1504 write_user_windows();
1503 pmap_activate_pmap(pmap); 1505 pmap_activate_pmap(pmap);
1504} 1506}
1505 1507
1506void 1508void
1507pmap_activate_pmap(struct pmap *pmap) 1509pmap_activate_pmap(struct pmap *pmap)
1508{ 1510{
1509 1511
1510 if (pmap_ctx(pmap) == 0) { 1512 if (pmap_ctx(pmap) == 0) {
1511 (void) ctx_alloc(pmap); 1513 (void) ctx_alloc(pmap);
1512 } 1514 }
1513 dmmu_set_secondary_context(pmap_ctx(pmap)); 1515 dmmu_set_secondary_context(pmap_ctx(pmap));
1514} 1516}
1515 1517
1516/* 1518/*
1517 * Deactivate the address space of the specified process. 1519 * Deactivate the address space of the specified process.
1518 */ 1520 */
1519void 1521void
1520pmap_deactivate(struct lwp *l) 1522pmap_deactivate(struct lwp *l)
1521{ 1523{
1522} 1524}
1523 1525
1524/* 1526/*
1525 * pmap_kenter_pa: [ INTERFACE ] 1527 * pmap_kenter_pa: [ INTERFACE ]
1526 * 1528 *
1527 * Enter a va -> pa mapping into the kernel pmap without any 1529 * Enter a va -> pa mapping into the kernel pmap without any
1528 * physical->virtual tracking. 1530 * physical->virtual tracking.
1529 * 1531 *
1530 * Note: no locking is necessary in this function. 1532 * Note: no locking is necessary in this function.
1531 */ 1533 */
1532void 1534void
1533pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 1535pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
1534{ 1536{
1535 pte_t tte; 1537 pte_t tte;
1536 paddr_t ptp; 1538 paddr_t ptp;
1537 struct pmap *pm = pmap_kernel(); 1539 struct pmap *pm = pmap_kernel();
1538 int i; 1540 int i;
1539 1541
1540 KASSERT(va < INTSTACK || va > EINTSTACK); 1542 KASSERT(va < INTSTACK || va > EINTSTACK);
1541 KASSERT(va < kdata || va > ekdata); 1543 KASSERT(va < kdata || va > ekdata);
1542 1544
1543 /* 1545 /*
1544 * Construct the TTE. 1546 * Construct the TTE.
1545 */ 1547 */
1546 1548
1547 ENTER_STAT(unmanaged); 1549 ENTER_STAT(unmanaged);
1548 if (pa & (PMAP_NVC|PMAP_NC)) { 1550 if (pa & (PMAP_NVC|PMAP_NC)) {
1549 ENTER_STAT(ci); 1551 ENTER_STAT(ci);
1550 } 1552 }
1551 1553
1552 tte.data = TSB_DATA(0, PGSZ_8K, pa, 1 /* Privileged */, 1554 tte.data = TSB_DATA(0, PGSZ_8K, pa, 1 /* Privileged */,
1553 (VM_PROT_WRITE & prot), 1555 (VM_PROT_WRITE & prot),
1554 !(pa & PMAP_NC), pa & (PMAP_NVC), 1, 0); 1556 !(pa & PMAP_NC), pa & (PMAP_NVC), 1, 0);
1555 /* We don't track mod/ref here. */ 1557 /* We don't track mod/ref here. */
1556 if (prot & VM_PROT_WRITE) 1558 if (prot & VM_PROT_WRITE)
1557 tte.data |= TLB_REAL_W|TLB_W; 1559 tte.data |= TLB_REAL_W|TLB_W;
1558 if (prot & VM_PROT_EXECUTE) 1560 if (prot & VM_PROT_EXECUTE)
1559 tte.data |= TLB_EXEC; 1561 tte.data |= TLB_EXEC;
1560 tte.data |= TLB_TSB_LOCK; /* wired */ 1562 tte.data |= TLB_TSB_LOCK; /* wired */
1561 ptp = 0; 1563 ptp = 0;
1562 1564
1563 retry: 1565 retry:
1564 i = pseg_set(pm, va, tte.data, ptp); 1566 i = pseg_set(pm, va, tte.data, ptp);
1565 if (i & 1) { 1567 if (i & 1) {
1566 KASSERT((i & 4) == 0); 1568 KASSERT((i & 4) == 0);
1567 ptp = 0; 1569 ptp = 0;
1568 if (!pmap_get_page(&ptp)) 1570 if (!pmap_get_page(&ptp))
1569 panic("pmap_kenter_pa: no pages"); 1571 panic("pmap_kenter_pa: no pages");
1570 ENTER_STAT(ptpneeded); 1572 ENTER_STAT(ptpneeded);
1571 goto retry; 1573 goto retry;
1572 } 1574 }
1573 if (ptp && i == 0) { 1575 if (ptp && i == 0) {
1574 /* We allocated a spare page but didn't use it. Free it. */ 1576 /* We allocated a spare page but didn't use it. Free it. */
1575 printf("pmap_kenter_pa: freeing unused page %llx\n", 1577 printf("pmap_kenter_pa: freeing unused page %llx\n",
1576 (long long)ptp); 1578 (long long)ptp);
1577 pmap_free_page_noflush(ptp); 1579 pmap_free_page_noflush(ptp);
1578 } 1580 }
1579#ifdef DEBUG 1581#ifdef DEBUG
1580 i = ptelookup_va(va); 1582 i = ptelookup_va(va);
1581 if (pmapdebug & PDB_ENTER) 1583 if (pmapdebug & PDB_ENTER)
1582 prom_printf("pmap_kenter_pa: va=%08x data=%08x:%08x " 1584 prom_printf("pmap_kenter_pa: va=%08x data=%08x:%08x "
1583 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32), 1585 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32),
1584 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]); 1586 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]);
1585 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) { 1587 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) {
1586 prom_printf("pmap_kenter_pa: evicting entry tag=%x:%08x " 1588 prom_printf("pmap_kenter_pa: evicting entry tag=%x:%08x "
1587 "data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1589 "data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1588 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag, 1590 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag,
1589 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data, 1591 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data,
1590 i, &curcpu()->ci_tsb_dmmu[i]); 1592 i, &curcpu()->ci_tsb_dmmu[i]);
1591 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1593 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1592 va, (int)(tte.data>>32), (int)tte.data, i, 1594 va, (int)(tte.data>>32), (int)tte.data, i,
1593 &curcpu()->ci_tsb_dmmu[i]); 1595 &curcpu()->ci_tsb_dmmu[i]);
1594 } 1596 }
1595#endif 1597#endif
1596} 1598}
1597 1599
1598/* 1600/*
1599 * pmap_kremove: [ INTERFACE ] 1601 * pmap_kremove: [ INTERFACE ]
1600 * 1602 *
1601 * Remove a mapping entered with pmap_kenter_pa() starting at va, 1603 * Remove a mapping entered with pmap_kenter_pa() starting at va,
1602 * for size bytes (assumed to be page rounded). 1604 * for size bytes (assumed to be page rounded).
1603 */ 1605 */
1604void 1606void
1605pmap_kremove(vaddr_t va, vsize_t size) 1607pmap_kremove(vaddr_t va, vsize_t size)
1606{ 1608{
1607 struct pmap *pm = pmap_kernel(); 1609 struct pmap *pm = pmap_kernel();
1608 int64_t data; 1610 int64_t data;
1609 paddr_t pa; 1611 paddr_t pa;
1610 int rv; 1612 int rv;
1611 bool flush = FALSE; 1613 bool flush = FALSE;
1612 1614
1613 KASSERT(va < INTSTACK || va > EINTSTACK); 1615 KASSERT(va < INTSTACK || va > EINTSTACK);
1614 KASSERT(va < kdata || va > ekdata); 1616 KASSERT(va < kdata || va > ekdata);
1615 1617
1616 DPRINTF(PDB_DEMAP, ("pmap_kremove: start 0x%lx size %lx\n", va, size)); 1618 DPRINTF(PDB_DEMAP, ("pmap_kremove: start 0x%lx size %lx\n", va, size));
1617 for (; size >= PAGE_SIZE; va += PAGE_SIZE, size -= PAGE_SIZE) { 1619 for (; size >= PAGE_SIZE; va += PAGE_SIZE, size -= PAGE_SIZE) {
1618 1620
1619#ifdef DIAGNOSTIC 1621#ifdef DIAGNOSTIC
1620 /* 1622 /*
1621 * Is this part of the permanent 4MB mapping? 1623 * Is this part of the permanent 4MB mapping?
1622 */ 1624 */
1623 if (va >= ktext && va < roundup(ekdata, 4*MEG)) 1625 if (va >= ktext && va < roundup(ekdata, 4*MEG))
1624 panic("pmap_kremove: va=%08x in locked TLB", (u_int)va); 1626 panic("pmap_kremove: va=%08x in locked TLB", (u_int)va);
1625#endif 1627#endif
1626 1628
1627 data = pseg_get(pm, va); 1629 data = pseg_get(pm, va);
1628 if ((data & TLB_V) == 0) { 1630 if ((data & TLB_V) == 0) {
1629 continue; 1631 continue;
1630 } 1632 }
1631 1633
1632 flush = TRUE; 1634 flush = TRUE;
1633 pa = data & TLB_PA_MASK; 1635 pa = data & TLB_PA_MASK;
1634 1636
1635 /* 1637 /*
1636 * We need to flip the valid bit and 1638 * We need to flip the valid bit and
1637 * clear the access statistics. 1639 * clear the access statistics.
1638 */ 1640 */
1639 1641
1640 rv = pseg_set(pm, va, 0, 0); 1642 rv = pseg_set(pm, va, 0, 0);
1641 if (rv & 1) 1643 if (rv & 1)
1642 panic("pmap_kremove: pseg_set needs spare, rv=%d\n", 1644 panic("pmap_kremove: pseg_set needs spare, rv=%d\n",
1643 rv); 1645 rv);
1644 DPRINTF(PDB_DEMAP, ("pmap_kremove: seg %x pdir %x pte %x\n", 1646 DPRINTF(PDB_DEMAP, ("pmap_kremove: seg %x pdir %x pte %x\n",
1645 (int)va_to_seg(va), (int)va_to_dir(va), 1647 (int)va_to_seg(va), (int)va_to_dir(va),
1646 (int)va_to_pte(va))); 1648 (int)va_to_pte(va)));
1647 REMOVE_STAT(removes); 1649 REMOVE_STAT(removes);
1648 1650
1649 tsb_invalidate(va, pm); 1651 tsb_invalidate(va, pm);
1650 REMOVE_STAT(tflushes); 1652 REMOVE_STAT(tflushes);
1651 1653
1652 /* 1654 /*
1653 * Here we assume nothing can get into the TLB 1655 * Here we assume nothing can get into the TLB
1654 * unless it has a PTE. 1656 * unless it has a PTE.
1655 */ 1657 */
1656 1658
1657 tlb_flush_pte(va, pm); 1659 tlb_flush_pte(va, pm);
1658 dcache_flush_page_all(pa); 1660 dcache_flush_page_all(pa);
1659 } 1661 }
1660 if (flush) 1662 if (flush)
1661 REMOVE_STAT(flushes); 1663 REMOVE_STAT(flushes);
1662} 1664}
1663 1665
1664/* 1666/*
1665 * Insert physical page at pa into the given pmap at virtual address va. 1667 * Insert physical page at pa into the given pmap at virtual address va.
1666 * Supports 64-bit pa so we can map I/O space. 1668 * Supports 64-bit pa so we can map I/O space.
1667 */ 1669 */
1668 1670
1669int 1671int
1670pmap_enter(struct pmap *pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 1672pmap_enter(struct pmap *pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
1671{ 1673{
1672 pte_t tte; 1674 pte_t tte;
1673 int64_t data; 1675 int64_t data;
1674 paddr_t opa = 0, ptp; /* XXX: gcc */ 1676 paddr_t opa = 0, ptp; /* XXX: gcc */
1675 pv_entry_t pvh, npv = NULL, freepv; 1677 pv_entry_t pvh, npv = NULL, freepv;
1676 struct vm_page *pg, *opg, *ptpg; 1678 struct vm_page *pg, *opg, *ptpg;
1677 int s, i, uncached = 0, error = 0; 1679 int s, i, uncached = 0, error = 0;
1678 int size = PGSZ_8K; /* PMAP_SZ_TO_TTE(pa); */ 1680 int size = PGSZ_8K; /* PMAP_SZ_TO_TTE(pa); */
1679 bool wired = (flags & PMAP_WIRED) != 0; 1681 bool wired = (flags & PMAP_WIRED) != 0;
1680 bool wasmapped = FALSE; 1682 bool wasmapped = FALSE;
1681 bool dopv = TRUE; 1683 bool dopv = TRUE;
1682 1684
1683 /* 1685 /*
1684 * Is this part of the permanent mappings? 1686 * Is this part of the permanent mappings?
1685 */ 1687 */
1686 KASSERT(pm != pmap_kernel() || va < INTSTACK || va > EINTSTACK); 1688 KASSERT(pm != pmap_kernel() || va < INTSTACK || va > EINTSTACK);
1687 KASSERT(pm != pmap_kernel() || va < kdata || va > ekdata); 1689 KASSERT(pm != pmap_kernel() || va < kdata || va > ekdata);
1688 1690
1689 /* Grab a spare PV. */ 1691 /* Grab a spare PV. */
1690 freepv = pool_cache_get(&pmap_pv_cache, PR_NOWAIT); 1692 freepv = pool_cache_get(&pmap_pv_cache, PR_NOWAIT);
1691 if (__predict_false(freepv == NULL)) { 1693 if (__predict_false(freepv == NULL)) {
1692 if (flags & PMAP_CANFAIL) 1694 if (flags & PMAP_CANFAIL)
1693 return (ENOMEM); 1695 return (ENOMEM);
1694 panic("pmap_enter: no pv entries available"); 1696 panic("pmap_enter: no pv entries available");
1695 } 1697 }
1696 freepv->pv_next = NULL; 1698 freepv->pv_next = NULL;
1697 1699
1698 /* 1700 /*
1699 * If a mapping at this address already exists, check if we're 1701 * If a mapping at this address already exists, check if we're
1700 * entering the same PA again. if it's different remove it. 1702 * entering the same PA again. if it's different remove it.
1701 */ 1703 */
1702 1704
1703 mutex_enter(&pmap_lock); 1705 mutex_enter(&pmap_lock);
1704 data = pseg_get(pm, va); 1706 data = pseg_get(pm, va);
1705 if (data & TLB_V) { 1707 if (data & TLB_V) {
1706 wasmapped = TRUE; 1708 wasmapped = TRUE;
1707 opa = data & TLB_PA_MASK; 1709 opa = data & TLB_PA_MASK;
1708 if (opa != pa) { 1710 if (opa != pa) {
1709 opg = PHYS_TO_VM_PAGE(opa); 1711 opg = PHYS_TO_VM_PAGE(opa);
1710 if (opg != NULL) { 1712 if (opg != NULL) {
1711 npv = pmap_remove_pv(pm, va, opg); 1713 npv = pmap_remove_pv(pm, va, opg);
1712 } 1714 }
1713 } 1715 }
1714 } 1716 }
1715 1717
1716 /* 1718 /*
1717 * Construct the TTE. 1719 * Construct the TTE.
1718 */ 1720 */
1719 pg = PHYS_TO_VM_PAGE(pa); 1721 pg = PHYS_TO_VM_PAGE(pa);
1720 if (pg) { 1722 if (pg) {
1721 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 1723 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
1722 1724
1723 pvh = &md->mdpg_pvh; 1725 pvh = &md->mdpg_pvh;
1724 uncached = (pvh->pv_va & (PV_ALIAS|PV_NVC)); 1726 uncached = (pvh->pv_va & (PV_ALIAS|PV_NVC));
1725#ifdef DIAGNOSTIC 1727#ifdef DIAGNOSTIC
1726 if ((flags & VM_PROT_ALL) & ~prot) 1728 if ((flags & VM_PROT_ALL) & ~prot)
1727 panic("pmap_enter: access_type exceeds prot"); 1729 panic("pmap_enter: access_type exceeds prot");
1728#endif 1730#endif
1729 /* 1731 /*
1730 * If we don't have the traphandler do it, 1732 * If we don't have the traphandler do it,
1731 * set the ref/mod bits now. 1733 * set the ref/mod bits now.
1732 */ 1734 */
1733 if (flags & VM_PROT_ALL) 1735 if (flags & VM_PROT_ALL)
1734 pvh->pv_va |= PV_REF; 1736 pvh->pv_va |= PV_REF;
1735 if (flags & VM_PROT_WRITE) 1737 if (flags & VM_PROT_WRITE)
1736 pvh->pv_va |= PV_MOD; 1738 pvh->pv_va |= PV_MOD;
1737 1739
1738 /* 1740 /*
1739 * make sure we have a pv entry ready if we need one. 1741 * make sure we have a pv entry ready if we need one.
1740 */ 1742 */
1741 if (pvh->pv_pmap == NULL || (wasmapped && opa == pa)) { 1743 if (pvh->pv_pmap == NULL || (wasmapped && opa == pa)) {
1742 if (npv != NULL) { 1744 if (npv != NULL) {
1743 /* free it */ 1745 /* free it */
1744 npv->pv_next = freepv; 1746 npv->pv_next = freepv;
1745 freepv = npv; 1747 freepv = npv;
1746 npv = NULL; 1748 npv = NULL;
1747 } 1749 }
1748 if (wasmapped && opa == pa) { 1750 if (wasmapped && opa == pa) {
1749 dopv = FALSE; 1751 dopv = FALSE;
1750 } 1752 }
1751 } else if (npv == NULL) { 1753 } else if (npv == NULL) {
1752 /* use the pre-allocated pv */ 1754 /* use the pre-allocated pv */
1753 npv = freepv; 1755 npv = freepv;
1754 freepv = freepv->pv_next; 1756 freepv = freepv->pv_next;
1755 } 1757 }
1756 ENTER_STAT(managed); 1758 ENTER_STAT(managed);
1757 } else { 1759 } else {
1758 ENTER_STAT(unmanaged); 1760 ENTER_STAT(unmanaged);
1759 dopv = FALSE; 1761 dopv = FALSE;
1760 if (npv != NULL) { 1762 if (npv != NULL) {
1761 /* free it */ 1763 /* free it */
1762 npv->pv_next = freepv; 1764 npv->pv_next = freepv;
1763 freepv = npv; 1765 freepv = npv;
1764 npv = NULL; 1766 npv = NULL;
1765 } 1767 }
1766 } 1768 }
1767 1769
1768#ifndef NO_VCACHE 1770#ifndef NO_VCACHE
1769 if (pa & PMAP_NVC) 1771 if (pa & PMAP_NVC)
1770#endif 1772#endif
1771 uncached = 1; 1773 uncached = 1;
1772 if (uncached) { 1774 if (uncached) {
1773 ENTER_STAT(ci); 1775 ENTER_STAT(ci);
1774 } 1776 }
1775 tte.data = TSB_DATA(0, size, pa, pm == pmap_kernel(), 1777 tte.data = TSB_DATA(0, size, pa, pm == pmap_kernel(),
1776 flags & VM_PROT_WRITE, !(pa & PMAP_NC), 1778 flags & VM_PROT_WRITE, !(pa & PMAP_NC),
1777 uncached, 1, pa & PMAP_LITTLE); 1779 uncached, 1, pa & PMAP_LITTLE);
1778#ifdef HWREF 1780#ifdef HWREF
1779 if (prot & VM_PROT_WRITE) 1781 if (prot & VM_PROT_WRITE)
1780 tte.data |= TLB_REAL_W; 1782 tte.data |= TLB_REAL_W;
1781 if (prot & VM_PROT_EXECUTE) 1783 if (prot & VM_PROT_EXECUTE)
1782 tte.data |= TLB_EXEC; 1784 tte.data |= TLB_EXEC;
1783#else 1785#else
1784 /* If it needs ref accounting do nothing. */ 1786 /* If it needs ref accounting do nothing. */
1785 if (!(flags & VM_PROT_READ)) { 1787 if (!(flags & VM_PROT_READ)) {
1786 mutex_exit(&pmap_lock); 1788 mutex_exit(&pmap_lock);
1787 goto out; 1789 goto out;
1788 } 1790 }
1789#endif 1791#endif
1790 if (flags & VM_PROT_EXECUTE) { 1792 if (flags & VM_PROT_EXECUTE) {
1791 if ((flags & (VM_PROT_READ|VM_PROT_WRITE)) == 0) 1793 if ((flags & (VM_PROT_READ|VM_PROT_WRITE)) == 0)
1792 tte.data |= TLB_EXEC_ONLY|TLB_EXEC; 1794 tte.data |= TLB_EXEC_ONLY|TLB_EXEC;
1793 else 1795 else
1794 tte.data |= TLB_EXEC; 1796 tte.data |= TLB_EXEC;
1795 } 1797 }
1796 if (wired) 1798 if (wired)
1797 tte.data |= TLB_TSB_LOCK; 1799 tte.data |= TLB_TSB_LOCK;
1798 ptp = 0; 1800 ptp = 0;
1799 1801
1800 retry: 1802 retry:
1801 i = pseg_set(pm, va, tte.data, ptp); 1803 i = pseg_set(pm, va, tte.data, ptp);
1802 if (i & 4) { 1804 if (i & 4) {
1803 /* ptp used as L3 */ 1805 /* ptp used as L3 */
1804 KASSERT(ptp != 0); 1806 KASSERT(ptp != 0);
1805 KASSERT((i & 3) == 0); 1807 KASSERT((i & 3) == 0);
1806 ptpg = PHYS_TO_VM_PAGE(ptp); 1808 ptpg = PHYS_TO_VM_PAGE(ptp);
1807 if (ptpg) { 1809 if (ptpg) {
1808 ptpg->offset = (uint64_t)va & (0xfffffLL << 23); 1810 ptpg->offset = (uint64_t)va & (0xfffffLL << 23);
1809 TAILQ_INSERT_TAIL(&pm->pm_obj.memq, ptpg, listq.queue); 1811 TAILQ_INSERT_TAIL(&pm->pm_obj.memq, ptpg, listq.queue);
1810 } else { 1812 } else {
1811 KASSERT(pm == pmap_kernel()); 1813 KASSERT(pm == pmap_kernel());
1812 } 1814 }
1813 } 1815 }
1814 if (i & 2) { 1816 if (i & 2) {
1815 /* ptp used as L2 */ 1817 /* ptp used as L2 */
1816 KASSERT(ptp != 0); 1818 KASSERT(ptp != 0);
1817 KASSERT((i & 4) == 0); 1819 KASSERT((i & 4) == 0);
1818 ptpg = PHYS_TO_VM_PAGE(ptp); 1820 ptpg = PHYS_TO_VM_PAGE(ptp);
1819 if (ptpg) { 1821 if (ptpg) {
1820 ptpg->offset = (((uint64_t)va >> 43) & 0x3ffLL) << 13; 1822 ptpg->offset = (((uint64_t)va >> 43) & 0x3ffLL) << 13;
1821 TAILQ_INSERT_TAIL(&pm->pm_obj.memq, ptpg, listq.queue); 1823 TAILQ_INSERT_TAIL(&pm->pm_obj.memq, ptpg, listq.queue);
1822 } else { 1824 } else {
1823 KASSERT(pm == pmap_kernel()); 1825 KASSERT(pm == pmap_kernel());
1824 } 1826 }
1825 } 1827 }
1826 if (i & 1) { 1828 if (i & 1) {
1827 KASSERT((i & 4) == 0); 1829 KASSERT((i & 4) == 0);
1828 ptp = 0; 1830 ptp = 0;
1829 if (!pmap_get_page(&ptp)) { 1831 if (!pmap_get_page(&ptp)) {
1830 mutex_exit(&pmap_lock); 1832 mutex_exit(&pmap_lock);
1831 if (flags & PMAP_CANFAIL) { 1833 if (flags & PMAP_CANFAIL) {
1832 if (npv != NULL) { 1834 if (npv != NULL) {
1833 /* free it */ 1835 /* free it */
1834 npv->pv_next = freepv; 1836 npv->pv_next = freepv;
1835 freepv = npv; 1837 freepv = npv;
1836 } 1838 }
1837 error = ENOMEM; 1839 error = ENOMEM;
1838 goto out; 1840 goto out;
1839 } else { 1841 } else {
1840 panic("pmap_enter: no pages"); 1842 panic("pmap_enter: no pages");
1841 } 1843 }
1842 } 1844 }
1843 ENTER_STAT(ptpneeded); 1845 ENTER_STAT(ptpneeded);
1844 goto retry; 1846 goto retry;
1845 } 1847 }
1846 if (ptp && i == 0) { 1848 if (ptp && i == 0) {
1847 /* We allocated a spare page but didn't use it. Free it. */ 1849 /* We allocated a spare page but didn't use it. Free it. */
1848 printf("pmap_enter: freeing unused page %llx\n", 1850 printf("pmap_enter: freeing unused page %llx\n",
1849 (long long)ptp); 1851 (long long)ptp);
1850 pmap_free_page_noflush(ptp); 1852 pmap_free_page_noflush(ptp);
1851 } 1853 }
1852 if (dopv) { 1854 if (dopv) {
1853 pmap_enter_pv(pm, va, pa, pg, npv); 1855 pmap_enter_pv(pm, va, pa, pg, npv);
1854 } 1856 }
1855 1857
1856 mutex_exit(&pmap_lock); 1858 mutex_exit(&pmap_lock);
1857#ifdef DEBUG 1859#ifdef DEBUG
1858 i = ptelookup_va(va); 1860 i = ptelookup_va(va);
1859 if (pmapdebug & PDB_ENTER) 1861 if (pmapdebug & PDB_ENTER)
1860 prom_printf("pmap_enter: va=%08x data=%08x:%08x " 1862 prom_printf("pmap_enter: va=%08x data=%08x:%08x "
1861 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32), 1863 "tsb_dmmu[%d]=%08x\n", va, (int)(tte.data>>32),
1862 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]); 1864 (int)tte.data, i, &curcpu()->ci_tsb_dmmu[i]);
1863 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) { 1865 if (pmapdebug & PDB_MMU_STEAL && curcpu()->ci_tsb_dmmu[i].data) {
1864 prom_printf("pmap_enter: evicting entry tag=%x:%08x " 1866 prom_printf("pmap_enter: evicting entry tag=%x:%08x "
1865 "data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1867 "data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1866 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag, 1868 (int)(curcpu()->ci_tsb_dmmu[i].tag>>32), (int)curcpu()->ci_tsb_dmmu[i].tag,
1867 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data, i, 1869 (int)(curcpu()->ci_tsb_dmmu[i].data>>32), (int)curcpu()->ci_tsb_dmmu[i].data, i,
1868 &curcpu()->ci_tsb_dmmu[i]); 1870 &curcpu()->ci_tsb_dmmu[i]);
1869 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n", 1871 prom_printf("with va=%08x data=%08x:%08x tsb_dmmu[%d]=%08x\n",
1870 va, (int)(tte.data>>32), (int)tte.data, i, 1872 va, (int)(tte.data>>32), (int)tte.data, i,
1871 &curcpu()->ci_tsb_dmmu[i]); 1873 &curcpu()->ci_tsb_dmmu[i]);
1872 } 1874 }
1873#endif 1875#endif
1874 1876
1875 if (flags & (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)) { 1877 if (flags & (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)) {
1876 1878
1877 /* 1879 /*
1878 * preload the TSB with the new entry, 1880 * preload the TSB with the new entry,
1879 * since we're going to need it immediately anyway. 1881 * since we're going to need it immediately anyway.
1880 */ 1882 */
1881 1883
1882 KASSERT(pmap_ctx(pm)>=0); 1884 KASSERT(pmap_ctx(pm)>=0);
1883 i = ptelookup_va(va); 1885 i = ptelookup_va(va);
1884 tte.tag = TSB_TAG(0, pmap_ctx(pm), va); 1886 tte.tag = TSB_TAG(0, pmap_ctx(pm), va);
1885 s = splhigh(); 1887 s = splhigh();
1886 if (wasmapped && pmap_is_on_mmu(pm)) { 1888 if (wasmapped && pmap_is_on_mmu(pm)) {
1887 tsb_invalidate(va, pm); 1889 tsb_invalidate(va, pm);
1888 } 1890 }
1889 if (flags & (VM_PROT_READ | VM_PROT_WRITE)) { 1891 if (flags & (VM_PROT_READ | VM_PROT_WRITE)) {
1890 curcpu()->ci_tsb_dmmu[i].tag = tte.tag; 1892 curcpu()->ci_tsb_dmmu[i].tag = tte.tag;
1891 __asm volatile("" : : : "memory"); 1893 __asm volatile("" : : : "memory");
1892 curcpu()->ci_tsb_dmmu[i].data = tte.data; 1894 curcpu()->ci_tsb_dmmu[i].data = tte.data;
1893 } 1895 }
1894 if (flags & VM_PROT_EXECUTE) { 1896 if (flags & VM_PROT_EXECUTE) {
1895 curcpu()->ci_tsb_immu[i].tag = tte.tag; 1897 curcpu()->ci_tsb_immu[i].tag = tte.tag;
1896 __asm volatile("" : : : "memory"); 1898 __asm volatile("" : : : "memory");
1897 curcpu()->ci_tsb_immu[i].data = tte.data; 1899 curcpu()->ci_tsb_immu[i].data = tte.data;
1898 } 1900 }
1899 1901
1900 /* 1902 /*
1901 * it's only necessary to flush the TLB if this page was 1903 * it's only necessary to flush the TLB if this page was
1902 * previously mapped, but for some reason it's a lot faster 1904 * previously mapped, but for some reason it's a lot faster
1903 * for the fork+exit microbenchmark if we always do it. 1905 * for the fork+exit microbenchmark if we always do it.
1904 */ 1906 */
1905 1907
1906 KASSERT(pmap_ctx(pm)>=0); 1908 KASSERT(pmap_ctx(pm)>=0);
1907#ifdef MULTIPROCESSOR 1909#ifdef MULTIPROCESSOR
1908 if (wasmapped && pmap_is_on_mmu(pm)) 1910 if (wasmapped && pmap_is_on_mmu(pm))
1909 tlb_flush_pte(va, pm); 1911 tlb_flush_pte(va, pm);
1910 else 1912 else
1911 sp_tlb_flush_pte(va, pmap_ctx(pm)); 1913 sp_tlb_flush_pte(va, pmap_ctx(pm));
1912#else 1914#else
1913 tlb_flush_pte(va, pm); 1915 tlb_flush_pte(va, pm);
1914#endif 1916#endif
1915 splx(s); 1917 splx(s);
1916 } else if (wasmapped && pmap_is_on_mmu(pm)) { 1918 } else if (wasmapped && pmap_is_on_mmu(pm)) {
1917 /* Force reload -- protections may be changed */ 1919 /* Force reload -- protections may be changed */
1918 KASSERT(pmap_ctx(pm)>=0); 1920 KASSERT(pmap_ctx(pm)>=0);
1919 tsb_invalidate(va, pm); 1921 tsb_invalidate(va, pm);
1920 tlb_flush_pte(va, pm); 1922 tlb_flush_pte(va, pm);
1921 } 1923 }
1922 1924
1923 /* We will let the fast mmu miss interrupt load the new translation */ 1925 /* We will let the fast mmu miss interrupt load the new translation */
1924 pv_check(); 1926 pv_check();
1925 out: 1927 out:
1926 /* Catch up on deferred frees. */ 1928 /* Catch up on deferred frees. */
1927 for (; freepv != NULL; freepv = npv) { 1929 for (; freepv != NULL; freepv = npv) {
1928 npv = freepv->pv_next; 1930 npv = freepv->pv_next;
1929 pool_cache_put(&pmap_pv_cache, freepv); 1931 pool_cache_put(&pmap_pv_cache, freepv);
1930 } 1932 }
1931 return error; 1933 return error;
1932} 1934}
1933 1935
1934void 1936void
1935pmap_remove_all(struct pmap *pm) 1937pmap_remove_all(struct pmap *pm)
1936{ 1938{
1937#ifdef MULTIPROCESSOR 1939#ifdef MULTIPROCESSOR
1938 struct cpu_info *ci; 1940 struct cpu_info *ci;
1939 sparc64_cpuset_t pmap_cpus_active; 1941 sparc64_cpuset_t pmap_cpus_active;
1940#endif 1942#endif
1941 1943
1942 if (pm == pmap_kernel()) { 1944 if (pm == pmap_kernel()) {
1943 return; 1945 return;
1944 } 1946 }
1945 write_user_windows(); 1947 write_user_windows();
1946 pm->pm_refs = 0; 1948 pm->pm_refs = 0;
1947 1949
1948 /* 1950 /*
1949 * XXXMRG: pmap_destroy() does exactly the same dance here. 1951 * XXXMRG: pmap_destroy() does exactly the same dance here.
1950 * surely one of them isn't necessary? 1952 * surely one of them isn't necessary?
1951 */ 1953 */
1952#ifdef MULTIPROCESSOR 1954#ifdef MULTIPROCESSOR
1953 CPUSET_CLEAR(pmap_cpus_active); 1955 CPUSET_CLEAR(pmap_cpus_active);
1954 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 1956 for (ci = cpus; ci != NULL; ci = ci->ci_next) {
1955 /* XXXMRG: Move the lock inside one or both tests? */ 1957 /* XXXMRG: Move the lock inside one or both tests? */
1956 mutex_enter(&ci->ci_ctx_lock); 1958 mutex_enter(&ci->ci_ctx_lock);
1957 if (CPUSET_HAS(cpus_active, ci->ci_index)) { 1959 if (CPUSET_HAS(cpus_active, ci->ci_index)) {
1958 if (pm->pm_ctx[ci->ci_index] > 0) { 1960 if (pm->pm_ctx[ci->ci_index] > 0) {
1959 CPUSET_ADD(pmap_cpus_active, ci->ci_index); 1961 CPUSET_ADD(pmap_cpus_active, ci->ci_index);
1960 ctx_free(pm, ci); 1962 ctx_free(pm, ci);
1961 } 1963 }
1962 } 1964 }
1963 mutex_exit(&ci->ci_ctx_lock); 1965 mutex_exit(&ci->ci_ctx_lock);
1964 } 1966 }
1965#else 1967#else
1966 if (pmap_ctx(pm)) { 1968 if (pmap_ctx(pm)) {
1967 mutex_enter(&curcpu()->ci_ctx_lock); 1969 mutex_enter(&curcpu()->ci_ctx_lock);
1968 ctx_free(pm, curcpu()); 1970 ctx_free(pm, curcpu());
1969 mutex_exit(&curcpu()->ci_ctx_lock); 1971 mutex_exit(&curcpu()->ci_ctx_lock);
1970 } 1972 }
1971#endif 1973#endif
1972 1974
1973 REMOVE_STAT(flushes); 1975 REMOVE_STAT(flushes);
1974 /* 1976 /*
1975 * XXXMRG: couldn't we do something less severe here, and 1977 * XXXMRG: couldn't we do something less severe here, and
1976 * only flush the right context on each CPU? 1978 * only flush the right context on each CPU?
1977 */ 1979 */
1978#ifdef MULTIPROCESSOR 1980#ifdef MULTIPROCESSOR
1979 smp_blast_dcache(pmap_cpus_active); 1981 smp_blast_dcache(pmap_cpus_active);
1980#else 1982#else
1981 sp_blast_dcache(dcache_size, dcache_line_size); 1983 sp_blast_dcache(dcache_size, dcache_line_size);
1982#endif 1984#endif
1983} 1985}
1984 1986
1985/* 1987/*
1986 * Remove the given range of mapping entries. 1988 * Remove the given range of mapping entries.
1987 */ 1989 */
1988void 1990void
1989pmap_remove(struct pmap *pm, vaddr_t va, vaddr_t endva) 1991pmap_remove(struct pmap *pm, vaddr_t va, vaddr_t endva)
1990{ 1992{
1991 int64_t data; 1993 int64_t data;
1992 paddr_t pa; 1994 paddr_t pa;
1993 struct vm_page *pg; 1995 struct vm_page *pg;
1994 pv_entry_t pv, freepv = NULL; 1996 pv_entry_t pv, freepv = NULL;
1995 int rv; 1997 int rv;
1996 bool flush = FALSE; 1998 bool flush = FALSE;
1997 1999
1998 /* 2000 /*
1999 * In here we should check each pseg and if there are no more entries, 2001 * In here we should check each pseg and if there are no more entries,
2000 * free it. It's just that linear scans of 8K pages gets expensive. 2002 * free it. It's just that linear scans of 8K pages gets expensive.
2001 */ 2003 */
2002 2004
2003 KASSERT(pm != pmap_kernel() || endva < INTSTACK || va > EINTSTACK); 2005 KASSERT(pm != pmap_kernel() || endva < INTSTACK || va > EINTSTACK);
2004 KASSERT(pm != pmap_kernel() || endva < kdata || va > ekdata); 2006 KASSERT(pm != pmap_kernel() || endva < kdata || va > ekdata);
2005 2007
2006 mutex_enter(&pmap_lock); 2008 mutex_enter(&pmap_lock);
2007 DPRINTF(PDB_REMOVE, ("pmap_remove(pm=%p, va=%p, endva=%p):", pm, 2009 DPRINTF(PDB_REMOVE, ("pmap_remove(pm=%p, va=%p, endva=%p):", pm,
2008 (void *)(u_long)va, (void *)(u_long)endva)); 2010 (void *)(u_long)va, (void *)(u_long)endva));
2009 REMOVE_STAT(calls); 2011 REMOVE_STAT(calls);
2010 2012
2011 /* Now do the real work */ 2013 /* Now do the real work */
2012 for (; va < endva; va += PAGE_SIZE) { 2014 for (; va < endva; va += PAGE_SIZE) {
2013#ifdef DIAGNOSTIC 2015#ifdef DIAGNOSTIC
2014 /* 2016 /*
2015 * Is this part of the permanent 4MB mapping? 2017 * Is this part of the permanent 4MB mapping?
2016 */ 2018 */
2017 if (pm == pmap_kernel() && va >= ktext && 2019 if (pm == pmap_kernel() && va >= ktext &&
2018 va < roundup(ekdata, 4*MEG)) 2020 va < roundup(ekdata, 4*MEG))
2019 panic("pmap_remove: va=%08llx in locked TLB", 2021 panic("pmap_remove: va=%08llx in locked TLB",
2020 (long long)va); 2022 (long long)va);
2021#endif 2023#endif
2022 2024
2023 data = pseg_get(pm, va); 2025 data = pseg_get(pm, va);
2024 if ((data & TLB_V) == 0) { 2026 if ((data & TLB_V) == 0) {
2025 continue; 2027 continue;
2026 } 2028 }
2027 2029
2028 flush = TRUE; 2030 flush = TRUE;
2029 /* First remove the pv entry, if there is one */ 2031 /* First remove the pv entry, if there is one */
2030 pa = data & TLB_PA_MASK; 2032 pa = data & TLB_PA_MASK;
2031 pg = PHYS_TO_VM_PAGE(pa); 2033 pg = PHYS_TO_VM_PAGE(pa);
2032 if (pg) { 2034 if (pg) {
2033 pv = pmap_remove_pv(pm, va, pg); 2035 pv = pmap_remove_pv(pm, va, pg);
2034 if (pv != NULL) { 2036 if (pv != NULL) {
2035 /* free it */ 2037 /* free it */
2036 pv->pv_next = freepv; 2038 pv->pv_next = freepv;
2037 freepv = pv; 2039 freepv = pv;
2038 } 2040 }
2039 } 2041 }
2040 2042
2041 /* 2043 /*
2042 * We need to flip the valid bit and 2044 * We need to flip the valid bit and
2043 * clear the access statistics. 2045 * clear the access statistics.
2044 */ 2046 */
2045 2047
2046 rv = pseg_set(pm, va, 0, 0); 2048 rv = pseg_set(pm, va, 0, 0);
2047 if (rv & 1) 2049 if (rv & 1)
2048 panic("pmap_remove: pseg_set needed spare, rv=%d!\n", 2050 panic("pmap_remove: pseg_set needed spare, rv=%d!\n",
2049 rv); 2051 rv);
2050 2052
2051 DPRINTF(PDB_REMOVE, (" clearing seg %x pte %x\n", 2053 DPRINTF(PDB_REMOVE, (" clearing seg %x pte %x\n",
2052 (int)va_to_seg(va), (int)va_to_pte(va))); 2054 (int)va_to_seg(va), (int)va_to_pte(va)));
2053 REMOVE_STAT(removes); 2055 REMOVE_STAT(removes);
2054 2056
2055 if (pm != pmap_kernel() && !pmap_has_ctx(pm)) 2057 if (pm != pmap_kernel() && !pmap_has_ctx(pm))
2056 continue; 2058 continue;
2057 2059
2058 /* 2060 /*
2059 * if the pmap is being torn down, don't bother flushing, 2061 * if the pmap is being torn down, don't bother flushing,
2060 * we already have done so. 2062 * we already have done so.
2061 */ 2063 */
2062 2064
2063 if (!pm->pm_refs) 2065 if (!pm->pm_refs)
2064 continue; 2066 continue;
2065 2067
2066 /* 2068 /*
2067 * Here we assume nothing can get into the TLB 2069 * Here we assume nothing can get into the TLB
2068 * unless it has a PTE. 2070 * unless it has a PTE.
2069 */ 2071 */
2070 2072
2071 KASSERT(pmap_ctx(pm)>=0); 2073 KASSERT(pmap_ctx(pm)>=0);
2072 tsb_invalidate(va, pm); 2074 tsb_invalidate(va, pm);
2073 REMOVE_STAT(tflushes); 2075 REMOVE_STAT(tflushes);
2074 tlb_flush_pte(va, pm); 2076 tlb_flush_pte(va, pm);
2075 dcache_flush_page_all(pa); 2077 dcache_flush_page_all(pa);
2076 } 2078 }
2077 if (flush && pm->pm_refs) 2079 if (flush && pm->pm_refs)
2078 REMOVE_STAT(flushes); 2080 REMOVE_STAT(flushes);
2079 DPRINTF(PDB_REMOVE, ("\n")); 2081 DPRINTF(PDB_REMOVE, ("\n"));
2080 pv_check(); 2082 pv_check();
2081 mutex_exit(&pmap_lock); 2083 mutex_exit(&pmap_lock);
2082 2084
2083 /* Catch up on deferred frees. */ 2085 /* Catch up on deferred frees. */
2084 for (; freepv != NULL; freepv = pv) { 2086 for (; freepv != NULL; freepv = pv) {
2085 pv = freepv->pv_next; 2087 pv = freepv->pv_next;
2086 pool_cache_put(&pmap_pv_cache, freepv); 2088 pool_cache_put(&pmap_pv_cache, freepv);
2087 } 2089 }
2088} 2090}
2089 2091
2090/* 2092/*
2091 * Change the protection on the specified range of this pmap. 2093 * Change the protection on the specified range of this pmap.
2092 */ 2094 */
2093void 2095void
2094pmap_protect(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 2096pmap_protect(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
2095{ 2097{
2096 paddr_t pa; 2098 paddr_t pa;
2097 int64_t data; 2099 int64_t data;
2098 struct vm_page *pg; 2100 struct vm_page *pg;
2099 pv_entry_t pv; 2101 pv_entry_t pv;
2100 int rv; 2102 int rv;
2101 2103
2102 KASSERT(pm != pmap_kernel() || eva < INTSTACK || sva > EINTSTACK); 2104 KASSERT(pm != pmap_kernel() || eva < INTSTACK || sva > EINTSTACK);
2103 KASSERT(pm != pmap_kernel() || eva < kdata || sva > ekdata); 2105 KASSERT(pm != pmap_kernel() || eva < kdata || sva > ekdata);
2104 2106
2105 if (prot == VM_PROT_NONE) { 2107 if (prot == VM_PROT_NONE) {
2106 pmap_remove(pm, sva, eva); 2108 pmap_remove(pm, sva, eva);
2107 return; 2109 return;
2108 } 2110 }
2109 2111
2110 mutex_enter(&pmap_lock); 2112 mutex_enter(&pmap_lock);
2111 sva = trunc_page(sva); 2113 sva = trunc_page(sva);
2112 for (; sva < eva; sva += PAGE_SIZE) { 2114 for (; sva < eva; sva += PAGE_SIZE) {
2113#ifdef DEBUG 2115#ifdef DEBUG
2114 /* 2116 /*
2115 * Is this part of the permanent 4MB mapping? 2117 * Is this part of the permanent 4MB mapping?
2116 */ 2118 */
2117 if (pm == pmap_kernel() && sva >= ktext && 2119 if (pm == pmap_kernel() && sva >= ktext &&
2118 sva < roundup(ekdata, 4 * MEG)) { 2120 sva < roundup(ekdata, 4 * MEG)) {
2119 prom_printf("pmap_protect: va=%08x in locked TLB\n", 2121 prom_printf("pmap_protect: va=%08x in locked TLB\n",
2120 sva); 2122 sva);
2121 prom_abort(); 2123 prom_abort();
2122 return; 2124 return;
2123 } 2125 }
2124#endif 2126#endif
2125 DPRINTF(PDB_CHANGEPROT, ("pmap_protect: va %p\n", 2127 DPRINTF(PDB_CHANGEPROT, ("pmap_protect: va %p\n",
2126 (void *)(u_long)sva)); 2128 (void *)(u_long)sva));
2127 data = pseg_get(pm, sva); 2129 data = pseg_get(pm, sva);
2128 if ((data & TLB_V) == 0) { 2130 if ((data & TLB_V) == 0) {
2129 continue; 2131 continue;
2130 } 2132 }
2131 2133
2132 pa = data & TLB_PA_MASK; 2134 pa = data & TLB_PA_MASK;
2133 DPRINTF(PDB_CHANGEPROT|PDB_REF, 2135 DPRINTF(PDB_CHANGEPROT|PDB_REF,
2134 ("pmap_protect: va=%08x data=%08llx " 2136 ("pmap_protect: va=%08x data=%08llx "
2135 "seg=%08x pte=%08x\n", 2137 "seg=%08x pte=%08x\n",
2136 (u_int)sva, (long long)pa, (int)va_to_seg(sva), 2138 (u_int)sva, (long long)pa, (int)va_to_seg(sva),
2137 (int)va_to_pte(sva))); 2139 (int)va_to_pte(sva)));
2138 2140
2139 pg = PHYS_TO_VM_PAGE(pa); 2141 pg = PHYS_TO_VM_PAGE(pa);
2140 if (pg) { 2142 if (pg) {
2141 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2143 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2142 2144
2143 /* Save REF/MOD info */ 2145 /* Save REF/MOD info */
2144 pv = &md->mdpg_pvh; 2146 pv = &md->mdpg_pvh;
2145 if (data & TLB_ACCESS) 2147 if (data & TLB_ACCESS)
2146 pv->pv_va |= PV_REF; 2148 pv->pv_va |= PV_REF;
2147 if (data & TLB_MODIFY) 2149 if (data & TLB_MODIFY)
2148 pv->pv_va |= PV_MOD; 2150 pv->pv_va |= PV_MOD;
2149 } 2151 }
2150 2152
2151 /* Just do the pmap and TSB, not the pv_list */ 2153 /* Just do the pmap and TSB, not the pv_list */
2152 if ((prot & VM_PROT_WRITE) == 0) 2154 if ((prot & VM_PROT_WRITE) == 0)
2153 data &= ~(TLB_W|TLB_REAL_W); 2155 data &= ~(TLB_W|TLB_REAL_W);
2154 if ((prot & VM_PROT_EXECUTE) == 0) 2156 if ((prot & VM_PROT_EXECUTE) == 0)
2155 data &= ~(TLB_EXEC); 2157 data &= ~(TLB_EXEC);
2156 2158
2157 rv = pseg_set(pm, sva, data, 0); 2159 rv = pseg_set(pm, sva, data, 0);
2158 if (rv & 1) 2160 if (rv & 1)
2159 panic("pmap_protect: pseg_set needs spare! rv=%d\n", 2161 panic("pmap_protect: pseg_set needs spare! rv=%d\n",
2160 rv); 2162 rv);
2161 2163
2162 if (pm != pmap_kernel() && !pmap_has_ctx(pm)) 2164 if (pm != pmap_kernel() && !pmap_has_ctx(pm))
2163 continue; 2165 continue;
2164 2166
2165 KASSERT(pmap_ctx(pm)>=0); 2167 KASSERT(pmap_ctx(pm)>=0);
2166 tsb_invalidate(sva, pm); 2168 tsb_invalidate(sva, pm);
2167 tlb_flush_pte(sva, pm); 2169 tlb_flush_pte(sva, pm);
2168 } 2170 }
2169 pv_check(); 2171 pv_check();
2170 mutex_exit(&pmap_lock); 2172 mutex_exit(&pmap_lock);
2171} 2173}
2172 2174
2173/* 2175/*
2174 * Extract the physical page address associated 2176 * Extract the physical page address associated
2175 * with the given map/virtual_address pair. 2177 * with the given map/virtual_address pair.
2176 */ 2178 */
2177bool 2179bool
2178pmap_extract(struct pmap *pm, vaddr_t va, paddr_t *pap) 2180pmap_extract(struct pmap *pm, vaddr_t va, paddr_t *pap)
2179{ 2181{
2180 paddr_t pa; 2182 paddr_t pa;
2181 int64_t data = 0; 2183 int64_t data = 0;
2182 2184
2183 if (pm == pmap_kernel() && va >= kdata && va < roundup(ekdata, 4*MEG)) { 2185 if (pm == pmap_kernel() && va >= kdata && va < roundup(ekdata, 4*MEG)) {
2184 /* Need to deal w/locked TLB entry specially. */ 2186 /* Need to deal w/locked TLB entry specially. */
2185 pa = pmap_kextract(va); 2187 pa = pmap_kextract(va);
2186 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n", 2188 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
2187 (u_long)va, (unsigned long long)pa)); 2189 (u_long)va, (unsigned long long)pa));
2188 if (pap != NULL) 2190 if (pap != NULL)
2189 *pap = pa; 2191 *pap = pa;
2190 return TRUE; 2192 return TRUE;
2191 } else if (pm == pmap_kernel() && va >= ktext && va < ektext) { 2193 } else if (pm == pmap_kernel() && va >= ktext && va < ektext) {
2192 /* Need to deal w/locked TLB entry specially. */ 2194 /* Need to deal w/locked TLB entry specially. */
2193 pa = pmap_kextract(va); 2195 pa = pmap_kextract(va);
2194 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n", 2196 DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
2195 (u_long)va, (unsigned long long)pa)); 2197 (u_long)va, (unsigned long long)pa));
2196 if (pap != NULL) 2198 if (pap != NULL)
2197 *pap = pa; 2199 *pap = pa;
2198 return TRUE; 2200 return TRUE;
2199 } else if (pm == pmap_kernel() && va >= INTSTACK && va < (INTSTACK + 64*KB)) { 2201 } else if (pm == pmap_kernel() && va >= INTSTACK && va < (INTSTACK + 64*KB)) {
2200 pa = (paddr_t)(curcpu()->ci_paddr - INTSTACK + va); 2202 pa = (paddr_t)(curcpu()->ci_paddr - INTSTACK + va);
2201 DPRINTF(PDB_EXTRACT, ("pmap_extract (intstack): va=%lx pa=%llx\n", 2203 DPRINTF(PDB_EXTRACT, ("pmap_extract (intstack): va=%lx pa=%llx\n",
2202 (u_long)va, (unsigned long long)pa)); 2204 (u_long)va, (unsigned long long)pa));
2203 if (pap != NULL) 2205 if (pap != NULL)
2204 *pap = pa; 2206 *pap = pa;
2205 return TRUE; 2207 return TRUE;
2206 } else { 2208 } else {
2207 data = pseg_get(pm, va); 2209 data = pseg_get(pm, va);
2208 pa = data & TLB_PA_MASK; 2210 pa = data & TLB_PA_MASK;
2209#ifdef DEBUG 2211#ifdef DEBUG
2210 if (pmapdebug & PDB_EXTRACT) { 2212 if (pmapdebug & PDB_EXTRACT) {
2211 paddr_t npa = ldxa((vaddr_t)&pm->pm_segs[va_to_seg(va)], 2213 paddr_t npa = ldxa((vaddr_t)&pm->pm_segs[va_to_seg(va)],
2212 ASI_PHYS_CACHED); 2214 ASI_PHYS_CACHED);
2213 printf("pmap_extract: va=%p segs[%ld]=%llx", 2215 printf("pmap_extract: va=%p segs[%ld]=%llx",
2214 (void *)(u_long)va, (long)va_to_seg(va), 2216 (void *)(u_long)va, (long)va_to_seg(va),
2215 (unsigned long long)npa); 2217 (unsigned long long)npa);
2216 if (npa) { 2218 if (npa) {
2217 npa = (paddr_t) 2219 npa = (paddr_t)
2218 ldxa((vaddr_t)&((paddr_t *)(u_long)npa) 2220 ldxa((vaddr_t)&((paddr_t *)(u_long)npa)
2219 [va_to_dir(va)], 2221 [va_to_dir(va)],
2220 ASI_PHYS_CACHED); 2222 ASI_PHYS_CACHED);
2221 printf(" segs[%ld][%ld]=%lx", 2223 printf(" segs[%ld][%ld]=%lx",
2222 (long)va_to_seg(va), 2224 (long)va_to_seg(va),
2223 (long)va_to_dir(va), (long)npa); 2225 (long)va_to_dir(va), (long)npa);
2224 } 2226 }
2225 if (npa) { 2227 if (npa) {
2226 npa = (paddr_t) 2228 npa = (paddr_t)
2227 ldxa((vaddr_t)&((paddr_t *)(u_long)npa) 2229 ldxa((vaddr_t)&((paddr_t *)(u_long)npa)
2228 [va_to_pte(va)], 2230 [va_to_pte(va)],
2229 ASI_PHYS_CACHED); 2231 ASI_PHYS_CACHED);
2230 printf(" segs[%ld][%ld][%ld]=%lx", 2232 printf(" segs[%ld][%ld][%ld]=%lx",
2231 (long)va_to_seg(va), 2233 (long)va_to_seg(va),
2232 (long)va_to_dir(va), 2234 (long)va_to_dir(va),
2233 (long)va_to_pte(va), (long)npa); 2235 (long)va_to_pte(va), (long)npa);
2234 } 2236 }
2235 printf(" pseg_get: %lx\n", (long)pa); 2237 printf(" pseg_get: %lx\n", (long)pa);
2236 } 2238 }
2237#endif 2239#endif
2238 } 2240 }
2239 if ((data & TLB_V) == 0) 2241 if ((data & TLB_V) == 0)
2240 return (FALSE); 2242 return (FALSE);
2241 if (pap != NULL) 2243 if (pap != NULL)
2242 *pap = pa + (va & PGOFSET); 2244 *pap = pa + (va & PGOFSET);
2243 return (TRUE); 2245 return (TRUE);
2244} 2246}
2245 2247
2246/* 2248/*
2247 * Change protection on a kernel address. 2249 * Change protection on a kernel address.
2248 * This should only be called from MD code. 2250 * This should only be called from MD code.
2249 */ 2251 */
2250void 2252void
2251pmap_kprotect(vaddr_t va, vm_prot_t prot) 2253pmap_kprotect(vaddr_t va, vm_prot_t prot)
2252{ 2254{
2253 struct pmap *pm = pmap_kernel(); 2255 struct pmap *pm = pmap_kernel();
2254 int64_t data; 2256 int64_t data;
2255 int rv; 2257 int rv;
2256 2258
2257 mutex_enter(&pmap_lock); 2259 mutex_enter(&pmap_lock);
2258 data = pseg_get(pm, va); 2260 data = pseg_get(pm, va);
2259 KASSERT(data & TLB_V); 2261 KASSERT(data & TLB_V);
2260 if (prot & VM_PROT_WRITE) { 2262 if (prot & VM_PROT_WRITE) {
2261 data |= (TLB_W|TLB_REAL_W); 2263 data |= (TLB_W|TLB_REAL_W);
2262 } else { 2264 } else {
2263 data &= ~(TLB_W|TLB_REAL_W); 2265 data &= ~(TLB_W|TLB_REAL_W);
2264 } 2266 }
2265 rv = pseg_set(pm, va, data, 0); 2267 rv = pseg_set(pm, va, data, 0);
2266 if (rv & 1) 2268 if (rv & 1)
2267 panic("pmap_kprotect: pseg_set needs spare! rv=%d", rv); 2269 panic("pmap_kprotect: pseg_set needs spare! rv=%d", rv);
2268 KASSERT(pmap_ctx(pm)>=0); 2270 KASSERT(pmap_ctx(pm)>=0);
2269 tsb_invalidate(va, pm); 2271 tsb_invalidate(va, pm);
2270 tlb_flush_pte(va, pm); 2272 tlb_flush_pte(va, pm);
2271 mutex_exit(&pmap_lock); 2273 mutex_exit(&pmap_lock);
2272} 2274}
2273 2275
2274/* 2276/*
2275 * Return the number bytes that pmap_dumpmmu() will dump. 2277 * Return the number bytes that pmap_dumpmmu() will dump.
2276 */ 2278 */
2277int 2279int
2278pmap_dumpsize(void) 2280pmap_dumpsize(void)
2279{ 2281{
2280 int sz; 2282 int sz;
2281 2283
2282 sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); 2284 sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
2283 sz += kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg); 2285 sz += kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg);
2284 sz += phys_installed_size * sizeof(phys_ram_seg_t); 2286 sz += phys_installed_size * sizeof(phys_ram_seg_t);
2285 2287
2286 return btodb(sz + DEV_BSIZE - 1); 2288 return btodb(sz + DEV_BSIZE - 1);
2287} 2289}
2288 2290
2289/* 2291/*
2290 * Write the mmu contents to the dump device. 2292 * Write the mmu contents to the dump device.
2291 * This gets appended to the end of a crash dump since 2293 * This gets appended to the end of a crash dump since
2292 * there is no in-core copy of kernel memory mappings on a 4/4c machine. 2294 * there is no in-core copy of kernel memory mappings on a 4/4c machine.
2293 * 2295 *
2294 * Write the core dump headers and MD data to the dump device. 2296 * Write the core dump headers and MD data to the dump device.
2295 * We dump the following items: 2297 * We dump the following items:
2296 * 2298 *
2297 * kcore_seg_t MI header defined in <sys/kcore.h>) 2299 * kcore_seg_t MI header defined in <sys/kcore.h>)
2298 * cpu_kcore_hdr_t MD header defined in <machine/kcore.h>) 2300 * cpu_kcore_hdr_t MD header defined in <machine/kcore.h>)
2299 * phys_ram_seg_t[phys_installed_size] physical memory segments 2301 * phys_ram_seg_t[phys_installed_size] physical memory segments
2300 */ 2302 */
2301int 2303int
2302pmap_dumpmmu(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t blkno) 2304pmap_dumpmmu(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t blkno)
2303{ 2305{
2304 kcore_seg_t *kseg; 2306 kcore_seg_t *kseg;
2305 cpu_kcore_hdr_t *kcpu; 2307 cpu_kcore_hdr_t *kcpu;
2306 phys_ram_seg_t memseg; 2308 phys_ram_seg_t memseg;
2307 struct cpu_kcore_4mbseg ktlb; 2309 struct cpu_kcore_4mbseg ktlb;
2308 int error = 0; 2310 int error = 0;
2309 int i; 2311 int i;
2310 int buffer[dbtob(1) / sizeof(int)]; 2312 int buffer[dbtob(1) / sizeof(int)];
2311 int *bp, *ep; 2313 int *bp, *ep;
2312 2314
2313#define EXPEDITE(p,n) do { \ 2315#define EXPEDITE(p,n) do { \
2314 int *sp = (void *)(p); \ 2316 int *sp = (void *)(p); \
2315 int sz = (n); \ 2317 int sz = (n); \
2316 while (sz > 0) { \ 2318 while (sz > 0) { \
2317 *bp++ = *sp++; \ 2319 *bp++ = *sp++; \
2318 if (bp >= ep) { \ 2320 if (bp >= ep) { \
2319 error = (*dump)(dumpdev, blkno, \ 2321 error = (*dump)(dumpdev, blkno, \
2320 (void *)buffer, dbtob(1)); \ 2322 (void *)buffer, dbtob(1)); \
2321 if (error != 0) \ 2323 if (error != 0) \
2322 return (error); \ 2324 return (error); \
2323 ++blkno; \ 2325 ++blkno; \
2324 bp = buffer; \ 2326 bp = buffer; \
2325 } \ 2327 } \
2326 sz -= 4; \ 2328 sz -= 4; \
2327 } \ 2329 } \
2328} while (0) 2330} while (0)
2329 2331
2330 /* Setup bookkeeping pointers */ 2332 /* Setup bookkeeping pointers */
2331 bp = buffer; 2333 bp = buffer;
2332 ep = &buffer[sizeof(buffer) / sizeof(buffer[0])]; 2334 ep = &buffer[sizeof(buffer) / sizeof(buffer[0])];
2333 2335
2334 /* Fill in MI segment header */ 2336 /* Fill in MI segment header */
2335 kseg = (kcore_seg_t *)bp; 2337 kseg = (kcore_seg_t *)bp;
2336 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 2338 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
2337 kseg->c_size = dbtob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t)); 2339 kseg->c_size = dbtob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t));
2338 2340
2339 /* Fill in MD segment header (interpreted by MD part of libkvm) */ 2341 /* Fill in MD segment header (interpreted by MD part of libkvm) */
2340 kcpu = (cpu_kcore_hdr_t *)((long)bp + ALIGN(sizeof(kcore_seg_t))); 2342 kcpu = (cpu_kcore_hdr_t *)((long)bp + ALIGN(sizeof(kcore_seg_t)));
2341 kcpu->cputype = CPU_SUN4U; 2343 kcpu->cputype = CPU_SUN4U;
2342 kcpu->kernbase = (uint64_t)KERNBASE; 2344 kcpu->kernbase = (uint64_t)KERNBASE;
2343 kcpu->cpubase = (uint64_t)CPUINFO_VA; 2345 kcpu->cpubase = (uint64_t)CPUINFO_VA;
2344 2346
2345 /* Describe the locked text segment */ 2347 /* Describe the locked text segment */
2346 kcpu->ktextbase = (uint64_t)ktext; 2348 kcpu->ktextbase = (uint64_t)ktext;
2347 kcpu->ktextp = (uint64_t)ktextp; 2349 kcpu->ktextp = (uint64_t)ktextp;
2348 kcpu->ktextsz = (uint64_t)ektext - ktext; 2350 kcpu->ktextsz = (uint64_t)ektext - ktext;
2349 if (kcpu->ktextsz > 4*MEG) 2351 if (kcpu->ktextsz > 4*MEG)
2350 kcpu->ktextsz = 0; /* old version can not work */ 2352 kcpu->ktextsz = 0; /* old version can not work */
2351 2353
2352 /* Describe locked data segment */ 2354 /* Describe locked data segment */
2353 kcpu->kdatabase = (uint64_t)kdata; 2355 kcpu->kdatabase = (uint64_t)kdata;
2354 kcpu->kdatap = (uint64_t)kdatap; 2356 kcpu->kdatap = (uint64_t)kdatap;
2355 kcpu->kdatasz = (uint64_t)ekdatap - kdatap; 2357 kcpu->kdatasz = (uint64_t)ekdatap - kdatap;
2356 2358
2357 /* new version of locked segments description */ 2359 /* new version of locked segments description */
2358 kcpu->newmagic = SPARC64_KCORE_NEWMAGIC; 2360 kcpu->newmagic = SPARC64_KCORE_NEWMAGIC;
2359 kcpu->num4mbsegs = kernel_tlb_slots; 2361 kcpu->num4mbsegs = kernel_tlb_slots;
2360 kcpu->off4mbsegs = ALIGN(sizeof(cpu_kcore_hdr_t)); 2362 kcpu->off4mbsegs = ALIGN(sizeof(cpu_kcore_hdr_t));
2361 2363
2362 /* description of per-cpu mappings */ 2364 /* description of per-cpu mappings */
2363 kcpu->numcpuinfos = sparc_ncpus; 2365 kcpu->numcpuinfos = sparc_ncpus;
2364 kcpu->percpusz = 64 * 1024; /* used to be 128k for some time */ 2366 kcpu->percpusz = 64 * 1024; /* used to be 128k for some time */
2365 kcpu->thiscpu = cpu_number(); /* which cpu is doing this dump */ 2367 kcpu->thiscpu = cpu_number(); /* which cpu is doing this dump */
2366 kcpu->cpusp = cpu0paddr - 64 * 1024 * sparc_ncpus; 2368 kcpu->cpusp = cpu0paddr - 64 * 1024 * sparc_ncpus;
2367 2369
2368 /* Now the memsegs */ 2370 /* Now the memsegs */
2369 kcpu->nmemseg = phys_installed_size; 2371 kcpu->nmemseg = phys_installed_size;
2370 kcpu->memsegoffset = kcpu->off4mbsegs 2372 kcpu->memsegoffset = kcpu->off4mbsegs
2371 + kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg); 2373 + kernel_tlb_slots * sizeof(struct cpu_kcore_4mbseg);
2372 2374
2373 /* Now we need to point this at our kernel pmap. */ 2375 /* Now we need to point this at our kernel pmap. */
2374 kcpu->nsegmap = STSZ; 2376 kcpu->nsegmap = STSZ;
2375 kcpu->segmapoffset = (uint64_t)pmap_kernel()->pm_physaddr; 2377 kcpu->segmapoffset = (uint64_t)pmap_kernel()->pm_physaddr;
2376 2378
2377 /* Note: we have assumed everything fits in buffer[] so far... */ 2379 /* Note: we have assumed everything fits in buffer[] so far... */
2378 bp = (int *)((long)kcpu + ALIGN(sizeof(cpu_kcore_hdr_t))); 2380 bp = (int *)((long)kcpu + ALIGN(sizeof(cpu_kcore_hdr_t)));
2379 2381
2380 /* write locked kernel 4MB TLBs */ 2382 /* write locked kernel 4MB TLBs */
2381 for (i = 0; i < kernel_tlb_slots; i++) { 2383 for (i = 0; i < kernel_tlb_slots; i++) {
2382 ktlb.va = kernel_tlbs[i].te_va; 2384 ktlb.va = kernel_tlbs[i].te_va;
2383 ktlb.pa = kernel_tlbs[i].te_pa; 2385 ktlb.pa = kernel_tlbs[i].te_pa;
2384 EXPEDITE(&ktlb, sizeof(ktlb)); 2386 EXPEDITE(&ktlb, sizeof(ktlb));
2385 } 2387 }
2386 2388
2387 /* write memsegs */ 2389 /* write memsegs */
2388 for (i = 0; i < phys_installed_size; i++) { 2390 for (i = 0; i < phys_installed_size; i++) {
2389 memseg.start = phys_installed[i].start; 2391 memseg.start = phys_installed[i].start;
2390 memseg.size = phys_installed[i].size; 2392 memseg.size = phys_installed[i].size;
2391 EXPEDITE(&memseg, sizeof(phys_ram_seg_t)); 2393 EXPEDITE(&memseg, sizeof(phys_ram_seg_t));
2392 } 2394 }
2393 2395
2394 if (bp != buffer) 2396 if (bp != buffer)
2395 error = (*dump)(dumpdev, blkno++, (void *)buffer, dbtob(1)); 2397 error = (*dump)(dumpdev, blkno++, (void *)buffer, dbtob(1));
2396 2398
2397 return (error); 2399 return (error);
2398} 2400}
2399 2401
2400/* 2402/*
2401 * Determine (non)existence of physical page 2403 * Determine (non)existence of physical page
2402 */ 2404 */
2403int 2405int
2404pmap_pa_exists(paddr_t pa) 2406pmap_pa_exists(paddr_t pa)
2405{ 2407{
2406 int i; 2408 int i;
2407 2409
2408 /* Just go through physical memory list & see if we're there */ 2410 /* Just go through physical memory list & see if we're there */
2409 for (i = 0; i < phys_installed_size; i++) { 2411 for (i = 0; i < phys_installed_size; i++) {
2410 if ((phys_installed[i].start <= pa) && 2412 if ((phys_installed[i].start <= pa) &&
2411 (phys_installed[i].start + 2413 (phys_installed[i].start +
2412 phys_installed[i].size >= pa)) 2414 phys_installed[i].size >= pa))
2413 return 1; 2415 return 1;
2414 } 2416 }
2415 return 0; 2417 return 0;
2416} 2418}
2417 2419
2418/* 2420/*
2419 * Lookup the appropriate TSB entry. 2421 * Lookup the appropriate TSB entry.
2420 * 2422 *
2421 * Here is the full official pseudo code: 2423 * Here is the full official pseudo code:
2422 * 2424 *
2423 */ 2425 */
2424 2426
2425#ifdef NOTYET 2427#ifdef NOTYET
2426int64 GenerateTSBPointer( 2428int64 GenerateTSBPointer(
2427 int64 va, /* Missing VA */ 2429 int64 va, /* Missing VA */
2428 PointerType type, /* 8K_POINTER or 16K_POINTER */ 2430 PointerType type, /* 8K_POINTER or 16K_POINTER */
2429 int64 TSBBase, /* TSB Register[63:13] << 13 */ 2431 int64 TSBBase, /* TSB Register[63:13] << 13 */
2430 Boolean split, /* TSB Register[12] */ 2432 Boolean split, /* TSB Register[12] */
2431 int TSBSize) /* TSB Register[2:0] */ 2433 int TSBSize) /* TSB Register[2:0] */
2432{ 2434{
2433 int64 vaPortion; 2435 int64 vaPortion;
2434 int64 TSBBaseMask; 2436 int64 TSBBaseMask;
2435 int64 splitMask; 2437 int64 splitMask;
2436 2438
2437 /* TSBBaseMask marks the bits from TSB Base Reg */ 2439 /* TSBBaseMask marks the bits from TSB Base Reg */
2438 TSBBaseMask = 0xffffffffffffe000 << 2440 TSBBaseMask = 0xffffffffffffe000 <<
2439 (split? (TSBsize + 1) : TSBsize); 2441 (split? (TSBsize + 1) : TSBsize);
2440 2442
2441 /* Shift va towards lsb appropriately and */ 2443 /* Shift va towards lsb appropriately and */
2442 /* zero out the original va page offset */ 2444 /* zero out the original va page offset */
2443 vaPortion = (va >> ((type == 8K_POINTER)? 9: 12)) & 2445 vaPortion = (va >> ((type == 8K_POINTER)? 9: 12)) &
2444 0xfffffffffffffff0; 2446 0xfffffffffffffff0;
2445 2447
2446 if (split) { 2448 if (split) {
2447 /* There's only one bit in question for split */ 2449 /* There's only one bit in question for split */
2448 splitMask = 1 << (13 + TSBsize); 2450 splitMask = 1 << (13 + TSBsize);