summaryrefslogtreecommitdiff
path: root/i386/intel/pmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'i386/intel/pmap.c')
-rw-r--r--i386/intel/pmap.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
index 2943d26..a3d9630 100644
--- a/i386/intel/pmap.c
+++ b/i386/intel/pmap.c
@@ -419,6 +419,12 @@ unsigned int inuse_ptepages_count = 0; /* debugging */
*/
pt_entry_t *kernel_page_dir;
+/*
+ * Two slots for temporary physical page mapping, to allow for
+ * physical-to-physical transfers.
+ */
+static pmap_mapwindow_t mapwindows[PMAP_NMAPWINDOWS];
+
static inline pt_entry_t *
pmap_pde(const pmap_t pmap, vm_offset_t addr)
{
@@ -774,6 +780,12 @@ void pmap_bootstrap(void)
}
for (; pte < ptable+NPTES; pte++)
{
+ if (va >= kernel_virtual_end - PMAP_NMAPWINDOWS * PAGE_SIZE);
+ {
+ pmap_mapwindow_t *win = &mapwindows[atop(va - (kernel_virtual_end - PMAP_NMAPWINDOWS * PAGE_SIZE))];
+ win->entry = pte;
+ win->vaddr = va;
+ }
WRITE_PTE(pte, 0);
va += INTEL_PGBYTES;
}
@@ -884,12 +896,41 @@ void pmap_clear_bootstrap_pagetable(pt_entry_t *base) {
}
#endif /* MACH_PV_PAGETABLES */
+/*
+ * Create a temporary mapping for a given physical entry
+ *
+ * This can be used to access physical pages which are not mapped 1:1 by
+ * phystokv().
+ */
+pmap_mapwindow_t *pmap_get_mapwindow(pt_entry_t entry)
+{
+ pmap_mapwindow_t *map;
+
+ /* Find an empty one. */
+ for (map = &mapwindows[0]; map < &mapwindows[sizeof (mapwindows) / sizeof (*mapwindows)]; map++)
+ if (!(*map->entry))
+ break;
+ assert(map < &mapwindows[sizeof (mapwindows) / sizeof (*mapwindows)]);
+
+ WRITE_PTE(map->entry, entry);
+ return map;
+}
+
+/*
+ * Destroy a temporary mapping for a physical entry
+ */
+void pmap_put_mapwindow(pmap_mapwindow_t *map)
+{
+ WRITE_PTE(map->entry, 0);
+ PMAP_UPDATE_TLBS(kernel_pmap, map->vaddr, map->vaddr + PAGE_SIZE);
+}
+
void pmap_virtual_space(startp, endp)
vm_offset_t *startp;
vm_offset_t *endp;
{
*startp = kernel_virtual_start;
- *endp = kernel_virtual_end;
+ *endp = kernel_virtual_end - PMAP_NMAPWINDOWS * PAGE_SIZE;
}
/*