diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-12-09 14:31:58 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-12-09 14:31:58 +0000 |
commit | 9542e90dfa3fb5369646f600c21d3c2863e6dd69 (patch) | |
tree | c86b4e53eaae863027ab437c751c813cf63bcf62 /sys/arch/i386 | |
parent | 580e00e95ea51b295ec9285aca0df412609003ac (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.c | 52 | ||||
-rw-r--r-- | sys/arch/i386/include/pmap.h | 10 |
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 */ /* |