1 /* efi.c - generic EFI support */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/misc.h>
21 #include <grub/charset.h>
22 #include <grub/efi/api.h>
23 #include <grub/efi/efi.h>
24 #include <grub/efi/console_control.h>
25 #include <grub/efi/pe32.h>
26 #include <grub/time.h>
27 #include <grub/term.h>
28 #include <grub/kernel.h>
31 /* The handle of GRUB itself. Filled in by the startup code. */
32 grub_efi_handle_t grub_efi_image_handle
;
34 /* The pointer to a system table. Filled in by the startup code. */
35 grub_efi_system_table_t
*grub_efi_system_table
;
37 static grub_efi_guid_t console_control_guid
= GRUB_EFI_CONSOLE_CONTROL_GUID
;
38 static grub_efi_guid_t loaded_image_guid
= GRUB_EFI_LOADED_IMAGE_GUID
;
39 static grub_efi_guid_t device_path_guid
= GRUB_EFI_DEVICE_PATH_GUID
;
42 grub_efi_locate_protocol (grub_efi_guid_t
*protocol
, void *registration
)
45 grub_efi_status_t status
;
47 status
= efi_call_3 (grub_efi_system_table
->boot_services
->locate_protocol
,
48 protocol
, registration
, &interface
);
49 if (status
!= GRUB_EFI_SUCCESS
)
55 /* Return the array of handles which meet the requirement. If successful,
56 the number of handles is stored in NUM_HANDLES. The array is allocated
59 grub_efi_locate_handle (grub_efi_locate_search_type_t search_type
,
60 grub_efi_guid_t
*protocol
,
62 grub_efi_uintn_t
*num_handles
)
64 grub_efi_boot_services_t
*b
;
65 grub_efi_status_t status
;
66 grub_efi_handle_t
*buffer
;
67 grub_efi_uintn_t buffer_size
= 8 * sizeof (grub_efi_handle_t
);
69 buffer
= grub_malloc (buffer_size
);
73 b
= grub_efi_system_table
->boot_services
;
74 status
= efi_call_5 (b
->locate_handle
, search_type
, protocol
, search_key
,
75 &buffer_size
, buffer
);
76 if (status
== GRUB_EFI_BUFFER_TOO_SMALL
)
79 buffer
= grub_malloc (buffer_size
);
83 status
= efi_call_5 (b
->locate_handle
, search_type
, protocol
, search_key
,
84 &buffer_size
, buffer
);
87 if (status
!= GRUB_EFI_SUCCESS
)
93 *num_handles
= buffer_size
/ sizeof (grub_efi_handle_t
);
98 grub_efi_open_protocol (grub_efi_handle_t handle
,
99 grub_efi_guid_t
*protocol
,
100 grub_efi_uint32_t attributes
)
102 grub_efi_boot_services_t
*b
;
103 grub_efi_status_t status
;
106 b
= grub_efi_system_table
->boot_services
;
107 status
= efi_call_6 (b
->open_protocol
, handle
,
110 grub_efi_image_handle
,
113 if (status
!= GRUB_EFI_SUCCESS
)
120 grub_efi_set_text_mode (int on
)
122 grub_efi_console_control_protocol_t
*c
;
123 grub_efi_screen_mode_t mode
, new_mode
;
125 c
= grub_efi_locate_protocol (&console_control_guid
, 0);
127 /* No console control protocol instance available, assume it is
128 already in text mode. */
131 if (efi_call_4 (c
->get_mode
, c
, &mode
, 0, 0) != GRUB_EFI_SUCCESS
)
134 new_mode
= on
? GRUB_EFI_SCREEN_TEXT
: GRUB_EFI_SCREEN_GRAPHICS
;
135 if (mode
!= new_mode
)
136 if (efi_call_2 (c
->set_mode
, c
, new_mode
) != GRUB_EFI_SUCCESS
)
143 grub_efi_stall (grub_efi_uintn_t microseconds
)
145 efi_call_1 (grub_efi_system_table
->boot_services
->stall
, microseconds
);
148 grub_efi_loaded_image_t
*
149 grub_efi_get_loaded_image (grub_efi_handle_t image_handle
)
151 return grub_efi_open_protocol (image_handle
,
153 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
160 efi_call_4 (grub_efi_system_table
->boot_services
->exit
,
161 grub_efi_image_handle
, GRUB_EFI_SUCCESS
, 0, 0);
166 grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size
,
167 grub_efi_uintn_t descriptor_size
,
168 grub_efi_uint32_t descriptor_version
,
169 grub_efi_memory_descriptor_t
*virtual_map
)
171 grub_efi_runtime_services_t
*r
;
172 grub_efi_status_t status
;
174 r
= grub_efi_system_table
->runtime_services
;
175 status
= efi_call_4 (r
->set_virtual_address_map
, memory_map_size
,
176 descriptor_size
, descriptor_version
, virtual_map
);
178 if (status
== GRUB_EFI_SUCCESS
)
179 return GRUB_ERR_NONE
;
181 return grub_error (GRUB_ERR_IO
, "set_virtual_address_map failed");
185 grub_efi_get_variable (const char *var
, const grub_efi_guid_t
*guid
,
186 grub_size_t
*datasize_out
)
188 grub_efi_status_t status
;
189 grub_efi_uintn_t datasize
= 0;
190 grub_efi_runtime_services_t
*r
;
191 grub_efi_char16_t
*var16
;
193 grub_size_t len
, len16
;
197 len
= grub_strlen (var
);
198 len16
= len
* GRUB_MAX_UTF16_PER_UTF8
;
199 var16
= grub_malloc ((len16
+ 1) * sizeof (var16
[0]));
202 len16
= grub_utf8_to_utf16 (var16
, len16
, (grub_uint8_t
*) var
, len
, NULL
);
205 r
= grub_efi_system_table
->runtime_services
;
207 status
= efi_call_5 (r
->get_variable
, var16
, guid
, NULL
, &datasize
, NULL
);
212 data
= grub_malloc (datasize
);
219 status
= efi_call_5 (r
->get_variable
, var16
, guid
, NULL
, &datasize
, data
);
222 if (status
== GRUB_EFI_SUCCESS
)
224 *datasize_out
= datasize
;
232 #pragma GCC diagnostic ignored "-Wcast-align"
234 /* Search the mods section from the PE32/PE32+ image. This code uses
235 a PE32 header, but should work with PE32+ as well. */
237 grub_efi_modules_addr (void)
239 grub_efi_loaded_image_t
*image
;
240 struct grub_pe32_header
*header
;
241 struct grub_pe32_coff_header
*coff_header
;
242 struct grub_pe32_section_table
*sections
;
243 struct grub_pe32_section_table
*section
;
244 struct grub_module_info
*info
;
247 image
= grub_efi_get_loaded_image (grub_efi_image_handle
);
251 header
= image
->image_base
;
252 coff_header
= &(header
->coff_header
);
254 = (struct grub_pe32_section_table
*) ((char *) coff_header
255 + sizeof (*coff_header
)
256 + coff_header
->optional_header_size
);
258 for (i
= 0, section
= sections
;
259 i
< coff_header
->num_sections
;
262 if (grub_strcmp (section
->name
, "mods") == 0)
266 if (i
== coff_header
->num_sections
)
269 info
= (struct grub_module_info
*) ((char *) image
->image_base
270 + section
->virtual_address
);
271 if (info
->magic
!= GRUB_MODULE_MAGIC
)
274 return (grub_addr_t
) info
;
277 #pragma GCC diagnostic error "-Wcast-align"
280 grub_efi_get_filename (grub_efi_device_path_t
*dp
)
286 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
287 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
289 if (type
== GRUB_EFI_END_DEVICE_PATH_TYPE
)
291 else if (type
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
292 && subtype
== GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
)
294 grub_efi_file_path_device_path_t
*fp
;
295 grub_efi_uint16_t len
;
301 size
= grub_strlen (name
);
308 len
= ((GRUB_EFI_DEVICE_PATH_LENGTH (dp
) - 4)
309 / sizeof (grub_efi_char16_t
));
310 p
= grub_realloc (name
, size
+ len
* 4 + 1);
318 fp
= (grub_efi_file_path_device_path_t
*) dp
;
319 *grub_utf16_to_utf8 ((grub_uint8_t
*) name
+ size
,
320 fp
->path_name
, len
) = '\0';
323 dp
= GRUB_EFI_NEXT_DEVICE_PATH (dp
);
328 /* EFI breaks paths with backslashes. */
331 for (p
= name
; *p
; p
++)
339 grub_efi_device_path_t
*
340 grub_efi_get_device_path (grub_efi_handle_t handle
)
342 return grub_efi_open_protocol (handle
, &device_path_guid
,
343 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
346 /* Print the chain of Device Path nodes. This is mainly for debugging. */
348 grub_efi_print_device_path (grub_efi_device_path_t
*dp
)
352 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
353 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
354 grub_efi_uint16_t len
= GRUB_EFI_DEVICE_PATH_LENGTH (dp
);
358 case GRUB_EFI_END_DEVICE_PATH_TYPE
:
361 case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
:
362 grub_printf ("/EndEntire\n");
363 //grub_putchar ('\n');
365 case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE
:
366 grub_printf ("/EndThis\n");
367 //grub_putchar ('\n');
370 grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype
);
375 case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE
:
378 case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE
:
380 grub_efi_pci_device_path_t pci
;
381 grub_memcpy (&pci
, dp
, len
);
382 grub_printf ("/PCI(%x,%x)",
383 (unsigned) pci
.function
, (unsigned) pci
.device
);
386 case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE
:
388 grub_efi_pccard_device_path_t pccard
;
389 grub_memcpy (&pccard
, dp
, len
);
390 grub_printf ("/PCCARD(%x)",
391 (unsigned) pccard
.function
);
394 case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE
:
396 grub_efi_memory_mapped_device_path_t mmapped
;
397 grub_memcpy (&mmapped
, dp
, len
);
398 grub_printf ("/MMap(%x,%llx,%llx)",
399 (unsigned) mmapped
.memory_type
,
400 (unsigned long long) mmapped
.start_address
,
401 (unsigned long long) mmapped
.end_address
);
404 case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE
:
406 grub_efi_vendor_device_path_t vendor
;
407 grub_memcpy (&vendor
, dp
, sizeof (vendor
));
408 grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
409 (unsigned) vendor
.vendor_guid
.data1
,
410 (unsigned) vendor
.vendor_guid
.data2
,
411 (unsigned) vendor
.vendor_guid
.data3
,
412 (unsigned) vendor
.vendor_guid
.data4
[0],
413 (unsigned) vendor
.vendor_guid
.data4
[1],
414 (unsigned) vendor
.vendor_guid
.data4
[2],
415 (unsigned) vendor
.vendor_guid
.data4
[3],
416 (unsigned) vendor
.vendor_guid
.data4
[4],
417 (unsigned) vendor
.vendor_guid
.data4
[5],
418 (unsigned) vendor
.vendor_guid
.data4
[6],
419 (unsigned) vendor
.vendor_guid
.data4
[7]);
422 case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE
:
424 grub_efi_controller_device_path_t controller
;
425 grub_memcpy (&controller
, dp
, len
);
426 grub_printf ("/Ctrl(%x)",
427 (unsigned) controller
.controller_number
);
431 grub_printf ("/UnknownHW(%x)", (unsigned) subtype
);
436 case GRUB_EFI_ACPI_DEVICE_PATH_TYPE
:
439 case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE
:
441 grub_efi_acpi_device_path_t acpi
;
442 grub_memcpy (&acpi
, dp
, len
);
443 grub_printf ("/ACPI(%x,%x)",
445 (unsigned) acpi
.uid
);
448 case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE
:
450 grub_efi_expanded_acpi_device_path_t eacpi
;
451 grub_memcpy (&eacpi
, dp
, sizeof (eacpi
));
452 grub_printf ("/ACPI(");
454 if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp
)[0] == '\0')
455 grub_printf ("%x,", (unsigned) eacpi
.hid
);
457 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp
));
459 if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp
)[0] == '\0')
460 grub_printf ("%x,", (unsigned) eacpi
.uid
);
462 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp
));
464 if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp
)[0] == '\0')
465 grub_printf ("%x)", (unsigned) eacpi
.cid
);
467 grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp
));
471 grub_printf ("/UnknownACPI(%x)", (unsigned) subtype
);
476 case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
:
479 case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE
:
481 grub_efi_atapi_device_path_t atapi
;
482 grub_memcpy (&atapi
, dp
, len
);
483 grub_printf ("/ATAPI(%x,%x,%x)",
484 (unsigned) atapi
.primary_secondary
,
485 (unsigned) atapi
.slave_master
,
486 (unsigned) atapi
.lun
);
489 case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE
:
491 grub_efi_scsi_device_path_t scsi
;
492 grub_memcpy (&scsi
, dp
, len
);
493 grub_printf ("/SCSI(%x,%x)",
495 (unsigned) scsi
.lun
);
498 case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE
:
500 grub_efi_fibre_channel_device_path_t fc
;
501 grub_memcpy (&fc
, dp
, len
);
502 grub_printf ("/FibreChannel(%llx,%llx)",
503 (unsigned long long) fc
.wwn
,
504 (unsigned long long) fc
.lun
);
507 case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE
:
509 grub_efi_1394_device_path_t firewire
;
510 grub_memcpy (&firewire
, dp
, len
);
511 grub_printf ("/1394(%llx)", (unsigned long long) firewire
.guid
);
514 case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE
:
516 grub_efi_usb_device_path_t usb
;
517 grub_memcpy (&usb
, dp
, len
);
518 grub_printf ("/USB(%x,%x)",
519 (unsigned) usb
.parent_port_number
,
520 (unsigned) usb
.interface
);
523 case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE
:
525 grub_efi_usb_class_device_path_t usb_class
;
526 grub_memcpy (&usb_class
, dp
, len
);
527 grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
528 (unsigned) usb_class
.vendor_id
,
529 (unsigned) usb_class
.product_id
,
530 (unsigned) usb_class
.device_class
,
531 (unsigned) usb_class
.device_subclass
,
532 (unsigned) usb_class
.device_protocol
);
535 case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE
:
537 grub_efi_i2o_device_path_t i2o
;
538 grub_memcpy (&i2o
, dp
, len
);
539 grub_printf ("/I2O(%x)", (unsigned) i2o
.tid
);
542 case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
:
544 grub_efi_mac_address_device_path_t mac
;
545 grub_memcpy (&mac
, dp
, len
);
546 grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
547 (unsigned) mac
.mac_address
[0],
548 (unsigned) mac
.mac_address
[1],
549 (unsigned) mac
.mac_address
[2],
550 (unsigned) mac
.mac_address
[3],
551 (unsigned) mac
.mac_address
[4],
552 (unsigned) mac
.mac_address
[5],
553 (unsigned) mac
.if_type
);
556 case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
:
558 grub_efi_ipv4_device_path_t ipv4
;
559 grub_memcpy (&ipv4
, dp
, len
);
560 grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
561 (unsigned) ipv4
.local_ip_address
[0],
562 (unsigned) ipv4
.local_ip_address
[1],
563 (unsigned) ipv4
.local_ip_address
[2],
564 (unsigned) ipv4
.local_ip_address
[3],
565 (unsigned) ipv4
.remote_ip_address
[0],
566 (unsigned) ipv4
.remote_ip_address
[1],
567 (unsigned) ipv4
.remote_ip_address
[2],
568 (unsigned) ipv4
.remote_ip_address
[3],
569 (unsigned) ipv4
.local_port
,
570 (unsigned) ipv4
.remote_port
,
571 (unsigned) ipv4
.protocol
,
572 (unsigned) ipv4
.static_ip_address
);
575 case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE
:
577 grub_efi_ipv6_device_path_t ipv6
;
578 grub_memcpy (&ipv6
, dp
, len
);
579 grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
580 (unsigned) ipv6
.local_ip_address
[0],
581 (unsigned) ipv6
.local_ip_address
[1],
582 (unsigned) ipv6
.local_ip_address
[2],
583 (unsigned) ipv6
.local_ip_address
[3],
584 (unsigned) ipv6
.local_ip_address
[4],
585 (unsigned) ipv6
.local_ip_address
[5],
586 (unsigned) ipv6
.local_ip_address
[6],
587 (unsigned) ipv6
.local_ip_address
[7],
588 (unsigned) ipv6
.remote_ip_address
[0],
589 (unsigned) ipv6
.remote_ip_address
[1],
590 (unsigned) ipv6
.remote_ip_address
[2],
591 (unsigned) ipv6
.remote_ip_address
[3],
592 (unsigned) ipv6
.remote_ip_address
[4],
593 (unsigned) ipv6
.remote_ip_address
[5],
594 (unsigned) ipv6
.remote_ip_address
[6],
595 (unsigned) ipv6
.remote_ip_address
[7],
596 (unsigned) ipv6
.local_port
,
597 (unsigned) ipv6
.remote_port
,
598 (unsigned) ipv6
.protocol
,
599 (unsigned) ipv6
.static_ip_address
);
602 case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE
:
604 grub_efi_infiniband_device_path_t ib
;
605 grub_memcpy (&ib
, dp
, len
);
606 grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
607 (unsigned) ib
.port_gid
[0], /* XXX */
608 (unsigned long long) ib
.remote_id
,
609 (unsigned long long) ib
.target_port_id
,
610 (unsigned long long) ib
.device_id
);
613 case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE
:
615 grub_efi_uart_device_path_t uart
;
616 grub_memcpy (&uart
, dp
, len
);
617 grub_printf ("/UART(%llu,%u,%x,%x)",
618 (unsigned long long) uart
.baud_rate
,
624 case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE
:
626 grub_efi_vendor_messaging_device_path_t vendor
;
627 grub_memcpy (&vendor
, dp
, sizeof (vendor
));
628 grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
629 (unsigned) vendor
.vendor_guid
.data1
,
630 (unsigned) vendor
.vendor_guid
.data2
,
631 (unsigned) vendor
.vendor_guid
.data3
,
632 (unsigned) vendor
.vendor_guid
.data4
[0],
633 (unsigned) vendor
.vendor_guid
.data4
[1],
634 (unsigned) vendor
.vendor_guid
.data4
[2],
635 (unsigned) vendor
.vendor_guid
.data4
[3],
636 (unsigned) vendor
.vendor_guid
.data4
[4],
637 (unsigned) vendor
.vendor_guid
.data4
[5],
638 (unsigned) vendor
.vendor_guid
.data4
[6],
639 (unsigned) vendor
.vendor_guid
.data4
[7]);
643 grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype
);
648 case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
:
651 case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE
:
653 grub_efi_hard_drive_device_path_t hd
;
654 grub_memcpy (&hd
, dp
, len
);
655 grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
657 (unsigned long long) hd
.partition_start
,
658 (unsigned long long) hd
.partition_size
,
659 (unsigned) hd
.partition_signature
[0],
660 (unsigned) hd
.partition_signature
[1],
661 (unsigned) hd
.partition_signature
[2],
662 (unsigned) hd
.partition_signature
[3],
663 (unsigned) hd
.partition_signature
[4],
664 (unsigned) hd
.partition_signature
[5],
665 (unsigned) hd
.partition_signature
[6],
666 (unsigned) hd
.partition_signature
[7],
667 (unsigned) hd
.mbr_type
,
668 (unsigned) hd
.signature_type
);
671 case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
:
673 grub_efi_cdrom_device_path_t cd
;
674 grub_memcpy (&cd
, dp
, len
);
675 grub_printf ("/CD(%u,%llx,%llx)",
677 (unsigned long long) cd
.partition_start
,
678 (unsigned long long) cd
.partition_size
);
681 case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE
:
683 grub_efi_vendor_media_device_path_t vendor
;
684 grub_memcpy (&vendor
, dp
, sizeof (vendor
));
685 grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
686 (unsigned) vendor
.vendor_guid
.data1
,
687 (unsigned) vendor
.vendor_guid
.data2
,
688 (unsigned) vendor
.vendor_guid
.data3
,
689 (unsigned) vendor
.vendor_guid
.data4
[0],
690 (unsigned) vendor
.vendor_guid
.data4
[1],
691 (unsigned) vendor
.vendor_guid
.data4
[2],
692 (unsigned) vendor
.vendor_guid
.data4
[3],
693 (unsigned) vendor
.vendor_guid
.data4
[4],
694 (unsigned) vendor
.vendor_guid
.data4
[5],
695 (unsigned) vendor
.vendor_guid
.data4
[6],
696 (unsigned) vendor
.vendor_guid
.data4
[7]);
699 case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
:
701 grub_efi_file_path_device_path_t
*fp
;
702 grub_uint8_t buf
[(len
- 4) * 2 + 1];
703 fp
= (grub_efi_file_path_device_path_t
*) dp
;
704 *grub_utf16_to_utf8 (buf
, fp
->path_name
,
705 (len
- 4) / sizeof (grub_efi_char16_t
))
707 grub_printf ("/File(%s)", buf
);
710 case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE
:
712 grub_efi_protocol_device_path_t proto
;
713 grub_memcpy (&proto
, dp
, sizeof (proto
));
714 grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
715 (unsigned) proto
.guid
.data1
,
716 (unsigned) proto
.guid
.data2
,
717 (unsigned) proto
.guid
.data3
,
718 (unsigned) proto
.guid
.data4
[0],
719 (unsigned) proto
.guid
.data4
[1],
720 (unsigned) proto
.guid
.data4
[2],
721 (unsigned) proto
.guid
.data4
[3],
722 (unsigned) proto
.guid
.data4
[4],
723 (unsigned) proto
.guid
.data4
[5],
724 (unsigned) proto
.guid
.data4
[6],
725 (unsigned) proto
.guid
.data4
[7]);
729 grub_printf ("/UnknownMedia(%x)", (unsigned) subtype
);
734 case GRUB_EFI_BIOS_DEVICE_PATH_TYPE
:
737 case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE
:
739 grub_efi_bios_device_path_t bios
;
740 grub_memcpy (&bios
, dp
, sizeof (bios
));
741 grub_printf ("/BIOS(%x,%x,%s)",
742 (unsigned) bios
.device_type
,
743 (unsigned) bios
.status_flags
,
748 grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype
);
754 grub_printf ("/UnknownType(%x,%x)\n",
761 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp
))
764 dp
= (grub_efi_device_path_t
*) ((char *) dp
+ len
);
768 /* Compare device paths. */
770 grub_efi_compare_device_paths (const grub_efi_device_path_t
*dp1
,
771 const grub_efi_device_path_t
*dp2
)
774 /* Return non-zero. */
779 grub_efi_uint8_t type1
, type2
;
780 grub_efi_uint8_t subtype1
, subtype2
;
781 grub_efi_uint16_t len1
, len2
;
784 type1
= GRUB_EFI_DEVICE_PATH_TYPE (dp1
);
785 type2
= GRUB_EFI_DEVICE_PATH_TYPE (dp2
);
788 return (int) type2
- (int) type1
;
790 subtype1
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1
);
791 subtype2
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2
);
793 if (subtype1
!= subtype2
)
794 return (int) subtype1
- (int) subtype2
;
796 len1
= GRUB_EFI_DEVICE_PATH_LENGTH (dp1
);
797 len2
= GRUB_EFI_DEVICE_PATH_LENGTH (dp2
);
800 return (int) len1
- (int) len2
;
802 ret
= grub_memcmp (dp1
, dp2
, len1
);
806 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1
))
809 dp1
= (grub_efi_device_path_t
*) ((char *) dp1
+ len1
);
810 dp2
= (grub_efi_device_path_t
*) ((char *) dp2
+ len2
);