Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156962390
D47746.id150711.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D47746.id150711.diff
View Options
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,197 @@
+/*-
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * Copyright (c) 2018 Andrew Turner
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#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,41 @@
+/*-
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * Copyright (c) 2018 Andrew Turner
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#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
Details
Attached
Mime Type
text/plain
Expires
Mon, May 18, 4:21 PM (11 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33256258
Default Alt Text
D47746.id150711.diff (14 KB)
Attached To
Mode
D47746: arm64: Split EFI map parsing code to a common file
Attached
Detach File
Event Timeline
Log In to Comment