Page MenuHomeFreeBSD

D47746.id151787.diff
No OneTemporary

D47746.id151787.diff

diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -40,6 +40,7 @@
#include <sys/csan.h>
#include <sys/devmap.h>
#include <sys/efi.h>
+#include <sys/efi_map.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/kdb.h>
@@ -457,172 +458,6 @@
return (false);
}
-typedef void (*efi_map_entry_cb)(struct efi_md *, void *argp);
-
-static void
-foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp)
-{
- struct efi_md *map, *p;
- size_t efisz;
- int ndesc, i;
-
- /*
- * Memory map data provided by UEFI via the GetMemoryMap
- * Boot Services API.
- */
- efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
- map = (struct efi_md *)((uint8_t *)efihdr + efisz);
-
- if (efihdr->descriptor_size == 0)
- return;
- ndesc = efihdr->memory_size / efihdr->descriptor_size;
-
- for (i = 0, p = map; i < ndesc; i++,
- p = efi_next_descriptor(p, efihdr->descriptor_size)) {
- cb(p, argp);
- }
-}
-
-/*
- * Handle the EFI memory map list.
- *
- * We will make two passes at this, the first (exclude == false) to populate
- * physmem with valid physical memory ranges from recognized map entry types.
- * In the second pass we will exclude memory ranges from physmem which must not
- * be used for general allocations, either because they are used by runtime
- * firmware or otherwise reserved.
- *
- * Adding the runtime-reserved memory ranges to physmem and excluding them
- * later ensures that they are included in the DMAP, but excluded from
- * phys_avail[].
- *
- * Entry types not explicitly listed here are ignored and not mapped.
- */
-static void
-handle_efi_map_entry(struct efi_md *p, void *argp)
-{
- bool exclude = *(bool *)argp;
-
- switch (p->md_type) {
- case EFI_MD_TYPE_RECLAIM:
- /*
- * The recomended location for ACPI tables. Map into the
- * DMAP so we can access them from userspace via /dev/mem.
- */
- case EFI_MD_TYPE_RT_CODE:
- /*
- * Some UEFI implementations put the system table in the
- * runtime code section. Include it in the DMAP, but will
- * be excluded from phys_avail.
- */
- case EFI_MD_TYPE_RT_DATA:
- /*
- * Runtime data will be excluded after the DMAP
- * region is created to stop it from being added
- * to phys_avail.
- */
- if (exclude) {
- physmem_exclude_region(p->md_phys,
- p->md_pages * EFI_PAGE_SIZE, EXFLAG_NOALLOC);
- break;
- }
- /* FALLTHROUGH */
- case EFI_MD_TYPE_CODE:
- case EFI_MD_TYPE_DATA:
- case EFI_MD_TYPE_BS_CODE:
- case EFI_MD_TYPE_BS_DATA:
- case EFI_MD_TYPE_FREE:
- /*
- * We're allowed to use any entry with these types.
- */
- if (!exclude)
- physmem_hardware_region(p->md_phys,
- p->md_pages * EFI_PAGE_SIZE);
- break;
- default:
- /* Other types shall not be handled by physmem. */
- break;
- }
-}
-
-static void
-add_efi_map_entries(struct efi_map_header *efihdr)
-{
- bool exclude = false;
- foreach_efi_map_entry(efihdr, handle_efi_map_entry, &exclude);
-}
-
-static void
-exclude_efi_map_entries(struct efi_map_header *efihdr)
-{
- bool exclude = true;
- foreach_efi_map_entry(efihdr, handle_efi_map_entry, &exclude);
-}
-
-static void
-print_efi_map_entry(struct efi_md *p, void *argp __unused)
-{
- const char *type;
- static const char *types[] = {
- "Reserved",
- "LoaderCode",
- "LoaderData",
- "BootServicesCode",
- "BootServicesData",
- "RuntimeServicesCode",
- "RuntimeServicesData",
- "ConventionalMemory",
- "UnusableMemory",
- "ACPIReclaimMemory",
- "ACPIMemoryNVS",
- "MemoryMappedIO",
- "MemoryMappedIOPortSpace",
- "PalCode",
- "PersistentMemory"
- };
-
- if (p->md_type < nitems(types))
- type = types[p->md_type];
- else
- type = "<INVALID>";
- printf("%23s %012lx %012lx %08lx ", type, p->md_phys,
- p->md_virt, p->md_pages);
- if (p->md_attr & EFI_MD_ATTR_UC)
- printf("UC ");
- if (p->md_attr & EFI_MD_ATTR_WC)
- printf("WC ");
- if (p->md_attr & EFI_MD_ATTR_WT)
- printf("WT ");
- if (p->md_attr & EFI_MD_ATTR_WB)
- printf("WB ");
- if (p->md_attr & EFI_MD_ATTR_UCE)
- printf("UCE ");
- if (p->md_attr & EFI_MD_ATTR_WP)
- printf("WP ");
- if (p->md_attr & EFI_MD_ATTR_RP)
- printf("RP ");
- if (p->md_attr & EFI_MD_ATTR_XP)
- printf("XP ");
- if (p->md_attr & EFI_MD_ATTR_NV)
- printf("NV ");
- if (p->md_attr & EFI_MD_ATTR_MORE_RELIABLE)
- printf("MORE_RELIABLE ");
- if (p->md_attr & EFI_MD_ATTR_RO)
- printf("RO ");
- if (p->md_attr & EFI_MD_ATTR_RT)
- printf("RUNTIME");
- printf("\n");
-}
-
-static void
-print_efi_map_entries(struct efi_map_header *efihdr)
-{
-
- printf("%23s %12s %12s %8s %4s\n",
- "Type", "Physical", "Virtual", "#Pages", "Attr");
- foreach_efi_map_entry(efihdr, print_efi_map_entry, NULL);
-}
-
/*
* Map the passed in VA in EFI space to a void * using the efi memory table to
* find the PA and return it in the DMAP, if it exists. We're used between the
@@ -659,7 +494,7 @@
{
struct early_map_data emd = { .va = va };
- foreach_efi_map_entry(efihdr, efi_early_map_entry, &emd);
+ efi_map_foreach_entry(efihdr, efi_early_map_entry, &emd);
if (emd.pa == 0)
return NULL;
return (void *)PHYS_TO_DMAP(emd.pa);
@@ -942,7 +777,7 @@
efihdr = (struct efi_map_header *)preload_search_info(preload_kmdp,
MODINFO_METADATA | MODINFOMD_EFI_MAP);
if (efihdr != NULL)
- add_efi_map_entries(efihdr);
+ efi_map_add_entries(efihdr);
#ifdef FDT
else {
/* Grab physical memory regions information from device tree. */
@@ -972,7 +807,7 @@
pmap_bootstrap(lastaddr - KERNBASE);
/* Exclude entries needed in the DMAP region, but not phys_avail */
if (efihdr != NULL)
- exclude_efi_map_entries(efihdr);
+ efi_map_exclude_entries(efihdr);
/* Do the same for reserve entries in the EFI MEMRESERVE table */
if (efi_systbl_phys != 0)
exclude_efi_memreserve(efi_systbl_phys);
@@ -1051,7 +886,7 @@
if (boothowto & RB_VERBOSE) {
if (efihdr != NULL)
- print_efi_map_entries(efihdr);
+ efi_map_print_entries(efihdr);
physmem_print_tables();
}
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -6,6 +6,7 @@
kern/msi_if.m optional intrng
kern/pic_if.m optional intrng
kern/subr_devmap.c standard
+kern/subr_efi_map.c standard
kern/subr_intr.c optional intrng
kern/subr_physmem.c standard
libkern/strlen.c standard
diff --git a/sys/kern/subr_efi_map.c b/sys/kern/subr_efi_map.c
new file mode 100644
--- /dev/null
+++ b/sys/kern/subr_efi_map.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * Copyright (c) 2018 Andrew Turner
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/efi.h>
+#include <sys/efi_map.h>
+#include <sys/physmem.h>
+
+#include <machine/efi.h>
+#include <machine/vmparam.h>
+
+void
+efi_map_foreach_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp)
+{
+ struct efi_md *map, *p;
+ size_t efisz;
+ int ndesc, i;
+
+ /*
+ * Memory map data provided by UEFI via the GetMemoryMap
+ * Boot Services API.
+ */
+ efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+ map = (struct efi_md *)((uint8_t *)efihdr + efisz);
+
+ if (efihdr->descriptor_size == 0)
+ return;
+ ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+ for (i = 0, p = map; i < ndesc; i++,
+ p = efi_next_descriptor(p, efihdr->descriptor_size)) {
+ cb(p, argp);
+ }
+}
+
+/*
+ * Handle the EFI memory map list.
+ *
+ * We will make two passes at this, the first (exclude == false) to populate
+ * physmem with valid physical memory ranges from recognized map entry types.
+ * In the second pass we will exclude memory ranges from physmem which must not
+ * be used for general allocations, either because they are used by runtime
+ * firmware or otherwise reserved.
+ *
+ * Adding the runtime-reserved memory ranges to physmem and excluding them
+ * later ensures that they are included in the DMAP, but excluded from
+ * phys_avail[].
+ *
+ * Entry types not explicitly listed here are ignored and not mapped.
+ */
+static void
+handle_efi_map_entry(struct efi_md *p, void *argp)
+{
+ bool exclude = *(bool *)argp;
+
+ switch (p->md_type) {
+ case EFI_MD_TYPE_RECLAIM:
+ /*
+ * The recomended location for ACPI tables. Map into the
+ * DMAP so we can access them from userspace via /dev/mem.
+ */
+ case EFI_MD_TYPE_RT_CODE:
+ /*
+ * Some UEFI implementations put the system table in the
+ * runtime code section. Include it in the DMAP, but will
+ * be excluded from phys_avail.
+ */
+ case EFI_MD_TYPE_RT_DATA:
+ /*
+ * Runtime data will be excluded after the DMAP
+ * region is created to stop it from being added
+ * to phys_avail.
+ */
+ if (exclude) {
+ physmem_exclude_region(p->md_phys,
+ p->md_pages * EFI_PAGE_SIZE, EXFLAG_NOALLOC);
+ break;
+ }
+ /* FALLTHROUGH */
+ case EFI_MD_TYPE_CODE:
+ case EFI_MD_TYPE_DATA:
+ case EFI_MD_TYPE_BS_CODE:
+ case EFI_MD_TYPE_BS_DATA:
+ case EFI_MD_TYPE_FREE:
+ /*
+ * We're allowed to use any entry with these types.
+ */
+ if (!exclude)
+ physmem_hardware_region(p->md_phys,
+ p->md_pages * EFI_PAGE_SIZE);
+ break;
+ default:
+ /* Other types shall not be handled by physmem. */
+ break;
+ }
+}
+
+void
+efi_map_add_entries(struct efi_map_header *efihdr)
+{
+ bool exclude = false;
+ efi_map_foreach_entry(efihdr, handle_efi_map_entry, &exclude);
+}
+
+void
+efi_map_exclude_entries(struct efi_map_header *efihdr)
+{
+ bool exclude = true;
+ efi_map_foreach_entry(efihdr, handle_efi_map_entry, &exclude);
+}
+
+static void
+print_efi_map_entry(struct efi_md *p, void *argp __unused)
+{
+ const char *type;
+ static const char *types[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode",
+ "PersistentMemory"
+ };
+
+ if (p->md_type < nitems(types))
+ type = types[p->md_type];
+ else
+ type = "<INVALID>";
+ printf("%23s %012lx %012lx %08lx ", type, p->md_phys,
+ p->md_virt, p->md_pages);
+ if (p->md_attr & EFI_MD_ATTR_UC)
+ printf("UC ");
+ if (p->md_attr & EFI_MD_ATTR_WC)
+ printf("WC ");
+ if (p->md_attr & EFI_MD_ATTR_WT)
+ printf("WT ");
+ if (p->md_attr & EFI_MD_ATTR_WB)
+ printf("WB ");
+ if (p->md_attr & EFI_MD_ATTR_UCE)
+ printf("UCE ");
+ if (p->md_attr & EFI_MD_ATTR_WP)
+ printf("WP ");
+ if (p->md_attr & EFI_MD_ATTR_RP)
+ printf("RP ");
+ if (p->md_attr & EFI_MD_ATTR_XP)
+ printf("XP ");
+ if (p->md_attr & EFI_MD_ATTR_NV)
+ printf("NV ");
+ if (p->md_attr & EFI_MD_ATTR_MORE_RELIABLE)
+ printf("MORE_RELIABLE ");
+ if (p->md_attr & EFI_MD_ATTR_RO)
+ printf("RO ");
+ if (p->md_attr & EFI_MD_ATTR_RT)
+ printf("RUNTIME");
+ printf("\n");
+}
+
+void
+efi_map_print_entries(struct efi_map_header *efihdr)
+{
+
+ printf("%23s %12s %12s %8s %4s\n",
+ "Type", "Physical", "Virtual", "#Pages", "Attr");
+ efi_map_foreach_entry(efihdr, print_efi_map_entry, NULL);
+}
diff --git a/sys/sys/efi_map.h b/sys/sys/efi_map.h
new file mode 100644
--- /dev/null
+++ b/sys/sys/efi_map.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * Copyright (c) 2018 Andrew Turner
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#ifndef _SYS_EFI_MAP_H_
+#define _SYS_EFI_MAP_H_
+
+#include <sys/efi.h>
+#include <machine/metadata.h>
+
+typedef void (*efi_map_entry_cb)(struct efi_md *, void *argp);
+
+void efi_map_foreach_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb,
+ void *argp);
+
+void efi_map_add_entries(struct efi_map_header *efihdr);
+void efi_map_exclude_entries(struct efi_map_header *efihdr);
+void efi_map_print_entries(struct efi_map_header *efihdr);
+
+#endif /* !_SYS_EFI_MAP_H_ */

File Metadata

Mime Type
text/plain
Expires
Mon, May 18, 7:01 PM (12 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33263734
Default Alt Text
D47746.id151787.diff (11 KB)

Event Timeline