diff options
author | jake <jake@FreeBSD.org> | 2001-08-03 01:27:15 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2001-08-03 01:27:15 +0000 |
commit | 424df267d7c76fe41d53b31be0041cd58c2717a3 (patch) | |
tree | aab7228d4534136b1764f779fc604e31cb5f0fc6 | |
parent | 524b50ae8e992a1d0d73c543d7ca736b37fb27aa (diff) | |
download | FreeBSD-src-424df267d7c76fe41d53b31be0041cd58c2717a3.zip FreeBSD-src-424df267d7c76fe41d53b31be0041cd58c2717a3.tar.gz |
Move some code related to managing pv entries from the pmap module to
the pv module. It works now that vtophys for sttes works.
-rw-r--r-- | sys/sparc64/include/pmap.h | 7 | ||||
-rw-r--r-- | sys/sparc64/include/pv.h | 59 | ||||
-rw-r--r-- | sys/sparc64/sparc64/pmap.c | 178 | ||||
-rw-r--r-- | sys/sparc64/sparc64/pv.c | 166 |
4 files changed, 209 insertions, 201 deletions
diff --git a/sys/sparc64/include/pmap.h b/sys/sparc64/include/pmap.h index 1a57d0e..752decf 100644 --- a/sys/sparc64/include/pmap.h +++ b/sys/sparc64/include/pmap.h @@ -29,7 +29,6 @@ #ifndef _MACHINE_PMAP_H_ #define _MACHINE_PMAP_H_ -#include <sys/kobj.h> #include <machine/tte.h> #define PMAP_CONTEXT_MAX 8192 @@ -61,4 +60,10 @@ extern vm_offset_t phys_avail[]; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; +static __inline int +pmap_track_modified(vm_offset_t va) +{ + return ((va < clean_sva) || (va >= clean_eva)); +} + #endif /* !_MACHINE_PMAP_H_ */ diff --git a/sys/sparc64/include/pv.h b/sys/sparc64/include/pv.h index e36d3f8..4f2a729 100644 --- a/sys/sparc64/include/pv.h +++ b/sys/sparc64/include/pv.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2001 Jake Burkholder. - * All rights reserved. + * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,11 +9,14 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * 3. Berkeley Software Design Inc's name may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -23,6 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * from BSDI: pmap.c,v 1.28.2.15 2000/04/27 03:10:31 cp Exp * $FreeBSD$ */ @@ -39,6 +42,8 @@ #define TTE_DATA offsetof(struct tte, tte_data) #define TTE_TAG offsetof(struct tte, tte_tag) +#define PVH_FIRST offsetof(struct pv_head, pvh_first) + #define PV_OFF(pa) ((vm_offset_t)(pa) - avail_start) #define PV_INDEX(pa) (PV_OFF(pa) >> PAGE_SHIFT) #define PV_SHIFT (3) @@ -48,6 +53,15 @@ #define ldxp(pa) ldxa(pa, ASI_PHYS_USE_EC) #define stxp(pa, val) stxa(pa, ASI_PHYS_USE_EC, val) +struct pv_entry { + vm_offset_t pv_next; + vm_offset_t pv_prev; +}; + +struct pv_head { + vm_offset_t pvh_first; +}; + extern vm_offset_t pv_table; extern u_long pv_generation; @@ -58,9 +72,9 @@ pv_lookup(vm_offset_t pa) } static __inline vm_offset_t -pv_get_first(vm_offset_t pvh) +pvh_get_first(vm_offset_t pvh) { - return (ldxp(pvh)); + return (ldxp(pvh + PVH_FIRST)); } static __inline vm_offset_t @@ -95,9 +109,9 @@ pv_get_tte_tag(vm_offset_t pstp) }) static __inline void -pv_set_first(vm_offset_t pvh, vm_offset_t first) +pvh_set_first(vm_offset_t pvh, vm_offset_t first) { - stxp(pvh, first); + stxp(pvh + PVH_FIRST, first); } static __inline void @@ -115,18 +129,18 @@ pv_set_prev(vm_offset_t pstp, vm_offset_t prev) static __inline void pv_remove_phys(vm_offset_t pstp) { - vm_offset_t pv_next; - vm_offset_t pv_prev; - - pv_next = pv_get_next(pstp); - pv_prev = pv_get_prev(pstp); - if (pv_next != 0) - pv_set_prev(pv_next, pv_prev); - stxp(pv_prev, pv_next); + vm_offset_t next; + vm_offset_t prev; + + next = pv_get_next(pstp); + prev = pv_get_prev(pstp); + if (next != 0) + pv_set_next(next, prev); + stxp(prev, next); } static __inline void -pv_bit_clear(vm_offset_t pstp, u_long bits) +pv_atomic_bit_clear(vm_offset_t pstp, u_long bits) { vm_offset_t dp; vm_offset_t d1; @@ -143,7 +157,7 @@ pv_bit_clear(vm_offset_t pstp, u_long bits) } static __inline void -pv_bit_set(vm_offset_t pstp, u_long bits) +pv_atomic_bit_set(vm_offset_t pstp, u_long bits) { vm_offset_t dp; vm_offset_t d1; @@ -160,7 +174,7 @@ pv_bit_set(vm_offset_t pstp, u_long bits) } static __inline int -pv_bit_test(vm_offset_t pstp, u_long bits) +pv_atomic_bit_test(vm_offset_t pstp, u_long bits) { vm_offset_t dp; @@ -169,7 +183,14 @@ pv_bit_test(vm_offset_t pstp, u_long bits) } void pv_dump(vm_offset_t pvh); + void pv_insert(pmap_t pm, vm_offset_t pa, vm_offset_t va, struct stte *stp); void pv_remove_virt(struct stte *stp); +void pv_bit_clear(vm_page_t m, u_long bits); +void pv_bit_set(vm_page_t m, u_long bits); +int pv_bit_test(vm_page_t m, u_long bits); + +void pv_global_remove_all(vm_page_t m); + #endif /* !_MACHINE_PV_H_ */ diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index 556e4b0..b46b0be 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -135,22 +135,6 @@ static u_int pmap_context_base; static vm_offset_t CADDR1; static vm_offset_t CADDR2; -static __inline int -pmap_track_modified(vm_offset_t va) -{ - return ((va < clean_sva) || (va >= clean_eva)); -} - -/* - * Manipulate tte bits of all virtual to physical mappings for the given page. - */ -static void pmap_bit_clear(vm_page_t m, u_long bits); -static void pmap_bit_set(vm_page_t m, u_long bits); -static int pmap_bit_test(vm_page_t m, u_long bits); - -static void pmap_local_remove_all(vm_page_t m); -static void pmap_global_remove_all(vm_page_t m); - /* * Allocate and free hardware context numbers. */ @@ -251,12 +235,12 @@ pmap_bootstrap(vm_offset_t skpa, vm_offset_t ekva) * Allocate physical memory for the heads of the stte alias chains. */ sz = round_page(((avail_end - avail_start) >> PAGE_SHIFT) * - sizeof (vm_offset_t)); + sizeof(struct pv_head)); pv_table = pmap_bootstrap_alloc(sz); /* XXX */ avail_start += sz; - for (i = 0; i < sz; i += sizeof(vm_offset_t)) - stxp(pv_table + i, 0); + for (i = 0; i < sz; i += sizeof(struct pv_head)) + pvh_set_first(pv_table + i, 0); /* * Set the start and end of kva. The kernel is loaded at the first @@ -573,9 +557,9 @@ pmap_page_protect(vm_page_t m, vm_prot_t prot) if (m->flags & PG_FICTITIOUS || prot & VM_PROT_WRITE) return; if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) - pmap_bit_clear(m, TD_W); + pv_bit_clear(m, TD_W); else - pmap_global_remove_all(m); + pv_global_remove_all(m); } void @@ -584,157 +568,7 @@ pmap_clear_modify(vm_page_t m) if (m->flags & PG_FICTITIOUS) return; - pmap_bit_clear(m, TD_MOD); -} - -static void -pmap_bit_clear(vm_page_t m, u_long bits) -{ - vm_offset_t pstp; - vm_offset_t pvh; - vm_offset_t pa; - vm_offset_t va; - struct tte tte; - - pa = VM_PAGE_TO_PHYS(m); - pvh = pv_lookup(pa); - PV_LOCK(); -#ifdef notyet -restart: -#endif - for (pstp = pv_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { - tte = pv_get_tte(pstp); - KASSERT(TD_PA(tte.tte_data) == pa, - ("pmap_bit_clear: corrupt alias chain")); - if ((tte.tte_data & bits) == 0) - continue; - va = tte_get_va(tte); - if (bits == TD_W && !pmap_track_modified(va)) - continue; - if (bits == TD_W && tte.tte_data & TD_MOD) { - vm_page_dirty(m); - bits |= TD_MOD; - } - pv_bit_clear(pstp, bits); -#ifdef notyet - generation = pv_generation; - PV_UNLOCK(); - /* XXX pass function and parameter to ipi call */ - ipi_all(IPI_TLB_PAGE_DEMAP); - PV_LOCK(); - if (generation != pv_generation) - goto restart; -#else - tlb_page_demap(TLB_DTLB, tte_get_ctx(tte), va); -#endif - } - PV_UNLOCK(); -} - -static void -pmap_bit_set(vm_page_t m, u_long bits) -{ - vm_offset_t pstp; - vm_offset_t pvh; - vm_offset_t pa; - struct tte tte; - - pa = VM_PAGE_TO_PHYS(m); - pvh = pv_lookup(pa); - PV_LOCK(); -#ifdef notyet -restart: -#endif - for (pstp = pv_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { - tte = pv_get_tte(pstp); - KASSERT(TD_PA(tte.tte_data) == pa, - ("pmap_bit_set: corrupt alias chain")); - if (tte.tte_data & bits) - continue; - pv_bit_set(pstp, bits); -#ifdef notyet - generation = pv_generation; - PV_UNLOCK(); - /* XXX pass function and parameter to ipi call */ - ipi_all(IPI_TLB_PAGE_DEMAP); - PV_LOCK(); - if (generation != pv_generation) - goto restart; -#else - tlb_page_demap(TLB_DTLB, tte_get_ctx(tte), tte_get_va(tte)); -#endif - } - PV_UNLOCK(); -} - -static int -pmap_bit_test(vm_page_t m, u_long bits) -{ - vm_offset_t pstp; - vm_offset_t pvh; - vm_offset_t pa; - - pa = VM_PAGE_TO_PHYS(m); - pvh = pv_lookup(pa); - PV_LOCK(); - for (pstp = pv_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { - if (pv_bit_test(pstp, bits)) { - PV_UNLOCK(); - return (1); - } - } - PV_UNLOCK(); - return (0); -} - -static void -pmap_global_remove_all(vm_page_t m) -{ - vm_offset_t pstp; - vm_offset_t pvh; - vm_offset_t pa; - - printf("pmap_global_remove_all\n"); - pa = VM_PAGE_TO_PHYS(m); - pvh = pv_lookup(pa); - pv_dump(pvh); - PV_LOCK(); - printf("pmap_global_remove_all: for\n"); - for (pstp = pv_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) - pv_bit_clear(pstp, TD_V); - printf("pmap_global_remove_all: done for\n"); - PV_UNLOCK(); - pmap_local_remove_all(m); - pv_dump(pvh); - PV_LOCK(); - printf("pmap_global_remove_all: while\n"); - while ((pstp = pv_get_first(pvh)) != 0) { - pv_dump(pvh); - pv_remove_phys(pstp); - } - printf("pmap_global_remove_all: done while\n"); - PV_UNLOCK(); - printf("pmap_global_remove_all: done\n"); -} - -static void -pmap_local_remove_all(vm_page_t m) -{ - vm_offset_t pstp; - vm_offset_t pvh; - vm_offset_t pa; - struct tte tte; - - pa = VM_PAGE_TO_PHYS(m); - pvh = pv_lookup(pa); - PV_LOCK(); - printf("pmap_local_remove_all: for\n"); - for (pstp = pv_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { - tte = pv_get_tte(pstp); - tsb_tte_local_remove(&tte); - } - printf("pmap_local_remove_all: done for\n"); - PV_UNLOCK(); + pv_bit_clear(m, TD_MOD); } void diff --git a/sys/sparc64/sparc64/pv.c b/sys/sparc64/sparc64/pv.c index 4affb53..ca2d29c 100644 --- a/sys/sparc64/sparc64/pv.c +++ b/sys/sparc64/sparc64/pv.c @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2001 Jake Burkholder. - * All rights reserved. + * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,11 +9,14 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * 3. Berkeley Software Design Inc's name may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -23,6 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * from BSDI: pmap.c,v 1.28.2.15 2000/04/27 03:10:31 cp Exp * $FreeBSD$ */ @@ -32,7 +35,8 @@ #include <vm/vm.h> #include <vm/vm_param.h> -#include <vm/pmap.h> +#include <vm/vm_kern.h> +#include <vm/vm_page.h> #include <machine/asi.h> #include <machine/frame.h> @@ -49,6 +53,11 @@ vm_offset_t pv_table; u_long pv_generation; +static void pv_local_remove_all(vm_offset_t pvh); + +/* + * Insert a mapped stte at the tail of an address alias chain. + */ void pv_insert(pmap_t pm, vm_offset_t pa, vm_offset_t va, struct stte *stp) { @@ -58,14 +67,17 @@ pv_insert(pmap_t pm, vm_offset_t pa, vm_offset_t va, struct stte *stp) pstp = tsb_stte_vtophys(pm, stp); pvh = pv_lookup(pa); PV_LOCK(); - if ((stp->st_next = pv_get_first(pvh)) != 0) + if ((stp->st_next = pvh_get_first(pvh)) != 0) pv_set_prev(stp->st_next, pstp + ST_NEXT); - pv_set_first(pvh, pstp); + pvh_set_first(pvh, pstp); stp->st_prev = pvh; pv_generation++; PV_UNLOCK(); } +/* + * Remove a mapped tte from its address alias chain. + */ void pv_remove_virt(struct stte *stp) { @@ -78,12 +90,148 @@ pv_remove_virt(struct stte *stp) } void +pv_bit_clear(vm_page_t m, u_long bits) +{ + vm_offset_t pstp; + vm_offset_t pvh; + vm_offset_t pa; + vm_offset_t va; + struct tte tte; + + pa = VM_PAGE_TO_PHYS(m); + pvh = pv_lookup(pa); + PV_LOCK(); +#ifdef notyet +restart: +#endif + for (pstp = pvh_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { + tte = pv_get_tte(pstp); + KASSERT(TD_PA(tte.tte_data) == pa, + ("pmap_bit_clear: corrupt alias chain")); + if ((tte.tte_data & bits) == 0) + continue; + va = tte_get_va(tte); + if (bits == TD_W && !pmap_track_modified(va)) + continue; + if (bits == TD_W && tte.tte_data & TD_MOD) { + vm_page_dirty(m); + bits |= TD_MOD; + } + pv_atomic_bit_clear(pstp, bits); +#ifdef notyet + generation = pv_generation; + PV_UNLOCK(); + /* XXX pass function and parameter to ipi call */ + ipi_all(IPI_TLB_PAGE_DEMAP); + PV_LOCK(); + if (generation != pv_generation) + goto restart; +#else + tlb_page_demap(TLB_DTLB, tte_get_ctx(tte), va); +#endif + } + PV_UNLOCK(); +} + +void +pv_bit_set(vm_page_t m, u_long bits) +{ + vm_offset_t pstp; + vm_offset_t pvh; + vm_offset_t pa; + struct tte tte; + + pa = VM_PAGE_TO_PHYS(m); + pvh = pv_lookup(pa); + PV_LOCK(); +#ifdef notyet +restart: +#endif + for (pstp = pvh_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { + tte = pv_get_tte(pstp); + KASSERT(TD_PA(tte.tte_data) == pa, + ("pmap_bit_set: corrupt alias chain")); + if (tte.tte_data & bits) + continue; + pv_atomic_bit_set(pstp, bits); +#ifdef notyet + generation = pv_generation; + PV_UNLOCK(); + /* XXX pass function and parameter to ipi call */ + ipi_all(IPI_TLB_PAGE_DEMAP); + PV_LOCK(); + if (generation != pv_generation) + goto restart; +#else + tlb_page_demap(TLB_DTLB, tte_get_ctx(tte), tte_get_va(tte)); +#endif + } + PV_UNLOCK(); +} + +int +pv_bit_test(vm_page_t m, u_long bits) +{ + vm_offset_t pstp; + vm_offset_t pvh; + vm_offset_t pa; + + pa = VM_PAGE_TO_PHYS(m); + pvh = pv_lookup(pa); + PV_LOCK(); + for (pstp = pvh_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { + if (pv_atomic_bit_test(pstp, bits)) { + PV_UNLOCK(); + return (1); + } + } + PV_UNLOCK(); + return (0); +} + +void +pv_global_remove_all(vm_page_t m) +{ + vm_offset_t pstp; + vm_offset_t pvh; + vm_offset_t pa; + + pa = VM_PAGE_TO_PHYS(m); + pvh = pv_lookup(pa); + PV_LOCK(); + pv_dump(pvh); + for (pstp = pvh_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) + pv_atomic_bit_clear(pstp, TD_V); + PV_UNLOCK(); + pv_local_remove_all(pvh); + PV_LOCK(); + while ((pstp = pvh_get_first(pvh)) != 0) + pv_remove_phys(pstp); + pv_dump(pvh); + PV_UNLOCK(); +} + +static void +pv_local_remove_all(vm_offset_t pvh) +{ + vm_offset_t pstp; + struct tte tte; + + PV_LOCK(); + for (pstp = pvh_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) { + tte = pv_get_tte(pstp); + tsb_tte_local_remove(&tte); + } + PV_UNLOCK(); +} + +void pv_dump(vm_offset_t pvh) { vm_offset_t pstp; - printf("pv_dump: pvh=%#lx first=%#lx\n", pvh, pv_get_first(pvh)); - for (pstp = pv_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) + printf("pv_dump: pvh=%#lx first=%#lx\n", pvh, pvh_get_first(pvh)); + for (pstp = pvh_get_first(pvh); pstp != 0; pstp = pv_get_next(pstp)) printf("\tpstp=%#lx next=%#lx prev=%#lx\n", pstp, pv_get_next(pstp), pv_get_prev(pstp)); printf("pv_dump: done\n"); |