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
;
337 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
338 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
340 if (type
== GRUB_EFI_END_DEVICE_PATH_TYPE
)
342 if (type
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
343 && subtype
== GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
)
345 grub_efi_uint16_t len
;
346 len
= ((GRUB_EFI_DEVICE_PATH_LENGTH (dp
) - 4)
347 / sizeof (grub_efi_char16_t
));
348 filesize
+= GRUB_MAX_UTF8_PER_UTF16
* len
+ 2;
351 dp
= GRUB_EFI_NEXT_DEVICE_PATH (dp
);
359 p
= name
= grub_malloc (filesize
);
365 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
366 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
368 if (type
== GRUB_EFI_END_DEVICE_PATH_TYPE
)
370 else if (type
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
371 && subtype
== GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
)
373 grub_efi_file_path_device_path_t
*fp
;
374 grub_efi_uint16_t len
;
375 grub_efi_char16_t
*dup_name
;
379 len
= ((GRUB_EFI_DEVICE_PATH_LENGTH (dp
) - 4)
380 / sizeof (grub_efi_char16_t
));
381 fp
= (grub_efi_file_path_device_path_t
*) dp
;
382 /* According to EFI spec Path Name is NULL terminated */
383 while (len
> 0 && fp
->path_name
[len
- 1] == 0)
386 dup_name
= grub_malloc (len
* sizeof (*dup_name
));
392 p
= (char *) grub_utf16_to_utf8 ((unsigned char *) p
,
393 grub_memcpy (dup_name
, fp
->path_name
, len
* sizeof (*dup_name
)),
395 grub_free (dup_name
);
398 dp
= GRUB_EFI_NEXT_DEVICE_PATH (dp
);
403 for (pi
= name
, p
= name
; *pi
;)
405 /* EFI breaks paths with backslashes. */
406 if (*pi
== '\\' || *pi
== '/')
409 while (*pi
== '\\' || *pi
== '/')
420 grub_efi_device_path_t
*
421 grub_efi_get_device_path (grub_efi_handle_t handle
)
423 return grub_efi_open_protocol (handle
, &device_path_guid
,
424 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
427 /* Return the device path node right before the end node. */
428 grub_efi_device_path_t
*
429 grub_efi_find_last_device_path (const grub_efi_device_path_t
*dp
)
431 grub_efi_device_path_t
*next
, *p
;
433 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp
))
436 for (p
= (grub_efi_device_path_t
*) dp
, next
= GRUB_EFI_NEXT_DEVICE_PATH (p
);
437 ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next
);
438 p
= next
, next
= GRUB_EFI_NEXT_DEVICE_PATH (next
))
444 /* Duplicate a device path. */
445 grub_efi_device_path_t
*
446 grub_efi_duplicate_device_path (const grub_efi_device_path_t
*dp
)
448 grub_efi_device_path_t
*p
;
449 grub_size_t total_size
= 0;
451 for (p
= (grub_efi_device_path_t
*) dp
;
453 p
= GRUB_EFI_NEXT_DEVICE_PATH (p
))
455 total_size
+= GRUB_EFI_DEVICE_PATH_LENGTH (p
);
456 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p
))
460 p
= grub_malloc (total_size
);
464 grub_memcpy (p
, dp
, total_size
);
469 dump_vendor_path (const char *type
, grub_efi_vendor_device_path_t
*vendor
)
471 grub_uint32_t vendor_data_len
= vendor
->header
.length
- sizeof (*vendor
);
472 grub_printf ("/%sVendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ",
474 (unsigned) vendor
->vendor_guid
.data1
,
475 (unsigned) vendor
->vendor_guid
.data2
,
476 (unsigned) vendor
->vendor_guid
.data3
,
477 (unsigned) vendor
->vendor_guid
.data4
[0],
478 (unsigned) vendor
->vendor_guid
.data4
[1],
479 (unsigned) vendor
->vendor_guid
.data4
[2],
480 (unsigned) vendor
->vendor_guid
.data4
[3],
481 (unsigned) vendor
->vendor_guid
.data4
[4],
482 (unsigned) vendor
->vendor_guid
.data4
[5],
483 (unsigned) vendor
->vendor_guid
.data4
[6],
484 (unsigned) vendor
->vendor_guid
.data4
[7],
486 if (vendor
->header
.length
> sizeof (*vendor
))
489 for (i
= 0; i
< vendor_data_len
; i
++)
490 grub_printf ("%02x ", vendor
->vendor_defined_data
[i
]);
496 /* Print the chain of Device Path nodes. This is mainly for debugging. */
498 grub_efi_print_device_path (grub_efi_device_path_t
*dp
)
502 grub_efi_uint8_t type
= GRUB_EFI_DEVICE_PATH_TYPE (dp
);
503 grub_efi_uint8_t subtype
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp
);
504 grub_efi_uint16_t len
= GRUB_EFI_DEVICE_PATH_LENGTH (dp
);
508 case GRUB_EFI_END_DEVICE_PATH_TYPE
:
511 case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
:
512 grub_printf ("/EndEntire\n");
513 //grub_putchar ('\n');
515 case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE
:
516 grub_printf ("/EndThis\n");
517 //grub_putchar ('\n');
520 grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype
);
525 case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE
:
528 case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE
:
530 grub_efi_pci_device_path_t
*pci
531 = (grub_efi_pci_device_path_t
*) dp
;
532 grub_printf ("/PCI(%x,%x)",
533 (unsigned) pci
->function
, (unsigned) pci
->device
);
536 case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE
:
538 grub_efi_pccard_device_path_t
*pccard
539 = (grub_efi_pccard_device_path_t
*) dp
;
540 grub_printf ("/PCCARD(%x)",
541 (unsigned) pccard
->function
);
544 case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE
:
546 grub_efi_memory_mapped_device_path_t
*mmapped
547 = (grub_efi_memory_mapped_device_path_t
*) dp
;
548 grub_printf ("/MMap(%x,%llx,%llx)",
549 (unsigned) mmapped
->memory_type
,
550 (unsigned long long) mmapped
->start_address
,
551 (unsigned long long) mmapped
->end_address
);
554 case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE
:
555 dump_vendor_path ("Hardware",
556 (grub_efi_vendor_device_path_t
*) dp
);
558 case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE
:
560 grub_efi_controller_device_path_t
*controller
561 = (grub_efi_controller_device_path_t
*) dp
;
562 grub_printf ("/Ctrl(%x)",
563 (unsigned) controller
->controller_number
);
567 grub_printf ("/UnknownHW(%x)", (unsigned) subtype
);
572 case GRUB_EFI_ACPI_DEVICE_PATH_TYPE
:
575 case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE
:
577 grub_efi_acpi_device_path_t
*acpi
578 = (grub_efi_acpi_device_path_t
*) dp
;
579 grub_printf ("/ACPI(%x,%x)",
580 (unsigned) acpi
->hid
,
581 (unsigned) acpi
->uid
);
584 case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE
:
586 grub_efi_expanded_acpi_device_path_t
*eacpi
587 = (grub_efi_expanded_acpi_device_path_t
*) dp
;
588 grub_printf ("/ACPI(");
590 if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp
)[0] == '\0')
591 grub_printf ("%x,", (unsigned) eacpi
->hid
);
593 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp
));
595 if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp
)[0] == '\0')
596 grub_printf ("%x,", (unsigned) eacpi
->uid
);
598 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp
));
600 if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp
)[0] == '\0')
601 grub_printf ("%x)", (unsigned) eacpi
->cid
);
603 grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp
));
607 grub_printf ("/UnknownACPI(%x)", (unsigned) subtype
);
612 case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
:
615 case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE
:
617 grub_efi_atapi_device_path_t
*atapi
618 = (grub_efi_atapi_device_path_t
*) dp
;
619 grub_printf ("/ATAPI(%x,%x,%x)",
620 (unsigned) atapi
->primary_secondary
,
621 (unsigned) atapi
->slave_master
,
622 (unsigned) atapi
->lun
);
625 case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE
:
627 grub_efi_scsi_device_path_t
*scsi
628 = (grub_efi_scsi_device_path_t
*) dp
;
629 grub_printf ("/SCSI(%x,%x)",
630 (unsigned) scsi
->pun
,
631 (unsigned) scsi
->lun
);
634 case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE
:
636 grub_efi_fibre_channel_device_path_t
*fc
637 = (grub_efi_fibre_channel_device_path_t
*) dp
;
638 grub_printf ("/FibreChannel(%llx,%llx)",
639 (unsigned long long) fc
->wwn
,
640 (unsigned long long) fc
->lun
);
643 case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE
:
645 grub_efi_1394_device_path_t
*firewire
646 = (grub_efi_1394_device_path_t
*) dp
;
647 grub_printf ("/1394(%llx)",
648 (unsigned long long) firewire
->guid
);
651 case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE
:
653 grub_efi_usb_device_path_t
*usb
654 = (grub_efi_usb_device_path_t
*) dp
;
655 grub_printf ("/USB(%x,%x)",
656 (unsigned) usb
->parent_port_number
,
657 (unsigned) usb
->usb_interface
);
660 case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE
:
662 grub_efi_usb_class_device_path_t
*usb_class
663 = (grub_efi_usb_class_device_path_t
*) dp
;
664 grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
665 (unsigned) usb_class
->vendor_id
,
666 (unsigned) usb_class
->product_id
,
667 (unsigned) usb_class
->device_class
,
668 (unsigned) usb_class
->device_subclass
,
669 (unsigned) usb_class
->device_protocol
);
672 case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE
:
674 grub_efi_i2o_device_path_t
*i2o
675 = (grub_efi_i2o_device_path_t
*) dp
;
676 grub_printf ("/I2O(%x)", (unsigned) i2o
->tid
);
679 case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
:
681 grub_efi_mac_address_device_path_t
*mac
682 = (grub_efi_mac_address_device_path_t
*) dp
;
683 grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
684 (unsigned) mac
->mac_address
[0],
685 (unsigned) mac
->mac_address
[1],
686 (unsigned) mac
->mac_address
[2],
687 (unsigned) mac
->mac_address
[3],
688 (unsigned) mac
->mac_address
[4],
689 (unsigned) mac
->mac_address
[5],
690 (unsigned) mac
->if_type
);
693 case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
:
695 grub_efi_ipv4_device_path_t
*ipv4
696 = (grub_efi_ipv4_device_path_t
*) dp
;
697 grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
698 (unsigned) ipv4
->local_ip_address
[0],
699 (unsigned) ipv4
->local_ip_address
[1],
700 (unsigned) ipv4
->local_ip_address
[2],
701 (unsigned) ipv4
->local_ip_address
[3],
702 (unsigned) ipv4
->remote_ip_address
[0],
703 (unsigned) ipv4
->remote_ip_address
[1],
704 (unsigned) ipv4
->remote_ip_address
[2],
705 (unsigned) ipv4
->remote_ip_address
[3],
706 (unsigned) ipv4
->local_port
,
707 (unsigned) ipv4
->remote_port
,
708 (unsigned) ipv4
->protocol
,
709 (unsigned) ipv4
->static_ip_address
);
712 case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE
:
714 grub_efi_ipv6_device_path_t
*ipv6
715 = (grub_efi_ipv6_device_path_t
*) dp
;
716 grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
717 (unsigned) ipv6
->local_ip_address
[0],
718 (unsigned) ipv6
->local_ip_address
[1],
719 (unsigned) ipv6
->local_ip_address
[2],
720 (unsigned) ipv6
->local_ip_address
[3],
721 (unsigned) ipv6
->local_ip_address
[4],
722 (unsigned) ipv6
->local_ip_address
[5],
723 (unsigned) ipv6
->local_ip_address
[6],
724 (unsigned) ipv6
->local_ip_address
[7],
725 (unsigned) ipv6
->remote_ip_address
[0],
726 (unsigned) ipv6
->remote_ip_address
[1],
727 (unsigned) ipv6
->remote_ip_address
[2],
728 (unsigned) ipv6
->remote_ip_address
[3],
729 (unsigned) ipv6
->remote_ip_address
[4],
730 (unsigned) ipv6
->remote_ip_address
[5],
731 (unsigned) ipv6
->remote_ip_address
[6],
732 (unsigned) ipv6
->remote_ip_address
[7],
733 (unsigned) ipv6
->local_port
,
734 (unsigned) ipv6
->remote_port
,
735 (unsigned) ipv6
->protocol
,
736 (unsigned) ipv6
->static_ip_address
);
739 case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE
:
741 grub_efi_infiniband_device_path_t
*ib
742 = (grub_efi_infiniband_device_path_t
*) dp
;
743 grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
744 (unsigned) ib
->port_gid
[0], /* XXX */
745 (unsigned long long) ib
->remote_id
,
746 (unsigned long long) ib
->target_port_id
,
747 (unsigned long long) ib
->device_id
);
750 case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE
:
752 grub_efi_uart_device_path_t
*uart
753 = (grub_efi_uart_device_path_t
*) dp
;
754 grub_printf ("/UART(%llu,%u,%x,%x)",
755 (unsigned long long) uart
->baud_rate
,
761 case GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE
:
763 grub_efi_sata_device_path_t
*sata
;
764 sata
= (grub_efi_sata_device_path_t
*) dp
;
765 grub_printf ("/Sata(%x,%x,%x)",
767 sata
->multiplier_port
,
772 case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE
:
773 dump_vendor_path ("Messaging",
774 (grub_efi_vendor_device_path_t
*) dp
);
777 grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype
);
782 case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
:
785 case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE
:
787 grub_efi_hard_drive_device_path_t
*hd
= (grub_efi_hard_drive_device_path_t
*) dp
;
788 grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
789 hd
->partition_number
,
790 (unsigned long long) hd
->partition_start
,
791 (unsigned long long) hd
->partition_size
,
792 (unsigned) hd
->partition_signature
[0],
793 (unsigned) hd
->partition_signature
[1],
794 (unsigned) hd
->partition_signature
[2],
795 (unsigned) hd
->partition_signature
[3],
796 (unsigned) hd
->partition_signature
[4],
797 (unsigned) hd
->partition_signature
[5],
798 (unsigned) hd
->partition_signature
[6],
799 (unsigned) hd
->partition_signature
[7],
800 (unsigned) hd
->partmap_type
,
801 (unsigned) hd
->signature_type
);
804 case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
:
806 grub_efi_cdrom_device_path_t
*cd
807 = (grub_efi_cdrom_device_path_t
*) dp
;
808 grub_printf ("/CD(%u,%llx,%llx)",
810 (unsigned long long) cd
->partition_start
,
811 (unsigned long long) cd
->partition_size
);
814 case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE
:
815 dump_vendor_path ("Media",
816 (grub_efi_vendor_device_path_t
*) dp
);
818 case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE
:
820 grub_efi_file_path_device_path_t
*fp
;
822 fp
= (grub_efi_file_path_device_path_t
*) dp
;
823 buf
= grub_malloc ((len
- 4) * 2 + 1);
826 grub_efi_char16_t
*dup_name
= grub_malloc (len
- 4);
829 grub_errno
= GRUB_ERR_NONE
;
830 grub_printf ("/File((null))");
834 *grub_utf16_to_utf8 (buf
, grub_memcpy (dup_name
, fp
->path_name
, len
- 4),
835 (len
- 4) / sizeof (grub_efi_char16_t
))
837 grub_free (dup_name
);
840 grub_errno
= GRUB_ERR_NONE
;
841 grub_printf ("/File(%s)", buf
);
845 case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE
:
847 grub_efi_protocol_device_path_t
*proto
848 = (grub_efi_protocol_device_path_t
*) dp
;
849 grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
850 (unsigned) proto
->guid
.data1
,
851 (unsigned) proto
->guid
.data2
,
852 (unsigned) proto
->guid
.data3
,
853 (unsigned) proto
->guid
.data4
[0],
854 (unsigned) proto
->guid
.data4
[1],
855 (unsigned) proto
->guid
.data4
[2],
856 (unsigned) proto
->guid
.data4
[3],
857 (unsigned) proto
->guid
.data4
[4],
858 (unsigned) proto
->guid
.data4
[5],
859 (unsigned) proto
->guid
.data4
[6],
860 (unsigned) proto
->guid
.data4
[7]);
864 grub_printf ("/UnknownMedia(%x)", (unsigned) subtype
);
869 case GRUB_EFI_BIOS_DEVICE_PATH_TYPE
:
872 case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE
:
874 grub_efi_bios_device_path_t
*bios
875 = (grub_efi_bios_device_path_t
*) dp
;
876 grub_printf ("/BIOS(%x,%x,%s)",
877 (unsigned) bios
->device_type
,
878 (unsigned) bios
->status_flags
,
883 grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype
);
889 grub_printf ("/UnknownType(%x,%x)\n",
896 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp
))
899 dp
= (grub_efi_device_path_t
*) ((char *) dp
+ len
);
903 /* Compare device paths. */
905 grub_efi_compare_device_paths (const grub_efi_device_path_t
*dp1
,
906 const grub_efi_device_path_t
*dp2
)
909 /* Return non-zero. */
914 grub_efi_uint8_t type1
, type2
;
915 grub_efi_uint8_t subtype1
, subtype2
;
916 grub_efi_uint16_t len1
, len2
;
919 type1
= GRUB_EFI_DEVICE_PATH_TYPE (dp1
);
920 type2
= GRUB_EFI_DEVICE_PATH_TYPE (dp2
);
923 return (int) type2
- (int) type1
;
925 subtype1
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1
);
926 subtype2
= GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2
);
928 if (subtype1
!= subtype2
)
929 return (int) subtype1
- (int) subtype2
;
931 len1
= GRUB_EFI_DEVICE_PATH_LENGTH (dp1
);
932 len2
= GRUB_EFI_DEVICE_PATH_LENGTH (dp2
);
935 return (int) len1
- (int) len2
;
937 ret
= grub_memcmp (dp1
, dp2
, len1
);
941 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1
))
944 dp1
= (grub_efi_device_path_t
*) ((char *) dp1
+ len1
);
945 dp2
= (grub_efi_device_path_t
*) ((char *) dp2
+ len2
);
951 void * grub_efi_allocate_iso_buf(grub_uint64_t size
)
953 grub_efi_boot_services_t
*b
;
954 grub_efi_status_t status
;
955 grub_efi_physical_address_t address
= 0;
956 grub_efi_uintn_t pages
= GRUB_EFI_BYTES_TO_PAGES(size
);
958 b
= grub_efi_system_table
->boot_services
;
959 status
= efi_call_4 (b
->allocate_pages
, GRUB_EFI_ALLOCATE_ANY_PAGES
, GRUB_EFI_RUNTIME_SERVICES_DATA
, pages
, &address
);
960 if (status
!= GRUB_EFI_SUCCESS
)
965 return (void *)(unsigned long)address
;