pmap.c (df9ab3049d40eb3ab4e15db20d6e796d11240e23) | pmap.c (3fb3086e98c3a8b20546685c0912d75eaec94025) |
---|---|
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 * $Id: pmap.c,v 1.35 1994/09/04 04:11:57 davidg Exp $ | 42 * $Id: pmap.c,v 1.36 1994/09/16 13:33:26 davidg Exp $ |
43 */ 44 45/* 46 * Derived from hp300 version by Mike Hibler, this version by William 47 * Jolitz uses a recursive map [a pde points to the page directory] to 48 * map the page tables using the pagetables themselves. This is done to 49 * reduce the impact on kernel virtual memory for lots of sparse address 50 * space, and to reduce the cost of memory to each process. --- 30 unchanged lines hidden (view full) --- 81 * this module may delay invalidate or reduced protection 82 * operations until such time as they are actually 83 * necessary. This module is given full information as 84 * to which processors are currently using which maps, 85 * and to when physical maps must be made correct. 86 */ 87 88#include <sys/param.h> | 43 */ 44 45/* 46 * Derived from hp300 version by Mike Hibler, this version by William 47 * Jolitz uses a recursive map [a pde points to the page directory] to 48 * map the page tables using the pagetables themselves. This is done to 49 * reduce the impact on kernel virtual memory for lots of sparse address 50 * space, and to reduce the cost of memory to each process. --- 30 unchanged lines hidden (view full) --- 81 * this module may delay invalidate or reduced protection 82 * operations until such time as they are actually 83 * necessary. This module is given full information as 84 * to which processors are currently using which maps, 85 * and to when physical maps must be made correct. 86 */ 87 88#include <sys/param.h> |
89#include <sys/systm.h> |
|
89#include <sys/proc.h> 90#include <sys/malloc.h> 91#include <sys/user.h> 92 93#include <vm/vm.h> 94#include <vm/vm_kern.h> 95#include <vm/vm_page.h> 96 --- 111 unchanged lines hidden (view full) --- 208 * with the given map/virtual_address pair. 209 */ 210 211vm_offset_t 212pmap_extract(pmap, va) 213 register pmap_t pmap; 214 vm_offset_t va; 215{ | 90#include <sys/proc.h> 91#include <sys/malloc.h> 92#include <sys/user.h> 93 94#include <vm/vm.h> 95#include <vm/vm_kern.h> 96#include <vm/vm_page.h> 97 --- 111 unchanged lines hidden (view full) --- 209 * with the given map/virtual_address pair. 210 */ 211 212vm_offset_t 213pmap_extract(pmap, va) 214 register pmap_t pmap; 215 vm_offset_t va; 216{ |
216 pd_entry_t save; | |
217 vm_offset_t pa; | 217 vm_offset_t pa; |
218 int s; | |
219 220 if (pmap && *pmap_pde(pmap, va)) { 221 vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME; 222 /* are we current address space or kernel? */ 223 if ( (pmap == kernel_pmap) 224 || (frame == ((int) PTDpde & PG_FRAME)) ) { 225 pa = *(int *) vtopte(va); 226 /* otherwise, we are alternate address space */ --- 28 unchanged lines hidden (view full) --- 255 return 1; 256 } 257 return 0; 258} 259 260/* 261 * find the vm_page_t of a pte (only) given va of pte and pmap 262 */ | 218 219 if (pmap && *pmap_pde(pmap, va)) { 220 vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME; 221 /* are we current address space or kernel? */ 222 if ( (pmap == kernel_pmap) 223 || (frame == ((int) PTDpde & PG_FRAME)) ) { 224 pa = *(int *) vtopte(va); 225 /* otherwise, we are alternate address space */ --- 28 unchanged lines hidden (view full) --- 254 return 1; 255 } 256 return 0; 257} 258 259/* 260 * find the vm_page_t of a pte (only) given va of pte and pmap 261 */ |
263inline vm_page_t | 262__inline vm_page_t |
264pmap_pte_vm_page(pmap, pt) 265 pmap_t pmap; 266 vm_offset_t pt; 267{ 268 pt = i386_trunc_page( pt); 269 pt = (pt - UPT_MIN_ADDRESS) / NBPG; 270 pt = ((vm_offset_t) pmap->pm_pdir[pt]) & PG_FRAME; 271 return PHYS_TO_VM_PAGE(pt); --- 129 unchanged lines hidden (view full) --- 401 * system needs to map virtual memory. 402 * pmap_init has been enhanced to support in a fairly consistant 403 * way, discontiguous physical memory. 404 */ 405void 406pmap_init(phys_start, phys_end) 407 vm_offset_t phys_start, phys_end; 408{ | 263pmap_pte_vm_page(pmap, pt) 264 pmap_t pmap; 265 vm_offset_t pt; 266{ 267 pt = i386_trunc_page( pt); 268 pt = (pt - UPT_MIN_ADDRESS) / NBPG; 269 pt = ((vm_offset_t) pmap->pm_pdir[pt]) & PG_FRAME; 270 return PHYS_TO_VM_PAGE(pt); --- 129 unchanged lines hidden (view full) --- 400 * system needs to map virtual memory. 401 * pmap_init has been enhanced to support in a fairly consistant 402 * way, discontiguous physical memory. 403 */ 404void 405pmap_init(phys_start, phys_end) 406 vm_offset_t phys_start, phys_end; 407{ |
409 vm_offset_t addr, addr2; | 408 vm_offset_t addr; |
410 vm_size_t npg, s; | 409 vm_size_t npg, s; |
411 int rv; | |
412 int i; | 410 int i; |
413 extern int KPTphys; | |
414 415 /* 416 * Now that kernel map has been allocated, we can mark as 417 * unavailable regions which we have mapped in locore. 418 */ 419 addr = atdevbase; 420 (void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0, 421 &addr, (0x100000-0xa0000), FALSE); --- 250 unchanged lines hidden (view full) --- 672 vm_page_t m; 673 /* 674 * we do this to keep recursion away 675 */ 676 pv_freelistcnt += PV_FREELIST_MIN; 677 /* 678 * allocate a physical page out of the vm system 679 */ | 411 412 /* 413 * Now that kernel map has been allocated, we can mark as 414 * unavailable regions which we have mapped in locore. 415 */ 416 addr = atdevbase; 417 (void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0, 418 &addr, (0x100000-0xa0000), FALSE); --- 250 unchanged lines hidden (view full) --- 669 vm_page_t m; 670 /* 671 * we do this to keep recursion away 672 */ 673 pv_freelistcnt += PV_FREELIST_MIN; 674 /* 675 * allocate a physical page out of the vm system 676 */ |
680 if (m = vm_page_alloc(kernel_object, pvva-vm_map_min(kernel_map))) { | 677 m = vm_page_alloc(kernel_object, pvva-vm_map_min(kernel_map)); 678 if (m) { |
681 int newentries; 682 int i; 683 pv_entry_t entry; 684 newentries = (NBPG/sizeof (struct pv_entry)); 685 /* 686 * wire the page 687 */ 688 vm_page_wire(m); --- 75 unchanged lines hidden (view full) --- 764 */ 765void 766pmap_remove_entry(pmap, pv, va) 767 struct pmap *pmap; 768 pv_entry_t pv; 769 vm_offset_t va; 770{ 771 pv_entry_t npv; | 679 int newentries; 680 int i; 681 pv_entry_t entry; 682 newentries = (NBPG/sizeof (struct pv_entry)); 683 /* 684 * wire the page 685 */ 686 vm_page_wire(m); --- 75 unchanged lines hidden (view full) --- 762 */ 763void 764pmap_remove_entry(pmap, pv, va) 765 struct pmap *pmap; 766 pv_entry_t pv; 767 vm_offset_t va; 768{ 769 pv_entry_t npv; |
772 int wired; | |
773 int s; 774 s = splhigh(); 775 if (pmap == pv->pv_pmap && va == pv->pv_va) { 776 npv = pv->pv_next; 777 if (npv) { 778 *pv = *npv; 779 free_pv_entry(npv); 780 } else { --- 94 unchanged lines hidden (view full) --- 875 /* 876 * Weed out invalid mappings. 877 * Note: we assume that the page directory table is 878 * always allocated, and in kernel virtual. 879 */ 880 881 if ( *pmap_pde(pmap, i386_ptob(sva)) == 0 ) { 882 /* We can race ahead here, straight to next pde.. */ | 770 int s; 771 s = splhigh(); 772 if (pmap == pv->pv_pmap && va == pv->pv_va) { 773 npv = pv->pv_next; 774 if (npv) { 775 *pv = *npv; 776 free_pv_entry(npv); 777 } else { --- 94 unchanged lines hidden (view full) --- 872 /* 873 * Weed out invalid mappings. 874 * Note: we assume that the page directory table is 875 * always allocated, and in kernel virtual. 876 */ 877 878 if ( *pmap_pde(pmap, i386_ptob(sva)) == 0 ) { 879 /* We can race ahead here, straight to next pde.. */ |
883 nextpde: | |
884 sva = ((sva + NPTEPG) & ~(NPTEPG - 1)); 885 continue; 886 } 887 888 ptq = ptp + sva; 889 890 /* 891 * search for page table entries, use string operations --- 81 unchanged lines hidden (view full) --- 973void 974pmap_remove_all(pa) 975 vm_offset_t pa; 976{ 977 register pv_entry_t pv, npv; 978 register pt_entry_t *pte, *ptp; 979 vm_offset_t va; 980 struct pmap *pmap; | 880 sva = ((sva + NPTEPG) & ~(NPTEPG - 1)); 881 continue; 882 } 883 884 ptq = ptp + sva; 885 886 /* 887 * search for page table entries, use string operations --- 81 unchanged lines hidden (view full) --- 969void 970pmap_remove_all(pa) 971 vm_offset_t pa; 972{ 973 register pv_entry_t pv, npv; 974 register pt_entry_t *pte, *ptp; 975 vm_offset_t va; 976 struct pmap *pmap; |
981 struct map *map; | |
982 vm_page_t m; 983 int s; 984 int anyvalid = 0; 985 986 /* 987 * Not one of ours 988 */ 989 if (!pmap_is_managed(pa)) --- 54 unchanged lines hidden (view full) --- 1044 vm_offset_t sva, eva; 1045 vm_prot_t prot; 1046{ 1047 register pt_entry_t *pte; 1048 register vm_offset_t va; 1049 int i386prot; 1050 register pt_entry_t *ptp; 1051 int evap = i386_btop(eva); | 977 vm_page_t m; 978 int s; 979 int anyvalid = 0; 980 981 /* 982 * Not one of ours 983 */ 984 if (!pmap_is_managed(pa)) --- 54 unchanged lines hidden (view full) --- 1039 vm_offset_t sva, eva; 1040 vm_prot_t prot; 1041{ 1042 register pt_entry_t *pte; 1043 register vm_offset_t va; 1044 int i386prot; 1045 register pt_entry_t *ptp; 1046 int evap = i386_btop(eva); |
1052 int s; | |
1053 int anyvalid = 0;; 1054 1055 if (pmap == NULL) 1056 return; 1057 1058 if ((prot & VM_PROT_READ) == VM_PROT_NONE) { 1059 pmap_remove(pmap, sva, eva); 1060 return; --- 112 unchanged lines hidden (view full) --- 1173 */ 1174 if (opa == pa) { 1175 /* 1176 * Wiring change, just update stats. 1177 * We don't worry about wiring PT pages as they remain 1178 * resident as long as there are valid mappings in them. 1179 * Hence, if a user page is wired, the PT page will be also. 1180 */ | 1047 int anyvalid = 0;; 1048 1049 if (pmap == NULL) 1050 return; 1051 1052 if ((prot & VM_PROT_READ) == VM_PROT_NONE) { 1053 pmap_remove(pmap, sva, eva); 1054 return; --- 112 unchanged lines hidden (view full) --- 1167 */ 1168 if (opa == pa) { 1169 /* 1170 * Wiring change, just update stats. 1171 * We don't worry about wiring PT pages as they remain 1172 * resident as long as there are valid mappings in them. 1173 * Hence, if a user page is wired, the PT page will be also. 1174 */ |
1181 if (wired && !pmap_pte_w(pte) || !wired && pmap_pte_w(pte)) { 1182 if (wired) 1183 pmap->pm_stats.wired_count++; 1184 else 1185 pmap->pm_stats.wired_count--; 1186 } | 1175 if (wired && !pmap_pte_w(pte)) 1176 pmap->pm_stats.wired_count++; 1177 else if (!wired && pmap_pte_w(pte)) 1178 pmap->pm_stats.wired_count--; 1179 |
1187 goto validate; 1188 } 1189 1190 /* 1191 * Mapping has changed, invalidate old range and fall through to 1192 * handle validating new mapping. 1193 */ 1194 if (opa) { --- 230 unchanged lines hidden (view full) --- 1425 1426 pmap_use_pt(pmap, va); 1427 1428 /* 1429 * Increment counters 1430 */ 1431 pmap->pm_stats.resident_count++; 1432 | 1180 goto validate; 1181 } 1182 1183 /* 1184 * Mapping has changed, invalidate old range and fall through to 1185 * handle validating new mapping. 1186 */ 1187 if (opa) { --- 230 unchanged lines hidden (view full) --- 1418 1419 pmap_use_pt(pmap, va); 1420 1421 /* 1422 * Increment counters 1423 */ 1424 pmap->pm_stats.resident_count++; 1425 |
1433validate: 1434 | |
1435 if (*pte) 1436 anyvalid++; 1437 /* 1438 * Now validate mapping with desired protection/wiring. 1439 */ 1440 *pte = (pt_entry_t) ( (int) (pa | PG_V | PG_u)); 1441 1442 return (anyvalid); --- 10 unchanged lines hidden (view full) --- 1453 vm_offset_t addr; 1454 vm_object_t object; 1455 vm_offset_t offset; 1456 vm_offset_t size; 1457{ 1458 1459 vm_offset_t tmpoff; 1460 vm_page_t p; | 1426 if (*pte) 1427 anyvalid++; 1428 /* 1429 * Now validate mapping with desired protection/wiring. 1430 */ 1431 *pte = (pt_entry_t) ( (int) (pa | PG_V | PG_u)); 1432 1433 return (anyvalid); --- 10 unchanged lines hidden (view full) --- 1444 vm_offset_t addr; 1445 vm_object_t object; 1446 vm_offset_t offset; 1447 vm_offset_t size; 1448{ 1449 1450 vm_offset_t tmpoff; 1451 vm_page_t p; |
1461 int s; 1462 vm_offset_t v, lastv=0; 1463 pt_entry_t pte; | 1452 vm_offset_t v; |
1464 vm_offset_t objbytes; 1465 int anyvalid = 0; 1466 1467 if (!pmap) 1468 return; 1469 1470 /* 1471 * if we are processing a major portion of the object, then --- 25 unchanged lines hidden (view full) --- 1497 p = p->listq.tqe_next; 1498 objbytes -= NBPG; 1499 } 1500 } else { 1501 /* 1502 * else lookup the pages one-by-one. 1503 */ 1504 for(tmpoff = 0; tmpoff < size; tmpoff += NBPG) { | 1453 vm_offset_t objbytes; 1454 int anyvalid = 0; 1455 1456 if (!pmap) 1457 return; 1458 1459 /* 1460 * if we are processing a major portion of the object, then --- 25 unchanged lines hidden (view full) --- 1486 p = p->listq.tqe_next; 1487 objbytes -= NBPG; 1488 } 1489 } else { 1490 /* 1491 * else lookup the pages one-by-one. 1492 */ 1493 for(tmpoff = 0; tmpoff < size; tmpoff += NBPG) { |
1505 if( p = vm_page_lookup(object, tmpoff + offset)) { | 1494 p = vm_page_lookup(object, tmpoff + offset); 1495 if (p) { |
1506 if( (p->flags & (PG_BUSY|PG_FICTITIOUS)) == 0) { 1507 vm_page_hold(p); 1508 v = i386_trunc_page(((vm_offset_t)vtopte( addr+tmpoff))); 1509 /* a fault might occur here */ 1510 *(volatile char *)v += 0; 1511 vm_page_unhold(p); 1512 anyvalid += pmap_enter_quick(pmap, addr+tmpoff, VM_PAGE_TO_PHYS(p)); 1513 } --- 19 unchanged lines hidden (view full) --- 1533 boolean_t wired; 1534{ 1535 register pt_entry_t *pte; 1536 1537 if (pmap == NULL) 1538 return; 1539 1540 pte = pmap_pte(pmap, va); | 1496 if( (p->flags & (PG_BUSY|PG_FICTITIOUS)) == 0) { 1497 vm_page_hold(p); 1498 v = i386_trunc_page(((vm_offset_t)vtopte( addr+tmpoff))); 1499 /* a fault might occur here */ 1500 *(volatile char *)v += 0; 1501 vm_page_unhold(p); 1502 anyvalid += pmap_enter_quick(pmap, addr+tmpoff, VM_PAGE_TO_PHYS(p)); 1503 } --- 19 unchanged lines hidden (view full) --- 1523 boolean_t wired; 1524{ 1525 register pt_entry_t *pte; 1526 1527 if (pmap == NULL) 1528 return; 1529 1530 pte = pmap_pte(pmap, va); |
1541 if (wired && !pmap_pte_w(pte) || !wired && pmap_pte_w(pte)) { 1542 if (wired) 1543 pmap->pm_stats.wired_count++; 1544 else 1545 pmap->pm_stats.wired_count--; 1546 } | 1531 1532 if (wired && !pmap_pte_w(pte)) 1533 pmap->pm_stats.wired_count++; 1534 else if (!wired && pmap_pte_w(pte)) 1535 pmap->pm_stats.wired_count--; 1536 |
1547 /* 1548 * Wiring is not a hardware characteristic so there is no need 1549 * to invalidate TLB. 1550 */ 1551 pmap_pte_set_w(pte, wired); 1552 /* 1553 * When unwiring, set the modified bit in the pte -- could have 1554 * been changed by the kernel --- 456 unchanged lines hidden --- | 1537 /* 1538 * Wiring is not a hardware characteristic so there is no need 1539 * to invalidate TLB. 1540 */ 1541 pmap_pte_set_w(pte, wired); 1542 /* 1543 * When unwiring, set the modified bit in the pte -- could have 1544 * been changed by the kernel --- 456 unchanged lines hidden --- |