diff options
Diffstat (limited to 'lib/efi_loader/efi_boottime.c')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 177 |
1 files changed, 67 insertions, 110 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index ca61e1ad41..97eb19cd14 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -26,14 +26,6 @@ LIST_HEAD(efi_obj_list); /* List of all events */ LIST_HEAD(efi_events); -/* - * If we're running on nasty systems (32bit ARM booting into non-EFI Linux) - * we need to do trickery with caches. Since we don't want to break the EFI - * aware boot path, only apply hacks when loading exiting directly (breaking - * direct Linux EFI booting along the way - oh well). - */ -static bool efi_is_direct_boot = true; - #ifdef CONFIG_ARM /* * The "gd" pointer lives in a register on ARM and AArch64 that we declare @@ -105,8 +97,8 @@ void efi_save_gd(void) /* * Special case handler for error/abort that just forces things back to u-boot - * world so we can dump out an abort msg, without any care about returning back - * to UEFI world. + * world so we can dump out an abort message, without any care about returning + * back to UEFI world. */ void efi_restore_gd(void) { @@ -183,7 +175,7 @@ static void efi_queue_event(struct efi_event *event, bool check_tpl) * is_valid_tpl() - check if the task priority level is valid * * @tpl: TPL level to check - * ReturnValue: status code + * Return: status code */ efi_status_t is_valid_tpl(efi_uintn_t tpl) { @@ -626,7 +618,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl, evt->notify_function = notify_function; evt->notify_context = notify_context; evt->group = group; - /* Disable timers on bootup */ + /* Disable timers on boot up */ evt->trigger_next = -1ULL; evt->is_queued = false; evt->is_signaled = false; @@ -732,7 +724,7 @@ void efi_timer_check(void) * efi_set_timer() - set the trigger time for a timer event or stop the event * @event: event for which the timer is set * @type: type of the timer - * @trigger_time: trigger period in multiples of 100ns + * @trigger_time: trigger period in multiples of 100 ns * * This is the function for internal usage in U-Boot. For the API function * implementing the SetTimer service see efi_set_timer_ext. @@ -747,8 +739,8 @@ efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type, return EFI_INVALID_PARAMETER; /* - * The parameter defines a multiple of 100ns. - * We use multiples of 1000ns. So divide by 10. + * The parameter defines a multiple of 100 ns. + * We use multiples of 1000 ns. So divide by 10. */ do_div(trigger_time, 10); @@ -774,7 +766,7 @@ efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type, * event * @event: event for which the timer is set * @type: type of the timer - * @trigger_time: trigger period in multiples of 100ns + * @trigger_time: trigger period in multiples of 100 ns * * This function implements the SetTimer service. * @@ -1061,7 +1053,7 @@ out: /** * efi_get_drivers() - get all drivers associated to a controller * @efiobj: handle of the controller - * @protocol: protocol guid (optional) + * @protocol: protocol GUID (optional) * @number_of_drivers: number of child controllers * @driver_handle_buffer: handles of the the drivers * @@ -1126,7 +1118,7 @@ static efi_status_t efi_get_drivers(struct efi_object *efiobj, /** * efi_disconnect_all_drivers() - disconnect all drivers from a controller * @efiobj: handle of the controller - * @protocol: protocol guid (optional) + * @protocol: protocol GUID (optional) * @child_handle: handle of the child to destroy * * This function implements the DisconnectController service. @@ -1408,7 +1400,7 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, if (!guid) return EFI_INVALID_PARAMETER; - /* Check for guid override */ + /* Check for GUID override */ for (i = 0; i < systab.nr_tables; i++) { if (!guidcmp(guid, &systab.tables[i].guid)) { if (table) @@ -1432,7 +1424,7 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, systab.nr_tables = i + 1; out: - /* systab.nr_tables may have changed. So we need to update the crc32 */ + /* systab.nr_tables may have changed. So we need to update the CRC32 */ efi_update_table_header_crc32(&systab.hdr); /* Notify that the configuration table was changed */ @@ -1478,20 +1470,35 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, * * Return: status code */ -efi_status_t efi_setup_loaded_image( - struct efi_loaded_image *info, struct efi_object *obj, - struct efi_device_path *device_path, - struct efi_device_path *file_path) +efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, + struct efi_device_path *file_path, + struct efi_loaded_image_obj **handle_ptr, + struct efi_loaded_image **info_ptr) { efi_status_t ret; + struct efi_loaded_image *info; + struct efi_loaded_image_obj *obj; + + info = calloc(1, sizeof(*info)); + if (!info) + return EFI_OUT_OF_RESOURCES; + obj = calloc(1, sizeof(*obj)); + if (!obj) { + free(info); + return EFI_OUT_OF_RESOURCES; + } /* Add internal object to object list */ - efi_add_handle(obj); - /* efi_exit() assumes that the handle points to the info */ - obj->handle = info; + efi_add_handle(&obj->parent); + + if (info_ptr) + *info_ptr = info; + if (handle_ptr) + *handle_ptr = obj; info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; info->file_path = file_path; + info->system_table = &systab; if (device_path) { info->device_handle = efi_dp_find_obj(device_path, NULL); @@ -1499,8 +1506,8 @@ efi_status_t efi_setup_loaded_image( * When asking for the device path interface, return * bootefi_device_path */ - ret = efi_add_protocol(obj->handle, &efi_guid_device_path, - device_path); + ret = efi_add_protocol(obj->parent.handle, + &efi_guid_device_path, device_path); if (ret != EFI_SUCCESS) goto failure; } @@ -1509,19 +1516,8 @@ efi_status_t efi_setup_loaded_image( * When asking for the loaded_image interface, just * return handle which points to loaded_image_info */ - ret = efi_add_protocol(obj->handle, &efi_guid_loaded_image, info); - if (ret != EFI_SUCCESS) - goto failure; - - ret = efi_add_protocol(obj->handle, - &efi_guid_device_path_to_text_protocol, - (void *)&efi_device_path_to_text); - if (ret != EFI_SUCCESS) - goto failure; - - ret = efi_add_protocol(obj->handle, - &efi_guid_device_path_utilities_protocol, - (void *)&efi_device_path_utilities); + ret = efi_add_protocol(obj->parent.handle, + &efi_guid_loaded_image, info); if (ret != EFI_SUCCESS) goto failure; @@ -1604,7 +1600,8 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_handle_t *image_handle) { struct efi_loaded_image *info; - struct efi_object *obj; + struct efi_loaded_image_obj **image_obj = + (struct efi_loaded_image_obj **)image_handle; efi_status_t ret; EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image, @@ -1620,18 +1617,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, goto error; } - info = calloc(1, sizeof(*info)); - if (!info) { - ret = EFI_OUT_OF_RESOURCES; - goto error; - } - obj = calloc(1, sizeof(*obj)); - if (!obj) { - free(info); - ret = EFI_OUT_OF_RESOURCES; - goto error; - } - if (!source_buffer) { struct efi_device_path *dp, *fp; @@ -1643,35 +1628,35 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, * file parts: */ efi_dp_split_file_path(file_path, &dp, &fp); - ret = efi_setup_loaded_image(info, obj, dp, fp); + ret = efi_setup_loaded_image(dp, fp, image_obj, &info); if (ret != EFI_SUCCESS) goto failure; } else { - /* In this case, file_path is the "device" path, ie. + /* In this case, file_path is the "device" path, i.e. * something like a HARDWARE_DEVICE:MEMORY_MAPPED */ - ret = efi_setup_loaded_image(info, obj, file_path, NULL); + ret = efi_setup_loaded_image(file_path, NULL, image_obj, &info); if (ret != EFI_SUCCESS) - goto failure; + goto error; } - info->reserved = efi_load_pe(source_buffer, info); - if (!info->reserved) { + (*image_obj)->entry = efi_load_pe(*image_obj, source_buffer, info); + if (!(*image_obj)->entry) { ret = EFI_UNSUPPORTED; goto failure; } info->system_table = &systab; info->parent_handle = parent_image; - *image_handle = obj->handle; return EFI_EXIT(EFI_SUCCESS); failure: + efi_delete_handle(*image_handle); + *image_handle = NULL; free(info); - efi_delete_handle(obj); error: return EFI_EXIT(ret); } /** - * efi_start_image() - dall the entry point of an image + * efi_start_image() - call the entry point of an image * @image_handle: handle of the image * @exit_data_size: size of the buffer * @exit_data: buffer to receive the exit data of the called image @@ -1687,18 +1672,14 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, unsigned long *exit_data_size, s16 **exit_data) { - EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, - struct efi_system_table *st); - struct efi_loaded_image *info = image_handle; + struct efi_loaded_image_obj *image_obj = + (struct efi_loaded_image_obj *)image_handle; efi_status_t ret; EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data); - entry = info->reserved; - - efi_is_direct_boot = false; /* call the image! */ - if (setjmp(&info->exit_jmp)) { + if (setjmp(&image_obj->exit_jmp)) { /* * We called the entry point of the child image with EFI_CALL * in the lines below. The child image called the Exit() boot @@ -1721,16 +1702,16 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, assert(__efi_entry_check()); debug("%sEFI: %lu returned by started image\n", __efi_nesting_dec(), - (unsigned long)((uintptr_t)info->exit_status & + (unsigned long)((uintptr_t)image_obj->exit_status & ~EFI_ERROR_MASK)); - return EFI_EXIT(info->exit_status); + return EFI_EXIT(image_obj->exit_status); } - ret = EFI_CALL(entry(image_handle, &systab)); + ret = EFI_CALL(image_obj->entry(image_handle, &systab)); /* * Usually UEFI applications call Exit() instead of returning. - * But because the world doesn not consist of ponies and unicorns, + * But because the world doesn't consist of ponies and unicorns, * we're happy to emulate that behavior on behalf of a payload * that forgot. */ @@ -1757,17 +1738,11 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, int16_t *exit_data) { /* - * We require that the handle points to the original loaded - * image protocol interface. - * - * For getting the longjmp address this is safer than locating - * the protocol because the protocol may have been reinstalled - * pointing to another memory location. - * * TODO: We should call the unload procedure of the loaded * image protocol. */ - struct efi_loaded_image *loaded_image_info = (void *)image_handle; + struct efi_loaded_image_obj *image_obj = + (struct efi_loaded_image_obj *)image_handle; EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status, exit_data_size, exit_data); @@ -1781,8 +1756,8 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, */ efi_restore_gd(); - loaded_image_info->exit_status = exit_status; - longjmp(&loaded_image_info->exit_jmp, 1); + image_obj->exit_status = exit_status; + longjmp(&image_obj->exit_jmp, 1); panic("EFI application exited"); } @@ -1811,21 +1786,6 @@ static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle) } /** - * efi_exit_caches() - fix up caches for EFI payloads if necessary - */ -static void efi_exit_caches(void) -{ -#if defined(CONFIG_ARM) && !defined(CONFIG_ARM64) - /* - * Grub on 32bit ARM needs to have caches disabled before jumping into - * a zImage, but does not know of all cache layers. Give it a hand. - */ - if (efi_is_direct_boot) - cleanup_before_linux(); -#endif -} - -/** * efi_exit_boot_services() - stop all boot services * @image_handle: handle of the loaded image * @map_key: key of the memory map @@ -1874,17 +1834,14 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, } } - /* TODO Should persist EFI variables here */ + /* TODO: Should persist EFI variables here */ board_quiesce_devices(); - /* Fix up caches for EFI payloads if necessary */ - efi_exit_caches(); - /* This stops all lingering devices */ bootm_disable_interrupts(); - /* Disable boottime services */ + /* Disable boot time services */ systab.con_in_handle = NULL; systab.con_in = NULL; systab.con_out_handle = NULL; @@ -2118,7 +2075,7 @@ static efi_status_t EFIAPI efi_protocols_per_handle( ++*protocol_buffer_count; } - /* Copy guids */ + /* Copy GUIDs */ if (*protocol_buffer_count) { size_t j = 0; @@ -2709,7 +2666,7 @@ static efi_status_t efi_bind_controller( * efi_connect_single_controller() - connect a single driver to a controller * @controller_handle: controller * @driver_image_handle: driver - * @remain_device_path: remainting path + * @remain_device_path: remaining path * * Return: status code */ @@ -2790,7 +2747,7 @@ static efi_status_t efi_connect_single_controller( * details. * * First all driver binding protocol handles are tried for binding drivers. - * Afterwards all handles that have openened a protocol of the controller + * Afterwards all handles that have opened a protocol of the controller * with EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER are connected to drivers. * * Return: status code @@ -3123,7 +3080,7 @@ struct efi_system_table __efi_runtime_data systab = { /** * efi_initialize_system_table() - Initialize system table * - * Return Value: status code + * Return: status code */ efi_status_t efi_initialize_system_table(void) { @@ -3135,7 +3092,7 @@ efi_status_t efi_initialize_system_table(void) sizeof(struct efi_configuration_table), (void **)&systab.tables); - /* Set crc32 field in table headers */ + /* Set CRC32 field in table headers */ efi_update_table_header_crc32(&systab.hdr); efi_update_table_header_crc32(&efi_runtime_services.hdr); efi_update_table_header_crc32(&efi_boot_services.hdr); |