/* efi.c - generic EFI support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/* The handle of GRUB itself. Filled in by the startup code. */
/* The pointer to a system table. Filled in by the startup code. */
void *
{
void *interface;
if (status != GRUB_EFI_SUCCESS)
return 0;
return interface;
}
/* Return the array of handles which meet the requirement. If successful,
the number of handles is stored in NUM_HANDLES. The array is allocated
from the heap. */
void *search_key,
{
if (! buffer)
return 0;
&buffer_size, buffer);
if (status == GRUB_EFI_BUFFER_TOO_SMALL)
{
if (! buffer)
return 0;
&buffer_size, buffer);
}
if (status != GRUB_EFI_SUCCESS)
{
return 0;
}
return buffer;
}
void *
{
void *interface;
if (status != GRUB_EFI_SUCCESS)
return 0;
return interface;
}
int
{
c = grub_efi_locate_protocol (&console_control_guid, 0);
if (! c)
/* No console control protocol instance available, assume it is
already in text mode. */
return 1;
return 0;
return 0;
return 1;
}
void
{
}
{
return grub_efi_open_protocol (image_handle,
}
void
grub_exit (void)
{
grub_efi_fini ();
grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
for (;;) ;
}
{
if (status == GRUB_EFI_SUCCESS)
return GRUB_ERR_NONE;
}
grub_rtc_get_time_ms (void)
{
/* What is possible in this case? */
return 0;
}
grub_get_rtc (void)
{
return grub_rtc_get_time_ms ();
}
a PE32 header, but should work with PE32+ as well. */
grub_efi_modules_addr (void)
{
if (! image)
return 0;
= (struct grub_pe32_section_table *) ((char *) coff_header
+ sizeof (*coff_header)
i < coff_header->num_sections;
i++, section++)
{
break;
}
if (i == coff_header->num_sections)
return 0;
+ section->virtual_address);
return 0;
return (grub_addr_t) info;
}
char *
{
char *name = 0;
while (1)
{
if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
break;
else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
{
char *p;
if (name)
{
size++;
}
else
size = 0;
/ sizeof (grub_efi_char16_t));
if (! p)
{
return 0;
}
name = p;
}
}
if (name)
{
/* EFI breaks paths with backslashes. */
char *p;
for (p = name; *p; p++)
if (*p == '\\')
*p = '/';
}
return name;
}
{
}
/* Print the chain of Device Path nodes. This is mainly for debugging. */
void
{
while (1)
{
switch (type)
{
switch (subtype)
{
grub_printf ("/EndEntire\n");
//grub_putchar ('\n');
break;
grub_printf ("/EndThis\n");
//grub_putchar ('\n');
break;
default:
break;
}
break;
switch (subtype)
{
{
grub_printf ("/PCI(%x,%x)",
}
break;
{
grub_printf ("/PCCARD(%x)",
}
break;
{
grub_printf ("/MMap(%x,%llx,%llx)",
(unsigned) mmapped.memory_type,
(unsigned long long) mmapped.start_address,
(unsigned long long) mmapped.end_address);
}
break;
{
grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
}
break;
{
grub_printf ("/Ctrl(%x)",
(unsigned) controller.controller_number);
}
break;
default:
break;
}
break;
switch (subtype)
{
{
grub_printf ("/ACPI(%x,%x)",
}
break;
{
grub_printf ("/ACPI(");
else
else
else
}
break;
default:
break;
}
break;
switch (subtype)
{
{
grub_printf ("/ATAPI(%x,%x,%x)",
(unsigned) atapi.primary_secondary,
(unsigned) atapi.slave_master,
}
break;
{
grub_printf ("/SCSI(%x,%x)",
}
break;
{
grub_printf ("/FibreChannel(%llx,%llx)",
}
break;
{
}
break;
{
grub_printf ("/USB(%x,%x)",
(unsigned) usb.parent_port_number,
}
break;
{
grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
(unsigned) usb_class.product_id,
(unsigned) usb_class.device_class,
(unsigned) usb_class.device_subclass,
(unsigned) usb_class.device_protocol);
}
break;
{
}
break;
{
grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
(unsigned) mac.mac_address[0],
}
break;
{
grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
(unsigned) ipv4.local_ip_address[0],
(unsigned) ipv4.remote_ip_address[0],
(unsigned) ipv4.local_port,
(unsigned) ipv4.remote_port,
(unsigned) ipv4.static_ip_address);
}
break;
{
grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
(unsigned) ipv6.local_ip_address[0],
(unsigned) ipv6.remote_ip_address[0],
(unsigned) ipv6.local_port,
(unsigned) ipv6.remote_port,
(unsigned) ipv6.static_ip_address);
}
break;
{
grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
(unsigned long long) ib.target_port_id,
}
break;
{
grub_printf ("/UART(%llu,%u,%x,%x)",
}
break;
{
grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
}
break;
default:
break;
}
break;
switch (subtype)
{
{
grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
(unsigned long long) hd.partition_start,
(unsigned long long) hd.partition_size,
(unsigned) hd.partition_signature[0],
(unsigned) hd.signature_type);
}
break;
{
grub_printf ("/CD(%u,%llx,%llx)",
(unsigned long long) cd.partition_start,
(unsigned long long) cd.partition_size);
}
break;
{
grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
}
break;
{
= '\0';
}
break;
{
grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
}
break;
default:
break;
}
break;
switch (subtype)
{
{
grub_printf ("/BIOS(%x,%x,%s)",
(unsigned) bios.device_type,
(unsigned) bios.status_flags,
(char *) (dp + 1));
}
break;
default:
break;
}
break;
default:
grub_printf ("/UnknownType(%x,%x)\n",
(unsigned) type,
(unsigned) subtype);
return;
break;
}
break;
}
}
/* Compare device paths. */
int
const grub_efi_device_path_t *dp2)
{
/* Return non-zero. */
return 1;
while (1)
{
int ret;
if (ret != 0)
return ret;
break;
}
return 0;
}