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>
30 #include <grub/loader.h>
32 /* The handle of GRUB itself. Filled in by the startup code. */
33 grub_efi_handle_t grub_efi_image_handle
;
35 /* The pointer to a system table. Filled in by the startup code. */
36 grub_efi_system_table_t
*grub_efi_system_table
;
38 static grub_efi_guid_t console_control_guid
= GRUB_EFI_CONSOLE_CONTROL_GUID
;
39 static grub_efi_guid_t loaded_image_guid
= GRUB_EFI_LOADED_IMAGE_GUID
;
40 static grub_efi_guid_t device_path_guid
= GRUB_EFI_DEVICE_PATH_GUID
;
43 grub_efi_locate_protocol (grub_efi_guid_t
*protocol
, void *registration
)
46 grub_efi_status_t status
;
48 status
= efi_call_3 (grub_efi_system_table
->boot_services
->locate_protocol
,
49 protocol
, registration
, &interface
);
50 if (status
!= GRUB_EFI_SUCCESS
)
56 /* Return the array of handles which meet the requirement. If successful,
57 the number of handles is stored in NUM_HANDLES. The array is allocated
60 grub_efi_locate_handle (grub_efi_locate_search_type_t search_type
,
61 grub_efi_guid_t
*protocol
,
63 grub_efi_uintn_t
*num_handles
)
65 grub_efi_boot_services_t
*b
;
66 grub_efi_status_t status
;
67 grub_efi_handle_t
*buffer
;
68 grub_efi_uintn_t buffer_size
= 8 * sizeof (grub_efi_handle_t
);
70 buffer
= grub_malloc (buffer_size
);
74 b
= grub_efi_system_table
->boot_services
;
75 status
= efi_call_5 (b
->locate_handle
, search_type
, protocol
, search_key
,
76 &buffer_size
, buffer
);
77 if (status
== GRUB_EFI_BUFFER_TOO_SMALL
)
80 buffer
= grub_malloc (buffer_size
);
84 status
= efi_call_5 (b
->locate_handle
, search_type
, protocol
, search_key
,
85 &buffer_size
, buffer
);
88 if (status
!= GRUB_EFI_SUCCESS
)
94 *num_handles
= buffer_size
/ sizeof (grub_efi_handle_t
);
99 grub_efi_open_protocol (grub_efi_handle_t handle
,
100 grub_efi_guid_t
*protocol
,
101 grub_efi_uint32_t attributes
)
103 grub_efi_boot_services_t
*b
;
104 grub_efi_status_t status
;
107 b
= grub_efi_system_table
->boot_services
;
108 status
= efi_call_6 (b
->open_protocol
, handle
,
111 grub_efi_image_handle
,
114 if (status
!= GRUB_EFI_SUCCESS
)
121 grub_efi_set_text_mode (int on
)
123 grub_efi_console_control_protocol_t
*c
;
124 grub_efi_screen_mode_t mode
, new_mode
;
126 c
= grub_efi_locate_protocol (&console_control_guid
, 0);
128 /* No console control protocol instance available, assume it is
129 already in text mode. */
132 if (efi_call_4 (c
->get_mode
, c
, &mode
, 0, 0) != GRUB_EFI_SUCCESS
)
135 new_mode
= on
? GRUB_EFI_SCREEN_TEXT
: GRUB_EFI_SCREEN_GRAPHICS
;
136 if (mode
!= new_mode
)
137 if (efi_call_2 (c
->set_mode
, c
, new_mode
) != GRUB_EFI_SUCCESS
)
144 grub_efi_stall (grub_efi_uintn_t microseconds
)
146 efi_call_1 (grub_efi_system_table
->boot_services
->stall
, microseconds
);
149 grub_efi_loaded_image_t
*
150 grub_efi_get_loaded_image (grub_efi_handle_t image_handle
)
152 return grub_efi_open_protocol (image_handle
,
154 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
160 grub_machine_fini (GRUB_LOADER_FLAG_NORETURN
);
161 efi_call_4 (grub_efi_system_table
->boot_services
->exit
,
162 grub_efi_image_handle
, GRUB_EFI_SUCCESS
, 0, 0);
167 grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size
,
168 grub_efi_uintn_t descriptor_size
,
169 grub_efi_uint32_t descriptor_version
,
170 grub_efi_memory_descriptor_t
*virtual_map
)
172 grub_efi_runtime_services_t
*r
;
173 grub_efi_status_t status
;
175 r
= grub_efi_system_table
->runtime_services
;
176 status
= efi_call_4 (r
->set_virtual_address_map
, memory_map_size
,
177 descriptor_size
, descriptor_version
, virtual_map
);
179 if (status
== GRUB_EFI_SUCCESS
)
180 return GRUB_ERR_NONE
;
182 return grub_error (GRUB_ERR_IO
, "set_virtual_address_map failed");
186 grub_efi_set_variable(const char *var
, const grub_efi_guid_t
*guid
,
187 void *data
, grub_size_t datasize
)
189 grub_efi_status_t status
;
190 grub_efi_runtime_services_t
*r
;
191 grub_efi_char16_t
*var16
;
192 grub_size_t len
, len16
;
194 len
= grub_strlen (var
);
195 len16
= len
* GRUB_MAX_UTF16_PER_UTF8
;
196 var16
= grub_malloc ((len16
+ 1) * sizeof (var16
[0]));
199 len16
= grub_utf8_to_utf16 (var16
, len16
, (grub_uint8_t
*) var
, len
, NULL
);
202 r
= grub_efi_system_table
->runtime_services
;
204 status
= efi_call_5 (r
->set_variable
, var16
, guid
,
205 (GRUB_EFI_VARIABLE_NON_VOLATILE
206 | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
207 | GRUB_EFI_VARIABLE_RUNTIME_ACCESS
),
210 if (status
== GRUB_EFI_SUCCESS
)
211 return GRUB_ERR_NONE
;
213 return grub_error (GRUB_ERR_IO
, "could not set EFI variable `%s'", var
);
217 grub_efi_get_variable (const char *var
, const grub_efi_guid_t
*guid
,
218 grub_size_t
*datasize_out
)
220 grub_efi_status_t status
;
221 grub_efi_uintn_t datasize
= 0;
222 grub_efi_runtime_services_t
*r
;
223 grub_efi_char16_t
*var16
;
225 grub_size_t len
, len16
;
229 len
= grub_strlen (var
);
230 len16
= len
* GRUB_MAX_UTF16_PER_UTF8
;
231 var16
= grub_malloc ((len16
+ 1) * sizeof (var16
[0]));
234 len16
= grub_utf8_to_utf16 (var16
, len16
, (grub_uint8_t
*) var
, len
, NULL
);
237 r
= grub_efi_system_table
->runtime_services
;
239 status
= efi_call_5 (r
->get_variable
, var16
, guid
, NULL
, &datasize
, NULL
);
241 if (status
!= GRUB_EFI_BUFFER_TOO_SMALL
|| !datasize
)
247 data
= grub_malloc (datasize
);
254 status
= efi_call_5 (r
->get_variable
, var16
, guid
, NULL
, &datasize
, data
);
257 if (status
== GRUB_EFI_SUCCESS
)
259 *datasize_out
= datasize
;
268 grub_efi_secure_boot (void)
270 grub_efi_guid_t efi_var_guid
= GRUB_EFI_GLOBAL_VARIABLE_GUID
;
271 grub_size_t datasize
;
272 char *secure_boot
= NULL
;
273 char *setup_mode
= NULL
;
274 grub_efi_boolean_t ret
= 0;
276 secure_boot
= grub_efi_get_variable ("SecureBoot", &efi_var_guid
, &datasize
);
278 if (datasize
!= 1 || !secure_boot
)
281 setup_mode
= grub_efi_get_variable ("SetupMode", &efi_var_guid
, &datasize
);
283 if (datasize
!= 1 || !setup_mode
)
286 if (*secure_boot
&& !*setup_mode
)
290 grub_free (secure_boot
);
291 grub_free (setup_mode
);
295 #pragma GCC diagnostic ignored "-Wcast-align"
297 /* Search the mods section from the PE32/PE32+ image. This code uses
298 a PE32 header, but should work with PE32+ as well. */
300 grub_efi_modules_addr (void)
302 grub_efi_loaded_image_t
*image
;
303 struct grub_pe32_header
*header
;
304 struct grub_pe32_coff_header
*coff_header
;
305 struct grub_pe32_section_table
*sections
;
306 struct grub_pe32_section_table
*section
;
307 struct grub_module_info
*info
;
310 image
= grub_efi_get_loaded_image (grub_efi_image_handle
);
314 header
= image
->image_base
;
315 coff_header
= &(header
->coff_header
);
317 = (struct grub_pe32_section_table
*) ((char *) coff_header
318 + sizeof (*coff_header
)
319 + coff_header
->optional_header_size
);
321 for (i
= 0, section
= sections
;
322 i
< coff_header
->num_sections
;
325 if (grub_strcmp (section
->name
, "mods") == 0)
329 if (i
== coff_header
->num_sections
)
332 info
= (struct grub_module_info
*) ((char *) image
->image_base
333 + section
->virtual_address
);
334 if (info
->magic
!= GRUB_MODULE_MAGIC
)
337 return (grub_addr_t
) info
;
340 #pragma GCC diagnostic error "-Wcast-align"
343 grub_efi_get_filename (grub_efi_device_path_t
*dp0
)
345 char *name
= 0, *p
, *pi
;
346 grub_size_t filesize
= 0;
347 grub_efi_device_path_t
*dp
;
353 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
354 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
356 if (type
== GRUB_EFI_END_DEVICE_PATH_TYPE
)
358 if (type
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
359 && subtype
== GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
)
361 grub_efi_uint16_t len
;
362 len
= ((GRUB_EFI_DEVICE_PATH_LENGTH (dp
) - 4)
363 / sizeof (grub_efi_char16_t
));
364 filesize
+= GRUB_MAX_UTF8_PER_UTF16
* len
+ 2;
367 dp
= GRUB_EFI_NEXT_DEVICE_PATH (dp
);
375 p
= name
= grub_malloc (filesize
);
381 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
382 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
384 if (type
== GRUB_EFI_END_DEVICE_PATH_TYPE
)
386 else if (type
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
387 && subtype
== GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
)
389 grub_efi_file_path_device_path_t
*fp
;
390 grub_efi_uint16_t len
;
394 len
= ((GRUB_EFI_DEVICE_PATH_LENGTH (dp
) - 4)
395 / sizeof (grub_efi_char16_t
));
396 fp
= (grub_efi_file_path_device_path_t
*) dp
;
397 /* According to EFI spec Path Name is NULL terminated */
398 while (len
> 0 && fp
->path_name
[len
- 1] == 0)
401 p
= (char *) grub_utf16_to_utf8 ((unsigned char *) p
, fp
->path_name
, len
);
404 dp
= GRUB_EFI_NEXT_DEVICE_PATH (dp
);
409 for (pi
= name
, p
= name
; *pi
;)
411 /* EFI breaks paths with backslashes. */
412 if (*pi
== '\\' || *pi
== '/')
415 while (*pi
== '\\' || *pi
== '/')
426 grub_efi_device_path_t
*
427 grub_efi_get_device_path (grub_efi_handle_t handle
)
429 return grub_efi_open_protocol (handle
, &device_path_guid
,
430 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
433 /* Return the device path node right before the end node. */
434 grub_efi_device_path_t
*
435 grub_efi_find_last_device_path (const grub_efi_device_path_t
*dp
)
437 grub_efi_device_path_t
*next
, *p
;
439 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp
))
442 for (p
= (grub_efi_device_path_t
*) dp
, next
= GRUB_EFI_NEXT_DEVICE_PATH (p
);
443 ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next
);
444 p
= next
, next
= GRUB_EFI_NEXT_DEVICE_PATH (next
))
450 /* Duplicate a device path. */
451 grub_efi_device_path_t
*
452 grub_efi_duplicate_device_path (const grub_efi_device_path_t
*dp
)
454 grub_efi_device_path_t
*p
;
455 grub_size_t total_size
= 0;
457 for (p
= (grub_efi_device_path_t
*) dp
;
459 p
= GRUB_EFI_NEXT_DEVICE_PATH (p
))
461 total_size
+= GRUB_EFI_DEVICE_PATH_LENGTH (p
);
462 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p
))
466 p
= grub_malloc (total_size
);
470 grub_memcpy (p
, dp
, total_size
);
475 dump_vendor_path (const char *type
, grub_efi_vendor_device_path_t
*vendor
)
477 grub_uint32_t vendor_data_len
= vendor
->header
.length
- sizeof (*vendor
);
478 grub_printf ("/%sVendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ",
480 (unsigned) vendor
->vendor_guid
.data1
,
481 (unsigned) vendor
->vendor_guid
.data2
,
482 (unsigned) vendor
->vendor_guid
.data3
,
483 (unsigned) vendor
->vendor_guid
.data4
[0],
484 (unsigned) vendor
->vendor_guid
.data4
[1],
485 (unsigned) vendor
->vendor_guid
.data4
[2],
486 (unsigned) vendor
->vendor_guid
.data4
[3],
487 (unsigned) vendor
->vendor_guid
.data4
[4],
488 (unsigned) vendor
->vendor_guid
.data4
[5],
489 (unsigned) vendor
->vendor_guid
.data4
[6],
490 (unsigned) vendor
->vendor_guid
.data4
[7],
492 if (vendor
->header
.length
> sizeof (*vendor
))
495 for (i
= 0; i
< vendor_data_len
; i
++)
496 grub_printf ("%02x ", vendor
->vendor_defined_data
[i
]);
502 /* Print the chain of Device Path nodes. This is mainly for debugging. */
504 grub_efi_print_device_path (grub_efi_device_path_t
*dp
)
508 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
509 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
510 grub_efi_uint16_t len
= GRUB_EFI_DEVICE_PATH_LENGTH (dp
);
514 case GRUB_EFI_END_DEVICE_PATH_TYPE
:
517 case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
:
518 grub_printf ("/EndEntire\n");
519 //grub_putchar ('\n');
521 case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE
:
522 grub_printf ("/EndThis\n");
523 //grub_putchar ('\n');
526 grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype
);
531 case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE
:
534 case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE
:
536 grub_efi_pci_device_path_t
*pci
537 = (grub_efi_pci_device_path_t
*) dp
;
538 grub_printf ("/PCI(%x,%x)",
539 (unsigned) pci
->function
, (unsigned) pci
->device
);
542 case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE
:
544 grub_efi_pccard_device_path_t
*pccard
545 = (grub_efi_pccard_device_path_t
*) dp
;
546 grub_printf ("/PCCARD(%x)",
547 (unsigned) pccard
->function
);
550 case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE
:
552 grub_efi_memory_mapped_device_path_t
*mmapped
553 = (grub_efi_memory_mapped_device_path_t
*) dp
;
554 grub_printf ("/MMap(%x,%llx,%llx)",
555 (unsigned) mmapped
->memory_type
,
556 (unsigned long long) mmapped
->start_address
,
557 (unsigned long long) mmapped
->end_address
);
560 case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE
:
561 dump_vendor_path ("Hardware",
562 (grub_efi_vendor_device_path_t
*) dp
);
564 case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE
:
566 grub_efi_controller_device_path_t
*controller
567 = (grub_efi_controller_device_path_t
*) dp
;
568 grub_printf ("/Ctrl(%x)",
569 (unsigned) controller
->controller_number
);
573 grub_printf ("/UnknownHW(%x)", (unsigned) subtype
);
578 case GRUB_EFI_ACPI_DEVICE_PATH_TYPE
:
581 case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE
:
583 grub_efi_acpi_device_path_t
*acpi
584 = (grub_efi_acpi_device_path_t
*) dp
;
585 grub_printf ("/ACPI(%x,%x)",
586 (unsigned) acpi
->hid
,
587 (unsigned) acpi
->uid
);
590 case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE
:
592 grub_efi_expanded_acpi_device_path_t
*eacpi
593 = (grub_efi_expanded_acpi_device_path_t
*) dp
;
594 grub_printf ("/ACPI(");
596 if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp
)[0] == '\0')
597 grub_printf ("%x,", (unsigned) eacpi
->hid
);
599 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp
));
601 if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp
)[0] == '\0')
602 grub_printf ("%x,", (unsigned) eacpi
->uid
);
604 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp
));
606 if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp
)[0] == '\0')
607 grub_printf ("%x)", (unsigned) eacpi
->cid
);
609 grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp
));
613 grub_printf ("/UnknownACPI(%x)", (unsigned) subtype
);
618 case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
:
621 case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE
:
623 grub_efi_atapi_device_path_t
*atapi
624 = (grub_efi_atapi_device_path_t
*) dp
;
625 grub_printf ("/ATAPI(%x,%x,%x)",
626 (unsigned) atapi
->primary_secondary
,
627 (unsigned) atapi
->slave_master
,
628 (unsigned) atapi
->lun
);
631 case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE
:
633 grub_efi_scsi_device_path_t
*scsi
634 = (grub_efi_scsi_device_path_t
*) dp
;
635 grub_printf ("/SCSI(%x,%x)",
636 (unsigned) scsi
->pun
,
637 (unsigned) scsi
->lun
);
640 case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE
:
642 grub_efi_fibre_channel_device_path_t
*fc
643 = (grub_efi_fibre_channel_device_path_t
*) dp
;
644 grub_printf ("/FibreChannel(%llx,%llx)",
645 (unsigned long long) fc
->wwn
,
646 (unsigned long long) fc
->lun
);
649 case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE
:
651 grub_efi_1394_device_path_t
*firewire
652 = (grub_efi_1394_device_path_t
*) dp
;
653 grub_printf ("/1394(%llx)",
654 (unsigned long long) firewire
->guid
);
657 case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE
:
659 grub_efi_usb_device_path_t
*usb
660 = (grub_efi_usb_device_path_t
*) dp
;
661 grub_printf ("/USB(%x,%x)",
662 (unsigned) usb
->parent_port_number
,
663 (unsigned) usb
->usb_interface
);
666 case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE
:
668 grub_efi_usb_class_device_path_t
*usb_class
669 = (grub_efi_usb_class_device_path_t
*) dp
;
670 grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
671 (unsigned) usb_class
->vendor_id
,
672 (unsigned) usb_class
->product_id
,
673 (unsigned) usb_class
->device_class
,
674 (unsigned) usb_class
->device_subclass
,
675 (unsigned) usb_class
->device_protocol
);
678 case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE
:
680 grub_efi_i2o_device_path_t
*i2o
681 = (grub_efi_i2o_device_path_t
*) dp
;
682 grub_printf ("/I2O(%x)", (unsigned) i2o
->tid
);
685 case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
:
687 grub_efi_mac_address_device_path_t
*mac
688 = (grub_efi_mac_address_device_path_t
*) dp
;
689 grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
690 (unsigned) mac
->mac_address
[0],
691 (unsigned) mac
->mac_address
[1],
692 (unsigned) mac
->mac_address
[2],
693 (unsigned) mac
->mac_address
[3],
694 (unsigned) mac
->mac_address
[4],
695 (unsigned) mac
->mac_address
[5],
696 (unsigned) mac
->if_type
);
699 case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
:
701 grub_efi_ipv4_device_path_t
*ipv4
702 = (grub_efi_ipv4_device_path_t
*) dp
;
703 grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
704 (unsigned) ipv4
->local_ip_address
[0],
705 (unsigned) ipv4
->local_ip_address
[1],
706 (unsigned) ipv4
->local_ip_address
[2],
707 (unsigned) ipv4
->local_ip_address
[3],
708 (unsigned) ipv4
->remote_ip_address
[0],
709 (unsigned) ipv4
->remote_ip_address
[1],
710 (unsigned) ipv4
->remote_ip_address
[2],
711 (unsigned) ipv4
->remote_ip_address
[3],
712 (unsigned) ipv4
->local_port
,
713 (unsigned) ipv4
->remote_port
,
714 (unsigned) ipv4
->protocol
,
715 (unsigned) ipv4
->static_ip_address
);
718 case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE
:
720 grub_efi_ipv6_device_path_t
*ipv6
721 = (grub_efi_ipv6_device_path_t
*) dp
;
722 grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
723 (unsigned) ipv6
->local_ip_address
[0],
724 (unsigned) ipv6
->local_ip_address
[1],
725 (unsigned) ipv6
->local_ip_address
[2],
726 (unsigned) ipv6
->local_ip_address
[3],
727 (unsigned) ipv6
->local_ip_address
[4],
728 (unsigned) ipv6
->local_ip_address
[5],
729 (unsigned) ipv6
->local_ip_address
[6],
730 (unsigned) ipv6
->local_ip_address
[7],
731 (unsigned) ipv6
->remote_ip_address
[0],
732 (unsigned) ipv6
->remote_ip_address
[1],
733 (unsigned) ipv6
->remote_ip_address
[2],
734 (unsigned) ipv6
->remote_ip_address
[3],
735 (unsigned) ipv6
->remote_ip_address
[4],
736 (unsigned) ipv6
->remote_ip_address
[5],
737 (unsigned) ipv6
->remote_ip_address
[6],
738 (unsigned) ipv6
->remote_ip_address
[7],
739 (unsigned) ipv6
->local_port
,
740 (unsigned) ipv6
->remote_port
,
741 (unsigned) ipv6
->protocol
,
742 (unsigned) ipv6
->static_ip_address
);
745 case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE
:
747 grub_efi_infiniband_device_path_t
*ib
748 = (grub_efi_infiniband_device_path_t
*) dp
;
749 grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
750 (unsigned) ib
->port_gid
[0], /* XXX */
751 (unsigned long long) ib
->remote_id
,
752 (unsigned long long) ib
->target_port_id
,
753 (unsigned long long) ib
->device_id
);
756 case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE
:
758 grub_efi_uart_device_path_t
*uart
759 = (grub_efi_uart_device_path_t
*) dp
;
760 grub_printf ("/UART(%llu,%u,%x,%x)",
761 (unsigned long long) uart
->baud_rate
,
767 case GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE
:
769 grub_efi_sata_device_path_t
*sata
;
770 sata
= (grub_efi_sata_device_path_t
*) dp
;
771 grub_printf ("/Sata(%x,%x,%x)",
773 sata
->multiplier_port
,
778 case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE
:
779 dump_vendor_path ("Messaging",
780 (grub_efi_vendor_device_path_t
*) dp
);
783 grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype
);
788 case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
:
791 case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE
:
793 grub_efi_hard_drive_device_path_t
*hd
= (grub_efi_hard_drive_device_path_t
*) dp
;
794 grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
795 hd
->partition_number
,
796 (unsigned long long) hd
->partition_start
,
797 (unsigned long long) hd
->partition_size
,
798 (unsigned) hd
->partition_signature
[0],
799 (unsigned) hd
->partition_signature
[1],
800 (unsigned) hd
->partition_signature
[2],
801 (unsigned) hd
->partition_signature
[3],
802 (unsigned) hd
->partition_signature
[4],
803 (unsigned) hd
->partition_signature
[5],
804 (unsigned) hd
->partition_signature
[6],
805 (unsigned) hd
->partition_signature
[7],
806 (unsigned) hd
->partmap_type
,
807 (unsigned) hd
->signature_type
);
810 case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
:
812 grub_efi_cdrom_device_path_t
*cd
813 = (grub_efi_cdrom_device_path_t
*) dp
;
814 grub_printf ("/CD(%u,%llx,%llx)",
816 (unsigned long long) cd
->partition_start
,
817 (unsigned long long) cd
->partition_size
);
820 case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE
:
821 dump_vendor_path ("Media",
822 (grub_efi_vendor_device_path_t
*) dp
);
824 case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
:
826 grub_efi_file_path_device_path_t
*fp
;
828 fp
= (grub_efi_file_path_device_path_t
*) dp
;
829 buf
= grub_malloc ((len
- 4) * 2 + 1);
831 *grub_utf16_to_utf8 (buf
, fp
->path_name
,
832 (len
- 4) / sizeof (grub_efi_char16_t
))
835 grub_errno
= GRUB_ERR_NONE
;
836 grub_printf ("/File(%s)", buf
);
840 case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE
:
842 grub_efi_protocol_device_path_t
*proto
843 = (grub_efi_protocol_device_path_t
*) dp
;
844 grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
845 (unsigned) proto
->guid
.data1
,
846 (unsigned) proto
->guid
.data2
,
847 (unsigned) proto
->guid
.data3
,
848 (unsigned) proto
->guid
.data4
[0],
849 (unsigned) proto
->guid
.data4
[1],
850 (unsigned) proto
->guid
.data4
[2],
851 (unsigned) proto
->guid
.data4
[3],
852 (unsigned) proto
->guid
.data4
[4],
853 (unsigned) proto
->guid
.data4
[5],
854 (unsigned) proto
->guid
.data4
[6],
855 (unsigned) proto
->guid
.data4
[7]);
859 grub_printf ("/UnknownMedia(%x)", (unsigned) subtype
);
864 case GRUB_EFI_BIOS_DEVICE_PATH_TYPE
:
867 case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE
:
869 grub_efi_bios_device_path_t
*bios
870 = (grub_efi_bios_device_path_t
*) dp
;
871 grub_printf ("/BIOS(%x,%x,%s)",
872 (unsigned) bios
->device_type
,
873 (unsigned) bios
->status_flags
,
878 grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype
);
884 grub_printf ("/UnknownType(%x,%x)\n",
891 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp
))
894 dp
= (grub_efi_device_path_t
*) ((char *) dp
+ len
);
898 /* Compare device paths. */
900 grub_efi_compare_device_paths (const grub_efi_device_path_t
*dp1
,
901 const grub_efi_device_path_t
*dp2
)
904 /* Return non-zero. */
909 grub_efi_uint8_t type1
, type2
;
910 grub_efi_uint8_t subtype1
, subtype2
;
911 grub_efi_uint16_t len1
, len2
;
914 type1
= GRUB_EFI_DEVICE_PATH_TYPE (dp1
);
915 type2
= GRUB_EFI_DEVICE_PATH_TYPE (dp2
);
918 return (int) type2
- (int) type1
;
920 subtype1
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1
);
921 subtype2
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2
);
923 if (subtype1
!= subtype2
)
924 return (int) subtype1
- (int) subtype2
;
926 len1
= GRUB_EFI_DEVICE_PATH_LENGTH (dp1
);
927 len2
= GRUB_EFI_DEVICE_PATH_LENGTH (dp2
);
930 return (int) len1
- (int) len2
;
932 ret
= grub_memcmp (dp1
, dp2
, len1
);
936 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1
))
939 dp1
= (grub_efi_device_path_t
*) ((char *) dp1
+ len1
);
940 dp2
= (grub_efi_device_path_t
*) ((char *) dp2
+ len2
);