diff options
Diffstat (limited to 'i386/i386/phys.c')
-rw-r--r-- | i386/i386/phys.c | 109 |
1 files changed, 93 insertions, 16 deletions
diff --git a/i386/i386/phys.c b/i386/i386/phys.c index ed4a309a..d55bdd9d 100644 --- a/i386/i386/phys.c +++ b/i386/i386/phys.c @@ -37,30 +37,74 @@ #include <vm/vm_page.h> #include <i386/pmap.h> +#include <i386/model_dep.h> #include <mach/machine/vm_param.h> +#define INTEL_PTE_W(p) (INTEL_PTE_VALID | INTEL_PTE_WRITE | INTEL_PTE_REF | INTEL_PTE_MOD | pa_to_pte(p)) +#define INTEL_PTE_R(p) (INTEL_PTE_VALID | INTEL_PTE_REF | pa_to_pte(p)) + /* * pmap_zero_page zeros the specified (machine independent) page. */ void -pmap_zero_page(p) - vm_offset_t p; +pmap_zero_page(vm_offset_t p) { assert(p != vm_page_fictitious_addr); - memset((void *)phystokv(p), 0, PAGE_SIZE); + vm_offset_t v; + pmap_mapwindow_t *map; + boolean_t mapped = p >= phys_last_addr; + + if (mapped) + { + map = pmap_get_mapwindow(INTEL_PTE_W(p)); + v = map->vaddr; + } + else + v = phystokv(p); + + memset((void*) v, 0, PAGE_SIZE); + + if (mapped) + pmap_put_mapwindow(map); } /* * pmap_copy_page copies the specified (machine independent) pages. */ void -pmap_copy_page(src, dst) - vm_offset_t src, dst; +pmap_copy_page( + vm_offset_t src, + vm_offset_t dst) { + vm_offset_t src_addr_v, dst_addr_v; + pmap_mapwindow_t *src_map, *dst_map; + boolean_t src_mapped = src >= phys_last_addr; + boolean_t dst_mapped = dst >= phys_last_addr; assert(src != vm_page_fictitious_addr); assert(dst != vm_page_fictitious_addr); - memcpy((void *)phystokv(dst), (void *)phystokv(src), PAGE_SIZE); + if (src_mapped) + { + src_map = pmap_get_mapwindow(INTEL_PTE_R(src)); + src_addr_v = src_map->vaddr; + } + else + src_addr_v = phystokv(src); + + if (dst_mapped) + { + dst_map = pmap_get_mapwindow(INTEL_PTE_W(dst)); + dst_addr_v = dst_map->vaddr; + } + else + dst_addr_v = phystokv(dst); + + memcpy((void *) dst_addr_v, (void *) src_addr_v, PAGE_SIZE); + + if (src_mapped) + pmap_put_mapwindow(src_map); + if (dst_mapped) + pmap_put_mapwindow(dst_map); } /* @@ -69,12 +113,29 @@ pmap_copy_page(src, dst) * Copy virtual memory to physical memory */ void -copy_to_phys(src_addr_v, dst_addr_p, count) - vm_offset_t src_addr_v, dst_addr_p; - int count; +copy_to_phys( + vm_offset_t src_addr_v, + vm_offset_t dst_addr_p, + int count) { + vm_offset_t dst_addr_v; + pmap_mapwindow_t *dst_map; + boolean_t mapped = dst_addr_p >= phys_last_addr; assert(dst_addr_p != vm_page_fictitious_addr); - memcpy((void *)phystokv(dst_addr_p), (void *)src_addr_v, count); + assert(pa_to_pte(dst_addr_p + count-1) == pa_to_pte(dst_addr_p)); + + if (mapped) + { + dst_map = pmap_get_mapwindow(INTEL_PTE_W(dst_addr_p)); + dst_addr_v = dst_map->vaddr; + } + else + dst_addr_v = phystokv(dst_addr_p); + + memcpy((void *)dst_addr_v, (void *)src_addr_v, count); + + if (mapped) + pmap_put_mapwindow(dst_map); } /* @@ -84,12 +145,29 @@ copy_to_phys(src_addr_v, dst_addr_p, count) * is assumed to be present (e.g. the buffer pool). */ void -copy_from_phys(src_addr_p, dst_addr_v, count) - vm_offset_t src_addr_p, dst_addr_v; - int count; +copy_from_phys( + vm_offset_t src_addr_p, + vm_offset_t dst_addr_v, + int count) { + vm_offset_t src_addr_v; + pmap_mapwindow_t *src_map; + boolean_t mapped = src_addr_p >= phys_last_addr; assert(src_addr_p != vm_page_fictitious_addr); - memcpy((void *)dst_addr_v, (void *)phystokv(src_addr_p), count); + assert(pa_to_pte(src_addr_p + count-1) == pa_to_pte(src_addr_p)); + + if (mapped) + { + src_map = pmap_get_mapwindow(INTEL_PTE_R(src_addr_p)); + src_addr_v = src_map->vaddr; + } + else + src_addr_v = phystokv(src_addr_p); + + memcpy((void *)dst_addr_v, (void *)src_addr_v, count); + + if (mapped) + pmap_put_mapwindow(src_map); } /* @@ -98,8 +176,7 @@ copy_from_phys(src_addr_p, dst_addr_v, count) * Convert a kernel virtual address to a physical address */ vm_offset_t -kvtophys(addr) -vm_offset_t addr; +kvtophys(vm_offset_t addr) { pt_entry_t *pte; |