Deleted Added
full compact
pmap.c (88786) pmap.c (88826)
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 88786 2002-01-01 21:14:58Z jake $
42 * $FreeBSD: head/sys/sparc64/sparc64/pmap.c 88826 2002-01-02 18:49:20Z tmm $
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

--- 135 unchanged lines hidden (view full) ---

186static void pmap_context_destroy(u_int i);
187
188/*
189 * Allocate physical memory for use in pmap_bootstrap.
190 */
191static vm_offset_t pmap_bootstrap_alloc(vm_size_t size);
192
193/*
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

--- 135 unchanged lines hidden (view full) ---

186static void pmap_context_destroy(u_int i);
187
188/*
189 * Allocate physical memory for use in pmap_bootstrap.
190 */
191static vm_offset_t pmap_bootstrap_alloc(vm_size_t size);
192
193/*
194 * If user pmap is processed with pmap_remove and with pmap_remove and the
195 * resident count drops to 0, there are no more pages to remove, so we
196 * need not continue.
197 */
198#define PMAP_REMOVE_DONE(pm) \
199 ((pm) != kernel_pmap && (pm)->pm_stats.resident_count == 0)
200
201/*
202 * The threshold (in bytes) above which tsb_foreach() is used in pmap_remove()
203 * and pmap_protect() instead of trying each virtual address.
204 */
205#define PMAP_TSB_THRESH ((TSB_SIZE / 2) * PAGE_SIZE)
206
207/* Callbacks for tsb_foreach. */
208tsb_callback_t pmap_remove_tte;
209tsb_callback_t pmap_protect_tte;
210
211/*
194 * Quick sort callout for comparing memory regions.
195 */
196static int mr_cmp(const void *a, const void *b);
197static int om_cmp(const void *a, const void *b);
198static int
199mr_cmp(const void *a, const void *b)
200{
201 return ((const struct mem_region *)a)->mr_start -

--- 356 unchanged lines hidden (view full) ---

558 tlb_page_demap(TLB_DTLB, TLB_CTX_KERNEL, va);
559 *tp = tte;
560}
561
562/*
563 * Map a wired page into kernel virtual address space. This additionally
564 * takes a flag argument wich is or'ed to the TTE data. This is used by
565 * bus_space_map().
212 * Quick sort callout for comparing memory regions.
213 */
214static int mr_cmp(const void *a, const void *b);
215static int om_cmp(const void *a, const void *b);
216static int
217mr_cmp(const void *a, const void *b)
218{
219 return ((const struct mem_region *)a)->mr_start -

--- 356 unchanged lines hidden (view full) ---

576 tlb_page_demap(TLB_DTLB, TLB_CTX_KERNEL, va);
577 *tp = tte;
578}
579
580/*
581 * Map a wired page into kernel virtual address space. This additionally
582 * takes a flag argument wich is or'ed to the TTE data. This is used by
583 * bus_space_map().
584 * NOTE: if the mapping is non-cacheable, it's the caller's responsibility
585 * to flush entries that might still be in the cache, if applicable.
566 */
567void
568pmap_kenter_flags(vm_offset_t va, vm_offset_t pa, u_long flags)
569{
570 struct tte tte;
571 struct tte *tp;
572
573 tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va);

--- 68 unchanged lines hidden (view full) ---

642{
643 int i;
644
645 for (i = 0; i < count; i++, va += PAGE_SIZE)
646 pmap_kenter(va, VM_PAGE_TO_PHYS(m[i]));
647}
648
649/*
586 */
587void
588pmap_kenter_flags(vm_offset_t va, vm_offset_t pa, u_long flags)
589{
590 struct tte tte;
591 struct tte *tp;
592
593 tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va);

--- 68 unchanged lines hidden (view full) ---

662{
663 int i;
664
665 for (i = 0; i < count; i++, va += PAGE_SIZE)
666 pmap_kenter(va, VM_PAGE_TO_PHYS(m[i]));
667}
668
669/*
670 * As above, but take an additional flags argument and call
671 * pmap_kenter_flags().
672 */
673void
674pmap_qenter_flags(vm_offset_t va, vm_page_t *m, int count, u_long fl)
675{
676 int i;
677
678 for (i = 0; i < count; i++, va += PAGE_SIZE)
679 pmap_kenter_flags(va, VM_PAGE_TO_PHYS(m[i]), fl);
680}
681
682/*
650 * Remove page mappings from kernel virtual address space. Intended for
651 * temporary mappings entered by pmap_qenter.
652 */
653void
654pmap_qremove(vm_offset_t va, int count)
655{
656 int i;
657

--- 433 unchanged lines hidden (view full) ---

1091 if (m->wire_count || m->hold_count || m->busy ||
1092 (m->flags & (PG_BUSY | PG_UNMANAGED)))
1093 continue;
1094 pv_remove_all(m);
1095 }
1096 pmap_pagedaemon_waken = 0;
1097}
1098
683 * Remove page mappings from kernel virtual address space. Intended for
684 * temporary mappings entered by pmap_qenter.
685 */
686void
687pmap_qremove(vm_offset_t va, int count)
688{
689 int i;
690

--- 433 unchanged lines hidden (view full) ---

1124 if (m->wire_count || m->hold_count || m->busy ||
1125 (m->flags & (PG_BUSY | PG_UNMANAGED)))
1126 continue;
1127 pv_remove_all(m);
1128 }
1129 pmap_pagedaemon_waken = 0;
1130}
1131
1132int
1133pmap_remove_tte(struct pmap *pm, struct tte *tp, vm_offset_t va)
1134{
1135 vm_page_t m;
1136
1137 m = PHYS_TO_VM_PAGE(TD_GET_PA(tp->tte_data));
1138 if ((tp->tte_data & TD_PV) != 0) {
1139 if ((tp->tte_data & TD_W) != 0 &&
1140 pmap_track_modified(pm, va))
1141 vm_page_dirty(m);
1142 if ((tp->tte_data & TD_REF) != 0)
1143 vm_page_flag_set(m, PG_REFERENCED);
1144 pv_remove(pm, m, va);
1145 pmap_cache_remove(m, va);
1146 }
1147 atomic_clear_long(&tp->tte_data, TD_V);
1148 tp->tte_tag = 0;
1149 tp->tte_data = 0;
1150 tlb_page_demap(TLB_ITLB | TLB_DTLB,
1151 pm->pm_context, va);
1152 if (PMAP_REMOVE_DONE(pm))
1153 return (0);
1154 return (1);
1155}
1156
1099/*
1100 * Remove the given range of addresses from the specified map.
1101 */
1102void
1103pmap_remove(pmap_t pm, vm_offset_t start, vm_offset_t end)
1104{
1105 struct tte *tp;
1157/*
1158 * Remove the given range of addresses from the specified map.
1159 */
1160void
1161pmap_remove(pmap_t pm, vm_offset_t start, vm_offset_t end)
1162{
1163 struct tte *tp;
1106 vm_page_t m;
1107
1108 CTR3(KTR_PMAP, "pmap_remove: ctx=%#lx start=%#lx end=%#lx",
1109 pm->pm_context, start, end);
1164
1165 CTR3(KTR_PMAP, "pmap_remove: ctx=%#lx start=%#lx end=%#lx",
1166 pm->pm_context, start, end);
1110 for (; start < end; start += PAGE_SIZE) {
1111 if ((tp = tsb_tte_lookup(pm, start)) != NULL) {
1112 m = PHYS_TO_VM_PAGE(TD_GET_PA(tp->tte_data));
1113 if ((tp->tte_data & TD_PV) != 0) {
1114 if ((tp->tte_data & TD_W) != 0 &&
1115 pmap_track_modified(pm, start))
1116 vm_page_dirty(m);
1117 if ((tp->tte_data & TD_REF) != 0)
1118 vm_page_flag_set(m, PG_REFERENCED);
1119 pv_remove(pm, m, start);
1120 pmap_cache_remove(m, start);
1167 if (PMAP_REMOVE_DONE(pm))
1168 return;
1169 if (end - start > PMAP_TSB_THRESH)
1170 tsb_foreach(pm, start, end, pmap_remove_tte);
1171 else {
1172 for (; start < end; start += PAGE_SIZE) {
1173 if ((tp = tsb_tte_lookup(pm, start)) != NULL) {
1174 if (!pmap_remove_tte(pm, tp, start))
1175 break;
1121 }
1176 }
1122 atomic_clear_long(&tp->tte_data, TD_V);
1123 tp->tte_tag = 0;
1124 tp->tte_data = 0;
1125 tlb_page_demap(TLB_ITLB | TLB_DTLB,
1126 pm->pm_context, start);
1127 }
1128 }
1129}
1130
1177 }
1178 }
1179}
1180
1181int
1182pmap_protect_tte(struct pmap *pm, struct tte *tp, vm_offset_t va)
1183{
1184 vm_page_t m;
1185 u_long data;
1186
1187 data = tp->tte_data;
1188 if ((data & TD_PV) != 0) {
1189 m = PHYS_TO_VM_PAGE(TD_GET_PA(data));
1190 if ((data & TD_REF) != 0) {
1191 vm_page_flag_set(m, PG_REFERENCED);
1192 data &= ~TD_REF;
1193 }
1194 if ((data & TD_W) != 0 &&
1195 pmap_track_modified(pm, va)) {
1196 vm_page_dirty(m);
1197 }
1198 }
1199
1200 data &= ~(TD_W | TD_SW);
1201
1202 CTR2(KTR_PMAP, "pmap_protect: new=%#lx old=%#lx",
1203 data, tp->tte_data);
1204
1205 if (data != tp->tte_data) {
1206 CTR0(KTR_PMAP, "pmap_protect: demap");
1207 tlb_page_demap(TLB_DTLB | TLB_ITLB,
1208 pm->pm_context, va);
1209 tp->tte_data = data;
1210 }
1211 return (0);
1212}
1213
1131/*
1132 * Set the physical protection on the specified range of this map as requested.
1133 */
1134void
1135pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1136{
1137 struct tte *tp;
1214/*
1215 * Set the physical protection on the specified range of this map as requested.
1216 */
1217void
1218pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1219{
1220 struct tte *tp;
1138 vm_page_t m;
1139 u_long data;
1140
1141 CTR4(KTR_PMAP, "pmap_protect: ctx=%#lx sva=%#lx eva=%#lx prot=%#lx",
1142 pm->pm_context, sva, eva, prot);
1143
1144 KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
1145 ("pmap_protect: non current pmap"));
1146
1147 if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1148 pmap_remove(pm, sva, eva);
1149 return;
1150 }
1151
1152 if (prot & VM_PROT_WRITE)
1153 return;
1154
1221
1222 CTR4(KTR_PMAP, "pmap_protect: ctx=%#lx sva=%#lx eva=%#lx prot=%#lx",
1223 pm->pm_context, sva, eva, prot);
1224
1225 KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
1226 ("pmap_protect: non current pmap"));
1227
1228 if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1229 pmap_remove(pm, sva, eva);
1230 return;
1231 }
1232
1233 if (prot & VM_PROT_WRITE)
1234 return;
1235
1155 for (; sva < eva; sva += PAGE_SIZE) {
1156 if ((tp = tsb_tte_lookup(pm, sva)) != NULL) {
1157 data = tp->tte_data;
1158 if ((data & TD_PV) != 0) {
1159 m = PHYS_TO_VM_PAGE(TD_GET_PA(data));
1160 if ((data & TD_REF) != 0) {
1161 vm_page_flag_set(m, PG_REFERENCED);
1162 data &= ~TD_REF;
1163 }
1164 if ((data & TD_W) != 0 &&
1165 pmap_track_modified(pm, sva)) {
1166 vm_page_dirty(m);
1167 }
1168 }
1169
1170 data &= ~(TD_W | TD_SW);
1171
1172 CTR2(KTR_PMAP, "pmap_protect: new=%#lx old=%#lx",
1173 data, tp->tte_data);
1174
1175 if (data != tp->tte_data) {
1176 CTR0(KTR_PMAP, "pmap_protect: demap");
1177 tlb_page_demap(TLB_DTLB | TLB_ITLB,
1178 pm->pm_context, sva);
1179 tp->tte_data = data;
1180 }
1236 if (eva - sva > PMAP_TSB_THRESH)
1237 tsb_foreach(pm, sva, eva, pmap_protect_tte);
1238 else {
1239 for (; sva < eva; sva += PAGE_SIZE) {
1240 if ((tp = tsb_tte_lookup(pm, sva)) != NULL)
1241 pmap_protect_tte(pm, tp, sva);
1181 }
1182 }
1183}
1184
1185/*
1186 * Map the given physical page at the specified virtual address in the
1187 * target pmap with the protection requested. If specified the page
1188 * will be wired down.

--- 123 unchanged lines hidden (view full) ---

1312 tte.tte_data |= TD_W;
1313 }
1314 if (pm->pm_context == TLB_CTX_KERNEL)
1315 tte.tte_data |= TD_P;
1316 if (prot & VM_PROT_WRITE)
1317 tte.tte_data |= TD_SW;
1318 if (prot & VM_PROT_EXECUTE) {
1319 tte.tte_data |= TD_EXEC;
1242 }
1243 }
1244}
1245
1246/*
1247 * Map the given physical page at the specified virtual address in the
1248 * target pmap with the protection requested. If specified the page
1249 * will be wired down.

--- 123 unchanged lines hidden (view full) ---

1373 tte.tte_data |= TD_W;
1374 }
1375 if (pm->pm_context == TLB_CTX_KERNEL)
1376 tte.tte_data |= TD_P;
1377 if (prot & VM_PROT_WRITE)
1378 tte.tte_data |= TD_SW;
1379 if (prot & VM_PROT_EXECUTE) {
1380 tte.tte_data |= TD_EXEC;
1320#if 0
1321 icache_inval_phys(pa, pa + PAGE_SIZE - 1);
1381 icache_inval_phys(pa, pa + PAGE_SIZE - 1);
1322#endif
1323 }
1324
1325 if (tp != NULL)
1326 *tp = tte;
1327 else
1328 tsb_tte_enter(pm, m, va, tte);
1329}
1330

--- 290 unchanged lines hidden ---
1382 }
1383
1384 if (tp != NULL)
1385 *tp = tte;
1386 else
1387 tsb_tte_enter(pm, m, va, tte);
1388}
1389

--- 290 unchanged lines hidden ---