Index: sys/dev/efidev/efirt.c =================================================================== --- sys/dev/efidev/efirt.c +++ sys/dev/efidev/efirt.c @@ -60,6 +60,7 @@ static struct efi_systbl *efi_systbl; static eventhandler_tag efi_shutdown_tag; +static struct efi_map_header *efihdr; /* * 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 +134,50 @@ return (false); } +static bool +efi_get_memory_map(void) +{ + caddr_t kmdp; + + if (efihdr != 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); + return (true); +} + +uint64_t +efi_memory_attribute(vm_paddr_t pa) +{ + struct efi_md *map, *p; + size_t efisz; + int i, ndesc; + + if (!efi_get_memory_map()) + return (0); + + efisz = roundup2(sizeof(struct efi_map_header), 16); + map = (struct efi_md *)((uint8_t *)efihdr + efisz); + if (efihdr->descriptor_size == 0) + return (0); + ndesc = efihdr->memory_size / efihdr->descriptor_size; + + for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p, + efihdr->descriptor_size)) { + if (pa >= p->md_phys && + pa < p->md_phys + p->md_pages * PAGE_SIZE) { + return (p->md_attr); + } + } + + return (EFI_MD_ATTR_UC); +} + static void efi_shutdown_final(void *dummy __unused, int howto) { @@ -149,10 +194,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; @@ -182,17 +225,12 @@ 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; + efisz = roundup2(sizeof(struct efi_map_header), 16); map = (struct efi_md *)((uint8_t *)efihdr + efisz); if (efihdr->descriptor_size == 0) return (ENOMEM); @@ -234,6 +272,23 @@ } #endif + if (bootverbose) { + printf("EFI RT Signature: %lx, 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); #endif /* _KERNEL */