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
This commit is contained in:
Warner Losh committed 2026-06-26 08:54:36 -06:00
1 parent 3e3fd1fde8
commit 59219fc76a
2 files changed
+45

No files matched your search

+1
View File
@@ -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);
+44
View File
@@ -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);
}
}