git: 59219fc76a4b - main - loader.efi: efiblk_memdisk_preload passes the VirtualDisks to FreeBSD
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 26 Jun 2026 14:59:22 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=59219fc76a4bde45039695373a662ad59432d451
commit 59219fc76a4bde45039695373a662ad59432d451
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-06-26 14:47:31 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-06-26 14:54:36 +0000
loader.efi: efiblk_memdisk_preload passes the VirtualDisks to FreeBSD
Set hint.md.%d.physaddr and hint.md.%d.len for each of the VirtualDisks.
The memory for these remains after we exit boot services so FreeBSD can
use them. This leverages the BIOS work we did for memdisks. In
hindsight, I should have passed this in via metadata, but it's been in a
release.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D57806
---
stand/efi/include/efilib.h | 1 +
stand/efi/libefi/efipart.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/stand/efi/include/efilib.h b/stand/efi/include/efilib.h
index a387c808fe64..96de2a6344a2 100644
--- a/stand/efi/include/efilib.h
+++ b/stand/efi/include/efilib.h
@@ -68,6 +68,7 @@ pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev);
pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev);
pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h);
pdinfo_t *efiblk_get_pdinfo_by_device_path(EFI_DEVICE_PATH *path);
+void efiblk_memdisk_preload(void);
/* libefi.c */
void *efi_get_table(EFI_GUID *tbl);
diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c
index c61a7fce2a47..e02993064d26 100644
--- a/stand/efi/libefi/efipart.c
+++ b/stand/efi/libefi/efipart.c
@@ -1250,3 +1250,47 @@ error:
free(blkbuf);
return (rc);
}
+
+/*
+ * Predicate: is this a VirtualDisk as far as UEFI is concerned?
+ */
+static bool
+testmd(pdinfo_t *hd, pdinfo_t *data __unused)
+{
+ EFI_DEVICE_PATH *node;
+
+ node = efi_devpath_last_node(hd->pd_devpath);
+ if (node == NULL)
+ return (false);
+ if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType(node) == MEDIA_RAM_DISK_DP)
+ return (true);
+
+ return (false);
+}
+
+/*
+ * Passes all the VirtualDisk instances to FreeBSD as a preloaded memory disk.
+ */
+void
+efiblk_memdisk_preload(void)
+{
+ MEDIA_RAM_DISK_DEVICE_PATH *ram;
+ uint64_t start, end;
+ pdinfo_t *md;
+ char key[32], value[32];
+ int i;
+
+ while ((md = efipart_get_pd(&pdinfo, testmd, NULL)) != NULL) {
+ ram = (MEDIA_RAM_DISK_DEVICE_PATH *)efi_devpath_last_node(md->pd_devpath);
+ i = ram->Instance;
+ start = ((uint64_t)ram->StartingAddr[1] << 32) | ram->StartingAddr[0];
+ end = ((uint64_t)ram->EndingAddr[1] << 32) | ram->EndingAddr[0];
+ snprintf(key, sizeof(key), "hint.md.%d.physaddr", i);
+ snprintf(value, sizeof(value), "0x%016x", start);
+ setenv(key, value, 1);
+ snprintf(key, sizeof(key), "hint.md.%d.len", i);
+ snprintf(value, sizeof(value), "0x%016x", end - start);
+ setenv(key, value, 1);
+ }
+}