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 ---