aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2011-07-16 20:34:02 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2011-07-16 20:34:02 +0000
commit08f72ab5dc95696336c46d626e71f97b5097c8f1 (patch)
tree0efdbda9581aa7379cc6727c9cf9dc8dc12dccdc /sys
parentae78a2ad864ff3ef2d5397b74bb6c64fdaa1d9bc (diff)
downloadsrc-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.c32
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);
}
/*