From d68f2690a91e97cc6cf977876f4b013438d09dd3 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 16 Nov 2012 20:03:50 +0000 Subject: fish --- master/jmm/efi-load-drivers-bis | 467 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 master/jmm/efi-load-drivers-bis (limited to 'master/jmm/efi-load-drivers-bis') diff --git a/master/jmm/efi-load-drivers-bis b/master/jmm/efi-load-drivers-bis new file mode 100644 index 0000000..9cef5f7 --- /dev/null +++ b/master/jmm/efi-load-drivers-bis @@ -0,0 +1,467 @@ +diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c +index fa1d0c7..16526d0 100644 +--- a/grub-core/kern/efi/efi.c ++++ b/grub-core/kern/efi/efi.c +@@ -37,6 +37,10 @@ grub_efi_system_table_t *grub_efi_system_table; + static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID; + static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID; + static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; ++static grub_efi_guid_t driver_binding_guid = GRUB_EFI_DRIVER_BINDING_GUID; ++static grub_efi_guid_t driver_configuration_guid = GRUB_EFI_DRIVER_CONFIGURATION_GUID; ++static grub_efi_guid_t driver_diagnostics_guid = GRUB_EFI_DRIVER_DIAGNOSTICS_GUID; ++static grub_efi_guid_t component_name_guid = GRUB_EFI_COMPONENT_NAME_GUID; + + void * + grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration) +@@ -740,3 +744,303 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) + dp = (grub_efi_device_path_t *) ((char *) dp + len); + } + } ++ ++ ++grub_efi_status_t grub_efi_free_pool (void *ptr) ++{ ++ grub_efi_boot_services_t *b; ++ b = grub_efi_system_table->boot_services; ++ ++ return efi_call_1 (b->free_pool, ptr); ++} ++ ++void * grub_efi_allocate_pool (grub_efi_memory_type_t type, grub_efi_uintn_t len) ++{ ++ grub_efi_boot_services_t *b; ++ grub_efi_status_t status; ++ void *ret; ++ b = grub_efi_system_table->boot_services; ++ ++ status = efi_call_3 (b->allocate_pool, type, len, &ret); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ return (void *) 0; ++ ++ return ret; ++} ++ ++ ++static int grub_efi_guid_cmp (grub_efi_guid_t * a, grub_efi_guid_t * b) ++{ ++ return grub_memcmp (a, b, sizeof (grub_efi_guid_t)); ++} ++ ++ ++ ++grub_efi_status_t ++grub_efi_scan_handle_database (grub_efi_handle_t driver_binding_handle, ++ grub_efi_uint32_t * ++ driver_binding_i, ++ grub_efi_handle_t controller_handle, ++ grub_efi_uint32_t * controller_i, ++ grub_efi_uintn_t * handle_count, ++ grub_efi_handle_t ** handle_buffer, ++ grub_efi_uint32_t ** handle_type) ++{ ++ grub_efi_boot_services_t *b; ++ grub_efi_status_t status; ++ grub_efi_uintn_t i, j, k; ++ grub_efi_guid_t **protocol_guid_array; ++ grub_efi_uintn_t array_count; ++ grub_efi_uintn_t protocol_index; ++ grub_efi_open_protocol_information_entry_t *open_info; ++ grub_efi_uintn_t open_info_count; ++ grub_efi_boolean_t driver_binding_i_valid; ++ grub_efi_boolean_t controller_i_valid; ++ ++ b = grub_efi_system_table->boot_services; ++ ++ driver_binding_i_valid = 0; ++ if (driver_binding_i != NULL) ++ { ++ *driver_binding_i = 0xffffffff; ++ } ++ ++ controller_i_valid = 0; ++ if (controller_i != NULL) ++ { ++ *controller_i = 0xffffffff; ++ } ++ *handle_count = 0; ++ *handle_buffer = NULL; ++ *handle_type = NULL; ++ ++ // ++ // Retrieve the list of all handles from the handle database ++ // ++ status = efi_call_5 (b->locate_handle_buffer, ++ GRUB_EFI_ALL_HANDLES, ++ NULL, NULL, handle_count, handle_buffer); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ goto error; ++ ++ *handle_type = grub_malloc (*handle_count * sizeof (grub_efi_uint32_t)); ++ if (!*handle_type) ++ goto error; ++ ++ for (i = 0; i < *handle_count; i++) ++ { ++ ++ // ++ // Assume that the handle type is unknown ++ // ++ (*handle_type)[i] = GRUB_EFI_HANDLE_TYPE_UNKNOWN; ++ ++ if (driver_binding_handle != NULL && driver_binding_i != NULL ++ && (*handle_buffer)[i] == driver_binding_handle) ++ { ++ *driver_binding_i = (grub_efi_uint32_t) i; ++ driver_binding_i_valid = 1; ++ } ++ ++ if (controller_handle != NULL && controller_i != NULL ++ && (*handle_buffer)[i] == controller_handle) ++ { ++ *controller_i = (grub_efi_uint32_t) i; ++ controller_i_valid = 1; ++ } ++ } ++ ++ for (i = 0; i < *handle_count; i++) ++ { ++ ++ // ++ // Retrieve the list of all the protocols on each handle ++ // ++ status = efi_call_3 (b->protocols_per_handle, ++ (*handle_buffer)[i], ++ &protocol_guid_array, &array_count); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ continue; ++ ++ for (protocol_index = 0; protocol_index < array_count; protocol_index++) ++ { ++ ++ if (grub_efi_guid_cmp ++ (protocol_guid_array[protocol_index], &loaded_image_guid) == 0) ++ { ++ (*handle_type)[i] |= GRUB_EFI_HANDLE_TYPE_IMAGE_HANDLE; ++ } ++ ++ if (grub_efi_guid_cmp ++ (protocol_guid_array[protocol_index], ++ &driver_binding_guid) == 0) ++ { ++ (*handle_type)[i] |= GRUB_EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE; ++ } ++ ++ if (grub_efi_guid_cmp ++ (protocol_guid_array[protocol_index], ++ &driver_configuration_guid) == 0) ++ { ++ (*handle_type)[i] |= ++ GRUB_EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE; ++ } ++ ++ if (grub_efi_guid_cmp ++ (protocol_guid_array[protocol_index], ++ &driver_diagnostics_guid) == 0) ++ { ++ (*handle_type)[i] |= ++ GRUB_EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE; ++ } ++ ++ if (grub_efi_guid_cmp ++ (protocol_guid_array[protocol_index], ++ &component_name_guid) == 0) ++ { ++ (*handle_type)[i] |= GRUB_EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE; ++ } ++ ++ if (grub_efi_guid_cmp ++ (protocol_guid_array[protocol_index], &device_path_guid) == 0) ++ { ++ (*handle_type)[i] |= GRUB_EFI_HANDLE_TYPE_DEVICE_HANDLE; ++ } ++ ++ // ++ // Retrieve the list of agents that have opened each protocol ++ // ++ status = efi_call_4 (b->open_protocol_information, ++ (*handle_buffer)[i], ++ protocol_guid_array[protocol_index], ++ &open_info, &open_info_count); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ continue; ++ ++ for (j = 0; j < open_info_count; j++) ++ { ++ ++ if (driver_binding_handle != NULL ++ && open_info[j].agent_handle == driver_binding_handle) ++ { ++ if ((open_info[j]. ++ attributes & GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER) == ++ GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER) ++ { ++ // ++ // Mark the device handle as being managed by the driver specified by driver_binding_handle ++ // ++ (*handle_type)[i] |= ++ (GRUB_EFI_HANDLE_TYPE_DEVICE_HANDLE | ++ GRUB_EFI_HANDLE_TYPE_CONTROLLER_HANDLE); ++ // ++ // Mark the driver_binding_handle as being a driver that is managing at least one controller ++ // ++ if (driver_binding_i_valid) ++ { ++ (*handle_type)[*driver_binding_i] |= ++ GRUB_EFI_HANDLE_TYPE_DEVICE_DRIVER; ++ } ++ } ++ if ((open_info[j]. ++ attributes & ++ GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == ++ GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ++ { ++ // ++ // Mark the driver_binding_handle as being a driver that is managing at least one child controller ++ // ++ if (driver_binding_i_valid) ++ { ++ (*handle_type)[*driver_binding_i] |= ++ GRUB_EFI_HANDLE_TYPE_BUS_DRIVER; ++ } ++ } ++ ++ if (controller_handle != NULL ++ && (*handle_buffer)[i] == controller_handle) ++ { ++ if ((open_info[j]. ++ attributes & ++ GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == ++ GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ++ { ++ for (k = 0; k < *handle_count; k++) ++ { ++ if ((*handle_buffer)[k] == ++ open_info[j].controller_handle) ++ { ++ (*handle_type)[k] |= ++ (GRUB_EFI_HANDLE_TYPE_DEVICE_HANDLE | ++ GRUB_EFI_HANDLE_TYPE_CHILD_HANDLE); ++ } ++ } ++ } ++ } ++ } ++ ++ ++ if (driver_binding_handle == NULL ++ && open_info[j].controller_handle == controller_handle) ++ { ++ if ((open_info[j]. ++ attributes & GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER) == ++ GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER) ++ { ++ for (k = 0; k < *handle_count; k++) ++ { ++ if ((*handle_buffer)[k] == ++ open_info[j].agent_handle) ++ { ++ (*handle_type)[k] |= ++ GRUB_EFI_HANDLE_TYPE_DEVICE_DRIVER; ++ } ++ } ++ } ++ if ((open_info[j]. ++ attributes & ++ GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == ++ GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ++ { ++ (*handle_type)[i] |= GRUB_EFI_HANDLE_TYPE_PARENT_HANDLE; ++ for (k = 0; k < *handle_count; k++) ++ { ++ if ((*handle_buffer)[k] == ++ open_info[j].agent_handle) ++ { ++ (*handle_type)[k] |= ++ GRUB_EFI_HANDLE_TYPE_BUS_DRIVER; ++ } ++ } ++ } ++ } ++ ++ } ++ grub_efi_free_pool (open_info); ++ ++ } ++ grub_efi_free_pool (protocol_guid_array); ++ } ++ ++ return GRUB_EFI_SUCCESS; ++ ++error: ++ if (*handle_type != NULL) ++ grub_free (*handle_type); ++ ++ if (*handle_buffer != NULL) ++ grub_efi_free_pool (*handle_buffer); ++ *handle_count = 0; ++ *handle_buffer = NULL; ++ *handle_type = NULL; ++ ++ return status; ++} ++ ++ ++ ++ +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c +index 1b0a872..a83bf2e 100644 +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -26,6 +26,66 @@ + #include + #include + ++static void bind_all_drivers (void) ++{ ++ grub_efi_uintn_t n_all_handles; ++ grub_efi_handle_t *all_handles; ++ grub_efi_status_t status; ++ grub_efi_boot_services_t *b; ++ grub_efi_uintn_t handle_count; ++ grub_efi_handle_t *handle_buffer; ++ grub_efi_uint32_t *handle_type; ++ unsigned int i, j; ++ ++ b = grub_efi_system_table->boot_services; ++ ++ all_handles = ++ grub_efi_locate_handle (GRUB_EFI_ALL_HANDLES, NULL, NULL, &n_all_handles); ++ ++ if (!all_handles) ++ return; ++ ++ for (i = 0; i < n_all_handles; ++i) ++ { ++ int is_device = 1; ++ ++ status = ++ grub_efi_scan_handle_database (NULL, NULL, all_handles[i], NULL, ++ &handle_count, &handle_buffer, ++ &handle_type); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ continue; ++ ++ if (handle_type[i] & GRUB_EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE) ++ is_device = 0; ++ if (handle_type[i] & GRUB_EFI_HANDLE_TYPE_IMAGE_HANDLE) ++ is_device = 0; ++ ++ if (is_device) ++ { ++ int is_parent = 0; ++ for (j = 0; j < handle_count; ++j) ++ { ++ if (handle_type[j] & GRUB_EFI_HANDLE_TYPE_PARENT_HANDLE) ++ is_parent = 1; ++ } ++ ++ if ((!is_parent) ++ && (handle_type[i] & GRUB_EFI_HANDLE_TYPE_DEVICE_HANDLE)) ++ { ++ efi_call_4 (b->connect_controller, all_handles[i], NULL, NULL, 1); ++ } ++ } ++ ++ grub_free (handle_type); ++ grub_efi_free_pool (handle_buffer); ++ } ++ ++ grub_free (all_handles); ++} ++ ++ + void + grub_efi_init (void) + { +@@ -39,6 +99,8 @@ grub_efi_init (void) + efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, + 0, 0, 0, NULL); + ++ bind_all_drivers(); ++ + grub_efidisk_init (); + } + +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 535a3e3..d8bce06 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -119,6 +119,26 @@ + { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ + } + ++#define GRUB_EFI_DRIVER_BINDING_GUID \ ++ { 0x18a031ab, 0xb443, 0x4d1a, \ ++ {0xa5, 0xc0, 0xc, 0x9, 0x26, 0x1e, 0x9f, 0x71 } \ ++ } ++ ++#define GRUB_EFI_DRIVER_CONFIGURATION_GUID \ ++ { 0x107a772b, 0xd5e1, 0x11d4, \ ++ {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ ++#define GRUB_EFI_DRIVER_DIAGNOSTICS_GUID \ ++ { 0x0784924f, 0xe296, 0x11d4, \ ++ { 0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ ++#define GRUB_EFI_COMPONENT_NAME_GUID \ ++ { 0x107a772c, 0xd5e1, 0x11d4, \ ++ {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ + struct grub_efi_sal_system_table + { + grub_uint32_t signature; +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index e9c57dd..a5b557b 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -68,6 +68,32 @@ void grub_efi_init (void); + void grub_efi_fini (void); + void grub_efi_set_prefix (void); + ++grub_efi_status_t EXPORT_FUNC(grub_efi_scan_handle_database) ( ++ grub_efi_handle_t driver_binding_handle, ++ grub_efi_uint32_t *driver_binding_handle_index, ++ grub_efi_handle_t controller_handle, ++ grub_efi_uint32_t *controller_handle_index, ++ grub_efi_uintn_t *handle_count, ++ grub_efi_handle_t **handle_buffer, ++ grub_efi_uint32_t **handle_type); ++ ++#define GRUB_EFI_HANDLE_TYPE_UNKNOWN 0x000 ++#define GRUB_EFI_HANDLE_TYPE_IMAGE_HANDLE 0x001 ++#define GRUB_EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE 0x002 ++#define GRUB_EFI_HANDLE_TYPE_DEVICE_DRIVER 0x004 ++#define GRUB_EFI_HANDLE_TYPE_BUS_DRIVER 0x008 ++#define GRUB_EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE 0x010 ++#define GRUB_EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE 0x020 ++#define GRUB_EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE 0x040 ++#define GRUB_EFI_HANDLE_TYPE_DEVICE_HANDLE 0x080 ++#define GRUB_EFI_HANDLE_TYPE_PARENT_HANDLE 0x100 ++#define GRUB_EFI_HANDLE_TYPE_CONTROLLER_HANDLE 0x200 ++#define GRUB_EFI_HANDLE_TYPE_CHILD_HANDLE 0x400 ++ ++void *EXPORT_FUNC(grub_efi_allocate_pool) (grub_efi_memory_type_t type, grub_efi_uintn_t len); ++grub_efi_status_t EXPORT_FUNC(grub_efi_free_pool) (void *); ++ ++ + /* Variables. */ + extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); + extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -- cgit v1.2.3