Changeset View
Changeset View
Standalone View
Standalone View
sys/boot/efi/loader/main.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#include <uuid.h> | #include <uuid.h> | ||||
#include <bootstrap.h> | #include <bootstrap.h> | ||||
#include <smbios.h> | #include <smbios.h> | ||||
#ifdef EFI_ZFS_BOOT | #ifdef EFI_ZFS_BOOT | ||||
#include <libzfs.h> | #include <libzfs.h> | ||||
#include "efizfs.h" | |||||
#endif | #endif | ||||
#include "loader_efi.h" | #include "loader_efi.h" | ||||
extern char bootprog_info[]; | extern char bootprog_info[]; | ||||
struct arch_switch archsw; /* MI/MD interface boundary */ | struct arch_switch archsw; /* MI/MD interface boundary */ | ||||
EFI_GUID acpi = ACPI_TABLE_GUID; | EFI_GUID acpi = ACPI_TABLE_GUID; | ||||
EFI_GUID acpi20 = ACPI_20_TABLE_GUID; | EFI_GUID acpi20 = ACPI_20_TABLE_GUID; | ||||
EFI_GUID devid = DEVICE_PATH_PROTOCOL; | EFI_GUID devid = DEVICE_PATH_PROTOCOL; | ||||
EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; | EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; | ||||
EFI_GUID mps = MPS_TABLE_GUID; | EFI_GUID mps = MPS_TABLE_GUID; | ||||
EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; | EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; | ||||
EFI_GUID smbios = SMBIOS_TABLE_GUID; | EFI_GUID smbios = SMBIOS_TABLE_GUID; | ||||
EFI_GUID dxe = DXE_SERVICES_TABLE_GUID; | EFI_GUID dxe = DXE_SERVICES_TABLE_GUID; | ||||
EFI_GUID hoblist = HOB_LIST_TABLE_GUID; | EFI_GUID hoblist = HOB_LIST_TABLE_GUID; | ||||
EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; | EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; | ||||
EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; | EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; | ||||
EFI_GUID fdtdtb = FDT_TABLE_GUID; | EFI_GUID fdtdtb = FDT_TABLE_GUID; | ||||
EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL; | EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL; | ||||
#ifdef EFI_ZFS_BOOT | |||||
static void efi_zfs_probe(void); | |||||
static uint64_t pool_guid; | |||||
#endif | |||||
static int | static int | ||||
has_keyboard(void) | has_keyboard(void) | ||||
{ | { | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
EFI_DEVICE_PATH *path; | EFI_DEVICE_PATH *path; | ||||
EFI_HANDLE *hin, *hin_end, *walker; | EFI_HANDLE *hin, *hin_end, *walker; | ||||
UINTN sz; | UINTN sz; | ||||
int retval = 0; | int retval = 0; | ||||
/* | /* | ||||
* Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and | * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and | ||||
* do the typical dance to get the right sized buffer. | * do the typical dance to get the right sized buffer. | ||||
*/ | */ | ||||
sz = 0; | sz = 0; | ||||
hin = NULL; | hin = NULL; | ||||
status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, 0); | status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, 0); | ||||
if (status == EFI_BUFFER_TOO_SMALL) { | if (status == EFI_BUFFER_TOO_SMALL) { | ||||
Show All 40 Lines | while (!IsDevicePathEnd(path)) { | ||||
/* | /* | ||||
* Check for USB keyboard node, if present. Unlike a | * Check for USB keyboard node, if present. Unlike a | ||||
* PS/2 keyboard, these definitely only appear when | * PS/2 keyboard, these definitely only appear when | ||||
* connected to the system. | * connected to the system. | ||||
*/ | */ | ||||
} else if (DevicePathType(path) == MESSAGING_DEVICE_PATH && | } else if (DevicePathType(path) == MESSAGING_DEVICE_PATH && | ||||
DevicePathSubType(path) == MSG_USB_CLASS_DP) { | DevicePathSubType(path) == MSG_USB_CLASS_DP) { | ||||
USB_CLASS_DEVICE_PATH *usb; | USB_CLASS_DEVICE_PATH *usb; | ||||
usb = (USB_CLASS_DEVICE_PATH *)(void *)path; | usb = (USB_CLASS_DEVICE_PATH *)(void *)path; | ||||
if (usb->DeviceClass == 3 && /* HID */ | if (usb->DeviceClass == 3 && /* HID */ | ||||
usb->DeviceSubClass == 1 && /* Boot devices */ | usb->DeviceSubClass == 1 && /* Boot devices */ | ||||
usb->DeviceProtocol == 1) { /* Boot keyboards */ | usb->DeviceProtocol == 1) { /* Boot keyboards */ | ||||
retval = 1; | retval = 1; | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 735 Lines • ▼ Show 20 Lines | if (status != EFI_SUCCESS) { | ||||
status = BS->UnloadImage(loaded_image); | status = BS->UnloadImage(loaded_image); | ||||
return (CMD_ERROR); | return (CMD_ERROR); | ||||
} | } | ||||
return (CMD_ERROR); /* not reached */ | return (CMD_ERROR); /* not reached */ | ||||
} | } | ||||
COMMAND_SET(chain, "chain", "chain load file", command_chain); | COMMAND_SET(chain, "chain", "chain load file", command_chain); | ||||
#ifdef EFI_ZFS_BOOT | |||||
static void | |||||
efi_zfs_probe(void) | |||||
{ | |||||
pdinfo_list_t *hdi; | |||||
pdinfo_t *hd, *pd = NULL; | |||||
EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; | |||||
EFI_LOADED_IMAGE *img; | |||||
char devname[SPECNAMELEN + 1]; | |||||
BS->HandleProtocol(IH, &imgid, (VOID**)&img); | |||||
hdi = efiblk_get_pdinfo_list(&efipart_hddev); | |||||
/* | |||||
* Find the handle for the boot device. The boot1 did find the | |||||
* device with loader binary, now we need to search for the | |||||
* same device and if it is part of the zfs pool, we record the | |||||
* pool GUID for currdev setup. | |||||
*/ | |||||
STAILQ_FOREACH(hd, hdi, pd_link) { | |||||
STAILQ_FOREACH(pd, &hd->pd_part, pd_link) { | |||||
snprintf(devname, sizeof(devname), "%s%dp%d:", | |||||
efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit); | |||||
if (pd->pd_handle == img->DeviceHandle) | |||||
(void) zfs_probe_dev(devname, &pool_guid); | |||||
else | |||||
(void) zfs_probe_dev(devname, NULL); | |||||
} | |||||
} | |||||
} | |||||
uint64_t | |||||
ldi_get_size(void *priv) | |||||
{ | |||||
int fd = (uintptr_t) priv; | |||||
uint64_t size; | |||||
ioctl(fd, DIOCGMEDIASIZE, &size); | |||||
return (size); | |||||
} | |||||
#endif |