summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-12-09 14:31:58 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-12-09 14:31:58 +0000
commit9542e90dfa3fb5369646f600c21d3c2863e6dd69 (patch)
treec86b4e53eaae863027ab437c751c813cf63bcf62 /sys/arch/i386
parent580e00e95ea51b295ec9285aca0df412609003ac (diff)
add two new MD only pmap apis to amd64 and i386 (not to be used in MI
code): pmap_flush_cache(vaddr_t, vsize_t) and pmap_flush_page(paddr_t) to flush the cache for virtual addresses and physical pages respectively using the clflush instruction. These apis will shortly be used by the agp bus_dma functions to avoid doing a wbinvd on each dmamap_sync. ok kettenis@, some comments from miod@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/pmap.c52
-rw-r--r--sys/arch/i386/include/pmap.h10
2 files changed, 58 insertions, 4 deletions
diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c
index 1dd8e011e9c..c8a00287213 100644
--- a/sys/arch/i386/i386/pmap.c
+++ b/sys/arch/i386/i386/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.145 2009/08/11 17:15:54 oga Exp $ */
+/* $OpenBSD: pmap.c,v 1.146 2009/12/09 14:31:57 oga Exp $ */
/* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */
/*
@@ -309,8 +309,8 @@ struct pool pmap_pmap_pool;
* special VAs and the PTEs that map them
*/
-static pt_entry_t *csrc_pte, *cdst_pte, *zero_pte, *ptp_pte;
-static caddr_t csrcp, cdstp, zerop, ptpp;
+static pt_entry_t *csrc_pte, *cdst_pte, *zero_pte, *ptp_pte, *flsh_pte;
+static caddr_t csrcp, cdstp, zerop, ptpp, flshp;
caddr_t vmmap; /* XXX: used by mem.c... it should really uvm_map_reserve it */
/* stuff to fix the pentium f00f bug */
@@ -863,6 +863,8 @@ pmap_bootstrap(vaddr_t kva_start)
ptpp = (caddr_t) virtual_avail+PAGE_SIZE*3; ptp_pte = pte+3;
+ flshp = (caddr_t) virtual_avail+PAGE_SIZE*4; flsh_pte = pte+4;
+
virtual_avail += PAGE_SIZE * MAXCPUS * NPTECL;
pte += MAXCPUS * NPTECL;
#else
@@ -877,6 +879,9 @@ pmap_bootstrap(vaddr_t kva_start)
ptpp = (caddr_t) virtual_avail; ptp_pte = pte;
virtual_avail += PAGE_SIZE; pte++;
+
+ flshp = (caddr_t) virtual_avail; flsh_pte = pte;
+ virtual_avail += PAGE_SIZE; pte++;
#endif
/* XXX: vmmap used by mem.c... should be uvm_map_reserve */
@@ -1799,6 +1804,47 @@ pmap_zero_page_uncached(paddr_t pa)
}
/*
+ * pmap_flush_cache: flush the cache for a virtual address.
+ */
+void
+pmap_flush_cache(vaddr_t addr, vsize_t len)
+{
+ vaddr_t i;
+
+ if (curcpu()->ci_cflushsz == 0) {
+ wbinvd();
+ return;
+ }
+
+ mfence();
+ for (i = addr; i < addr + len; i += curcpu()->ci_cflushsz)
+ clflush(i);
+ mfence();
+}
+
+void
+pmap_flush_page(paddr_t pa)
+{
+#ifdef MULTIPROCESSOR
+ int id = cpu_number();
+#endif
+ pt_entry_t *pte = PTESLEW(flsh_pte, id);
+ caddr_t va = VASLEW(flshp, id);
+
+ KDASSERT(PHYS_TO_VM_PAGE(pa) != NULL);
+#ifdef DIAGNOSTIC
+ if (*pte)
+ panic("pmap_flush_page: lock botch");
+#endif
+
+ *pte = (pa & PG_FRAME) | PG_V | PG_RW;
+ pmap_update_pg(va);
+ pmap_flush_cache((vaddr_t)va, PAGE_SIZE);
+ *pte = 0;
+ pmap_update_pg(va);
+}
+
+/*
* pmap_copy_page: copy a page
*/
diff --git a/sys/arch/i386/include/pmap.h b/sys/arch/i386/include/pmap.h
index c380b253d44..bd62351d892 100644
--- a/sys/arch/i386/include/pmap.h
+++ b/sys/arch/i386/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.53 2009/08/11 17:15:54 oga Exp $ */
+/* $OpenBSD: pmap.h,v 1.54 2009/12/09 14:31:57 oga Exp $ */
/* $NetBSD: pmap.h,v 1.44 2000/04/24 17:18:18 thorpej Exp $ */
/*
@@ -402,6 +402,14 @@ void pmap_tlb_shootwait(void);
void pmap_prealloc_lowmem_ptp(paddr_t);
+/*
+ * functions for flushing the cache for vaddrs and pages.
+ * these functions are not part of the MI pmap interface and thus
+ * should not be used as such.
+ */
+void pmap_flush_cache(vaddr_t, vsize_t);
+void pmap_flush_page(paddr_t);
+
#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */
/*