mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-30 18:05:48 +01:00 
			
		
		
		
	Merge tag 'efi-2019-07-rc4-2' of git://git.denx.de/u-boot-efi
Pull request for UEFI sub-system for v2019.07-rc4-2 Support for managing the non-volatile attribute of UEFI variables is added though we do not have a backend for persistence yet. Error messages for changes of UEFI variables are provided. UEFI boottime service implementations are corrected.
This commit is contained in:
		| @@ -20,13 +20,6 @@ static uint64_t rockchip_get_ticks(void) | ||||
| 	return timebase_h << 32 | timebase_l; | ||||
| } | ||||
|  | ||||
| static uint64_t usec_to_tick(unsigned int usec) | ||||
| { | ||||
| 	uint64_t tick = usec; | ||||
| 	tick *= CONFIG_SYS_TIMER_RATE / (1000 * 1000); | ||||
| 	return tick; | ||||
| } | ||||
|  | ||||
| void rockchip_udelay(unsigned int usec) | ||||
| { | ||||
| 	uint64_t tmp; | ||||
|   | ||||
| @@ -558,6 +558,7 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag, | ||||
| 	} | ||||
|  | ||||
| 	ret = EFI_CALL(RT->set_variable(var_name16, &guid, | ||||
| 					EFI_VARIABLE_NON_VOLATILE | | ||||
| 					EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||
| 					EFI_VARIABLE_RUNTIME_ACCESS, | ||||
| 					size, data)); | ||||
| @@ -909,6 +910,7 @@ static int do_efi_boot_next(cmd_tbl_t *cmdtp, int flag, | ||||
| 	guid = efi_global_variable_guid; | ||||
| 	size = sizeof(u16); | ||||
| 	ret = EFI_CALL(RT->set_variable(L"BootNext", &guid, | ||||
| 					EFI_VARIABLE_NON_VOLATILE | | ||||
| 					EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||
| 					EFI_VARIABLE_RUNTIME_ACCESS, | ||||
| 					size, &bootnext)); | ||||
| @@ -964,6 +966,7 @@ static int do_efi_boot_order(cmd_tbl_t *cmdtp, int flag, | ||||
|  | ||||
| 	guid = efi_global_variable_guid; | ||||
| 	ret = EFI_CALL(RT->set_variable(L"BootOrder", &guid, | ||||
| 					EFI_VARIABLE_NON_VOLATILE | | ||||
| 					EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||
| 					EFI_VARIABLE_RUNTIME_ACCESS, | ||||
| 					size, bootorder)); | ||||
|   | ||||
| @@ -1344,8 +1344,9 @@ U_BOOT_CMD_COMPLETE( | ||||
| 	setenv, CONFIG_SYS_MAXARGS, 0,	do_env_set, | ||||
| 	"set environment variables", | ||||
| #if defined(CONFIG_CMD_NVEDIT_EFI) | ||||
| 	"-e name [value ...]\n" | ||||
| 	"-e [-nv] name [value ...]\n" | ||||
| 	"    - set UEFI variable 'name' to 'value' ...'\n" | ||||
| 	"      'nv' option makes the variable non-volatile\n" | ||||
| 	"    - delete UEFI variable 'name' if 'value' not specified\n" | ||||
| #endif | ||||
| 	"setenv [-f] name value ...\n" | ||||
|   | ||||
| @@ -349,6 +349,7 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||
| 	u16 *var_name16 = NULL, *p; | ||||
| 	size_t len; | ||||
| 	efi_guid_t guid; | ||||
| 	u32 attributes; | ||||
| 	efi_status_t ret; | ||||
|  | ||||
| 	if (argc == 1) | ||||
| @@ -362,6 +363,16 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||
| 		return CMD_RET_FAILURE; | ||||
| 	} | ||||
|  | ||||
| 	attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||
| 		     EFI_VARIABLE_RUNTIME_ACCESS; | ||||
| 	if (!strcmp(argv[1], "-nv")) { | ||||
| 		attributes |= EFI_VARIABLE_NON_VOLATILE; | ||||
| 		argc--; | ||||
| 		argv++; | ||||
| 		if (argc == 1) | ||||
| 			return CMD_RET_SUCCESS; | ||||
| 	} | ||||
|  | ||||
| 	var_name = argv[1]; | ||||
| 	if (argc == 2) { | ||||
| 		/* delete */ | ||||
| @@ -391,9 +402,7 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | ||||
| 	utf8_utf16_strncpy(&p, var_name, len + 1); | ||||
|  | ||||
| 	guid = efi_global_variable_guid; | ||||
| 	ret = EFI_CALL(efi_set_variable(var_name16, &guid, | ||||
| 					EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||
| 					EFI_VARIABLE_RUNTIME_ACCESS, | ||||
| 	ret = EFI_CALL(efi_set_variable(var_name16, &guid, attributes, | ||||
| 					size, value)); | ||||
| 	if (ret == EFI_SUCCESS) { | ||||
| 		ret = CMD_RET_SUCCESS; | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #define _TIME_H | ||||
|  | ||||
| #include <linux/typecheck.h> | ||||
| #include <linux/types.h> | ||||
|  | ||||
| unsigned long get_timer(unsigned long base); | ||||
|  | ||||
| @@ -21,6 +22,14 @@ unsigned long timer_get_us(void); | ||||
|  */ | ||||
| void timer_test_add_offset(unsigned long offset); | ||||
|  | ||||
| /** | ||||
|  * usec_to_tick() - convert microseconds to clock ticks | ||||
|  * | ||||
|  * @usec:	duration in microseconds | ||||
|  * Return:	duration in clock ticks | ||||
|  */ | ||||
| uint64_t usec_to_tick(unsigned long usec); | ||||
|  | ||||
| /* | ||||
|  *	These inlines deal with timer wrapping correctly. You are | ||||
|  *	strongly encouraged to use them | ||||
|   | ||||
| @@ -210,7 +210,8 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle) | ||||
| 		ret = EFI_CALL(efi_set_variable( | ||||
| 					L"BootNext", | ||||
| 					(efi_guid_t *)&efi_global_variable_guid, | ||||
| 					0, 0, &bootnext)); | ||||
| 					EFI_VARIABLE_NON_VOLATILE, 0, | ||||
| 					&bootnext)); | ||||
|  | ||||
| 		/* load BootNext */ | ||||
| 		if (ret == EFI_SUCCESS) { | ||||
|   | ||||
| @@ -1153,11 +1153,15 @@ static efi_status_t efi_get_drivers(efi_handle_t handle, | ||||
| 				++count; | ||||
| 		} | ||||
| 	} | ||||
| 	*number_of_drivers = 0; | ||||
| 	if (!count) { | ||||
| 		*driver_handle_buffer = NULL; | ||||
| 		return EFI_SUCCESS; | ||||
| 	} | ||||
| 	/* | ||||
| 	 * Create buffer. In case of duplicate driver assignments the buffer | ||||
| 	 * will be too large. But that does not harm. | ||||
| 	 */ | ||||
| 	*number_of_drivers = 0; | ||||
| 	*driver_handle_buffer = calloc(count, sizeof(efi_handle_t)); | ||||
| 	if (!*driver_handle_buffer) | ||||
| 		return EFI_OUT_OF_RESOURCES; | ||||
| @@ -1213,7 +1217,8 @@ static efi_status_t efi_disconnect_all_drivers | ||||
| 			      &driver_handle_buffer); | ||||
| 	if (ret != EFI_SUCCESS) | ||||
| 		return ret; | ||||
|  | ||||
| 	if (!number_of_drivers) | ||||
| 		return EFI_SUCCESS; | ||||
| 	ret = EFI_NOT_FOUND; | ||||
| 	while (number_of_drivers) { | ||||
| 		r = EFI_CALL(efi_disconnect_controller( | ||||
| @@ -1985,8 +1990,14 @@ out: | ||||
|  */ | ||||
| static efi_status_t EFIAPI efi_stall(unsigned long microseconds) | ||||
| { | ||||
| 	u64 end_tick; | ||||
|  | ||||
| 	EFI_ENTRY("%ld", microseconds); | ||||
| 	udelay(microseconds); | ||||
|  | ||||
| 	end_tick = get_ticks() + usec_to_tick(microseconds); | ||||
| 	while (get_ticks() < end_tick) | ||||
| 		efi_timer_check(); | ||||
|  | ||||
| 	return EFI_EXIT(EFI_SUCCESS); | ||||
| } | ||||
|  | ||||
| @@ -2868,12 +2879,46 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, | ||||
|  * @image_obj:			handle of the loaded image | ||||
|  * @loaded_image_protocol:	loaded image protocol | ||||
|  */ | ||||
| static void efi_delete_image(struct efi_loaded_image_obj *image_obj, | ||||
| static efi_status_t efi_delete_image | ||||
| 			(struct efi_loaded_image_obj *image_obj, | ||||
| 			 struct efi_loaded_image *loaded_image_protocol) | ||||
| { | ||||
| 	struct efi_object *efiobj; | ||||
| 	efi_status_t r, ret = EFI_SUCCESS; | ||||
|  | ||||
| close_next: | ||||
| 	list_for_each_entry(efiobj, &efi_obj_list, link) { | ||||
| 		struct efi_handler *protocol; | ||||
|  | ||||
| 		list_for_each_entry(protocol, &efiobj->protocols, link) { | ||||
| 			struct efi_open_protocol_info_item *info; | ||||
|  | ||||
| 			list_for_each_entry(info, &protocol->open_infos, link) { | ||||
| 				if (info->info.agent_handle != | ||||
| 				    (efi_handle_t)image_obj) | ||||
| 					continue; | ||||
| 				r = EFI_CALL(efi_close_protocol | ||||
| 						(efiobj, protocol->guid, | ||||
| 						 info->info.agent_handle, | ||||
| 						 info->info.controller_handle | ||||
| 						)); | ||||
| 				if (r !=  EFI_SUCCESS) | ||||
| 					ret = r; | ||||
| 				/* | ||||
| 				 * Closing protocols may results in further | ||||
| 				 * items being deleted. To play it safe loop | ||||
| 				 * over all elements again. | ||||
| 				 */ | ||||
| 				goto close_next; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	efi_free_pages((uintptr_t)loaded_image_protocol->image_base, | ||||
| 		       efi_size_in_pages(loaded_image_protocol->image_size)); | ||||
| 	efi_delete_handle(&image_obj->header); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -430,6 +430,7 @@ static efi_status_t EFIAPI efi_cout_enable_cursor( | ||||
| 	EFI_ENTRY("%p, %d", this, enable); | ||||
|  | ||||
| 	printf(ESC"[?25%c", enable ? 'h' : 'l'); | ||||
| 	efi_con_mode.cursor_visible = !!enable; | ||||
|  | ||||
| 	return EFI_EXIT(EFI_SUCCESS); | ||||
| } | ||||
|   | ||||
| @@ -230,6 +230,7 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, | ||||
| 	struct efi_mem_list *newlist; | ||||
| 	bool carve_again; | ||||
| 	uint64_t carved_pages = 0; | ||||
| 	struct efi_event *evt; | ||||
|  | ||||
| 	EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__, | ||||
| 		  start, pages, memory_type, overlap_only_ram ? "yes" : "no"); | ||||
| @@ -315,6 +316,16 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, | ||||
| 	/* And make sure memory is listed in descending order */ | ||||
| 	efi_mem_sort(); | ||||
|  | ||||
| 	/* Notify that the memory map was changed */ | ||||
| 	list_for_each_entry(evt, &efi_events, link) { | ||||
| 		if (evt->group && | ||||
| 		    !guidcmp(evt->group, | ||||
| 			     &efi_guid_event_group_memory_map_change)) { | ||||
| 			efi_signal_event(evt, false); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return start; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -125,6 +125,8 @@ static const char *parse_attr(const char *str, u32 *attrp) | ||||
|  | ||||
| 		if ((s = prefix(str, "ro"))) { | ||||
| 			attr |= READ_ONLY; | ||||
| 		} else if ((s = prefix(str, "nv"))) { | ||||
| 			attr |= EFI_VARIABLE_NON_VOLATILE; | ||||
| 		} else if ((s = prefix(str, "boot"))) { | ||||
| 			attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS; | ||||
| 		} else if ((s = prefix(str, "run"))) { | ||||
| @@ -468,7 +470,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1); | ||||
| 	val = malloc(2 * data_size + strlen("{ro,run,boot,nv}(blob)") + 1); | ||||
| 	if (!val) { | ||||
| 		ret = EFI_OUT_OF_RESOURCES; | ||||
| 		goto out; | ||||
| @@ -480,12 +482,16 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, | ||||
| 	 * store attributes | ||||
| 	 * TODO: several attributes are not supported | ||||
| 	 */ | ||||
| 	attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); | ||||
| 	attributes &= (EFI_VARIABLE_NON_VOLATILE | | ||||
| 		       EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||
| 		       EFI_VARIABLE_RUNTIME_ACCESS); | ||||
| 	s += sprintf(s, "{"); | ||||
| 	while (attributes) { | ||||
| 		u32 attr = 1 << (ffs(attributes) - 1); | ||||
|  | ||||
| 		if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) | ||||
| 		if (attr == EFI_VARIABLE_NON_VOLATILE) | ||||
| 			s += sprintf(s, "nv"); | ||||
| 		else if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) | ||||
| 			s += sprintf(s, "boot"); | ||||
| 		else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) | ||||
| 			s += sprintf(s, "run"); | ||||
|   | ||||
| @@ -139,7 +139,7 @@ unsigned long __weak notrace timer_get_us(void) | ||||
| 	return tick_to_time(get_ticks() * 1000); | ||||
| } | ||||
|  | ||||
| static uint64_t usec_to_tick(unsigned long usec) | ||||
| uint64_t usec_to_tick(unsigned long usec) | ||||
| { | ||||
| 	uint64_t tick = usec; | ||||
| 	tick *= get_tbclk(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user