pmap.c (100718) | pmap.c (100771) |
---|---|
1/* 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * Copyright (c) 1994 John S. Dyson 5 * All rights reserved. 6 * Copyright (c) 1994 David Greenman 7 * All rights reserved. 8 * --- 25 unchanged lines hidden (view full) --- 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 | 1/* 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * Copyright (c) 1994 John S. Dyson 5 * All rights reserved. 6 * Copyright (c) 1994 David Greenman 7 * All rights reserved. 8 * --- 25 unchanged lines hidden (view full) --- 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 |
42 * $FreeBSD: head/sys/sparc64/sparc64/pmap.c 100718 2002-07-26 15:54:04Z jake $ | 42 * $FreeBSD: head/sys/sparc64/sparc64/pmap.c 100771 2002-07-27 21:57:38Z jake $ |
43 */ 44 45/* 46 * Manages physical address maps. 47 * 48 * In addition to hardware address maps, this module is called upon to 49 * provide software-use-only maps which may or may not be stored in the 50 * same form as hardware maps. These pseudo-maps are used to store --- 102 unchanged lines hidden (view full) --- 153 154static boolean_t pmap_initialized = FALSE; 155 156/* 157 * Allocate physical memory for use in pmap_bootstrap. 158 */ 159static vm_offset_t pmap_bootstrap_alloc(vm_size_t size); 160 | 43 */ 44 45/* 46 * Manages physical address maps. 47 * 48 * In addition to hardware address maps, this module is called upon to 49 * provide software-use-only maps which may or may not be stored in the 50 * same form as hardware maps. These pseudo-maps are used to store --- 102 unchanged lines hidden (view full) --- 153 154static boolean_t pmap_initialized = FALSE; 155 156/* 157 * Allocate physical memory for use in pmap_bootstrap. 158 */ 159static vm_offset_t pmap_bootstrap_alloc(vm_size_t size); 160 |
161static vm_offset_t pmap_map_direct(vm_page_t m); 162 |
|
161/* 162 * If user pmap is processed with pmap_remove and with pmap_remove and the 163 * resident count drops to 0, there are no more pages to remove, so we 164 * need not continue. 165 */ 166#define PMAP_REMOVE_DONE(pm) \ 167 ((pm) != kernel_pmap && (pm)->pm_stats.resident_count == 0) 168 --- 344 unchanged lines hidden (view full) --- 513 int i; 514 515 for (i = 0; i < vm_page_array_size; i++) { 516 vm_page_t m; 517 518 m = &vm_page_array[i]; 519 STAILQ_INIT(&m->md.tte_list); 520 m->md.flags = 0; | 163/* 164 * If user pmap is processed with pmap_remove and with pmap_remove and the 165 * resident count drops to 0, there are no more pages to remove, so we 166 * need not continue. 167 */ 168#define PMAP_REMOVE_DONE(pm) \ 169 ((pm) != kernel_pmap && (pm)->pm_stats.resident_count == 0) 170 --- 344 unchanged lines hidden (view full) --- 515 int i; 516 517 for (i = 0; i < vm_page_array_size; i++) { 518 vm_page_t m; 519 520 m = &vm_page_array[i]; 521 STAILQ_INIT(&m->md.tte_list); 522 m->md.flags = 0; |
523 m->md.color = 0; |
|
521 } 522 523 for (i = 0; i < translations_size; i++) { 524 addr = translations[i].om_start; 525 size = translations[i].om_size; 526 if (addr < 0xf0000000) /* XXX */ 527 continue; 528 result = vm_map_find(kernel_map, NULL, 0, &addr, size, TRUE, --- 47 unchanged lines hidden (view full) --- 576 return (0); 577 return (TTE_GET_PA(tp) | (va & TTE_GET_PAGE_MASK(tp))); 578} 579 580int 581pmap_cache_enter(vm_page_t m, vm_offset_t va) 582{ 583 struct tte *tp; | 524 } 525 526 for (i = 0; i < translations_size; i++) { 527 addr = translations[i].om_start; 528 size = translations[i].om_size; 529 if (addr < 0xf0000000) /* XXX */ 530 continue; 531 result = vm_map_find(kernel_map, NULL, 0, &addr, size, TRUE, --- 47 unchanged lines hidden (view full) --- 579 return (0); 580 return (TTE_GET_PA(tp) | (va & TTE_GET_PAGE_MASK(tp))); 581} 582 583int 584pmap_cache_enter(vm_page_t m, vm_offset_t va) 585{ 586 struct tte *tp; |
587 int color; |
|
584 int c, i; 585 586 CTR2(KTR_PMAP, "pmap_cache_enter: m=%p va=%#lx", m, va); 587 PMAP_STATS_INC(pmap_ncache_enter); | 588 int c, i; 589 590 CTR2(KTR_PMAP, "pmap_cache_enter: m=%p va=%#lx", m, va); 591 PMAP_STATS_INC(pmap_ncache_enter); |
588 for (i = 0, c = 0; i < DCACHE_COLORS; i++) { 589 if (i != DCACHE_COLOR(va) && m->md.colors[i] != 0) | 592 color = DCACHE_COLOR(va); 593 m->md.colors[color]++; 594 if (m->md.color == color) { 595 CTR0(KTR_PMAP, "pmap_cache_enter: cacheable"); 596 return (1); 597 } 598 for (c = 0, i = 0; i < DCACHE_COLORS; i++) { 599 if (m->md.colors[i] != 0) |
590 c++; 591 } | 600 c++; 601 } |
592 m->md.colors[DCACHE_COLOR(va)]++; 593 if (c == 0) { | 602 if (c == 1) { 603 m->md.color = color; 604 dcache_page_inval(VM_PAGE_TO_PHYS(m)); |
594 CTR0(KTR_PMAP, "pmap_cache_enter: cacheable"); 595 return (1); 596 } 597 PMAP_STATS_INC(pmap_ncache_enter_nc); | 605 CTR0(KTR_PMAP, "pmap_cache_enter: cacheable"); 606 return (1); 607 } 608 PMAP_STATS_INC(pmap_ncache_enter_nc); |
598 if ((m->md.flags & PG_UNCACHEABLE) != 0) { | 609 if (m->md.color == -1) { |
599 CTR0(KTR_PMAP, "pmap_cache_enter: already uncacheable"); 600 return (0); 601 } 602 CTR0(KTR_PMAP, "pmap_cache_enter: marking uncacheable"); 603 STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) { 604 tp->tte_data &= ~TD_CV; 605 tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp)); 606 } 607 dcache_page_inval(VM_PAGE_TO_PHYS(m)); | 610 CTR0(KTR_PMAP, "pmap_cache_enter: already uncacheable"); 611 return (0); 612 } 613 CTR0(KTR_PMAP, "pmap_cache_enter: marking uncacheable"); 614 STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) { 615 tp->tte_data &= ~TD_CV; 616 tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp)); 617 } 618 dcache_page_inval(VM_PAGE_TO_PHYS(m)); |
608 m->md.flags |= PG_UNCACHEABLE; | 619 m->md.color = -1; |
609 return (0); 610} 611 612void 613pmap_cache_remove(vm_page_t m, vm_offset_t va) 614{ 615 struct tte *tp; | 620 return (0); 621} 622 623void 624pmap_cache_remove(vm_page_t m, vm_offset_t va) 625{ 626 struct tte *tp; |
627 int color; |
|
616 int c, i; 617 618 CTR3(KTR_PMAP, "pmap_cache_remove: m=%p va=%#lx c=%d", m, va, 619 m->md.colors[DCACHE_COLOR(va)]); 620 KASSERT(m->md.colors[DCACHE_COLOR(va)] > 0, 621 ("pmap_cache_remove: no mappings %d <= 0", 622 m->md.colors[DCACHE_COLOR(va)])); | 628 int c, i; 629 630 CTR3(KTR_PMAP, "pmap_cache_remove: m=%p va=%#lx c=%d", m, va, 631 m->md.colors[DCACHE_COLOR(va)]); 632 KASSERT(m->md.colors[DCACHE_COLOR(va)] > 0, 633 ("pmap_cache_remove: no mappings %d <= 0", 634 m->md.colors[DCACHE_COLOR(va)])); |
623 m->md.colors[DCACHE_COLOR(va)]--; 624 for (i = 0, c = 0; i < DCACHE_COLORS; i++) { | 635 color = DCACHE_COLOR(va); 636 m->md.colors[color]--; 637 if (m->md.color != -1 || m->md.colors[color] != 0) 638 return; 639 for (c = 0, i = 0; i < DCACHE_COLORS; i++) { |
625 if (m->md.colors[i] != 0) 626 c++; 627 } | 640 if (m->md.colors[i] != 0) 641 c++; 642 } |
628 if (c > 1 || (m->md.flags & PG_UNCACHEABLE) == 0) | 643 if (c > 1) |
629 return; 630 STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) { 631 tp->tte_data |= TD_CV; 632 tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp)); 633 } | 644 return; 645 STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) { 646 tp->tte_data |= TD_CV; 647 tlb_page_demap(TTE_GET_PMAP(tp), TTE_GET_VA(tp)); 648 } |
634 m->md.flags &= ~PG_UNCACHEABLE; | 649 m->md.color = color; |
635} 636 637/* 638 * Map a wired page into kernel virtual address space. 639 */ 640void 641pmap_kenter(vm_offset_t va, vm_offset_t pa) 642{ --- 112 unchanged lines hidden (view full) --- 755 tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_REF | TD_SW | 756 TD_CP | TD_CV | TD_P | TD_W; 757 } 758 tlb_range_demap(kernel_pmap, sva, sva + (pa_end - pa_start) - 1); 759 *virt = va; 760 return (sva); 761} 762 | 650} 651 652/* 653 * Map a wired page into kernel virtual address space. 654 */ 655void 656pmap_kenter(vm_offset_t va, vm_offset_t pa) 657{ --- 112 unchanged lines hidden (view full) --- 770 tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_REF | TD_SW | 771 TD_CP | TD_CV | TD_P | TD_W; 772 } 773 tlb_range_demap(kernel_pmap, sva, sva + (pa_end - pa_start) - 1); 774 *virt = va; 775 return (sva); 776} 777 |
778static vm_offset_t 779pmap_map_direct(vm_page_t m) 780{ 781 vm_offset_t pa; 782 vm_offset_t va; 783 784 pa = VM_PAGE_TO_PHYS(m); 785 if (m->md.color == -1) 786 va = TLB_DIRECT_MASK | pa | TLB_DIRECT_UNCACHEABLE; 787 else 788 va = TLB_DIRECT_MASK | pa | 789 (m->md.color << TLB_DIRECT_COLOR_SHIFT); 790 return (va << TLB_DIRECT_SHIFT); 791} 792 |
|
763/* 764 * Map a list of wired pages into kernel virtual address space. This is 765 * intended for temporary mappings which do not need page modification or 766 * references recorded. Existing mappings in the region are overwritten. 767 */ 768void 769pmap_qenter(vm_offset_t sva, vm_page_t *m, int count) 770{ --- 636 unchanged lines hidden (view full) --- 1407} 1408 1409/* 1410 * Zero a page of physical memory by temporarily mapping it into the tlb. 1411 */ 1412void 1413pmap_zero_page(vm_page_t m) 1414{ | 793/* 794 * Map a list of wired pages into kernel virtual address space. This is 795 * intended for temporary mappings which do not need page modification or 796 * references recorded. Existing mappings in the region are overwritten. 797 */ 798void 799pmap_qenter(vm_offset_t sva, vm_page_t *m, int count) 800{ --- 636 unchanged lines hidden (view full) --- 1437} 1438 1439/* 1440 * Zero a page of physical memory by temporarily mapping it into the tlb. 1441 */ 1442void 1443pmap_zero_page(vm_page_t m) 1444{ |
1415 vm_offset_t pa; | 1445 vm_offset_t va; |
1416 | 1446 |
1417 pa = VM_PAGE_TO_PHYS(m); 1418 CTR1(KTR_PMAP, "pmap_zero_page: pa=%#lx", pa); 1419 dcache_page_inval(pa); 1420 aszero(ASI_PHYS_USE_EC, pa, PAGE_SIZE); | 1447 va = pmap_map_direct(m); 1448 CTR2(KTR_PMAP, "pmap_zero_page: pa=%#lx va=%#lx", 1449 VM_PAGE_TO_PHYS(m), va); 1450 bzero((void *)va, PAGE_SIZE); |
1421} 1422 1423void 1424pmap_zero_page_area(vm_page_t m, int off, int size) 1425{ | 1451} 1452 1453void 1454pmap_zero_page_area(vm_page_t m, int off, int size) 1455{ |
1426 vm_offset_t pa; | 1456 vm_offset_t va; |
1427 | 1457 |
1428 pa = VM_PAGE_TO_PHYS(m); 1429 CTR3(KTR_PMAP, "pmap_zero_page_area: pa=%#lx off=%#x size=%#x", 1430 pa, off, size); | |
1431 KASSERT(off + size <= PAGE_SIZE, ("pmap_zero_page_area: bad off/size")); | 1458 KASSERT(off + size <= PAGE_SIZE, ("pmap_zero_page_area: bad off/size")); |
1432 dcache_page_inval(pa); 1433 aszero(ASI_PHYS_USE_EC, pa + off, size); | 1459 va = pmap_map_direct(m); 1460 CTR4(KTR_PMAP, "pmap_zero_page_area: pa=%#lx va=%#lx off=%#x size=%#x", 1461 VM_PAGE_TO_PHYS(m), va, off, size); 1462 bzero((void *)(va + off), size); |
1434} 1435 1436void 1437pmap_zero_page_idle(vm_page_t m) 1438{ | 1463} 1464 1465void 1466pmap_zero_page_idle(vm_page_t m) 1467{ |
1439 vm_offset_t pa = VM_PAGE_TO_PHYS(m); | 1468 vm_offset_t va; |
1440 | 1469 |
1441 CTR1(KTR_PMAP, "pmap_zero_page_idle: pa=%#lx", pa); 1442#ifdef SMP 1443 mtx_lock(&Giant); 1444#endif 1445 dcache_inval_phys(pa, pa + PAGE_SIZE - 1); 1446#ifdef SMP 1447 mtx_unlock(&Giant); 1448#endif 1449 aszero(ASI_PHYS_USE_EC, pa, PAGE_SIZE); | 1470 va = pmap_map_direct(m); 1471 CTR2(KTR_PMAP, "pmap_zero_page_idle: pa=%#lx va=%#lx", 1472 VM_PAGE_TO_PHYS(m), va); 1473 bzero((void *)va, PAGE_SIZE); |
1450} 1451 1452/* 1453 * Copy a page of physical memory by temporarily mapping it into the tlb. 1454 */ 1455void 1456pmap_copy_page(vm_page_t msrc, vm_page_t mdst) 1457{ 1458 vm_offset_t dst; 1459 vm_offset_t src; 1460 | 1474} 1475 1476/* 1477 * Copy a page of physical memory by temporarily mapping it into the tlb. 1478 */ 1479void 1480pmap_copy_page(vm_page_t msrc, vm_page_t mdst) 1481{ 1482 vm_offset_t dst; 1483 vm_offset_t src; 1484 |
1461 dst = VM_PAGE_TO_PHYS(mdst); 1462 src = VM_PAGE_TO_PHYS(msrc); 1463 CTR2(KTR_PMAP, "pmap_copy_page: src=%#lx dst=%#lx", src, dst); 1464 dcache_page_inval(dst); 1465 ascopy(ASI_PHYS_USE_EC, src, dst, PAGE_SIZE); | 1485 src = pmap_map_direct(msrc); 1486 dst = pmap_map_direct(mdst); 1487 CTR4(KTR_PMAP, "pmap_zero_page: src=%#lx va=%#lx dst=%#lx va=%#lx", 1488 VM_PAGE_TO_PHYS(msrc), src, VM_PAGE_TO_PHYS(mdst), dst); 1489 bcopy((void *)src, (void *)dst, PAGE_SIZE); |
1466} 1467 1468/* 1469 * Make the specified page pageable (or not). Unneeded. 1470 */ 1471void 1472pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, 1473 boolean_t pageable) --- 228 unchanged lines hidden --- | 1490} 1491 1492/* 1493 * Make the specified page pageable (or not). Unneeded. 1494 */ 1495void 1496pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, 1497 boolean_t pageable) --- 228 unchanged lines hidden --- |