Index: sys/dev/efidev/efirt.c
===================================================================
--- sys/dev/efidev/efirt.c
+++ sys/dev/efidev/efirt.c
@@ -60,6 +60,10 @@
 
 static struct efi_systbl *efi_systbl;
 static eventhandler_tag efi_shutdown_tag;
+static struct efi_map_header *efihdr;
+static size_t efi_hdr_sz;
+static struct efi_md *efi_map;
+static int efi_map_ndesc;
 /*
  * The following pointers point to tables in the EFI runtime service data pages.
  * Care should be taken to make sure that we've properly entered the EFI runtime
@@ -133,6 +137,88 @@
 	return (false);
 }
 
+static int
+efi_map_compare(const void *key, const void *member)
+{
+	uint64_t pa;
+	const struct efi_md *md;
+
+	pa = *(const uint64_t *)key;
+	md = (const struct efi_md *)member;
+
+	if (pa >= (uintptr_t)md->md_phys &&
+	  pa < (uintptr_t)md->md_phys + md->md_pages * PAGE_SIZE)
+		return (0);
+	if (pa < (uintptr_t)md->md_phys)
+		return (-1);
+	return (1);
+}
+
+static int
+efi_map_qsort_compare(const void *p1, const void *p2)
+{
+	const struct efi_md *md1;
+	const struct efi_md *md2;
+
+	md1 = (const struct efi_md *)p1;
+	md2 = (const struct efi_md *)p2;
+	return (((uintptr_t)md1->md_phys > (uintptr_t)md2->md_phys) - 
+	    ((uintptr_t)md1->md_phys < (uintptr_t)md2->md_phys));
+}
+
+static bool
+efi_get_memory_map(void)
+{
+	caddr_t kmdp;
+
+	if (efi_map != NULL)
+		return (true);
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		kmdp = preload_search_by_type("elf64 kernel");
+	efihdr = (struct efi_map_header *)preload_search_info(kmdp,
+	    MODINFO_METADATA | MODINFOMD_EFI_MAP);
+	if (efihdr == NULL)
+		return (false);
+	efi_hdr_sz = roundup2(sizeof(struct efi_map_header), 16);
+	efi_map = (struct efi_md *)((uint8_t *)efihdr + efi_hdr_sz);
+	if (efihdr->descriptor_size == 0)
+		return (false);
+	efi_map_ndesc = efihdr->memory_size / efihdr->descriptor_size;
+	qsort(efi_map, efi_map_ndesc, efihdr->descriptor_size,
+	    efi_map_qsort_compare);
+	return (true);
+}
+
+uint64_t
+efi_memory_attribute(vm_paddr_t pa, vm_paddr_t *out)
+{
+	struct efi_md *p, *n;
+
+	if (!efi_get_memory_map())
+		return (0);
+	p = bsearch(&pa, efi_map, efi_map_ndesc, efihdr->descriptor_size,
+	  efi_map_compare);
+	if (p == NULL)
+		return (EFI_MD_ATTR_UC);
+	if (out == NULL)
+		return (p->md_attr);
+	*out = pa + (p->md_pages - 1) * PAGE_SIZE;
+	n = p;
+	do {
+		pa += n->md_pages * PAGE_SIZE;
+		n = bsearch(&pa, efi_map, efi_map_ndesc,
+		  efihdr->descriptor_size, efi_map_compare);
+		if (n == NULL)
+			break;
+		if (n->md_attr == p->md_attr)
+			*out = pa + (n->md_pages - 1) * PAGE_SIZE;
+		else
+			break;
+	} while (1);
+	return (p->md_attr);
+}
+
 static void
 efi_shutdown_final(void *dummy __unused, int howto)
 {
@@ -149,12 +235,8 @@
 static int
 efi_init(void)
 {
-	struct efi_map_header *efihdr;
-	struct efi_md *map;
 	struct efi_rt *rtdm;
-	caddr_t kmdp;
-	size_t efisz;
-	int ndesc, rt_disabled;
+	int rt_disabled;
 
 	rt_disabled = 0;
 	TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled);
@@ -182,23 +264,13 @@
 			printf("EFI config table is not present\n");
 	}
 
-	kmdp = preload_search_by_type("elf kernel");
-	if (kmdp == NULL)
-		kmdp = preload_search_by_type("elf64 kernel");
-	efihdr = (struct efi_map_header *)preload_search_info(kmdp,
-	    MODINFO_METADATA | MODINFOMD_EFI_MAP);
-	if (efihdr == NULL) {
+	if (!efi_get_memory_map()) {
 		if (bootverbose)
 			printf("EFI map is not present\n");
 		return (0);
 	}
-	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
-	map = (struct efi_md *)((uint8_t *)efihdr + efisz);
-	if (efihdr->descriptor_size == 0)
-		return (ENOMEM);
 
-	ndesc = efihdr->memory_size / efihdr->descriptor_size;
-	if (!efi_create_1t1_map(map, ndesc, efihdr->descriptor_size)) {
+	if (!efi_create_1t1_map(efi_map, efi_map_ndesc, efihdr->descriptor_size)) {
 		if (bootverbose)
 			printf("EFI cannot create runtime map\n");
 		return (ENOMEM);
@@ -223,8 +295,8 @@
 	 * the EFI map, and fail to attach if not.
 	 */
 	rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime);
-	if (rtdm == NULL || !efi_is_in_map(map, ndesc, efihdr->descriptor_size,
-	    (vm_offset_t)rtdm->rt_gettime)) {
+	if (rtdm == NULL || !efi_is_in_map(efi_map, efi_map_ndesc,
+	    efihdr->descriptor_size, (vm_offset_t)rtdm->rt_gettime)) {
 		if (bootverbose)
 			printf(
 			 "EFI runtime services table has an invalid pointer\n");
@@ -234,6 +306,23 @@
 	}
 #endif
 
+	if (bootverbose) {
+		printf("EFI RT Signature: %jx, Revision=%x, Size=%x, CRC32=%x\n",
+		    efi_runtime->rt_hdr.th_sig,
+		    efi_runtime->rt_hdr.th_rev,
+		    efi_runtime->rt_hdr.th_hdrsz,
+		    efi_runtime->rt_hdr.th_crc32);
+		printf("EFI RT Get Time: %p\n", efi_runtime->rt_gettime);
+		printf("EFI RT Set Time: %p\n", efi_runtime->rt_settime);
+		printf("EFI RT Get Wakeup Time: %p\n",
+		    efi_runtime->rt_getwaketime);
+		printf("EFI RT Set Wakeup Time: %p\n",
+		    efi_runtime->rt_setwaketime);
+		printf("EFI RT Get Var: %p\n", efi_runtime->rt_getvar);
+		printf("EFI RT Get Next Var: %p\n", efi_runtime->rt_scanvar);
+		printf("EFI RT Set Var: %p\n", efi_runtime->rt_setvar);
+	}
+
 	/*
 	 * We use SHUTDOWN_PRI_LAST - 1 to trigger after IPMI, but before ACPI.
 	 */
Index: sys/sys/efi.h
===================================================================
--- sys/sys/efi.h
+++ sys/sys/efi.h
@@ -192,6 +192,7 @@
 int efi_var_nextname(size_t *namesize, uint16_t *name, struct uuid *vendor);
 int efi_var_set(uint16_t *name, struct uuid *vendor, uint32_t attrib,
     size_t datasize, void *data);
+uint64_t efi_memory_attribute(vm_paddr_t pa, vm_paddr_t *out);
 
 #endif	/* _KERNEL */