diff options
author | Marcel Moolenaar <marcel@FreeBSD.org> | 2011-07-16 20:34:02 +0000 |
---|---|---|
committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2011-07-16 20:34:02 +0000 |
commit | 08f72ab5dc95696336c46d626e71f97b5097c8f1 (patch) | |
tree | 0efdbda9581aa7379cc6727c9cf9dc8dc12dccdc /sys | |
parent | ae78a2ad864ff3ef2d5397b74bb6c64fdaa1d9bc (diff) | |
download | src-08f72ab5dc95696336c46d626e71f97b5097c8f1.tar.gz src-08f72ab5dc95696336c46d626e71f97b5097c8f1.zip |
Don't assume pmap_mapdev() gets called only for memory mapped I/O
addresses (i.e. uncacheable). ACPI in particular uses pmap_mapdev()
rather excessively (number of calls) just to get a valid KVA. To
that end, have pmap_mapdev():
1. cache the last result so that we don't waste time for multiple
consecutive invocations with the same PA/SZ.
2. find the memory descriptor that covers the PA and return NULL
if none was found or when the PA is for a common DRAM address.
3. Use either a region 6 or region 7 KVA, in accordance with the
memory attribute.
Notes
Notes:
svn path=/head/; revision=224116
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ia64/ia64/pmap.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index f8f86b633a92..0e34f36ccaca 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> #include <machine/bootinfo.h> +#include <machine/efi.h> #include <machine/md_var.h> #include <machine/pal.h> @@ -2235,12 +2236,37 @@ pmap_remove_write(vm_page_t m) * NOT real memory. */ void * -pmap_mapdev(vm_paddr_t pa, vm_size_t size) +pmap_mapdev(vm_paddr_t pa, vm_size_t sz) { + static void *last_va = NULL; + static vm_paddr_t last_pa = 0; + static vm_size_t last_sz = 0; + struct efi_md *md; vm_offset_t va; - va = pa | IA64_RR_BASE(6); - return ((void *)va); + if (pa == last_pa && sz == last_sz) + return (last_va); + + md = efi_md_find(pa); + if (md == NULL) { + printf("%s: [%#lx..%#lx] not covered by memory descriptor\n", + __func__, pa, pa + sz - 1); + return (NULL); + } + + if (md->md_type == EFI_MD_TYPE_FREE) { + printf("%s: [%#lx..%#lx] is in DRAM\n", __func__, pa, + pa + sz - 1); + return (NULL); + } + + va = (md->md_attr & EFI_MD_ATTR_WB) ? IA64_PHYS_TO_RR7(pa) : + IA64_PHYS_TO_RR6(pa); + + last_va = (void *)va; + last_pa = pa; + last_sz = sz; + return (last_va); } /* |