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->runtime_services->reset_system,
162 GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
169 grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
170 efi_call_4 (grub_efi_system_table->boot_services->exit,
171 grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
176 grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
177 grub_efi_uintn_t descriptor_size,
178 grub_efi_uint32_t descriptor_version,
179 grub_efi_memory_descriptor_t *virtual_map)
181 grub_efi_runtime_services_t *r;
182 grub_efi_status_t status;
184 r = grub_efi_system_table->runtime_services;
185 status = efi_call_4 (r->set_virtual_address_map, memory_map_size,
186 descriptor_size, descriptor_version, virtual_map);
188 if (status == GRUB_EFI_SUCCESS)
189 return GRUB_ERR_NONE;
191 return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed");
195 grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
196 void *data, grub_size_t datasize)
198 grub_efi_status_t status;
199 grub_efi_runtime_services_t *r;
200 grub_efi_char16_t *var16;
201 grub_size_t len, len16;
203 len = grub_strlen (var);
204 len16 = len * GRUB_MAX_UTF16_PER_UTF8;
205 var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
208 len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
211 r = grub_efi_system_table->runtime_services;
213 status = efi_call_5 (r->set_variable, var16, guid,
214 (GRUB_EFI_VARIABLE_NON_VOLATILE
215 | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
216 | GRUB_EFI_VARIABLE_RUNTIME_ACCESS),
219 if (status == GRUB_EFI_SUCCESS)
220 return GRUB_ERR_NONE;
222 return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
226 grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
227 grub_size_t *datasize_out)
229 grub_efi_status_t status;
230 grub_efi_uintn_t datasize = 0;
231 grub_efi_runtime_services_t *r;
232 grub_efi_char16_t *var16;
234 grub_size_t len, len16;
238 len = grub_strlen (var);
239 len16 = len * GRUB_MAX_UTF16_PER_UTF8;
240 var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
243 len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
246 r = grub_efi_system_table->runtime_services;
248 status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL);
250 if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
256 data = grub_malloc (datasize);
263 status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
266 if (status == GRUB_EFI_SUCCESS)
268 *datasize_out = datasize;
276 #pragma GCC diagnostic ignored "-Wcast-align"
278 /* Search the mods section from the PE32/PE32+ image. This code uses
279 a PE32 header, but should work with PE32+ as well. */
281 grub_efi_modules_addr (void)
283 grub_efi_loaded_image_t *image;
284 struct grub_pe32_header *header;
285 struct grub_pe32_coff_header *coff_header;
286 struct grub_pe32_section_table *sections;
287 struct grub_pe32_section_table *section;
288 struct grub_module_info *info;
291 image = grub_efi_get_loaded_image (grub_efi_image_handle);
295 header = image->image_base;
296 coff_header = &(header->coff_header);
298 = (struct grub_pe32_section_table *) ((char *) coff_header
299 + sizeof (*coff_header)
300 + coff_header->optional_header_size);
302 for (i = 0, section = sections;
303 i < coff_header->num_sections;
306 if (grub_strcmp (section->name, "mods") == 0)
310 if (i == coff_header->num_sections)
313 info = (struct grub_module_info *) ((char *) image->image_base
314 + section->virtual_address);
315 if (info->magic != GRUB_MODULE_MAGIC)
318 return (grub_addr_t) info;
321 #pragma GCC diagnostic error "-Wcast-align"
324 grub_efi_get_filename (grub_efi_device_path_t *dp0)
326 char *name = 0, *p, *pi;
327 grub_size_t filesize = 0;
328 grub_efi_device_path_t *dp;
334 grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
335 grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
337 if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
339 if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
340 && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
342 grub_efi_uint16_t len;
343 len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
344 / sizeof (grub_efi_char16_t));
345 filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
348 dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
356 p = name = grub_malloc (filesize);
362 grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
363 grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
365 if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
367 else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
368 && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
370 grub_efi_file_path_device_path_t *fp;
371 grub_efi_uint16_t len;
375 len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
376 / sizeof (grub_efi_char16_t));
377 fp = (grub_efi_file_path_device_path_t *) dp;
378 /* According to EFI spec Path Name is NULL terminated */
379 while (len > 0 && fp->path_name[len - 1] == 0)
382 p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len);
385 dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
390 for (pi = name, p = name; *pi;)
392 /* EFI breaks paths with backslashes. */
393 if (*pi == '\\' || *pi == '/')
396 while (*pi == '\\' || *pi == '/')
407 grub_efi_device_path_t *
408 grub_efi_get_device_path (grub_efi_handle_t handle)
410 return grub_efi_open_protocol (handle, &device_path_guid,
411 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
414 /* Return the device path node right before the end node. */
415 grub_efi_device_path_t *
416 grub_efi_find_last_device_path (const grub_efi_device_path_t *dp)
418 grub_efi_device_path_t *next, *p;
420 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
423 for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
424 ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
425 p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
431 /* Duplicate a device path. */
432 grub_efi_device_path_t *
433 grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
435 grub_efi_device_path_t *p;
436 grub_size_t total_size = 0;
438 for (p = (grub_efi_device_path_t *) dp;
440 p = GRUB_EFI_NEXT_DEVICE_PATH (p))
442 total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
443 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
447 p = grub_malloc (total_size);
451 grub_memcpy (p, dp, total_size);
456 dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
458 grub_uint32_t vendor_data_len = vendor->header.length - sizeof (*vendor);
459 grub_printf ("/%sVendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ",
461 (unsigned) vendor->vendor_guid.data1,
462 (unsigned) vendor->vendor_guid.data2,
463 (unsigned) vendor->vendor_guid.data3,
464 (unsigned) vendor->vendor_guid.data4[0],
465 (unsigned) vendor->vendor_guid.data4[1],
466 (unsigned) vendor->vendor_guid.data4[2],
467 (unsigned) vendor->vendor_guid.data4[3],
468 (unsigned) vendor->vendor_guid.data4[4],
469 (unsigned) vendor->vendor_guid.data4[5],
470 (unsigned) vendor->vendor_guid.data4[6],
471 (unsigned) vendor->vendor_guid.data4[7],
473 if (vendor->header.length > sizeof (*vendor))
476 for (i = 0; i < vendor_data_len; i++)
477 grub_printf ("%02x ", vendor->vendor_defined_data[i]);
483 /* Print the chain of Device Path nodes. This is mainly for debugging. */
485 grub_efi_print_device_path (grub_efi_device_path_t *dp)
489 grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
490 grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
491 grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
495 case GRUB_EFI_END_DEVICE_PATH_TYPE:
498 case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
499 grub_printf ("/EndEntire\n");
500 //grub_putchar ('\n');
502 case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
503 grub_printf ("/EndThis\n");
504 //grub_putchar ('\n');
507 grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
512 case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE:
515 case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE:
517 grub_efi_pci_device_path_t *pci
518 = (grub_efi_pci_device_path_t *) dp;
519 grub_printf ("/PCI(%x,%x)",
520 (unsigned) pci->function, (unsigned) pci->device);
523 case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE:
525 grub_efi_pccard_device_path_t *pccard
526 = (grub_efi_pccard_device_path_t *) dp;
527 grub_printf ("/PCCARD(%x)",
528 (unsigned) pccard->function);
531 case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE:
533 grub_efi_memory_mapped_device_path_t *mmapped
534 = (grub_efi_memory_mapped_device_path_t *) dp;
535 grub_printf ("/MMap(%x,%llx,%llx)",
536 (unsigned) mmapped->memory_type,
537 (unsigned long long) mmapped->start_address,
538 (unsigned long long) mmapped->end_address);
541 case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
542 dump_vendor_path ("Hardware",
543 (grub_efi_vendor_device_path_t *) dp);
545 case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
547 grub_efi_controller_device_path_t *controller
548 = (grub_efi_controller_device_path_t *) dp;
549 grub_printf ("/Ctrl(%x)",
550 (unsigned) controller->controller_number);
554 grub_printf ("/UnknownHW(%x)", (unsigned) subtype);
559 case GRUB_EFI_ACPI_DEVICE_PATH_TYPE:
562 case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE:
564 grub_efi_acpi_device_path_t *acpi
565 = (grub_efi_acpi_device_path_t *) dp;
566 grub_printf ("/ACPI(%x,%x)",
567 (unsigned) acpi->hid,
568 (unsigned) acpi->uid);
571 case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
573 grub_efi_expanded_acpi_device_path_t *eacpi
574 = (grub_efi_expanded_acpi_device_path_t *) dp;
575 grub_printf ("/ACPI(");
577 if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
578 grub_printf ("%x,", (unsigned) eacpi->hid);
580 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
582 if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
583 grub_printf ("%x,", (unsigned) eacpi->uid);
585 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
587 if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
588 grub_printf ("%x)", (unsigned) eacpi->cid);
590 grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp));
594 grub_printf ("/UnknownACPI(%x)", (unsigned) subtype);
599 case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE:
602 case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE:
604 grub_efi_atapi_device_path_t *atapi
605 = (grub_efi_atapi_device_path_t *) dp;
606 grub_printf ("/ATAPI(%x,%x,%x)",
607 (unsigned) atapi->primary_secondary,
608 (unsigned) atapi->slave_master,
609 (unsigned) atapi->lun);
612 case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE:
614 grub_efi_scsi_device_path_t *scsi
615 = (grub_efi_scsi_device_path_t *) dp;
616 grub_printf ("/SCSI(%x,%x)",
617 (unsigned) scsi->pun,
618 (unsigned) scsi->lun);
621 case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
623 grub_efi_fibre_channel_device_path_t *fc
624 = (grub_efi_fibre_channel_device_path_t *) dp;
625 grub_printf ("/FibreChannel(%llx,%llx)",
626 (unsigned long long) fc->wwn,
627 (unsigned long long) fc->lun);
630 case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE:
632 grub_efi_1394_device_path_t *firewire
633 = (grub_efi_1394_device_path_t *) dp;
634 grub_printf ("/1394(%llx)",
635 (unsigned long long) firewire->guid);
638 case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE:
640 grub_efi_usb_device_path_t *usb
641 = (grub_efi_usb_device_path_t *) dp;
642 grub_printf ("/USB(%x,%x)",
643 (unsigned) usb->parent_port_number,
644 (unsigned) usb->usb_interface);
647 case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
649 grub_efi_usb_class_device_path_t *usb_class
650 = (grub_efi_usb_class_device_path_t *) dp;
651 grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
652 (unsigned) usb_class->vendor_id,
653 (unsigned) usb_class->product_id,
654 (unsigned) usb_class->device_class,
655 (unsigned) usb_class->device_subclass,
656 (unsigned) usb_class->device_protocol);
659 case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE:
661 grub_efi_i2o_device_path_t *i2o
662 = (grub_efi_i2o_device_path_t *) dp;
663 grub_printf ("/I2O(%x)", (unsigned) i2o->tid);
666 case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
668 grub_efi_mac_address_device_path_t *mac
669 = (grub_efi_mac_address_device_path_t *) dp;
670 grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
671 (unsigned) mac->mac_address[0],
672 (unsigned) mac->mac_address[1],
673 (unsigned) mac->mac_address[2],
674 (unsigned) mac->mac_address[3],
675 (unsigned) mac->mac_address[4],
676 (unsigned) mac->mac_address[5],
677 (unsigned) mac->if_type);
680 case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE:
682 grub_efi_ipv4_device_path_t *ipv4
683 = (grub_efi_ipv4_device_path_t *) dp;
684 grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
685 (unsigned) ipv4->local_ip_address[0],
686 (unsigned) ipv4->local_ip_address[1],
687 (unsigned) ipv4->local_ip_address[2],
688 (unsigned) ipv4->local_ip_address[3],
689 (unsigned) ipv4->remote_ip_address[0],
690 (unsigned) ipv4->remote_ip_address[1],
691 (unsigned) ipv4->remote_ip_address[2],
692 (unsigned) ipv4->remote_ip_address[3],
693 (unsigned) ipv4->local_port,
694 (unsigned) ipv4->remote_port,
695 (unsigned) ipv4->protocol,
696 (unsigned) ipv4->static_ip_address);
699 case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE:
701 grub_efi_ipv6_device_path_t *ipv6
702 = (grub_efi_ipv6_device_path_t *) dp;
703 grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
704 (unsigned) ipv6->local_ip_address[0],
705 (unsigned) ipv6->local_ip_address[1],
706 (unsigned) ipv6->local_ip_address[2],
707 (unsigned) ipv6->local_ip_address[3],
708 (unsigned) ipv6->local_ip_address[4],
709 (unsigned) ipv6->local_ip_address[5],
710 (unsigned) ipv6->local_ip_address[6],
711 (unsigned) ipv6->local_ip_address[7],
712 (unsigned) ipv6->remote_ip_address[0],
713 (unsigned) ipv6->remote_ip_address[1],
714 (unsigned) ipv6->remote_ip_address[2],
715 (unsigned) ipv6->remote_ip_address[3],
716 (unsigned) ipv6->remote_ip_address[4],
717 (unsigned) ipv6->remote_ip_address[5],
718 (unsigned) ipv6->remote_ip_address[6],
719 (unsigned) ipv6->remote_ip_address[7],
720 (unsigned) ipv6->local_port,
721 (unsigned) ipv6->remote_port,
722 (unsigned) ipv6->protocol,
723 (unsigned) ipv6->static_ip_address);
726 case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
728 grub_efi_infiniband_device_path_t *ib
729 = (grub_efi_infiniband_device_path_t *) dp;
730 grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
731 (unsigned) ib->port_gid[0], /* XXX */
732 (unsigned long long) ib->remote_id,
733 (unsigned long long) ib->target_port_id,
734 (unsigned long long) ib->device_id);
737 case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE:
739 grub_efi_uart_device_path_t *uart
740 = (grub_efi_uart_device_path_t *) dp;
741 grub_printf ("/UART(%llu,%u,%x,%x)",
742 (unsigned long long) uart->baud_rate,
748 case GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE:
750 grub_efi_sata_device_path_t *sata;
751 sata = (grub_efi_sata_device_path_t *) dp;
752 grub_printf ("/Sata(%x,%x,%x)",
754 sata->multiplier_port,
759 case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
760 dump_vendor_path ("Messaging",
761 (grub_efi_vendor_device_path_t *) dp);
764 grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
769 case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE:
772 case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
774 grub_efi_hard_drive_device_path_t *hd = (grub_efi_hard_drive_device_path_t *) dp;
775 grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
776 hd->partition_number,
777 (unsigned long long) hd->partition_start,
778 (unsigned long long) hd->partition_size,
779 (unsigned) hd->partition_signature[0],
780 (unsigned) hd->partition_signature[1],
781 (unsigned) hd->partition_signature[2],
782 (unsigned) hd->partition_signature[3],
783 (unsigned) hd->partition_signature[4],
784 (unsigned) hd->partition_signature[5],
785 (unsigned) hd->partition_signature[6],
786 (unsigned) hd->partition_signature[7],
787 (unsigned) hd->partmap_type,
788 (unsigned) hd->signature_type);
791 case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
793 grub_efi_cdrom_device_path_t *cd
794 = (grub_efi_cdrom_device_path_t *) dp;
795 grub_printf ("/CD(%u,%llx,%llx)",
797 (unsigned long long) cd->partition_start,
798 (unsigned long long) cd->partition_size);
801 case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
802 dump_vendor_path ("Media",
803 (grub_efi_vendor_device_path_t *) dp);
805 case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
807 grub_efi_file_path_device_path_t *fp;
809 fp = (grub_efi_file_path_device_path_t *) dp;
810 buf = grub_malloc ((len - 4) * 2 + 1);
812 *grub_utf16_to_utf8 (buf, fp->path_name,
813 (len - 4) / sizeof (grub_efi_char16_t))
816 grub_errno = GRUB_ERR_NONE;
817 grub_printf ("/File(%s)", buf);
821 case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
823 grub_efi_protocol_device_path_t *proto
824 = (grub_efi_protocol_device_path_t *) dp;
825 grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
826 (unsigned) proto->guid.data1,
827 (unsigned) proto->guid.data2,
828 (unsigned) proto->guid.data3,
829 (unsigned) proto->guid.data4[0],
830 (unsigned) proto->guid.data4[1],
831 (unsigned) proto->guid.data4[2],
832 (unsigned) proto->guid.data4[3],
833 (unsigned) proto->guid.data4[4],
834 (unsigned) proto->guid.data4[5],
835 (unsigned) proto->guid.data4[6],
836 (unsigned) proto->guid.data4[7]);
840 grub_printf ("/UnknownMedia(%x)", (unsigned) subtype);
845 case GRUB_EFI_BIOS_DEVICE_PATH_TYPE:
848 case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE:
850 grub_efi_bios_device_path_t *bios
851 = (grub_efi_bios_device_path_t *) dp;
852 grub_printf ("/BIOS(%x,%x,%s)",
853 (unsigned) bios->device_type,
854 (unsigned) bios->status_flags,
859 grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype);
865 grub_printf ("/UnknownType(%x,%x)\n",
872 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
875 dp = (grub_efi_device_path_t *) ((char *) dp + len);
879 /* Compare device paths. */
881 grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
882 const grub_efi_device_path_t *dp2)
885 /* Return non-zero. */
890 grub_efi_uint8_t type1, type2;
891 grub_efi_uint8_t subtype1, subtype2;
892 grub_efi_uint16_t len1, len2;
895 type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
896 type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
899 return (int) type2 - (int) type1;
901 subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
902 subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
904 if (subtype1 != subtype2)
905 return (int) subtype1 - (int) subtype2;
907 len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
908 len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
911 return (int) len1 - (int) len2;
913 ret = grub_memcmp (dp1, dp2, len1);
917 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
920 dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
921 dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);