Hi,
On Sun, 30 Jul 2017 12:20:27 +1000
Jonathan Gray <[email protected]> wrote:
> On Sat, Jul 29, 2017 at 09:01:35PM +0200, Patrick Wildt wrote:
>> On Sat, Jul 29, 2017 at 02:59:19PM +0200, Mark Kettenis wrote:
>> > This is apparently very hard. Caught this on arm64 where
>> > efi_device_path_depth() returned 0, which resulted in always selecting
>> > the first device. Clearly if the first path component (i = 0) matches
>> > the desired type, we should return 1, not 0. Here is the amd64
>> > version of the diff which is easier to test for people.
>> >
>> > ok?
>>
>> God damn, this feels like the tenth time this thing has to be fixed up.
>> Fix looks good to me, please commit that on arm64 and armv7 as well.
>>
>> ok patrick@
>
> The changes to arm64 broke boot on the overdrive 1000.
I'm ok for the diff.
But I'm not sure what's happing on arm64.
Fukaumi and I are discussing whether we should copy the result of
device path protocol. As far as we know for this moment, on bhyve, we
need to copy it. The diff following from Fukaumi which copies he the
device path.
I'm not sure this problem is related to the problem you reported. But
I think sharing this may help us.
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c
b/sys/arch/amd64/stand/efiboot/efiboot.c
index 4114f9137b5..5945146373b 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -50,9 +50,12 @@ UINTN mmap_key;
static EFI_GUID imgp_guid = LOADED_IMAGE_PROTOCOL;
static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
+static EFI_GUID devpu_guid = DEVICE_PATH_UTILITIES_PROTOCOL;
u_long efi_loadaddr;
static int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
+static EFI_DEVICE_PATH *
+ efi_device_path_duplicate(EFI_DEVICE_PATH *dp);
static int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *,
int);
static void efi_heap_init(void);
@@ -94,7 +97,7 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
if (DevicePathType(dp) == MEDIA_DEVICE_PATH &&
DevicePathSubType(dp) == MEDIA_HARDDRIVE_DP) {
bios_bootdev = 0x80;
- efi_bootdp = dp0;
+ efi_bootdp = efi_device_path_duplicate(dp0);
break;
}
}
@@ -228,6 +231,20 @@ efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype)
return (-1);
}
+static EFI_DEVICE_PATH *
+efi_device_path_duplicate(EFI_DEVICE_PATH *dp)
+{
+ EFI_DEVICE_PATH *dup = NULL;
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL *devpu = NULL;
+ EFI_STATUS status;
+
+ status = EFI_CALL(BS->LocateProtocol, &devpu_guid, NULL,
+ (void **)&devpu);
+ if (!EFI_ERROR(status))
+ dup = (void *)EFI_CALL(devpu->DuplicateDevicePath, dp);
+ return dup;
+}
+
static int
efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn)
{
diff --git a/sys/stand/efi/include/efidevp.h b/sys/stand/efi/include/efidevp.h
index 1feb424c820..e0e441ddaf6 100644
--- a/sys/stand/efi/include/efidevp.h
+++ b/sys/stand/efi/include/efidevp.h
@@ -451,4 +451,74 @@ typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL {
EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText;
} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
+#define DEVICE_PATH_UTILITIES_PROTOCOL
\
+ { 0x379be4e, 0xd706, 0x437d, { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72,
0xa4 } }
+
+INTERFACE_DECL(_EFI_DEVICE_PATH_UTILITIES_PROTOCOL);
+
+typedef
+UINTN
+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE) (
+ IN struct _EFI_DEVICE_PATH *DevicePath
+ );
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH) (
+ IN struct _EFI_DEVICE_PATH *DevicePath
+ );
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_PATH) (
+ IN struct _EFI_DEVICE_PATH *Src1,
+ IN struct _EFI_DEVICE_PATH *Src2
+ );
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_NODE) (
+ IN struct _EFI_DEVICE_PATH *DevicePath,
+ IN struct _EFI_DEVICE_PATH *DeviceNode
+ );
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE) (
+ IN struct _EFI_DEVICE_PATH *DevicePath,
+ IN struct _EFI_DEVICE_PATH *DevicePathInstance
+ );
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE) (
+ IN OUT struct _EFI_DEVICE_PATH **DevicePathInstance,
+ OUT UINTN *DevicePathInstanceSize OPTIONAL
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE) (
+ IN struct _EFI_DEVICE_PATH *DevicePath
+ );
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_CREATE_NODE) (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ );
+
+typedef struct _EFI_DEVICE_PATH_UTILITIES_PROTOCOL {
+ EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
+ EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode;
+ EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance;
+ EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode;
+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
+
#endif