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

Reply via email to