summaryrefslogtreecommitdiff
path: root/i386/i386/phys.c
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386/phys.c')
-rw-r--r--i386/i386/phys.c109
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;