Page MenuHomeFreeBSD

D20347.id58045.diff
No OneTemporary

D20347.id58045.diff

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,57 @@
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 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 (0);
+ efi_map_ndesc = efihdr->memory_size / efihdr->descriptor_size;
+ return (true);
+}
+
+uint64_t
+efi_memory_attribute(vm_paddr_t pa)
+{
+ struct efi_md *p;
+
+ if (!efi_get_memory_map())
+ return (0);
+ p = bsearch(&pa, efi_map, efi_map_ndesc, efihdr->descriptor_size,
+ efi_map_compare);
+ return (p == NULL ? EFI_MD_ATTR_UC : p->md_attr);
+}
+
static void
efi_shutdown_final(void *dummy __unused, int howto)
{
@@ -149,12 +204,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 +233,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 +264,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 +275,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);
#endif /* _KERNEL */

File Metadata

Mime Type
text/plain
Expires
Tue, May 19, 7:58 AM (16 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33301114
Default Alt Text
D20347.id58045.diff (4 KB)

Event Timeline