diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 0012e59..ad891ff 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -95,6 +95,7 @@ if COND_i386_efi KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/net.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif @@ -123,6 +124,7 @@ if COND_x86_64_efi KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/net.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2cdcc7b..e297c4f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -107,6 +107,7 @@ kernel = { x86 = kern/i386/pit.c; x86_efi = disk/efi/efidisk.c; + x86_efi = net/efi/efinet.c; x86_efi = kern/efi/efi.c; x86_efi = kern/efi/init.c; x86_efi = kern/efi/mm.c; diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index a83bf2e..a8fd647 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,7 @@ grub_efi_init (void) bind_all_drivers(); grub_efidisk_init (); + grub_efinet_init (); } void @@ -132,6 +134,12 @@ grub_efi_set_prefix (void) image = grub_efi_get_loaded_image (grub_efi_image_handle); if (image) { + if (!device) { + device = grub_efinet_get_device_name (image->device_handle); + /* If we net booted - hard code the prefix */ + if (device) + path = grub_strdup("/grub/"); + } if (!device) device = grub_efidisk_get_device_name (image->device_handle); else if (device[0] == ',' || !device[0]) @@ -187,6 +195,7 @@ grub_efi_set_prefix (void) void grub_efi_fini (void) { + grub_efinet_fini (); grub_efidisk_fini (); grub_console_fini (); } diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c index f73f828..fe6971c 100644 --- a/grub-core/kern/i386/efi/init.c +++ b/grub-core/kern/i386/efi/init.c @@ -30,8 +30,8 @@ void grub_machine_init (void) { - grub_efi_init (); grub_tsc_init (); + grub_efi_init (); } void diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index 5dd5ada..74bbd47 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -225,7 +226,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), dp = grub_efi_get_device_path (dev_handle); } - if (! dev->disk || ! dev_handle || ! dp) + if (dev->net) + { + dev_handle = grub_efinet_get_device_handle (dev->net); + if (dev_handle) + dp = grub_efi_get_device_path (dev_handle); + } + + if ((! dev->disk && ! dev->net ) || ! dev_handle || ! dp) { grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device"); goto fail; diff --git a/grub-core/net/efi/efinet.c b/grub-core/net/efi/efinet.c new file mode 100644 index 0000000..ca7ff09 --- /dev/null +++ b/grub-core/net/efi/efinet.c @@ -0,0 +1,548 @@ +/* efinet.c - EFI network access using SNI. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SNI_DEV_NAME_LEN 10 + +static grub_err_t grub_efinet_start (struct grub_net *); + +static grub_ether_addr ether_broadcast = + { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} }; + +struct grub_sni_data +{ + grub_efi_handle_t handle; + grub_efi_device_path_t *device_path; + grub_efi_simple_network_t *sni; + struct grub_sni_data *next; +}; + +static grub_efi_guid_t sni_guid = GRUB_EFI_SIMPLE_NETWORK_PROTOCOL; + +static struct grub_sni_data *sni_devices; + +/* Return the device path node right before the end node. */ +static grub_efi_device_path_t * +find_last_device_path (const grub_efi_device_path_t * dp) +{ + grub_efi_device_path_t *next, *p; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + return 0; + + for (p = (grub_efi_device_path_t *) dp, next = + GRUB_EFI_NEXT_DEVICE_PATH (p); !GRUB_EFI_END_ENTIRE_DEVICE_PATH (next); + p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next)) + ; + + return p; +} + +/* Compare device paths. */ +static int +compare_device_paths (const grub_efi_device_path_t * dp1, + const grub_efi_device_path_t * dp2) +{ + if (!dp1 || !dp2) + /* Return non-zero. */ + return 1; + + while (1) + { + grub_efi_uint8_t type1, type2; + grub_efi_uint8_t subtype1, subtype2; + grub_efi_uint16_t len1, len2; + int ret; + + type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1); + type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); + + if (type1 != type2) + return (int) type2 - (int) type1; + + subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1); + subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); + + if (subtype1 != subtype2) + return (int) subtype1 - (int) subtype2; + + len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1); + len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); + + if (len1 != len2) + return (int) len1 - (int) len2; + + ret = grub_memcmp (dp1, dp2, len1); + if (ret != 0) + return ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1)) + break; + + dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1); + dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); + } + + return 0; +} + + + +static void +free_devices (struct grub_sni_data *devices) +{ + struct grub_sni_data *p, *q; + + for (p = devices; p; p = q) + { + q = p->next; + grub_free (p); + } +} + + +/* Add a device into a list of devices in an ascending order. */ +static void +add_device (struct grub_sni_data *d) +{ + struct grub_sni_data **p; + + + for (p = &sni_devices; *p; p = &((*p)->next)) + { + int ret; + + ret = compare_device_paths (find_last_device_path ((*p)->device_path), + find_last_device_path (d->device_path)); + if (ret == 0) + ret = compare_device_paths ((*p)->device_path, d->device_path); + if (ret == 0) + return; + else if (ret > 0) + break; + } + + + d->next = (*p); + (*p) = d; +} + + + +static void +make_devices (void) +{ + grub_efi_uintn_t num_handles; + grub_efi_handle_t *handles; + grub_efi_handle_t *handle; + + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &sni_guid, + 0, &num_handles); + + if (!handles) + return; + + + + for (handle = handles; num_handles--; handle++) + { + grub_efi_simple_network_t *sni; + grub_efi_device_path_t *dp; + struct grub_sni_data *d; + + + dp = grub_efi_get_device_path (*handle); + + sni = grub_efi_open_protocol (*handle, &sni_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!sni) + continue; + + + d = grub_malloc (sizeof (*d)); + if (!d) + { + grub_free (handles); + return; + } + + d->handle = *handle; + d->device_path = dp; + d->sni = sni; + + add_device (d); + + } + + + grub_free (handles); + +} +static void +enumerate_snis (void) +{ + make_devices (); +} + + +static int +get_unit_number (const char *name) +{ + unsigned long unit; + + if (name[0] != 's' || name[1] != 'n' || name[2] != 'i') + goto fail; + + unit = grub_strtoul (name + 3, 0, 10); + if (grub_errno != GRUB_ERR_NONE) + goto fail; + + return (int) unit; + +fail: + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a sni"); + return -1; +} + +static struct grub_sni_data * +get_device (int num) +{ + struct grub_sni_data *d; + + for (d = sni_devices; d && num; d = d->next, num--); + + if (num == 0) + return d; + + return 0; +} + + +static int +tx_worker (struct grub_net *net, const void *frame, int len) +{ + struct grub_sni_data *private = (struct grub_sni_data *) net->data; + grub_uint64_t current_time, tx_time; + void *buf = NULL; + grub_efi_status_t status; + + static int need_bodge = 1; + + /* GRR the beasty EFI on the 64bit macminis doesn't return */ + /* addresses from sni->transmit in sni->get_status, so we have to bodge */ + /* the obvious bodge of looking at tx_good_frames in ->statistics */ + /* doesn't work as that call appears to be missing on macs, the alternative */ + /* is to flush the transmit q before and return whenever any buffer is */ + /* returned. */ + + /* Flush list of frames */ + do + { + buf = NULL; + efi_call_3 (private->sni->get_status, private->sni, NULL, + (void **) &buf); + } + while (buf); + + + tx_time = grub_get_time_ms (); + + status = + efi_call_7 (private->sni->transmit, private->sni, 0, len, (void *) frame, NULL, + NULL, NULL); + + if (status == GRUB_EFI_NOT_READY) + return 0; /*Try again */ + + if (status != GRUB_EFI_SUCCESS) + { + grub_efinet_start (net); /*Reset the interface */ + return 0; /*Try again */ + } + + do + { + current_time = grub_get_time_ms (); + buf = NULL; + status = + efi_call_3 (private->sni->get_status, private->sni, NULL, + (void **) &buf); + + if (status != GRUB_EFI_SUCCESS) + continue; + + if (buf == frame) + { + /*EFI did TRT we can return success */ + need_bodge = 0; + return len; + } + + if (need_bodge) + return len; + + } + while ((current_time - tx_time) < 1000); + + /*Tx timed out reset and try again */ + grub_efinet_start (net); /*Reset the interface */ + return 0; /*Try again */ + +} + + + +static grub_err_t +grub_efinet_open (const char *name, struct grub_net *net) +{ + int num; + struct grub_sni_data *d = NULL; + + + if (name && grub_strncmp(name,"sni",3)) { + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); + } + + if (name) + { + num = get_unit_number (name); + if (num < 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); + net->name = grub_strdup (name); + } + else + { + num = 0; + net->name = grub_strdup ("sni0"); + } + + d = get_device (num); + + if (!d) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); + + + grub_printf("DEVICE PATH to `%s'...\n",name); + grub_efi_print_device_path(d->device_path); + grub_printf("\n"); + +//net->id=num; + net->data = d; + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_efinet_start (struct grub_net *net) +{ + struct grub_sni_data *private = (struct grub_sni_data *) net->data; + grub_efi_status_t status; + + int tries = 3; + + efi_call_1 (private->sni->shutdown, private->sni); + status = efi_call_3 (private->sni->initialize, private->sni, 0, 0); + + +#if 0 + efi_call_1 (private->sni->shutdown, private->sni); + efi_call_1 (private->sni->stop, private->sni); +#endif + + do + { + status = efi_call_1 (private->sni->start, private->sni); + if (status != GRUB_EFI_SUCCESS) + { + efi_call_1 (private->sni->shutdown, private->sni); + efi_call_1 (private->sni->stop, private->sni); + } + } + while ((status != GRUB_EFI_SUCCESS) && (tries--)); + + if (status != GRUB_EFI_SUCCESS) + return -1; + + status = efi_call_3 (private->sni->initialize, private->sni, 0, 0); + if (status != GRUB_EFI_SUCCESS) + goto fail; + + status = + efi_call_6 (private->sni->receive_filters, private->sni, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST, 0, 0, 0, NULL); + if (status != GRUB_EFI_SUCCESS) + goto fail; + + if (private->sni->mode->state != grub_efi_simple_network_initialized) + goto fail; + + if (private->sni->mode->hw_address_size != GRUB_ETH_ALEN) + goto fail; + + grub_memcpy (&net->my_eth_addr, private->sni->mode->current_address, + GRUB_ETH_ALEN); + + net->is_running++; + + return 0; + +fail: + + efi_call_1 (private->sni->shutdown, private->sni); + efi_call_1 (private->sni->stop, private->sni); + return -1; +} + +static void +grub_efinet_stop (struct grub_net *net) +{ + struct grub_sni_data *private = (struct grub_sni_data *) net->data; + + efi_call_1 (private->sni->shutdown, private->sni); + efi_call_1 (private->sni->stop, private->sni); + net->is_running = 0; +} + + +static void +grub_efinet_close (struct grub_net *net) +{ + grub_efinet_stop (net); + grub_free ((void *) net->name); /*name is const char * */ +} + + +static grub_err_t +grub_efinet_send (struct grub_net *net, const void *frame, int len) +{ + int tries = 3; + int ret; + + if (len <= 0) + return -1; + + do + { + ret = tx_worker (net, frame, len); + if (ret > 0) + break; + } + while (tries--); + + + /* vodoo here - efi seems to drop packets in the TxQ for a short */ + /* while after sending a broadcast packet - god alone knows why */ + + if (!grub_memcmp (frame, ðer_broadcast, GRUB_ETH_ALEN)) + { + efi_call_1 (grub_efi_system_table->boot_services->stall, 100000); + } + + return (ret > 0) ? GRUB_ERR_NONE : GRUB_ERR_WRITE_ERROR; + +} + + +static grub_err_t +grub_efinet_recv (struct grub_net *net, void *frame, int *lenp) +{ + struct grub_sni_data *private = (struct grub_sni_data *) net->data; + grub_efi_status_t st; + grub_efi_uintn_t len = GRUB_ETH_FRAME_LEN; + + st = + efi_call_7 (private->sni->receive, private->sni, NULL, &len, frame, NULL, + NULL, NULL); + + *lenp = len; + + + if (st == GRUB_EFI_NOT_READY) + return GRUB_ERR_TIMEOUT; + else if (st != GRUB_EFI_SUCCESS) + return GRUB_ERR_READ_ERROR; + + + return GRUB_ERR_NONE; +} + +static struct grub_net_dev sni_net_dev = { + .name = "sni", + .open = grub_efinet_open, + .start = grub_efinet_start, + .stop = grub_efinet_stop, + .close = grub_efinet_close, + .send = grub_efinet_send, + .recv = grub_efinet_recv, + .next = 0 +}; + +grub_efi_handle_t +grub_efinet_get_device_handle(struct grub_net *net) +{ + struct grub_sni_data *private = (struct grub_sni_data *) net->data; + return private->handle; +} + +void +grub_efinet_init (void) +{ + enumerate_snis (); + grub_net_dev_register (&sni_net_dev); +} + +void +grub_efinet_fini (void) +{ + grub_net_dev_unregister (&sni_net_dev); + free_devices (sni_devices); +} + +char * grub_efinet_get_device_name(grub_efi_handle_t *h) +{ + struct grub_sni_data *p; + int i=0; + + while ((p=get_device(i))) { + if (p && (p->handle == h)) { + char *ret=grub_malloc (SNI_DEV_NAME_LEN); + grub_snprintf(ret,SNI_DEV_NAME_LEN,"sni%d",i); + ret[SNI_DEV_NAME_LEN-1] = 0; + return ret; + } + i++; + } + + return NULL; +} diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index db63eec..a965d60 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -232,6 +232,12 @@ enum GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8, }; +#define GRUB_EFI_SIMPLE_NETWORK_PROTOCOL \ + { 0xA19832B9, 0xAC25, 0x11D3, \ + {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D} \ + } + + /* Enumerations. */ enum grub_efi_timer_delay { @@ -1254,6 +1260,138 @@ struct grub_efi_block_io }; typedef struct grub_efi_block_io grub_efi_block_io_t; + +struct grub_efi_network_statistics { + grub_efi_uint64_t rx_total_frames; + grub_efi_uint64_t rx_good_frames; + grub_efi_uint64_t rx_undersize_frames; + grub_efi_uint64_t rx_oversize_frames; + grub_efi_uint64_t rx_dropped_frames; + grub_efi_uint64_t rx_unicast_frames; + grub_efi_uint64_t rx_broadcast_frames; + grub_efi_uint64_t rx_multicast_frames; + grub_efi_uint64_t rx_crc_error_frames; + grub_efi_uint64_t rx_total_bytes; + + grub_efi_uint64_t tx_total_frames; + grub_efi_uint64_t tx_good_frames; + grub_efi_uint64_t tx_undersize_frames; + grub_efi_uint64_t tx_oversize_frames; + grub_efi_uint64_t tx_dropped_frames; + grub_efi_uint64_t tx_unicast_frames; + grub_efi_uint64_t tx_broadcast_frames; + grub_efi_uint64_t tx_multicast_frames; + grub_efi_uint64_t tx_crc_error_frames; + grub_efi_uint64_t tx_total_bytes; + + grub_efi_uint64_t collisions; + grub_efi_uint64_t unsupported_protocol; +}; +typedef struct grub_efi_network_statistics grub_efi_network_statistics_t; + +enum grub_efi_simple_network_state { + grub_efi_simple_network_stopped, + grub_efi_simple_network_started, + grub_efi_simple_network_initialized, + grub_efi_simple_network_max_state +}; +typedef enum grub_efi_simple_network_state grub_efi_simple_network_state_t; + +#define GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01 +#define GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02 +#define GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04 +#define GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08 +#define GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10 + + +#define GRUB_EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01 +#define GRUB_EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02 +#define GRUB_EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04 +#define GRUB_EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08 + +#define GRUB_EFI_MAX_MCAST_FILTER_CNT 16 +struct grub_efi_simple_network_mode +{ + grub_efi_uint32_t state; + grub_efi_uint32_t hw_address_size; + grub_efi_uint32_t media_header_size; + grub_efi_uint32_t max_packet_size; + grub_efi_uint32_t nv_ram_size; + grub_efi_uint32_t nv_ram_access_size; + grub_efi_uint32_t receive_filter_mask; + grub_efi_uint32_t receive_filter_setting; + grub_efi_uint32_t max_mcast_filter_count; + grub_efi_uint32_t mcast_filter_count; + grub_efi_mac_address_t mcast_filter[GRUB_EFI_MAX_MCAST_FILTER_CNT]; + grub_efi_mac_address_t current_address; + grub_efi_mac_address_t broadcast_address; + grub_efi_mac_address_t permanent_address; + grub_efi_uint8_t if_type; + grub_efi_boolean_t mac_address_changeable; + grub_efi_boolean_t multiple_tx_supported; + grub_efi_boolean_t media_present_supported; + grub_efi_boolean_t media_present; +}; +typedef struct grub_efi_simple_network_mode grub_efi_simple_network_mode_t; + + +struct grub_efi_simple_network +{ + grub_efi_uint64_t revision; + grub_efi_status_t (*start) (struct grub_efi_simple_network *this); + grub_efi_status_t (*stop) (struct grub_efi_simple_network *this); + grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, + grub_efi_uintn_t extra_rx_buffer_size, + grub_efi_uintn_t extra_tx_buffer_size); + grub_efi_status_t (*reset) (struct grub_efi_simple_network *this, + grub_efi_boolean_t extended_verification); + grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this); + grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this, + grub_efi_uint32_t enable, + grub_efi_uint32_t disable, + grub_efi_boolean_t reset_mcast_filter, + grub_efi_uintn_t mcast_filter_count, + grub_efi_mac_address_t *mcast_filter); + grub_efi_status_t (*station_address) (struct grub_efi_simple_network *this, + grub_efi_boolean_t reset, + grub_efi_mac_address_t *new); + grub_efi_status_t (*statistics) (struct grub_efi_simple_network *this, + grub_efi_boolean_t reset, + grub_efi_uintn_t *statistics_size, + grub_efi_network_statistics_t *statistics_table); + grub_efi_status_t (*mcast_ip_to_mac) (struct grub_efi_simple_network *this, + grub_efi_boolean_t ipv6, + grub_efi_ip_address_t *ip, + grub_efi_mac_address_t *mac); + grub_efi_status_t (*nvdata) (struct grub_efi_simple_network *this, + grub_efi_boolean_t read_write, + grub_efi_uintn_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*get_status) (struct grub_efi_simple_network *this, + grub_efi_uint32_t *interrupt_status, + void **tx_buf); + grub_efi_status_t (*transmit) (struct grub_efi_simple_network *this, + grub_efi_uintn_t header_size, + grub_efi_uintn_t buffer_size, + void *buffer, + grub_efi_mac_address_t *src_addr, + grub_efi_mac_address_t *dst_addr, + grub_efi_uint16_t *protocol); + grub_efi_status_t (*receive) (struct grub_efi_simple_network *this, + grub_efi_uintn_t *header_size, + grub_efi_uintn_t *buffer_size, + void *buffer, + grub_efi_mac_address_t *src_addr, + grub_efi_mac_address_t *dst_addr, + grub_efi_uint16_t *protocol); + grub_efi_status_t (*wait_for_packet) (grub_efi_event_t event); + grub_efi_simple_network_mode_t *mode; +}; +typedef struct grub_efi_simple_network grub_efi_simple_network_t; + + + #if GRUB_TARGET_SIZEOF_VOID_P == 4 #define efi_call_0(func) func() diff --git a/include/grub/efi/net.h b/include/grub/efi/net.h new file mode 100644 index 0000000..368eaab --- /dev/null +++ b/include/grub/efi/net.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * 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 . + */ + +#ifndef GRUB_EFI_NET_HEADER +#define GRUB_EFI_NET_HEADER 1 + +#include +#include +#include + +grub_efi_handle_t +EXPORT_FUNC(grub_efinet_get_device_handle) (grub_net_t net); +char *EXPORT_FUNC(grub_efinet_get_device_name) (grub_efi_handle_t *handle); + +void grub_efinet_init (void); +void grub_efinet_fini (void); + +#endif /* ! GRUB_EFI_NET_HEADER */