Author: marcel
Date: Sat Jul 16 20:34:02 2011
New Revision: 224116
URL: http://svn.freebsd.org/changeset/base/224116

Log:
  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.

Modified:
  head/sys/ia64/ia64/pmap.c

Modified: head/sys/ia64/ia64/pmap.c
==============================================================================
--- head/sys/ia64/ia64/pmap.c   Sat Jul 16 20:31:29 2011        (r224115)
+++ head/sys/ia64/ia64/pmap.c   Sat Jul 16 20:34:02 2011        (r224116)
@@ -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);
 }
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to