Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/powerpc/aim/mmu_oea.c
105687 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause AND BSD-4-Clause
3
*
4
* Copyright (c) 2001 The NetBSD Foundation, Inc.
5
* All rights reserved.
6
*
7
* This code is derived from software contributed to The NetBSD Foundation
8
* by Matt Thomas <[email protected]> of Allegro Networks, Inc.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
* POSSIBILITY OF SUCH DAMAGE.
30
*/
31
/*-
32
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
33
* Copyright (C) 1995, 1996 TooLs GmbH.
34
* All rights reserved.
35
*
36
* Redistribution and use in source and binary forms, with or without
37
* modification, are permitted provided that the following conditions
38
* are met:
39
* 1. Redistributions of source code must retain the above copyright
40
* notice, this list of conditions and the following disclaimer.
41
* 2. Redistributions in binary form must reproduce the above copyright
42
* notice, this list of conditions and the following disclaimer in the
43
* documentation and/or other materials provided with the distribution.
44
* 3. All advertising materials mentioning features or use of this software
45
* must display the following acknowledgement:
46
* This product includes software developed by TooLs GmbH.
47
* 4. The name of TooLs GmbH may not be used to endorse or promote products
48
* derived from this software without specific prior written permission.
49
*
50
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
51
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
55
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
56
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
57
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
58
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60
*
61
* $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $
62
*/
63
/*-
64
* Copyright (C) 2001 Benno Rice.
65
* All rights reserved.
66
*
67
* Redistribution and use in source and binary forms, with or without
68
* modification, are permitted provided that the following conditions
69
* are met:
70
* 1. Redistributions of source code must retain the above copyright
71
* notice, this list of conditions and the following disclaimer.
72
* 2. Redistributions in binary form must reproduce the above copyright
73
* notice, this list of conditions and the following disclaimer in the
74
* documentation and/or other materials provided with the distribution.
75
*
76
* THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
77
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
78
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
79
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
80
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
81
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
82
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
83
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
84
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
85
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
86
*/
87
88
#include <sys/cdefs.h>
89
/*
90
* Manages physical address maps.
91
*
92
* Since the information managed by this module is also stored by the
93
* logical address mapping module, this module may throw away valid virtual
94
* to physical mappings at almost any time. However, invalidations of
95
* mappings must be done as requested.
96
*
97
* In order to cope with hardware architectures which make virtual to
98
* physical map invalidates expensive, this module may delay invalidate
99
* reduced protection operations until such time as they are actually
100
* necessary. This module is given full information as to which processors
101
* are currently using which maps, and to when physical maps must be made
102
* correct.
103
*/
104
105
#include "opt_kstack_pages.h"
106
107
#include <sys/param.h>
108
#include <sys/kernel.h>
109
#include <sys/conf.h>
110
#include <sys/queue.h>
111
#include <sys/cpuset.h>
112
#include <sys/kerneldump.h>
113
#include <sys/ktr.h>
114
#include <sys/lock.h>
115
#include <sys/mman.h>
116
#include <sys/msgbuf.h>
117
#include <sys/mutex.h>
118
#include <sys/proc.h>
119
#include <sys/rwlock.h>
120
#include <sys/sched.h>
121
#include <sys/sysctl.h>
122
#include <sys/systm.h>
123
#include <sys/vmmeter.h>
124
125
#include <dev/ofw/openfirm.h>
126
127
#include <vm/vm.h>
128
#include <vm/pmap.h>
129
#include <vm/vm_param.h>
130
#include <vm/vm_kern.h>
131
#include <vm/vm_page.h>
132
#include <vm/vm_map.h>
133
#include <vm/vm_object.h>
134
#include <vm/vm_extern.h>
135
#include <vm/vm_page.h>
136
#include <vm/vm_phys.h>
137
#include <vm/vm_pageout.h>
138
#include <vm/vm_radix.h>
139
#include <vm/uma.h>
140
141
#include <machine/cpu.h>
142
#include <machine/platform.h>
143
#include <machine/bat.h>
144
#include <machine/frame.h>
145
#include <machine/md_var.h>
146
#include <machine/psl.h>
147
#include <machine/pte.h>
148
#include <machine/smp.h>
149
#include <machine/sr.h>
150
#include <machine/mmuvar.h>
151
#include <machine/trap.h>
152
153
#define MOEA_DEBUG
154
155
#define TODO panic("%s: not implemented", __func__);
156
157
#define VSID_MAKE(sr, hash) ((sr) | (((hash) & 0xfffff) << 4))
158
#define VSID_TO_SR(vsid) ((vsid) & 0xf)
159
#define VSID_TO_HASH(vsid) (((vsid) >> 4) & 0xfffff)
160
161
/* Get physical address from PVO. */
162
#define PVO_PADDR(pvo) ((pvo)->pvo_pte.pte.pte_lo & PTE_RPGN)
163
164
struct ofw_map {
165
vm_offset_t om_va;
166
vm_size_t om_len;
167
vm_offset_t om_pa;
168
u_int om_mode;
169
};
170
171
extern unsigned char _etext[];
172
extern unsigned char _end[];
173
174
/*
175
* Map of physical memory regions.
176
*/
177
static struct mem_region *regions;
178
static struct mem_region *pregions;
179
static u_int phys_avail_count;
180
static int regions_sz, pregions_sz;
181
static struct ofw_map *translations;
182
183
/*
184
* Lock for the pteg and pvo tables.
185
*/
186
struct mtx moea_table_mutex;
187
struct mtx moea_vsid_mutex;
188
189
/* tlbie instruction synchronization */
190
static struct mtx tlbie_mtx;
191
192
/*
193
* PTEG data.
194
*/
195
static struct pteg *moea_pteg_table;
196
u_int moea_pteg_count;
197
u_int moea_pteg_mask;
198
199
/*
200
* PVO data.
201
*/
202
struct pvo_head *moea_pvo_table; /* pvo entries by pteg index */
203
struct pvo_head moea_pvo_kunmanaged =
204
LIST_HEAD_INITIALIZER(moea_pvo_kunmanaged); /* list of unmanaged pages */
205
206
static struct rwlock_padalign pvh_global_lock;
207
208
uma_zone_t moea_upvo_zone; /* zone for pvo entries for unmanaged pages */
209
uma_zone_t moea_mpvo_zone; /* zone for pvo entries for managed pages */
210
211
#define BPVO_POOL_SIZE 32768
212
static struct pvo_entry *moea_bpvo_pool;
213
static int moea_bpvo_pool_index = 0;
214
215
#define VSID_NBPW (sizeof(u_int32_t) * 8)
216
static u_int moea_vsid_bitmap[NPMAPS / VSID_NBPW];
217
218
static bool moea_initialized = false;
219
220
/*
221
* Statistics.
222
*/
223
u_int moea_pte_valid = 0;
224
u_int moea_pte_overflow = 0;
225
u_int moea_pte_replacements = 0;
226
u_int moea_pvo_entries = 0;
227
u_int moea_pvo_enter_calls = 0;
228
u_int moea_pvo_remove_calls = 0;
229
u_int moea_pte_spills = 0;
230
SYSCTL_INT(_machdep, OID_AUTO, moea_pte_valid, CTLFLAG_RD, &moea_pte_valid,
231
0, "");
232
SYSCTL_INT(_machdep, OID_AUTO, moea_pte_overflow, CTLFLAG_RD,
233
&moea_pte_overflow, 0, "");
234
SYSCTL_INT(_machdep, OID_AUTO, moea_pte_replacements, CTLFLAG_RD,
235
&moea_pte_replacements, 0, "");
236
SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_entries, CTLFLAG_RD, &moea_pvo_entries,
237
0, "");
238
SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_enter_calls, CTLFLAG_RD,
239
&moea_pvo_enter_calls, 0, "");
240
SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_remove_calls, CTLFLAG_RD,
241
&moea_pvo_remove_calls, 0, "");
242
SYSCTL_INT(_machdep, OID_AUTO, moea_pte_spills, CTLFLAG_RD,
243
&moea_pte_spills, 0, "");
244
245
/*
246
* Allocate physical memory for use in moea_bootstrap.
247
*/
248
static vm_offset_t moea_bootstrap_alloc(vm_size_t, u_int);
249
250
/*
251
* PTE calls.
252
*/
253
static int moea_pte_insert(u_int, struct pte *);
254
255
/*
256
* PVO calls.
257
*/
258
static int moea_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *,
259
vm_offset_t, vm_paddr_t, u_int, int);
260
static void moea_pvo_remove(struct pvo_entry *, int);
261
static struct pvo_entry *moea_pvo_find_va(pmap_t, vm_offset_t, int *);
262
static struct pte *moea_pvo_to_pte(const struct pvo_entry *, int);
263
264
/*
265
* Utility routines.
266
*/
267
static int moea_enter_locked(pmap_t, vm_offset_t, vm_page_t,
268
vm_prot_t, u_int, int8_t);
269
static void moea_syncicache(vm_paddr_t, vm_size_t);
270
static bool moea_query_bit(vm_page_t, int);
271
static u_int moea_clear_bit(vm_page_t, int);
272
static void moea_kremove(vm_offset_t);
273
int moea_pte_spill(vm_offset_t);
274
275
/*
276
* Kernel MMU interface
277
*/
278
void moea_clear_modify(vm_page_t);
279
void moea_copy_page(vm_page_t, vm_page_t);
280
void moea_copy_pages(vm_page_t *ma, vm_offset_t a_offset,
281
vm_page_t *mb, vm_offset_t b_offset, int xfersize);
282
int moea_enter(pmap_t, vm_offset_t, vm_page_t, vm_prot_t, u_int,
283
int8_t);
284
void moea_enter_object(pmap_t, vm_offset_t, vm_offset_t, vm_page_t,
285
vm_prot_t);
286
void moea_enter_quick(pmap_t, vm_offset_t, vm_page_t, vm_prot_t);
287
vm_paddr_t moea_extract(pmap_t, vm_offset_t);
288
vm_page_t moea_extract_and_hold(pmap_t, vm_offset_t, vm_prot_t);
289
void moea_init(void);
290
bool moea_is_modified(vm_page_t);
291
bool moea_is_prefaultable(pmap_t, vm_offset_t);
292
bool moea_is_referenced(vm_page_t);
293
int moea_ts_referenced(vm_page_t);
294
vm_offset_t moea_map(vm_offset_t *, vm_paddr_t, vm_paddr_t, int);
295
static int moea_mincore(pmap_t, vm_offset_t, vm_paddr_t *);
296
bool moea_page_exists_quick(pmap_t, vm_page_t);
297
void moea_page_init(vm_page_t);
298
int moea_page_wired_mappings(vm_page_t);
299
int moea_pinit(pmap_t);
300
void moea_pinit0(pmap_t);
301
void moea_protect(pmap_t, vm_offset_t, vm_offset_t, vm_prot_t);
302
void moea_qenter(vm_offset_t, vm_page_t *, int);
303
void moea_qremove(vm_offset_t, int);
304
void moea_release(pmap_t);
305
void moea_remove(pmap_t, vm_offset_t, vm_offset_t);
306
void moea_remove_all(vm_page_t);
307
void moea_remove_write(vm_page_t);
308
void moea_unwire(pmap_t, vm_offset_t, vm_offset_t);
309
void moea_zero_page(vm_page_t);
310
void moea_zero_page_area(vm_page_t, int, int);
311
void moea_activate(struct thread *);
312
void moea_deactivate(struct thread *);
313
void moea_cpu_bootstrap(int);
314
void moea_bootstrap(vm_offset_t, vm_offset_t);
315
void *moea_mapdev(vm_paddr_t, vm_size_t);
316
void *moea_mapdev_attr(vm_paddr_t, vm_size_t, vm_memattr_t);
317
void moea_unmapdev(void *, vm_size_t);
318
vm_paddr_t moea_kextract(vm_offset_t);
319
void moea_kenter_attr(vm_offset_t, vm_paddr_t, vm_memattr_t);
320
void moea_kenter(vm_offset_t, vm_paddr_t);
321
void moea_page_set_memattr(vm_page_t m, vm_memattr_t ma);
322
int moea_dev_direct_mapped(vm_paddr_t, vm_size_t);
323
static void moea_sync_icache(pmap_t, vm_offset_t, vm_size_t);
324
void moea_dumpsys_map(vm_paddr_t pa, size_t sz, void **va);
325
void moea_scan_init(void);
326
vm_offset_t moea_quick_enter_page(vm_page_t m);
327
void moea_quick_remove_page(vm_offset_t addr);
328
bool moea_page_is_mapped(vm_page_t m);
329
bool moea_ps_enabled(pmap_t pmap);
330
static int moea_map_user_ptr(pmap_t pm,
331
volatile const void *uaddr, void **kaddr, size_t ulen, size_t *klen);
332
static int moea_decode_kernel_ptr(vm_offset_t addr,
333
int *is_user, vm_offset_t *decoded_addr);
334
335
static struct pmap_funcs moea_methods = {
336
.clear_modify = moea_clear_modify,
337
.copy_page = moea_copy_page,
338
.copy_pages = moea_copy_pages,
339
.enter = moea_enter,
340
.enter_object = moea_enter_object,
341
.enter_quick = moea_enter_quick,
342
.extract = moea_extract,
343
.extract_and_hold = moea_extract_and_hold,
344
.init = moea_init,
345
.is_modified = moea_is_modified,
346
.is_prefaultable = moea_is_prefaultable,
347
.is_referenced = moea_is_referenced,
348
.ts_referenced = moea_ts_referenced,
349
.map = moea_map,
350
.page_exists_quick = moea_page_exists_quick,
351
.page_init = moea_page_init,
352
.page_wired_mappings = moea_page_wired_mappings,
353
.pinit = moea_pinit,
354
.pinit0 = moea_pinit0,
355
.protect = moea_protect,
356
.qenter = moea_qenter,
357
.qremove = moea_qremove,
358
.release = moea_release,
359
.remove = moea_remove,
360
.remove_all = moea_remove_all,
361
.mincore = moea_mincore,
362
.remove_write = moea_remove_write,
363
.sync_icache = moea_sync_icache,
364
.unwire = moea_unwire,
365
.zero_page = moea_zero_page,
366
.zero_page_area = moea_zero_page_area,
367
.activate = moea_activate,
368
.deactivate = moea_deactivate,
369
.page_set_memattr = moea_page_set_memattr,
370
.quick_enter_page = moea_quick_enter_page,
371
.quick_remove_page = moea_quick_remove_page,
372
.page_is_mapped = moea_page_is_mapped,
373
.ps_enabled = moea_ps_enabled,
374
375
/* Internal interfaces */
376
.bootstrap = moea_bootstrap,
377
.cpu_bootstrap = moea_cpu_bootstrap,
378
.mapdev_attr = moea_mapdev_attr,
379
.mapdev = moea_mapdev,
380
.unmapdev = moea_unmapdev,
381
.kextract = moea_kextract,
382
.kenter = moea_kenter,
383
.kenter_attr = moea_kenter_attr,
384
.dev_direct_mapped = moea_dev_direct_mapped,
385
.dumpsys_pa_init = moea_scan_init,
386
.dumpsys_map_chunk = moea_dumpsys_map,
387
.map_user_ptr = moea_map_user_ptr,
388
.decode_kernel_ptr = moea_decode_kernel_ptr,
389
};
390
391
MMU_DEF(oea_mmu, MMU_TYPE_OEA, moea_methods);
392
393
static __inline uint32_t
394
moea_calc_wimg(vm_paddr_t pa, vm_memattr_t ma)
395
{
396
uint32_t pte_lo;
397
int i;
398
399
if (ma != VM_MEMATTR_DEFAULT) {
400
switch (ma) {
401
case VM_MEMATTR_UNCACHEABLE:
402
return (PTE_I | PTE_G);
403
case VM_MEMATTR_CACHEABLE:
404
return (PTE_M);
405
case VM_MEMATTR_WRITE_COMBINING:
406
case VM_MEMATTR_WRITE_BACK:
407
case VM_MEMATTR_PREFETCHABLE:
408
return (PTE_I);
409
case VM_MEMATTR_WRITE_THROUGH:
410
return (PTE_W | PTE_M);
411
}
412
}
413
414
/*
415
* Assume the page is cache inhibited and access is guarded unless
416
* it's in our available memory array.
417
*/
418
pte_lo = PTE_I | PTE_G;
419
for (i = 0; i < pregions_sz; i++) {
420
if ((pa >= pregions[i].mr_start) &&
421
(pa < (pregions[i].mr_start + pregions[i].mr_size))) {
422
pte_lo = PTE_M;
423
break;
424
}
425
}
426
427
return pte_lo;
428
}
429
430
/*
431
* Translate OFW translations into VM attributes.
432
*/
433
static __inline vm_memattr_t
434
moea_bootstrap_convert_wimg(uint32_t mode)
435
{
436
437
switch (mode) {
438
case (PTE_I | PTE_G):
439
/* PCI device memory */
440
return VM_MEMATTR_UNCACHEABLE;
441
case (PTE_M):
442
/* Explicitly coherent */
443
return VM_MEMATTR_CACHEABLE;
444
case 0: /* Default claim */
445
case 2: /* Alternate PP bits set by OF for the original payload */
446
/* "Normal" memory. */
447
return VM_MEMATTR_DEFAULT;
448
449
default:
450
/* Err on the side of caution for unknowns */
451
/* XXX should we panic instead? */
452
return VM_MEMATTR_UNCACHEABLE;
453
}
454
}
455
456
static void
457
tlbie(vm_offset_t va)
458
{
459
460
mtx_lock_spin(&tlbie_mtx);
461
__asm __volatile("ptesync");
462
__asm __volatile("tlbie %0" :: "r"(va));
463
__asm __volatile("eieio; tlbsync; ptesync");
464
mtx_unlock_spin(&tlbie_mtx);
465
}
466
467
static void
468
tlbia(void)
469
{
470
vm_offset_t va;
471
472
for (va = 0; va < 0x00040000; va += 0x00001000) {
473
__asm __volatile("tlbie %0" :: "r"(va));
474
powerpc_sync();
475
}
476
__asm __volatile("tlbsync");
477
powerpc_sync();
478
}
479
480
static __inline int
481
va_to_sr(u_int *sr, vm_offset_t va)
482
{
483
return (sr[(uintptr_t)va >> ADDR_SR_SHFT]);
484
}
485
486
static __inline u_int
487
va_to_pteg(u_int sr, vm_offset_t addr)
488
{
489
u_int hash;
490
491
hash = (sr & SR_VSID_MASK) ^ (((u_int)addr & ADDR_PIDX) >>
492
ADDR_PIDX_SHFT);
493
return (hash & moea_pteg_mask);
494
}
495
496
static __inline struct pvo_head *
497
vm_page_to_pvoh(vm_page_t m)
498
{
499
500
return (&m->md.mdpg_pvoh);
501
}
502
503
static __inline void
504
moea_attr_clear(vm_page_t m, int ptebit)
505
{
506
507
rw_assert(&pvh_global_lock, RA_WLOCKED);
508
m->md.mdpg_attrs &= ~ptebit;
509
}
510
511
static __inline int
512
moea_attr_fetch(vm_page_t m)
513
{
514
515
return (m->md.mdpg_attrs);
516
}
517
518
static __inline void
519
moea_attr_save(vm_page_t m, int ptebit)
520
{
521
522
rw_assert(&pvh_global_lock, RA_WLOCKED);
523
m->md.mdpg_attrs |= ptebit;
524
}
525
526
static __inline int
527
moea_pte_compare(const struct pte *pt, const struct pte *pvo_pt)
528
{
529
if (pt->pte_hi == pvo_pt->pte_hi)
530
return (1);
531
532
return (0);
533
}
534
535
static __inline int
536
moea_pte_match(struct pte *pt, u_int sr, vm_offset_t va, int which)
537
{
538
return (pt->pte_hi & ~PTE_VALID) ==
539
(((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
540
((va >> ADDR_API_SHFT) & PTE_API) | which);
541
}
542
543
static __inline void
544
moea_pte_create(struct pte *pt, u_int sr, vm_offset_t va, u_int pte_lo)
545
{
546
547
mtx_assert(&moea_table_mutex, MA_OWNED);
548
549
/*
550
* Construct a PTE. Default to IMB initially. Valid bit only gets
551
* set when the real pte is set in memory.
552
*
553
* Note: Don't set the valid bit for correct operation of tlb update.
554
*/
555
pt->pte_hi = ((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
556
(((va & ADDR_PIDX) >> ADDR_API_SHFT) & PTE_API);
557
pt->pte_lo = pte_lo;
558
}
559
560
static __inline void
561
moea_pte_synch(struct pte *pt, struct pte *pvo_pt)
562
{
563
564
mtx_assert(&moea_table_mutex, MA_OWNED);
565
pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF | PTE_CHG);
566
}
567
568
static __inline void
569
moea_pte_clear(struct pte *pt, vm_offset_t va, int ptebit)
570
{
571
572
mtx_assert(&moea_table_mutex, MA_OWNED);
573
574
/*
575
* As shown in Section 7.6.3.2.3
576
*/
577
pt->pte_lo &= ~ptebit;
578
tlbie(va);
579
}
580
581
static __inline void
582
moea_pte_set(struct pte *pt, struct pte *pvo_pt)
583
{
584
585
mtx_assert(&moea_table_mutex, MA_OWNED);
586
pvo_pt->pte_hi |= PTE_VALID;
587
588
/*
589
* Update the PTE as defined in section 7.6.3.1.
590
* Note that the REF/CHG bits are from pvo_pt and thus should have
591
* been saved so this routine can restore them (if desired).
592
*/
593
pt->pte_lo = pvo_pt->pte_lo;
594
powerpc_sync();
595
pt->pte_hi = pvo_pt->pte_hi;
596
powerpc_sync();
597
moea_pte_valid++;
598
}
599
600
static __inline void
601
moea_pte_unset(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
602
{
603
604
mtx_assert(&moea_table_mutex, MA_OWNED);
605
pvo_pt->pte_hi &= ~PTE_VALID;
606
607
/*
608
* Force the reg & chg bits back into the PTEs.
609
*/
610
powerpc_sync();
611
612
/*
613
* Invalidate the pte.
614
*/
615
pt->pte_hi &= ~PTE_VALID;
616
617
tlbie(va);
618
619
/*
620
* Save the reg & chg bits.
621
*/
622
moea_pte_synch(pt, pvo_pt);
623
moea_pte_valid--;
624
}
625
626
static __inline void
627
moea_pte_change(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
628
{
629
630
/*
631
* Invalidate the PTE
632
*/
633
moea_pte_unset(pt, pvo_pt, va);
634
moea_pte_set(pt, pvo_pt);
635
}
636
637
/*
638
* Quick sort callout for comparing memory regions.
639
*/
640
static int om_cmp(const void *a, const void *b);
641
642
static int
643
om_cmp(const void *a, const void *b)
644
{
645
const struct ofw_map *mapa;
646
const struct ofw_map *mapb;
647
648
mapa = a;
649
mapb = b;
650
if (mapa->om_pa < mapb->om_pa)
651
return (-1);
652
else if (mapa->om_pa > mapb->om_pa)
653
return (1);
654
else
655
return (0);
656
}
657
658
void
659
moea_cpu_bootstrap(int ap)
660
{
661
u_int sdr;
662
int i;
663
664
if (ap) {
665
powerpc_sync();
666
__asm __volatile("mtdbatu 0,%0" :: "r"(battable[0].batu));
667
__asm __volatile("mtdbatl 0,%0" :: "r"(battable[0].batl));
668
isync();
669
__asm __volatile("mtibatu 0,%0" :: "r"(battable[0].batu));
670
__asm __volatile("mtibatl 0,%0" :: "r"(battable[0].batl));
671
isync();
672
}
673
674
__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
675
__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
676
isync();
677
678
__asm __volatile("mtibatu 1,%0" :: "r"(0));
679
__asm __volatile("mtdbatu 2,%0" :: "r"(0));
680
__asm __volatile("mtibatu 2,%0" :: "r"(0));
681
__asm __volatile("mtdbatu 3,%0" :: "r"(0));
682
__asm __volatile("mtibatu 3,%0" :: "r"(0));
683
isync();
684
685
for (i = 0; i < 16; i++)
686
mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
687
powerpc_sync();
688
689
sdr = (u_int)moea_pteg_table | (moea_pteg_mask >> 10);
690
__asm __volatile("mtsdr1 %0" :: "r"(sdr));
691
isync();
692
693
tlbia();
694
}
695
696
void
697
moea_bootstrap(vm_offset_t kernelstart, vm_offset_t kernelend)
698
{
699
ihandle_t mmui;
700
phandle_t chosen, mmu;
701
int sz;
702
int i, j;
703
vm_size_t size, physsz, hwphyssz;
704
vm_offset_t pa, va, off;
705
void *dpcpu;
706
707
/*
708
* Map PCI memory space.
709
*/
710
battable[0x8].batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
711
battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
712
713
battable[0x9].batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
714
battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
715
716
battable[0xa].batl = BATL(0xa0000000, BAT_I|BAT_G, BAT_PP_RW);
717
battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs);
718
719
battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW);
720
battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs);
721
722
powerpc_sync();
723
724
/* map pci space */
725
__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
726
__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
727
isync();
728
729
/* set global direct map flag */
730
hw_direct_map = 1;
731
732
mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
733
CTR0(KTR_PMAP, "moea_bootstrap: physical memory");
734
735
for (i = 0; i < pregions_sz; i++) {
736
vm_offset_t pa;
737
vm_offset_t end;
738
739
CTR3(KTR_PMAP, "physregion: %#x - %#x (%#x)",
740
pregions[i].mr_start,
741
pregions[i].mr_start + pregions[i].mr_size,
742
pregions[i].mr_size);
743
/*
744
* Install entries into the BAT table to allow all
745
* of physmem to be convered by on-demand BAT entries.
746
* The loop will sometimes set the same battable element
747
* twice, but that's fine since they won't be used for
748
* a while yet.
749
*/
750
pa = pregions[i].mr_start & 0xf0000000;
751
end = pregions[i].mr_start + pregions[i].mr_size;
752
do {
753
u_int n = pa >> ADDR_SR_SHFT;
754
755
battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW);
756
battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
757
pa += SEGMENT_LENGTH;
758
} while (pa < end);
759
}
760
761
if (PHYS_AVAIL_ENTRIES < regions_sz)
762
panic("moea_bootstrap: phys_avail too small");
763
764
phys_avail_count = 0;
765
physsz = 0;
766
hwphyssz = 0;
767
TUNABLE_ULONG_FETCH("hw.physmem", (u_long *) &hwphyssz);
768
for (i = 0, j = 0; i < regions_sz; i++, j += 2) {
769
CTR3(KTR_PMAP, "region: %#x - %#x (%#x)", regions[i].mr_start,
770
regions[i].mr_start + regions[i].mr_size,
771
regions[i].mr_size);
772
if (hwphyssz != 0 &&
773
(physsz + regions[i].mr_size) >= hwphyssz) {
774
if (physsz < hwphyssz) {
775
phys_avail[j] = regions[i].mr_start;
776
phys_avail[j + 1] = regions[i].mr_start +
777
hwphyssz - physsz;
778
physsz = hwphyssz;
779
phys_avail_count++;
780
}
781
break;
782
}
783
phys_avail[j] = regions[i].mr_start;
784
phys_avail[j + 1] = regions[i].mr_start + regions[i].mr_size;
785
phys_avail_count++;
786
physsz += regions[i].mr_size;
787
}
788
789
/* Check for overlap with the kernel and exception vectors */
790
for (j = 0; j < 2*phys_avail_count; j+=2) {
791
if (phys_avail[j] < EXC_LAST)
792
phys_avail[j] += EXC_LAST;
793
794
if (kernelstart >= phys_avail[j] &&
795
kernelstart < phys_avail[j+1]) {
796
if (kernelend < phys_avail[j+1]) {
797
phys_avail[2*phys_avail_count] =
798
(kernelend & ~PAGE_MASK) + PAGE_SIZE;
799
phys_avail[2*phys_avail_count + 1] =
800
phys_avail[j+1];
801
phys_avail_count++;
802
}
803
804
phys_avail[j+1] = kernelstart & ~PAGE_MASK;
805
}
806
807
if (kernelend >= phys_avail[j] &&
808
kernelend < phys_avail[j+1]) {
809
if (kernelstart > phys_avail[j]) {
810
phys_avail[2*phys_avail_count] = phys_avail[j];
811
phys_avail[2*phys_avail_count + 1] =
812
kernelstart & ~PAGE_MASK;
813
phys_avail_count++;
814
}
815
816
phys_avail[j] = (kernelend & ~PAGE_MASK) + PAGE_SIZE;
817
}
818
}
819
820
physmem = btoc(physsz);
821
822
/*
823
* Allocate PTEG table.
824
*/
825
#ifdef PTEGCOUNT
826
moea_pteg_count = PTEGCOUNT;
827
#else
828
moea_pteg_count = 0x1000;
829
830
while (moea_pteg_count < physmem)
831
moea_pteg_count <<= 1;
832
833
moea_pteg_count >>= 1;
834
#endif /* PTEGCOUNT */
835
836
size = moea_pteg_count * sizeof(struct pteg);
837
CTR2(KTR_PMAP, "moea_bootstrap: %d PTEGs, %d bytes", moea_pteg_count,
838
size);
839
moea_pteg_table = (struct pteg *)moea_bootstrap_alloc(size, size);
840
CTR1(KTR_PMAP, "moea_bootstrap: PTEG table at %p", moea_pteg_table);
841
bzero((void *)moea_pteg_table, moea_pteg_count * sizeof(struct pteg));
842
moea_pteg_mask = moea_pteg_count - 1;
843
844
/*
845
* Allocate pv/overflow lists.
846
*/
847
size = sizeof(struct pvo_head) * moea_pteg_count;
848
moea_pvo_table = (struct pvo_head *)moea_bootstrap_alloc(size,
849
PAGE_SIZE);
850
CTR1(KTR_PMAP, "moea_bootstrap: PVO table at %p", moea_pvo_table);
851
for (i = 0; i < moea_pteg_count; i++)
852
LIST_INIT(&moea_pvo_table[i]);
853
854
/*
855
* Initialize the lock that synchronizes access to the pteg and pvo
856
* tables.
857
*/
858
mtx_init(&moea_table_mutex, "pmap table", NULL, MTX_DEF |
859
MTX_RECURSE);
860
mtx_init(&moea_vsid_mutex, "VSID table", NULL, MTX_DEF);
861
862
mtx_init(&tlbie_mtx, "tlbie", NULL, MTX_SPIN);
863
864
/*
865
* Initialise the unmanaged pvo pool.
866
*/
867
moea_bpvo_pool = (struct pvo_entry *)moea_bootstrap_alloc(
868
BPVO_POOL_SIZE*sizeof(struct pvo_entry), 0);
869
moea_bpvo_pool_index = 0;
870
871
/*
872
* Make sure kernel vsid is allocated as well as VSID 0.
873
*/
874
moea_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS - 1)) / VSID_NBPW]
875
|= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
876
moea_vsid_bitmap[0] |= 1;
877
878
/*
879
* Initialize the kernel pmap (which is statically allocated).
880
*/
881
PMAP_LOCK_INIT(kernel_pmap);
882
for (i = 0; i < 16; i++)
883
kernel_pmap->pm_sr[i] = EMPTY_SEGMENT + i;
884
CPU_FILL(&kernel_pmap->pm_active);
885
RB_INIT(&kernel_pmap->pmap_pvo);
886
887
/*
888
* Initialize the global pv list lock.
889
*/
890
rw_init(&pvh_global_lock, "pmap pv global");
891
892
/*
893
* Set up the Open Firmware mappings
894
*/
895
chosen = OF_finddevice("/chosen");
896
if (chosen != -1 && OF_getprop(chosen, "mmu", &mmui, 4) != -1 &&
897
(mmu = OF_instance_to_package(mmui)) != -1 &&
898
(sz = OF_getproplen(mmu, "translations")) != -1) {
899
translations = NULL;
900
for (i = 0; phys_avail[i] != 0; i += 2) {
901
if (phys_avail[i + 1] >= sz) {
902
translations = (struct ofw_map *)phys_avail[i];
903
break;
904
}
905
}
906
if (translations == NULL)
907
panic("moea_bootstrap: no space to copy translations");
908
bzero(translations, sz);
909
if (OF_getprop(mmu, "translations", translations, sz) == -1)
910
panic("moea_bootstrap: can't get ofw translations");
911
CTR0(KTR_PMAP, "moea_bootstrap: translations");
912
sz /= sizeof(*translations);
913
qsort(translations, sz, sizeof (*translations), om_cmp);
914
for (i = 0; i < sz; i++) {
915
CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
916
translations[i].om_pa, translations[i].om_va,
917
translations[i].om_len);
918
919
/*
920
* If the mapping is 1:1, let the RAM and device
921
* on-demand BAT tables take care of the translation.
922
*
923
* However, always enter mappings for segment 16,
924
* which is mixed-protection and therefore not
925
* compatible with a BAT entry.
926
*/
927
if ((translations[i].om_va >> ADDR_SR_SHFT) != 0xf &&
928
translations[i].om_va == translations[i].om_pa)
929
continue;
930
931
/* Enter the pages */
932
for (off = 0; off < translations[i].om_len;
933
off += PAGE_SIZE)
934
moea_kenter_attr(translations[i].om_va + off,
935
translations[i].om_pa + off,
936
moea_bootstrap_convert_wimg(translations[i].om_mode));
937
}
938
}
939
940
/*
941
* Calculate the last available physical address.
942
*/
943
for (i = 0; phys_avail[i + 2] != 0; i += 2)
944
;
945
Maxmem = powerpc_btop(phys_avail[i + 1]);
946
947
moea_cpu_bootstrap(0);
948
mtmsr(mfmsr() | PSL_DR | PSL_IR);
949
pmap_bootstrapped++;
950
951
/*
952
* Set the start and end of kva.
953
*/
954
virtual_avail = VM_MIN_KERNEL_ADDRESS;
955
virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS;
956
957
/*
958
* Allocate a kernel stack with a guard page for thread0 and map it
959
* into the kernel page map.
960
*/
961
pa = moea_bootstrap_alloc(kstack_pages * PAGE_SIZE, PAGE_SIZE);
962
va = virtual_avail + KSTACK_GUARD_PAGES * PAGE_SIZE;
963
virtual_avail = va + kstack_pages * PAGE_SIZE;
964
CTR2(KTR_PMAP, "moea_bootstrap: kstack0 at %#x (%#x)", pa, va);
965
thread0.td_kstack = va;
966
thread0.td_kstack_pages = kstack_pages;
967
for (i = 0; i < kstack_pages; i++) {
968
moea_kenter(va, pa);
969
pa += PAGE_SIZE;
970
va += PAGE_SIZE;
971
}
972
973
/*
974
* Allocate virtual address space for the message buffer.
975
*/
976
pa = msgbuf_phys = moea_bootstrap_alloc(msgbufsize, PAGE_SIZE);
977
msgbufp = (struct msgbuf *)virtual_avail;
978
va = virtual_avail;
979
virtual_avail += round_page(msgbufsize);
980
while (va < virtual_avail) {
981
moea_kenter(va, pa);
982
pa += PAGE_SIZE;
983
va += PAGE_SIZE;
984
}
985
986
/*
987
* Allocate virtual address space for the dynamic percpu area.
988
*/
989
pa = moea_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
990
dpcpu = (void *)virtual_avail;
991
va = virtual_avail;
992
virtual_avail += DPCPU_SIZE;
993
while (va < virtual_avail) {
994
moea_kenter(va, pa);
995
pa += PAGE_SIZE;
996
va += PAGE_SIZE;
997
}
998
dpcpu_init(dpcpu, 0);
999
}
1000
1001
/*
1002
* Activate a user pmap. The pmap must be activated before it's address
1003
* space can be accessed in any way.
1004
*/
1005
void
1006
moea_activate(struct thread *td)
1007
{
1008
pmap_t pm, pmr;
1009
1010
/*
1011
* Load all the data we need up front to encourage the compiler to
1012
* not issue any loads while we have interrupts disabled below.
1013
*/
1014
pm = &td->td_proc->p_vmspace->vm_pmap;
1015
pmr = pm->pmap_phys;
1016
1017
CPU_SET(PCPU_GET(cpuid), &pm->pm_active);
1018
PCPU_SET(curpmap, pmr);
1019
1020
mtsrin(USER_SR << ADDR_SR_SHFT, td->td_pcb->pcb_cpu.aim.usr_vsid);
1021
}
1022
1023
void
1024
moea_deactivate(struct thread *td)
1025
{
1026
pmap_t pm;
1027
1028
pm = &td->td_proc->p_vmspace->vm_pmap;
1029
CPU_CLR(PCPU_GET(cpuid), &pm->pm_active);
1030
PCPU_SET(curpmap, NULL);
1031
}
1032
1033
void
1034
moea_unwire(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
1035
{
1036
struct pvo_entry key, *pvo;
1037
1038
PMAP_LOCK(pm);
1039
key.pvo_vaddr = sva;
1040
for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key);
1041
pvo != NULL && PVO_VADDR(pvo) < eva;
1042
pvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo)) {
1043
if ((pvo->pvo_vaddr & PVO_WIRED) == 0)
1044
panic("moea_unwire: pvo %p is missing PVO_WIRED", pvo);
1045
pvo->pvo_vaddr &= ~PVO_WIRED;
1046
pm->pm_stats.wired_count--;
1047
}
1048
PMAP_UNLOCK(pm);
1049
}
1050
1051
void
1052
moea_copy_page(vm_page_t msrc, vm_page_t mdst)
1053
{
1054
vm_offset_t dst;
1055
vm_offset_t src;
1056
1057
dst = VM_PAGE_TO_PHYS(mdst);
1058
src = VM_PAGE_TO_PHYS(msrc);
1059
1060
bcopy((void *)src, (void *)dst, PAGE_SIZE);
1061
}
1062
1063
void
1064
moea_copy_pages(vm_page_t *ma, vm_offset_t a_offset,
1065
vm_page_t *mb, vm_offset_t b_offset, int xfersize)
1066
{
1067
void *a_cp, *b_cp;
1068
vm_offset_t a_pg_offset, b_pg_offset;
1069
int cnt;
1070
1071
while (xfersize > 0) {
1072
a_pg_offset = a_offset & PAGE_MASK;
1073
cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
1074
a_cp = (char *)VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT]) +
1075
a_pg_offset;
1076
b_pg_offset = b_offset & PAGE_MASK;
1077
cnt = min(cnt, PAGE_SIZE - b_pg_offset);
1078
b_cp = (char *)VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT]) +
1079
b_pg_offset;
1080
bcopy(a_cp, b_cp, cnt);
1081
a_offset += cnt;
1082
b_offset += cnt;
1083
xfersize -= cnt;
1084
}
1085
}
1086
1087
/*
1088
* Zero a page of physical memory by temporarily mapping it into the tlb.
1089
*/
1090
void
1091
moea_zero_page(vm_page_t m)
1092
{
1093
vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1094
1095
bzero((void *)pa, PAGE_SIZE);
1096
}
1097
1098
void
1099
moea_zero_page_area(vm_page_t m, int off, int size)
1100
{
1101
vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1102
void *va = (void *)(pa + off);
1103
1104
bzero(va, size);
1105
}
1106
1107
vm_offset_t
1108
moea_quick_enter_page(vm_page_t m)
1109
{
1110
1111
return (VM_PAGE_TO_PHYS(m));
1112
}
1113
1114
void
1115
moea_quick_remove_page(vm_offset_t addr)
1116
{
1117
}
1118
1119
bool
1120
moea_page_is_mapped(vm_page_t m)
1121
{
1122
return (!LIST_EMPTY(&(m)->md.mdpg_pvoh));
1123
}
1124
1125
bool
1126
moea_ps_enabled(pmap_t pmap __unused)
1127
{
1128
return (false);
1129
}
1130
1131
/*
1132
* Map the given physical page at the specified virtual address in the
1133
* target pmap with the protection requested. If specified the page
1134
* will be wired down.
1135
*/
1136
int
1137
moea_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1138
u_int flags, int8_t psind)
1139
{
1140
int error;
1141
1142
for (;;) {
1143
rw_wlock(&pvh_global_lock);
1144
PMAP_LOCK(pmap);
1145
error = moea_enter_locked(pmap, va, m, prot, flags, psind);
1146
rw_wunlock(&pvh_global_lock);
1147
PMAP_UNLOCK(pmap);
1148
if (error != ENOMEM)
1149
return (KERN_SUCCESS);
1150
if ((flags & PMAP_ENTER_NOSLEEP) != 0)
1151
return (KERN_RESOURCE_SHORTAGE);
1152
VM_OBJECT_ASSERT_UNLOCKED(m->object);
1153
vm_wait(NULL);
1154
}
1155
}
1156
1157
/*
1158
* Map the given physical page at the specified virtual address in the
1159
* target pmap with the protection requested. If specified the page
1160
* will be wired down.
1161
*
1162
* The global pvh and pmap must be locked.
1163
*/
1164
static int
1165
moea_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1166
u_int flags, int8_t psind __unused)
1167
{
1168
struct pvo_head *pvo_head;
1169
uma_zone_t zone;
1170
u_int pte_lo, pvo_flags;
1171
int error;
1172
1173
if (pmap_bootstrapped)
1174
rw_assert(&pvh_global_lock, RA_WLOCKED);
1175
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
1176
if ((m->oflags & VPO_UNMANAGED) == 0) {
1177
if ((flags & PMAP_ENTER_QUICK_LOCKED) == 0)
1178
VM_PAGE_OBJECT_BUSY_ASSERT(m);
1179
else
1180
VM_OBJECT_ASSERT_LOCKED(m->object);
1181
}
1182
1183
if ((m->oflags & VPO_UNMANAGED) != 0 || !moea_initialized) {
1184
pvo_head = &moea_pvo_kunmanaged;
1185
zone = moea_upvo_zone;
1186
pvo_flags = 0;
1187
} else {
1188
pvo_head = vm_page_to_pvoh(m);
1189
zone = moea_mpvo_zone;
1190
pvo_flags = PVO_MANAGED;
1191
}
1192
1193
pte_lo = moea_calc_wimg(VM_PAGE_TO_PHYS(m), pmap_page_get_memattr(m));
1194
1195
if (prot & VM_PROT_WRITE) {
1196
pte_lo |= PTE_BW;
1197
if (pmap_bootstrapped &&
1198
(m->oflags & VPO_UNMANAGED) == 0)
1199
vm_page_aflag_set(m, PGA_WRITEABLE);
1200
} else
1201
pte_lo |= PTE_BR;
1202
1203
if ((flags & PMAP_ENTER_WIRED) != 0)
1204
pvo_flags |= PVO_WIRED;
1205
1206
error = moea_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
1207
pte_lo, pvo_flags);
1208
1209
/*
1210
* Flush the real page from the instruction cache. This has be done
1211
* for all user mappings to prevent information leakage via the
1212
* instruction cache. moea_pvo_enter() returns ENOENT for the first
1213
* mapping for a page.
1214
*/
1215
if (pmap != kernel_pmap && error == ENOENT &&
1216
(pte_lo & (PTE_I | PTE_G)) == 0)
1217
moea_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
1218
1219
return (error);
1220
}
1221
1222
/*
1223
* Maps a sequence of resident pages belonging to the same object.
1224
* The sequence begins with the given page m_start. This page is
1225
* mapped at the given virtual address start. Each subsequent page is
1226
* mapped at a virtual address that is offset from start by the same
1227
* amount as the page is offset from m_start within the object. The
1228
* last page in the sequence is the page with the largest offset from
1229
* m_start that can be mapped at a virtual address less than the given
1230
* virtual address end. Not every virtual page between start and end
1231
* is mapped; only those for which a resident page exists with the
1232
* corresponding offset from m_start are mapped.
1233
*/
1234
void
1235
moea_enter_object(pmap_t pm, vm_offset_t start, vm_offset_t end,
1236
vm_page_t m_start, vm_prot_t prot)
1237
{
1238
struct pctrie_iter pages;
1239
vm_offset_t va;
1240
vm_page_t m;
1241
1242
VM_OBJECT_ASSERT_LOCKED(m_start->object);
1243
1244
vm_page_iter_limit_init(&pages, m_start->object,
1245
m_start->pindex + atop(end - start));
1246
m = vm_radix_iter_lookup(&pages, m_start->pindex);
1247
rw_wlock(&pvh_global_lock);
1248
PMAP_LOCK(pm);
1249
while (m != NULL) {
1250
va = start + ptoa(m->pindex - m_start->pindex);
1251
moea_enter_locked(pm, va, m, prot &
1252
(VM_PROT_READ | VM_PROT_EXECUTE), PMAP_ENTER_QUICK_LOCKED,
1253
0);
1254
m = vm_radix_iter_step(&pages);
1255
}
1256
rw_wunlock(&pvh_global_lock);
1257
PMAP_UNLOCK(pm);
1258
}
1259
1260
void
1261
moea_enter_quick(pmap_t pm, vm_offset_t va, vm_page_t m,
1262
vm_prot_t prot)
1263
{
1264
1265
rw_wlock(&pvh_global_lock);
1266
PMAP_LOCK(pm);
1267
moea_enter_locked(pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
1268
PMAP_ENTER_QUICK_LOCKED, 0);
1269
rw_wunlock(&pvh_global_lock);
1270
PMAP_UNLOCK(pm);
1271
}
1272
1273
vm_paddr_t
1274
moea_extract(pmap_t pm, vm_offset_t va)
1275
{
1276
struct pvo_entry *pvo;
1277
vm_paddr_t pa;
1278
1279
PMAP_LOCK(pm);
1280
pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
1281
if (pvo == NULL)
1282
pa = 0;
1283
else
1284
pa = PVO_PADDR(pvo) | (va & ADDR_POFF);
1285
PMAP_UNLOCK(pm);
1286
return (pa);
1287
}
1288
1289
/*
1290
* Atomically extract and hold the physical page with the given
1291
* pmap and virtual address pair if that mapping permits the given
1292
* protection.
1293
*/
1294
vm_page_t
1295
moea_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
1296
{
1297
struct pvo_entry *pvo;
1298
vm_page_t m;
1299
1300
m = NULL;
1301
PMAP_LOCK(pmap);
1302
pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
1303
if (pvo != NULL && (pvo->pvo_pte.pte.pte_hi & PTE_VALID) &&
1304
((pvo->pvo_pte.pte.pte_lo & PTE_PP) == PTE_RW ||
1305
(prot & VM_PROT_WRITE) == 0)) {
1306
m = PHYS_TO_VM_PAGE(PVO_PADDR(pvo));
1307
if (!vm_page_wire_mapped(m))
1308
m = NULL;
1309
}
1310
PMAP_UNLOCK(pmap);
1311
return (m);
1312
}
1313
1314
void
1315
moea_init(void)
1316
{
1317
1318
moea_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry),
1319
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
1320
UMA_ZONE_VM | UMA_ZONE_NOFREE);
1321
moea_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry),
1322
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
1323
UMA_ZONE_VM | UMA_ZONE_NOFREE);
1324
moea_initialized = true;
1325
}
1326
1327
bool
1328
moea_is_referenced(vm_page_t m)
1329
{
1330
bool rv;
1331
1332
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1333
("moea_is_referenced: page %p is not managed", m));
1334
rw_wlock(&pvh_global_lock);
1335
rv = moea_query_bit(m, PTE_REF);
1336
rw_wunlock(&pvh_global_lock);
1337
return (rv);
1338
}
1339
1340
bool
1341
moea_is_modified(vm_page_t m)
1342
{
1343
bool rv;
1344
1345
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1346
("moea_is_modified: page %p is not managed", m));
1347
1348
/*
1349
* If the page is not busied then this check is racy.
1350
*/
1351
if (!pmap_page_is_write_mapped(m))
1352
return (false);
1353
1354
rw_wlock(&pvh_global_lock);
1355
rv = moea_query_bit(m, PTE_CHG);
1356
rw_wunlock(&pvh_global_lock);
1357
return (rv);
1358
}
1359
1360
bool
1361
moea_is_prefaultable(pmap_t pmap, vm_offset_t va)
1362
{
1363
struct pvo_entry *pvo;
1364
bool rv;
1365
1366
PMAP_LOCK(pmap);
1367
pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
1368
rv = pvo == NULL || (pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0;
1369
PMAP_UNLOCK(pmap);
1370
return (rv);
1371
}
1372
1373
void
1374
moea_clear_modify(vm_page_t m)
1375
{
1376
1377
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1378
("moea_clear_modify: page %p is not managed", m));
1379
vm_page_assert_busied(m);
1380
1381
if (!pmap_page_is_write_mapped(m))
1382
return;
1383
rw_wlock(&pvh_global_lock);
1384
moea_clear_bit(m, PTE_CHG);
1385
rw_wunlock(&pvh_global_lock);
1386
}
1387
1388
/*
1389
* Clear the write and modified bits in each of the given page's mappings.
1390
*/
1391
void
1392
moea_remove_write(vm_page_t m)
1393
{
1394
struct pvo_entry *pvo;
1395
struct pte *pt;
1396
pmap_t pmap;
1397
u_int lo;
1398
1399
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1400
("moea_remove_write: page %p is not managed", m));
1401
vm_page_assert_busied(m);
1402
1403
if (!pmap_page_is_write_mapped(m))
1404
return;
1405
rw_wlock(&pvh_global_lock);
1406
lo = moea_attr_fetch(m);
1407
powerpc_sync();
1408
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
1409
pmap = pvo->pvo_pmap;
1410
PMAP_LOCK(pmap);
1411
if ((pvo->pvo_pte.pte.pte_lo & PTE_PP) != PTE_BR) {
1412
pt = moea_pvo_to_pte(pvo, -1);
1413
pvo->pvo_pte.pte.pte_lo &= ~PTE_PP;
1414
pvo->pvo_pte.pte.pte_lo |= PTE_BR;
1415
if (pt != NULL) {
1416
moea_pte_synch(pt, &pvo->pvo_pte.pte);
1417
lo |= pvo->pvo_pte.pte.pte_lo;
1418
pvo->pvo_pte.pte.pte_lo &= ~PTE_CHG;
1419
moea_pte_change(pt, &pvo->pvo_pte.pte,
1420
pvo->pvo_vaddr);
1421
mtx_unlock(&moea_table_mutex);
1422
}
1423
}
1424
PMAP_UNLOCK(pmap);
1425
}
1426
if ((lo & PTE_CHG) != 0) {
1427
moea_attr_clear(m, PTE_CHG);
1428
vm_page_dirty(m);
1429
}
1430
vm_page_aflag_clear(m, PGA_WRITEABLE);
1431
rw_wunlock(&pvh_global_lock);
1432
}
1433
1434
/*
1435
* moea_ts_referenced:
1436
*
1437
* Return a count of reference bits for a page, clearing those bits.
1438
* It is not necessary for every reference bit to be cleared, but it
1439
* is necessary that 0 only be returned when there are truly no
1440
* reference bits set.
1441
*
1442
* XXX: The exact number of bits to check and clear is a matter that
1443
* should be tested and standardized at some point in the future for
1444
* optimal aging of shared pages.
1445
*/
1446
int
1447
moea_ts_referenced(vm_page_t m)
1448
{
1449
int count;
1450
1451
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1452
("moea_ts_referenced: page %p is not managed", m));
1453
rw_wlock(&pvh_global_lock);
1454
count = moea_clear_bit(m, PTE_REF);
1455
rw_wunlock(&pvh_global_lock);
1456
return (count);
1457
}
1458
1459
/*
1460
* Modify the WIMG settings of all mappings for a page.
1461
*/
1462
void
1463
moea_page_set_memattr(vm_page_t m, vm_memattr_t ma)
1464
{
1465
struct pvo_entry *pvo;
1466
struct pvo_head *pvo_head;
1467
struct pte *pt;
1468
pmap_t pmap;
1469
u_int lo;
1470
1471
if (m->md.mdpg_cache_attrs == ma)
1472
return;
1473
1474
if ((m->oflags & VPO_UNMANAGED) != 0) {
1475
m->md.mdpg_cache_attrs = ma;
1476
return;
1477
}
1478
1479
rw_wlock(&pvh_global_lock);
1480
pvo_head = vm_page_to_pvoh(m);
1481
lo = moea_calc_wimg(VM_PAGE_TO_PHYS(m), ma);
1482
1483
LIST_FOREACH(pvo, pvo_head, pvo_vlink) {
1484
pmap = pvo->pvo_pmap;
1485
PMAP_LOCK(pmap);
1486
pt = moea_pvo_to_pte(pvo, -1);
1487
pvo->pvo_pte.pte.pte_lo &= ~PTE_WIMG;
1488
pvo->pvo_pte.pte.pte_lo |= lo;
1489
if (pt != NULL) {
1490
moea_pte_change(pt, &pvo->pvo_pte.pte,
1491
pvo->pvo_vaddr);
1492
if (pvo->pvo_pmap == kernel_pmap)
1493
isync();
1494
}
1495
mtx_unlock(&moea_table_mutex);
1496
PMAP_UNLOCK(pmap);
1497
}
1498
m->md.mdpg_cache_attrs = ma;
1499
rw_wunlock(&pvh_global_lock);
1500
}
1501
1502
/*
1503
* Map a wired page into kernel virtual address space.
1504
*/
1505
void
1506
moea_kenter(vm_offset_t va, vm_paddr_t pa)
1507
{
1508
1509
moea_kenter_attr(va, pa, VM_MEMATTR_DEFAULT);
1510
}
1511
1512
void
1513
moea_kenter_attr(vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma)
1514
{
1515
u_int pte_lo;
1516
int error;
1517
1518
#if 0
1519
if (va < VM_MIN_KERNEL_ADDRESS)
1520
panic("moea_kenter: attempt to enter non-kernel address %#x",
1521
va);
1522
#endif
1523
1524
pte_lo = moea_calc_wimg(pa, ma);
1525
1526
PMAP_LOCK(kernel_pmap);
1527
error = moea_pvo_enter(kernel_pmap, moea_upvo_zone,
1528
&moea_pvo_kunmanaged, va, pa, pte_lo, PVO_WIRED);
1529
1530
if (error != 0 && error != ENOENT)
1531
panic("moea_kenter: failed to enter va %#x pa %#x: %d", va,
1532
pa, error);
1533
1534
PMAP_UNLOCK(kernel_pmap);
1535
}
1536
1537
/*
1538
* Extract the physical page address associated with the given kernel virtual
1539
* address.
1540
*/
1541
vm_paddr_t
1542
moea_kextract(vm_offset_t va)
1543
{
1544
struct pvo_entry *pvo;
1545
vm_paddr_t pa;
1546
1547
/*
1548
* Allow direct mappings on 32-bit OEA
1549
*/
1550
if (va < VM_MIN_KERNEL_ADDRESS) {
1551
return (va);
1552
}
1553
1554
PMAP_LOCK(kernel_pmap);
1555
pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
1556
KASSERT(pvo != NULL, ("moea_kextract: no addr found"));
1557
pa = PVO_PADDR(pvo) | (va & ADDR_POFF);
1558
PMAP_UNLOCK(kernel_pmap);
1559
return (pa);
1560
}
1561
1562
/*
1563
* Remove a wired page from kernel virtual address space.
1564
*/
1565
void
1566
moea_kremove(vm_offset_t va)
1567
{
1568
1569
moea_remove(kernel_pmap, va, va + PAGE_SIZE);
1570
}
1571
1572
/*
1573
* Provide a kernel pointer corresponding to a given userland pointer.
1574
* The returned pointer is valid until the next time this function is
1575
* called in this thread. This is used internally in copyin/copyout.
1576
*/
1577
int
1578
moea_map_user_ptr(pmap_t pm, volatile const void *uaddr,
1579
void **kaddr, size_t ulen, size_t *klen)
1580
{
1581
size_t l;
1582
register_t vsid;
1583
1584
*kaddr = (char *)USER_ADDR + ((uintptr_t)uaddr & ~SEGMENT_MASK);
1585
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - (char *)(*kaddr);
1586
if (l > ulen)
1587
l = ulen;
1588
if (klen)
1589
*klen = l;
1590
else if (l != ulen)
1591
return (EFAULT);
1592
1593
vsid = va_to_vsid(pm, (vm_offset_t)uaddr);
1594
1595
/* Mark segment no-execute */
1596
vsid |= SR_N;
1597
1598
/* If we have already set this VSID, we can just return */
1599
if (curthread->td_pcb->pcb_cpu.aim.usr_vsid == vsid)
1600
return (0);
1601
1602
__asm __volatile("isync");
1603
curthread->td_pcb->pcb_cpu.aim.usr_segm =
1604
(uintptr_t)uaddr >> ADDR_SR_SHFT;
1605
curthread->td_pcb->pcb_cpu.aim.usr_vsid = vsid;
1606
__asm __volatile("mtsr %0,%1; isync" :: "n"(USER_SR), "r"(vsid));
1607
1608
return (0);
1609
}
1610
1611
/*
1612
* Figure out where a given kernel pointer (usually in a fault) points
1613
* to from the VM's perspective, potentially remapping into userland's
1614
* address space.
1615
*/
1616
static int
1617
moea_decode_kernel_ptr(vm_offset_t addr, int *is_user,
1618
vm_offset_t *decoded_addr)
1619
{
1620
vm_offset_t user_sr;
1621
1622
if ((addr >> ADDR_SR_SHFT) == (USER_ADDR >> ADDR_SR_SHFT)) {
1623
user_sr = curthread->td_pcb->pcb_cpu.aim.usr_segm;
1624
addr &= ADDR_PIDX | ADDR_POFF;
1625
addr |= user_sr << ADDR_SR_SHFT;
1626
*decoded_addr = addr;
1627
*is_user = 1;
1628
} else {
1629
*decoded_addr = addr;
1630
*is_user = 0;
1631
}
1632
1633
return (0);
1634
}
1635
1636
/*
1637
* Map a range of physical addresses into kernel virtual address space.
1638
*
1639
* The value passed in *virt is a suggested virtual address for the mapping.
1640
* Architectures which can support a direct-mapped physical to virtual region
1641
* can return the appropriate address within that region, leaving '*virt'
1642
* unchanged. We cannot and therefore do not; *virt is updated with the
1643
* first usable address after the mapped region.
1644
*/
1645
vm_offset_t
1646
moea_map(vm_offset_t *virt, vm_paddr_t pa_start,
1647
vm_paddr_t pa_end, int prot)
1648
{
1649
vm_offset_t sva, va;
1650
1651
sva = *virt;
1652
va = sva;
1653
for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE)
1654
moea_kenter(va, pa_start);
1655
*virt = va;
1656
return (sva);
1657
}
1658
1659
/*
1660
* Returns true if the pmap's pv is one of the first
1661
* 16 pvs linked to from this page. This count may
1662
* be changed upwards or downwards in the future; it
1663
* is only necessary that true be returned for a small
1664
* subset of pmaps for proper page aging.
1665
*/
1666
bool
1667
moea_page_exists_quick(pmap_t pmap, vm_page_t m)
1668
{
1669
int loops;
1670
struct pvo_entry *pvo;
1671
bool rv;
1672
1673
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1674
("moea_page_exists_quick: page %p is not managed", m));
1675
loops = 0;
1676
rv = false;
1677
rw_wlock(&pvh_global_lock);
1678
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
1679
if (pvo->pvo_pmap == pmap) {
1680
rv = true;
1681
break;
1682
}
1683
if (++loops >= 16)
1684
break;
1685
}
1686
rw_wunlock(&pvh_global_lock);
1687
return (rv);
1688
}
1689
1690
void
1691
moea_page_init(vm_page_t m)
1692
{
1693
1694
m->md.mdpg_attrs = 0;
1695
m->md.mdpg_cache_attrs = VM_MEMATTR_DEFAULT;
1696
LIST_INIT(&m->md.mdpg_pvoh);
1697
}
1698
1699
/*
1700
* Return the number of managed mappings to the given physical page
1701
* that are wired.
1702
*/
1703
int
1704
moea_page_wired_mappings(vm_page_t m)
1705
{
1706
struct pvo_entry *pvo;
1707
int count;
1708
1709
count = 0;
1710
if ((m->oflags & VPO_UNMANAGED) != 0)
1711
return (count);
1712
rw_wlock(&pvh_global_lock);
1713
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink)
1714
if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
1715
count++;
1716
rw_wunlock(&pvh_global_lock);
1717
return (count);
1718
}
1719
1720
static u_int moea_vsidcontext;
1721
1722
int
1723
moea_pinit(pmap_t pmap)
1724
{
1725
int i, mask;
1726
u_int entropy;
1727
1728
RB_INIT(&pmap->pmap_pvo);
1729
1730
entropy = 0;
1731
__asm __volatile("mftb %0" : "=r"(entropy));
1732
1733
if ((pmap->pmap_phys = (pmap_t)moea_kextract((vm_offset_t)pmap))
1734
== NULL) {
1735
pmap->pmap_phys = pmap;
1736
}
1737
1738
mtx_lock(&moea_vsid_mutex);
1739
/*
1740
* Allocate some segment registers for this pmap.
1741
*/
1742
for (i = 0; i < NPMAPS; i += VSID_NBPW) {
1743
u_int hash, n;
1744
1745
/*
1746
* Create a new value by multiplying by a prime and adding in
1747
* entropy from the timebase register. This is to make the
1748
* VSID more random so that the PT hash function collides
1749
* less often. (Note that the prime casues gcc to do shifts
1750
* instead of a multiply.)
1751
*/
1752
moea_vsidcontext = (moea_vsidcontext * 0x1105) + entropy;
1753
hash = moea_vsidcontext & (NPMAPS - 1);
1754
if (hash == 0) /* 0 is special, avoid it */
1755
continue;
1756
n = hash >> 5;
1757
mask = 1 << (hash & (VSID_NBPW - 1));
1758
hash = (moea_vsidcontext & 0xfffff);
1759
if (moea_vsid_bitmap[n] & mask) { /* collision? */
1760
/* anything free in this bucket? */
1761
if (moea_vsid_bitmap[n] == 0xffffffff) {
1762
entropy = (moea_vsidcontext >> 20);
1763
continue;
1764
}
1765
i = ffs(~moea_vsid_bitmap[n]) - 1;
1766
mask = 1 << i;
1767
hash &= rounddown2(0xfffff, VSID_NBPW);
1768
hash |= i;
1769
}
1770
KASSERT(!(moea_vsid_bitmap[n] & mask),
1771
("Allocating in-use VSID group %#x\n", hash));
1772
moea_vsid_bitmap[n] |= mask;
1773
for (i = 0; i < 16; i++)
1774
pmap->pm_sr[i] = VSID_MAKE(i, hash);
1775
mtx_unlock(&moea_vsid_mutex);
1776
return (1);
1777
}
1778
1779
mtx_unlock(&moea_vsid_mutex);
1780
panic("moea_pinit: out of segments");
1781
}
1782
1783
/*
1784
* Initialize the pmap associated with process 0.
1785
*/
1786
void
1787
moea_pinit0(pmap_t pm)
1788
{
1789
1790
PMAP_LOCK_INIT(pm);
1791
moea_pinit(pm);
1792
bzero(&pm->pm_stats, sizeof(pm->pm_stats));
1793
}
1794
1795
/*
1796
* Set the physical protection on the specified range of this map as requested.
1797
*/
1798
void
1799
moea_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva,
1800
vm_prot_t prot)
1801
{
1802
struct pvo_entry *pvo, *tpvo, key;
1803
struct pte *pt;
1804
1805
KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
1806
("moea_protect: non current pmap"));
1807
1808
if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1809
moea_remove(pm, sva, eva);
1810
return;
1811
}
1812
1813
rw_wlock(&pvh_global_lock);
1814
PMAP_LOCK(pm);
1815
key.pvo_vaddr = sva;
1816
for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key);
1817
pvo != NULL && PVO_VADDR(pvo) < eva; pvo = tpvo) {
1818
tpvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo);
1819
1820
/*
1821
* Grab the PTE pointer before we diddle with the cached PTE
1822
* copy.
1823
*/
1824
pt = moea_pvo_to_pte(pvo, -1);
1825
/*
1826
* Change the protection of the page.
1827
*/
1828
pvo->pvo_pte.pte.pte_lo &= ~PTE_PP;
1829
pvo->pvo_pte.pte.pte_lo |= PTE_BR;
1830
1831
/*
1832
* If the PVO is in the page table, update that pte as well.
1833
*/
1834
if (pt != NULL) {
1835
moea_pte_change(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr);
1836
mtx_unlock(&moea_table_mutex);
1837
}
1838
}
1839
rw_wunlock(&pvh_global_lock);
1840
PMAP_UNLOCK(pm);
1841
}
1842
1843
/*
1844
* Map a list of wired pages into kernel virtual address space. This is
1845
* intended for temporary mappings which do not need page modification or
1846
* references recorded. Existing mappings in the region are overwritten.
1847
*/
1848
void
1849
moea_qenter(vm_offset_t sva, vm_page_t *m, int count)
1850
{
1851
vm_offset_t va;
1852
1853
va = sva;
1854
while (count-- > 0) {
1855
moea_kenter(va, VM_PAGE_TO_PHYS(*m));
1856
va += PAGE_SIZE;
1857
m++;
1858
}
1859
}
1860
1861
/*
1862
* Remove page mappings from kernel virtual address space. Intended for
1863
* temporary mappings entered by moea_qenter.
1864
*/
1865
void
1866
moea_qremove(vm_offset_t sva, int count)
1867
{
1868
vm_offset_t va;
1869
1870
va = sva;
1871
while (count-- > 0) {
1872
moea_kremove(va);
1873
va += PAGE_SIZE;
1874
}
1875
}
1876
1877
void
1878
moea_release(pmap_t pmap)
1879
{
1880
int idx, mask;
1881
1882
/*
1883
* Free segment register's VSID
1884
*/
1885
if (pmap->pm_sr[0] == 0)
1886
panic("moea_release");
1887
1888
mtx_lock(&moea_vsid_mutex);
1889
idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
1890
mask = 1 << (idx % VSID_NBPW);
1891
idx /= VSID_NBPW;
1892
moea_vsid_bitmap[idx] &= ~mask;
1893
mtx_unlock(&moea_vsid_mutex);
1894
}
1895
1896
/*
1897
* Remove the given range of addresses from the specified map.
1898
*/
1899
void
1900
moea_remove(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
1901
{
1902
struct pvo_entry *pvo, *tpvo, key;
1903
1904
rw_wlock(&pvh_global_lock);
1905
PMAP_LOCK(pm);
1906
key.pvo_vaddr = sva;
1907
for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key);
1908
pvo != NULL && PVO_VADDR(pvo) < eva; pvo = tpvo) {
1909
tpvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo);
1910
moea_pvo_remove(pvo, -1);
1911
}
1912
PMAP_UNLOCK(pm);
1913
rw_wunlock(&pvh_global_lock);
1914
}
1915
1916
/*
1917
* Remove physical page from all pmaps in which it resides. moea_pvo_remove()
1918
* will reflect changes in pte's back to the vm_page.
1919
*/
1920
void
1921
moea_remove_all(vm_page_t m)
1922
{
1923
struct pvo_head *pvo_head;
1924
struct pvo_entry *pvo, *next_pvo;
1925
pmap_t pmap;
1926
1927
rw_wlock(&pvh_global_lock);
1928
pvo_head = vm_page_to_pvoh(m);
1929
for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
1930
next_pvo = LIST_NEXT(pvo, pvo_vlink);
1931
1932
pmap = pvo->pvo_pmap;
1933
PMAP_LOCK(pmap);
1934
moea_pvo_remove(pvo, -1);
1935
PMAP_UNLOCK(pmap);
1936
}
1937
if ((m->a.flags & PGA_WRITEABLE) && moea_query_bit(m, PTE_CHG)) {
1938
moea_attr_clear(m, PTE_CHG);
1939
vm_page_dirty(m);
1940
}
1941
vm_page_aflag_clear(m, PGA_WRITEABLE);
1942
rw_wunlock(&pvh_global_lock);
1943
}
1944
1945
static int
1946
moea_mincore(pmap_t pm, vm_offset_t va, vm_paddr_t *pap)
1947
{
1948
struct pvo_entry *pvo;
1949
vm_paddr_t pa;
1950
vm_page_t m;
1951
int val;
1952
bool managed;
1953
1954
PMAP_LOCK(pm);
1955
1956
pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
1957
if (pvo != NULL) {
1958
pa = PVO_PADDR(pvo);
1959
m = PHYS_TO_VM_PAGE(pa);
1960
managed = (pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED;
1961
val = MINCORE_INCORE;
1962
} else {
1963
PMAP_UNLOCK(pm);
1964
return (0);
1965
}
1966
1967
PMAP_UNLOCK(pm);
1968
1969
if (m == NULL)
1970
return (0);
1971
1972
if (managed) {
1973
if (moea_is_modified(m))
1974
val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
1975
1976
if (moea_is_referenced(m))
1977
val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
1978
}
1979
1980
if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
1981
(MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) &&
1982
managed) {
1983
*pap = pa;
1984
}
1985
1986
return (val);
1987
}
1988
1989
/*
1990
* Allocate a physical page of memory directly from the phys_avail map.
1991
* Can only be called from moea_bootstrap before avail start and end are
1992
* calculated.
1993
*/
1994
static vm_offset_t
1995
moea_bootstrap_alloc(vm_size_t size, u_int align)
1996
{
1997
vm_offset_t s, e;
1998
int i, j;
1999
2000
size = round_page(size);
2001
for (i = 0; phys_avail[i + 1] != 0; i += 2) {
2002
if (align != 0)
2003
s = roundup2(phys_avail[i], align);
2004
else
2005
s = phys_avail[i];
2006
e = s + size;
2007
2008
if (s < phys_avail[i] || e > phys_avail[i + 1])
2009
continue;
2010
2011
if (s == phys_avail[i]) {
2012
phys_avail[i] += size;
2013
} else if (e == phys_avail[i + 1]) {
2014
phys_avail[i + 1] -= size;
2015
} else {
2016
for (j = phys_avail_count * 2; j > i; j -= 2) {
2017
phys_avail[j] = phys_avail[j - 2];
2018
phys_avail[j + 1] = phys_avail[j - 1];
2019
}
2020
2021
phys_avail[i + 3] = phys_avail[i + 1];
2022
phys_avail[i + 1] = s;
2023
phys_avail[i + 2] = e;
2024
phys_avail_count++;
2025
}
2026
2027
return (s);
2028
}
2029
panic("moea_bootstrap_alloc: could not allocate memory");
2030
}
2031
2032
static void
2033
moea_syncicache(vm_paddr_t pa, vm_size_t len)
2034
{
2035
__syncicache((void *)pa, len);
2036
}
2037
2038
static int
2039
moea_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
2040
vm_offset_t va, vm_paddr_t pa, u_int pte_lo, int flags)
2041
{
2042
struct pvo_entry *pvo;
2043
u_int sr;
2044
int first;
2045
u_int ptegidx;
2046
int i;
2047
int bootstrap;
2048
2049
moea_pvo_enter_calls++;
2050
first = 0;
2051
bootstrap = 0;
2052
2053
/*
2054
* Compute the PTE Group index.
2055
*/
2056
va &= ~ADDR_POFF;
2057
sr = va_to_sr(pm->pm_sr, va);
2058
ptegidx = va_to_pteg(sr, va);
2059
2060
/*
2061
* Remove any existing mapping for this page. Reuse the pvo entry if
2062
* there is a mapping.
2063
*/
2064
mtx_lock(&moea_table_mutex);
2065
LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
2066
if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
2067
if (PVO_PADDR(pvo) == pa &&
2068
(pvo->pvo_pte.pte.pte_lo & PTE_PP) ==
2069
(pte_lo & PTE_PP)) {
2070
/*
2071
* The PTE is not changing. Instead, this may
2072
* be a request to change the mapping's wired
2073
* attribute.
2074
*/
2075
mtx_unlock(&moea_table_mutex);
2076
if ((flags & PVO_WIRED) != 0 &&
2077
(pvo->pvo_vaddr & PVO_WIRED) == 0) {
2078
pvo->pvo_vaddr |= PVO_WIRED;
2079
pm->pm_stats.wired_count++;
2080
} else if ((flags & PVO_WIRED) == 0 &&
2081
(pvo->pvo_vaddr & PVO_WIRED) != 0) {
2082
pvo->pvo_vaddr &= ~PVO_WIRED;
2083
pm->pm_stats.wired_count--;
2084
}
2085
return (0);
2086
}
2087
moea_pvo_remove(pvo, -1);
2088
break;
2089
}
2090
}
2091
2092
/*
2093
* If we aren't overwriting a mapping, try to allocate.
2094
*/
2095
if (moea_initialized) {
2096
pvo = uma_zalloc(zone, M_NOWAIT);
2097
} else {
2098
if (moea_bpvo_pool_index >= BPVO_POOL_SIZE) {
2099
panic("moea_enter: bpvo pool exhausted, %d, %d, %d",
2100
moea_bpvo_pool_index, BPVO_POOL_SIZE,
2101
BPVO_POOL_SIZE * sizeof(struct pvo_entry));
2102
}
2103
pvo = &moea_bpvo_pool[moea_bpvo_pool_index];
2104
moea_bpvo_pool_index++;
2105
bootstrap = 1;
2106
}
2107
2108
if (pvo == NULL) {
2109
mtx_unlock(&moea_table_mutex);
2110
return (ENOMEM);
2111
}
2112
2113
moea_pvo_entries++;
2114
pvo->pvo_vaddr = va;
2115
pvo->pvo_pmap = pm;
2116
LIST_INSERT_HEAD(&moea_pvo_table[ptegidx], pvo, pvo_olink);
2117
pvo->pvo_vaddr &= ~ADDR_POFF;
2118
if (flags & PVO_WIRED)
2119
pvo->pvo_vaddr |= PVO_WIRED;
2120
if (pvo_head != &moea_pvo_kunmanaged)
2121
pvo->pvo_vaddr |= PVO_MANAGED;
2122
if (bootstrap)
2123
pvo->pvo_vaddr |= PVO_BOOTSTRAP;
2124
2125
moea_pte_create(&pvo->pvo_pte.pte, sr, va, pa | pte_lo);
2126
2127
/*
2128
* Add to pmap list
2129
*/
2130
RB_INSERT(pvo_tree, &pm->pmap_pvo, pvo);
2131
2132
/*
2133
* Remember if the list was empty and therefore will be the first
2134
* item.
2135
*/
2136
if (LIST_FIRST(pvo_head) == NULL)
2137
first = 1;
2138
LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
2139
2140
if (pvo->pvo_vaddr & PVO_WIRED)
2141
pm->pm_stats.wired_count++;
2142
pm->pm_stats.resident_count++;
2143
2144
i = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte);
2145
KASSERT(i < 8, ("Invalid PTE index"));
2146
if (i >= 0) {
2147
PVO_PTEGIDX_SET(pvo, i);
2148
} else {
2149
panic("moea_pvo_enter: overflow");
2150
moea_pte_overflow++;
2151
}
2152
mtx_unlock(&moea_table_mutex);
2153
2154
return (first ? ENOENT : 0);
2155
}
2156
2157
static void
2158
moea_pvo_remove(struct pvo_entry *pvo, int pteidx)
2159
{
2160
struct pte *pt;
2161
2162
/*
2163
* If there is an active pte entry, we need to deactivate it (and
2164
* save the ref & cfg bits).
2165
*/
2166
pt = moea_pvo_to_pte(pvo, pteidx);
2167
if (pt != NULL) {
2168
moea_pte_unset(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr);
2169
mtx_unlock(&moea_table_mutex);
2170
PVO_PTEGIDX_CLR(pvo);
2171
} else {
2172
moea_pte_overflow--;
2173
}
2174
2175
/*
2176
* Update our statistics.
2177
*/
2178
pvo->pvo_pmap->pm_stats.resident_count--;
2179
if (pvo->pvo_vaddr & PVO_WIRED)
2180
pvo->pvo_pmap->pm_stats.wired_count--;
2181
2182
/*
2183
* Remove this PVO from the PV and pmap lists.
2184
*/
2185
LIST_REMOVE(pvo, pvo_vlink);
2186
RB_REMOVE(pvo_tree, &pvo->pvo_pmap->pmap_pvo, pvo);
2187
2188
/*
2189
* Save the REF/CHG bits into their cache if the page is managed.
2190
* Clear PGA_WRITEABLE if all mappings of the page have been removed.
2191
*/
2192
if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED) {
2193
struct vm_page *pg;
2194
2195
pg = PHYS_TO_VM_PAGE(PVO_PADDR(pvo));
2196
if (pg != NULL) {
2197
moea_attr_save(pg, pvo->pvo_pte.pte.pte_lo &
2198
(PTE_REF | PTE_CHG));
2199
if (LIST_EMPTY(&pg->md.mdpg_pvoh))
2200
vm_page_aflag_clear(pg, PGA_WRITEABLE);
2201
}
2202
}
2203
2204
/*
2205
* Remove this from the overflow list and return it to the pool
2206
* if we aren't going to reuse it.
2207
*/
2208
LIST_REMOVE(pvo, pvo_olink);
2209
if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
2210
uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? moea_mpvo_zone :
2211
moea_upvo_zone, pvo);
2212
moea_pvo_entries--;
2213
moea_pvo_remove_calls++;
2214
}
2215
2216
static __inline int
2217
moea_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
2218
{
2219
int pteidx;
2220
2221
/*
2222
* We can find the actual pte entry without searching by grabbing
2223
* the PTEG index from 3 unused bits in pte_lo[11:9] and by
2224
* noticing the HID bit.
2225
*/
2226
pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
2227
if (pvo->pvo_pte.pte.pte_hi & PTE_HID)
2228
pteidx ^= moea_pteg_mask * 8;
2229
2230
return (pteidx);
2231
}
2232
2233
static struct pvo_entry *
2234
moea_pvo_find_va(pmap_t pm, vm_offset_t va, int *pteidx_p)
2235
{
2236
struct pvo_entry *pvo;
2237
int ptegidx;
2238
u_int sr;
2239
2240
va &= ~ADDR_POFF;
2241
sr = va_to_sr(pm->pm_sr, va);
2242
ptegidx = va_to_pteg(sr, va);
2243
2244
mtx_lock(&moea_table_mutex);
2245
LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
2246
if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
2247
if (pteidx_p)
2248
*pteidx_p = moea_pvo_pte_index(pvo, ptegidx);
2249
break;
2250
}
2251
}
2252
mtx_unlock(&moea_table_mutex);
2253
2254
return (pvo);
2255
}
2256
2257
static struct pte *
2258
moea_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
2259
{
2260
struct pte *pt;
2261
2262
/*
2263
* If we haven't been supplied the ptegidx, calculate it.
2264
*/
2265
if (pteidx == -1) {
2266
int ptegidx;
2267
u_int sr;
2268
2269
sr = va_to_sr(pvo->pvo_pmap->pm_sr, pvo->pvo_vaddr);
2270
ptegidx = va_to_pteg(sr, pvo->pvo_vaddr);
2271
pteidx = moea_pvo_pte_index(pvo, ptegidx);
2272
}
2273
2274
pt = &moea_pteg_table[pteidx >> 3].pt[pteidx & 7];
2275
mtx_lock(&moea_table_mutex);
2276
2277
if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
2278
panic("moea_pvo_to_pte: pvo %p has valid pte in pvo but no "
2279
"valid pte index", pvo);
2280
}
2281
2282
if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
2283
panic("moea_pvo_to_pte: pvo %p has valid pte index in pvo "
2284
"pvo but no valid pte", pvo);
2285
}
2286
2287
if ((pt->pte_hi ^ (pvo->pvo_pte.pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
2288
if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0) {
2289
panic("moea_pvo_to_pte: pvo %p has valid pte in "
2290
"moea_pteg_table %p but invalid in pvo", pvo, pt);
2291
}
2292
2293
if (((pt->pte_lo ^ pvo->pvo_pte.pte.pte_lo) & ~(PTE_CHG|PTE_REF))
2294
!= 0) {
2295
panic("moea_pvo_to_pte: pvo %p pte does not match "
2296
"pte %p in moea_pteg_table", pvo, pt);
2297
}
2298
2299
mtx_assert(&moea_table_mutex, MA_OWNED);
2300
return (pt);
2301
}
2302
2303
if (pvo->pvo_pte.pte.pte_hi & PTE_VALID) {
2304
panic("moea_pvo_to_pte: pvo %p has invalid pte %p in "
2305
"moea_pteg_table but valid in pvo: %8x, %8x", pvo, pt, pvo->pvo_pte.pte.pte_hi, pt->pte_hi);
2306
}
2307
2308
mtx_unlock(&moea_table_mutex);
2309
return (NULL);
2310
}
2311
2312
/*
2313
* XXX: THIS STUFF SHOULD BE IN pte.c?
2314
*/
2315
int
2316
moea_pte_spill(vm_offset_t addr)
2317
{
2318
struct pvo_entry *source_pvo, *victim_pvo;
2319
struct pvo_entry *pvo;
2320
int ptegidx, i, j;
2321
u_int sr;
2322
struct pteg *pteg;
2323
struct pte *pt;
2324
2325
moea_pte_spills++;
2326
2327
sr = mfsrin(addr);
2328
ptegidx = va_to_pteg(sr, addr);
2329
2330
/*
2331
* Have to substitute some entry. Use the primary hash for this.
2332
* Use low bits of timebase as random generator.
2333
*/
2334
pteg = &moea_pteg_table[ptegidx];
2335
mtx_lock(&moea_table_mutex);
2336
__asm __volatile("mftb %0" : "=r"(i));
2337
i &= 7;
2338
pt = &pteg->pt[i];
2339
2340
source_pvo = NULL;
2341
victim_pvo = NULL;
2342
LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
2343
/*
2344
* We need to find a pvo entry for this address.
2345
*/
2346
if (source_pvo == NULL &&
2347
moea_pte_match(&pvo->pvo_pte.pte, sr, addr,
2348
pvo->pvo_pte.pte.pte_hi & PTE_HID)) {
2349
/*
2350
* Now found an entry to be spilled into the pteg.
2351
* The PTE is now valid, so we know it's active.
2352
*/
2353
j = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte);
2354
2355
if (j >= 0) {
2356
PVO_PTEGIDX_SET(pvo, j);
2357
moea_pte_overflow--;
2358
mtx_unlock(&moea_table_mutex);
2359
return (1);
2360
}
2361
2362
source_pvo = pvo;
2363
2364
if (victim_pvo != NULL)
2365
break;
2366
}
2367
2368
/*
2369
* We also need the pvo entry of the victim we are replacing
2370
* so save the R & C bits of the PTE.
2371
*/
2372
if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
2373
moea_pte_compare(pt, &pvo->pvo_pte.pte)) {
2374
victim_pvo = pvo;
2375
if (source_pvo != NULL)
2376
break;
2377
}
2378
}
2379
2380
if (source_pvo == NULL) {
2381
mtx_unlock(&moea_table_mutex);
2382
return (0);
2383
}
2384
2385
if (victim_pvo == NULL) {
2386
if ((pt->pte_hi & PTE_HID) == 0)
2387
panic("moea_pte_spill: victim p-pte (%p) has no pvo"
2388
"entry", pt);
2389
2390
/*
2391
* If this is a secondary PTE, we need to search it's primary
2392
* pvo bucket for the matching PVO.
2393
*/
2394
LIST_FOREACH(pvo, &moea_pvo_table[ptegidx ^ moea_pteg_mask],
2395
pvo_olink) {
2396
/*
2397
* We also need the pvo entry of the victim we are
2398
* replacing so save the R & C bits of the PTE.
2399
*/
2400
if (moea_pte_compare(pt, &pvo->pvo_pte.pte)) {
2401
victim_pvo = pvo;
2402
break;
2403
}
2404
}
2405
2406
if (victim_pvo == NULL)
2407
panic("moea_pte_spill: victim s-pte (%p) has no pvo"
2408
"entry", pt);
2409
}
2410
2411
/*
2412
* We are invalidating the TLB entry for the EA we are replacing even
2413
* though it's valid. If we don't, we lose any ref/chg bit changes
2414
* contained in the TLB entry.
2415
*/
2416
source_pvo->pvo_pte.pte.pte_hi &= ~PTE_HID;
2417
2418
moea_pte_unset(pt, &victim_pvo->pvo_pte.pte, victim_pvo->pvo_vaddr);
2419
moea_pte_set(pt, &source_pvo->pvo_pte.pte);
2420
2421
PVO_PTEGIDX_CLR(victim_pvo);
2422
PVO_PTEGIDX_SET(source_pvo, i);
2423
moea_pte_replacements++;
2424
2425
mtx_unlock(&moea_table_mutex);
2426
return (1);
2427
}
2428
2429
static __inline struct pvo_entry *
2430
moea_pte_spillable_ident(u_int ptegidx)
2431
{
2432
struct pte *pt;
2433
struct pvo_entry *pvo_walk, *pvo = NULL;
2434
2435
LIST_FOREACH(pvo_walk, &moea_pvo_table[ptegidx], pvo_olink) {
2436
if (pvo_walk->pvo_vaddr & PVO_WIRED)
2437
continue;
2438
2439
if (!(pvo_walk->pvo_pte.pte.pte_hi & PTE_VALID))
2440
continue;
2441
2442
pt = moea_pvo_to_pte(pvo_walk, -1);
2443
2444
if (pt == NULL)
2445
continue;
2446
2447
pvo = pvo_walk;
2448
2449
mtx_unlock(&moea_table_mutex);
2450
if (!(pt->pte_lo & PTE_REF))
2451
return (pvo_walk);
2452
}
2453
2454
return (pvo);
2455
}
2456
2457
static int
2458
moea_pte_insert(u_int ptegidx, struct pte *pvo_pt)
2459
{
2460
struct pte *pt;
2461
struct pvo_entry *victim_pvo;
2462
int i;
2463
int victim_idx;
2464
u_int pteg_bkpidx = ptegidx;
2465
2466
mtx_assert(&moea_table_mutex, MA_OWNED);
2467
2468
/*
2469
* First try primary hash.
2470
*/
2471
for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
2472
if ((pt->pte_hi & PTE_VALID) == 0) {
2473
pvo_pt->pte_hi &= ~PTE_HID;
2474
moea_pte_set(pt, pvo_pt);
2475
return (i);
2476
}
2477
}
2478
2479
/*
2480
* Now try secondary hash.
2481
*/
2482
ptegidx ^= moea_pteg_mask;
2483
2484
for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
2485
if ((pt->pte_hi & PTE_VALID) == 0) {
2486
pvo_pt->pte_hi |= PTE_HID;
2487
moea_pte_set(pt, pvo_pt);
2488
return (i);
2489
}
2490
}
2491
2492
/* Try again, but this time try to force a PTE out. */
2493
ptegidx = pteg_bkpidx;
2494
2495
victim_pvo = moea_pte_spillable_ident(ptegidx);
2496
if (victim_pvo == NULL) {
2497
ptegidx ^= moea_pteg_mask;
2498
victim_pvo = moea_pte_spillable_ident(ptegidx);
2499
}
2500
2501
if (victim_pvo == NULL) {
2502
panic("moea_pte_insert: overflow");
2503
return (-1);
2504
}
2505
2506
victim_idx = moea_pvo_pte_index(victim_pvo, ptegidx);
2507
2508
if (pteg_bkpidx == ptegidx)
2509
pvo_pt->pte_hi &= ~PTE_HID;
2510
else
2511
pvo_pt->pte_hi |= PTE_HID;
2512
2513
/*
2514
* Synchronize the sacrifice PTE with its PVO, then mark both
2515
* invalid. The PVO will be reused when/if the VM system comes
2516
* here after a fault.
2517
*/
2518
pt = &moea_pteg_table[victim_idx >> 3].pt[victim_idx & 7];
2519
2520
if (pt->pte_hi != victim_pvo->pvo_pte.pte.pte_hi)
2521
panic("Victim PVO doesn't match PTE! PVO: %8x, PTE: %8x", victim_pvo->pvo_pte.pte.pte_hi, pt->pte_hi);
2522
2523
/*
2524
* Set the new PTE.
2525
*/
2526
moea_pte_unset(pt, &victim_pvo->pvo_pte.pte, victim_pvo->pvo_vaddr);
2527
PVO_PTEGIDX_CLR(victim_pvo);
2528
moea_pte_overflow++;
2529
moea_pte_set(pt, pvo_pt);
2530
2531
return (victim_idx & 7);
2532
}
2533
2534
static bool
2535
moea_query_bit(vm_page_t m, int ptebit)
2536
{
2537
struct pvo_entry *pvo;
2538
struct pte *pt;
2539
2540
rw_assert(&pvh_global_lock, RA_WLOCKED);
2541
if (moea_attr_fetch(m) & ptebit)
2542
return (true);
2543
2544
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2545
/*
2546
* See if we saved the bit off. If so, cache it and return
2547
* success.
2548
*/
2549
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
2550
moea_attr_save(m, ptebit);
2551
return (true);
2552
}
2553
}
2554
2555
/*
2556
* No luck, now go through the hard part of looking at the PTEs
2557
* themselves. Sync so that any pending REF/CHG bits are flushed to
2558
* the PTEs.
2559
*/
2560
powerpc_sync();
2561
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2562
/*
2563
* See if this pvo has a valid PTE. if so, fetch the
2564
* REF/CHG bits from the valid PTE. If the appropriate
2565
* ptebit is set, cache it and return success.
2566
*/
2567
pt = moea_pvo_to_pte(pvo, -1);
2568
if (pt != NULL) {
2569
moea_pte_synch(pt, &pvo->pvo_pte.pte);
2570
mtx_unlock(&moea_table_mutex);
2571
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
2572
moea_attr_save(m, ptebit);
2573
return (true);
2574
}
2575
}
2576
}
2577
2578
return (false);
2579
}
2580
2581
static u_int
2582
moea_clear_bit(vm_page_t m, int ptebit)
2583
{
2584
u_int count;
2585
struct pvo_entry *pvo;
2586
struct pte *pt;
2587
2588
rw_assert(&pvh_global_lock, RA_WLOCKED);
2589
2590
/*
2591
* Clear the cached value.
2592
*/
2593
moea_attr_clear(m, ptebit);
2594
2595
/*
2596
* Sync so that any pending REF/CHG bits are flushed to the PTEs (so
2597
* we can reset the right ones). note that since the pvo entries and
2598
* list heads are accessed via BAT0 and are never placed in the page
2599
* table, we don't have to worry about further accesses setting the
2600
* REF/CHG bits.
2601
*/
2602
powerpc_sync();
2603
2604
/*
2605
* For each pvo entry, clear the pvo's ptebit. If this pvo has a
2606
* valid pte clear the ptebit from the valid pte.
2607
*/
2608
count = 0;
2609
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2610
pt = moea_pvo_to_pte(pvo, -1);
2611
if (pt != NULL) {
2612
moea_pte_synch(pt, &pvo->pvo_pte.pte);
2613
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
2614
count++;
2615
moea_pte_clear(pt, PVO_VADDR(pvo), ptebit);
2616
}
2617
mtx_unlock(&moea_table_mutex);
2618
}
2619
pvo->pvo_pte.pte.pte_lo &= ~ptebit;
2620
}
2621
2622
return (count);
2623
}
2624
2625
/*
2626
* Return true if the physical range is encompassed by the battable[idx]
2627
*/
2628
static int
2629
moea_bat_mapped(int idx, vm_paddr_t pa, vm_size_t size)
2630
{
2631
u_int prot;
2632
u_int32_t start;
2633
u_int32_t end;
2634
u_int32_t bat_ble;
2635
2636
/*
2637
* Return immediately if not a valid mapping
2638
*/
2639
if (!(battable[idx].batu & BAT_Vs))
2640
return (EINVAL);
2641
2642
/*
2643
* The BAT entry must be cache-inhibited, guarded, and r/w
2644
* so it can function as an i/o page
2645
*/
2646
prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW);
2647
if (prot != (BAT_I|BAT_G|BAT_PP_RW))
2648
return (EPERM);
2649
2650
/*
2651
* The address should be within the BAT range. Assume that the
2652
* start address in the BAT has the correct alignment (thus
2653
* not requiring masking)
2654
*/
2655
start = battable[idx].batl & BAT_PBS;
2656
bat_ble = (battable[idx].batu & ~(BAT_EBS)) | 0x03;
2657
end = start | (bat_ble << 15) | 0x7fff;
2658
2659
if ((pa < start) || ((pa + size) > end))
2660
return (ERANGE);
2661
2662
return (0);
2663
}
2664
2665
int
2666
moea_dev_direct_mapped(vm_paddr_t pa, vm_size_t size)
2667
{
2668
int i;
2669
2670
/*
2671
* This currently does not work for entries that
2672
* overlap 256M BAT segments.
2673
*/
2674
2675
for(i = 0; i < 16; i++)
2676
if (moea_bat_mapped(i, pa, size) == 0)
2677
return (0);
2678
2679
return (EFAULT);
2680
}
2681
2682
/*
2683
* Map a set of physical memory pages into the kernel virtual
2684
* address space. Return a pointer to where it is mapped. This
2685
* routine is intended to be used for mapping device memory,
2686
* NOT real memory.
2687
*/
2688
void *
2689
moea_mapdev(vm_paddr_t pa, vm_size_t size)
2690
{
2691
2692
return (moea_mapdev_attr(pa, size, VM_MEMATTR_DEFAULT));
2693
}
2694
2695
void *
2696
moea_mapdev_attr(vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
2697
{
2698
vm_offset_t va, tmpva, ppa, offset;
2699
int i;
2700
2701
ppa = trunc_page(pa);
2702
offset = pa & PAGE_MASK;
2703
size = roundup(offset + size, PAGE_SIZE);
2704
2705
/*
2706
* If the physical address lies within a valid BAT table entry,
2707
* return the 1:1 mapping. This currently doesn't work
2708
* for regions that overlap 256M BAT segments.
2709
*/
2710
for (i = 0; i < 16; i++) {
2711
if (moea_bat_mapped(i, pa, size) == 0)
2712
return ((void *) pa);
2713
}
2714
2715
va = kva_alloc(size);
2716
if (!va)
2717
panic("moea_mapdev: Couldn't alloc kernel virtual memory");
2718
2719
for (tmpva = va; size > 0;) {
2720
moea_kenter_attr(tmpva, ppa, ma);
2721
tlbie(tmpva);
2722
size -= PAGE_SIZE;
2723
tmpva += PAGE_SIZE;
2724
ppa += PAGE_SIZE;
2725
}
2726
2727
return ((void *)(va + offset));
2728
}
2729
2730
void
2731
moea_unmapdev(void *p, vm_size_t size)
2732
{
2733
vm_offset_t base, offset, va;
2734
2735
/*
2736
* If this is outside kernel virtual space, then it's a
2737
* battable entry and doesn't require unmapping
2738
*/
2739
va = (vm_offset_t)p;
2740
if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= virtual_end)) {
2741
base = trunc_page(va);
2742
offset = va & PAGE_MASK;
2743
size = roundup(offset + size, PAGE_SIZE);
2744
moea_qremove(base, atop(size));
2745
kva_free(base, size);
2746
}
2747
}
2748
2749
static void
2750
moea_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
2751
{
2752
struct pvo_entry *pvo;
2753
vm_offset_t lim;
2754
vm_paddr_t pa;
2755
vm_size_t len;
2756
2757
PMAP_LOCK(pm);
2758
while (sz > 0) {
2759
lim = round_page(va + 1);
2760
len = MIN(lim - va, sz);
2761
pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
2762
if (pvo != NULL) {
2763
pa = PVO_PADDR(pvo) | (va & ADDR_POFF);
2764
moea_syncicache(pa, len);
2765
}
2766
va += len;
2767
sz -= len;
2768
}
2769
PMAP_UNLOCK(pm);
2770
}
2771
2772
void
2773
moea_dumpsys_map(vm_paddr_t pa, size_t sz, void **va)
2774
{
2775
2776
*va = (void *)pa;
2777
}
2778
2779
extern struct dump_pa dump_map[PHYS_AVAIL_SZ + 1];
2780
2781
void
2782
moea_scan_init(void)
2783
{
2784
struct pvo_entry *pvo;
2785
vm_offset_t va;
2786
int i;
2787
2788
if (!do_minidump) {
2789
/* Initialize phys. segments for dumpsys(). */
2790
memset(&dump_map, 0, sizeof(dump_map));
2791
mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
2792
for (i = 0; i < pregions_sz; i++) {
2793
dump_map[i].pa_start = pregions[i].mr_start;
2794
dump_map[i].pa_size = pregions[i].mr_size;
2795
}
2796
return;
2797
}
2798
2799
/* Virtual segments for minidumps: */
2800
memset(&dump_map, 0, sizeof(dump_map));
2801
2802
/* 1st: kernel .data and .bss. */
2803
dump_map[0].pa_start = trunc_page((uintptr_t)_etext);
2804
dump_map[0].pa_size =
2805
round_page((uintptr_t)_end) - dump_map[0].pa_start;
2806
2807
/* 2nd: msgbuf and tables (see pmap_bootstrap()). */
2808
dump_map[1].pa_start = (vm_paddr_t)msgbufp->msg_ptr;
2809
dump_map[1].pa_size = round_page(msgbufp->msg_size);
2810
2811
/* 3rd: kernel VM. */
2812
va = dump_map[1].pa_start + dump_map[1].pa_size;
2813
/* Find start of next chunk (from va). */
2814
while (va < virtual_end) {
2815
/* Don't dump the buffer cache. */
2816
if (va >= kmi.buffer_sva && va < kmi.buffer_eva) {
2817
va = kmi.buffer_eva;
2818
continue;
2819
}
2820
pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
2821
if (pvo != NULL && (pvo->pvo_pte.pte.pte_hi & PTE_VALID))
2822
break;
2823
va += PAGE_SIZE;
2824
}
2825
if (va < virtual_end) {
2826
dump_map[2].pa_start = va;
2827
va += PAGE_SIZE;
2828
/* Find last page in chunk. */
2829
while (va < virtual_end) {
2830
/* Don't run into the buffer cache. */
2831
if (va == kmi.buffer_sva)
2832
break;
2833
pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF,
2834
NULL);
2835
if (pvo == NULL ||
2836
!(pvo->pvo_pte.pte.pte_hi & PTE_VALID))
2837
break;
2838
va += PAGE_SIZE;
2839
}
2840
dump_map[2].pa_size = va - dump_map[2].pa_start;
2841
}
2842
}
2843
2844