mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	efi_loader: define UpdateCapsule api
In this commit, skeleton functions for capsule-related API's are added under CONFIG_EFI_UPDATE_CAPSULE configuration. Detailed implementation for a specific capsule type will be added in the succeeding patches. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
This commit is contained in:
		
				
					committed by
					
						 Heinrich Schuchardt
						Heinrich Schuchardt
					
				
			
			
				
	
			
			
			
						parent
						
							96ec4b1a18
						
					
				
				
					commit
					2bc27ca8a0
				
			| @@ -217,6 +217,10 @@ enum efi_reset_type { | |||||||
| #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE	0x00020000 | #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE	0x00020000 | ||||||
| #define CAPSULE_FLAGS_INITIATE_RESET		0x00040000 | #define CAPSULE_FLAGS_INITIATE_RESET		0x00040000 | ||||||
|  |  | ||||||
|  | #define EFI_CAPSULE_REPORT_GUID \ | ||||||
|  | 	EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ | ||||||
|  | 		 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) | ||||||
|  |  | ||||||
| struct efi_capsule_header { | struct efi_capsule_header { | ||||||
| 	efi_guid_t capsule_guid; | 	efi_guid_t capsule_guid; | ||||||
| 	u32 header_size; | 	u32 header_size; | ||||||
| @@ -224,6 +228,14 @@ struct efi_capsule_header { | |||||||
| 	u32 capsule_image_size; | 	u32 capsule_image_size; | ||||||
| } __packed; | } __packed; | ||||||
|  |  | ||||||
|  | struct efi_capsule_result_variable_header { | ||||||
|  | 	u32 variable_total_size; | ||||||
|  | 	u32 reserved; | ||||||
|  | 	efi_guid_t capsule_guid; | ||||||
|  | 	struct efi_time capsule_processed; | ||||||
|  | 	efi_status_t capsule_status; | ||||||
|  | } __packed; | ||||||
|  |  | ||||||
| #define EFI_RT_SUPPORTED_GET_TIME			0x0001 | #define EFI_RT_SUPPORTED_GET_TIME			0x0001 | ||||||
| #define EFI_RT_SUPPORTED_SET_TIME			0x0002 | #define EFI_RT_SUPPORTED_SET_TIME			0x0002 | ||||||
| #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME		0x0004 | #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME		0x0004 | ||||||
|   | |||||||
| @@ -210,6 +210,8 @@ extern const efi_guid_t efi_guid_cert_type_pkcs7; | |||||||
|  |  | ||||||
| /* GUID of RNG protocol */ | /* GUID of RNG protocol */ | ||||||
| extern const efi_guid_t efi_guid_rng_protocol; | extern const efi_guid_t efi_guid_rng_protocol; | ||||||
|  | /* GUID of capsule update result */ | ||||||
|  | extern const efi_guid_t efi_guid_capsule_report; | ||||||
|  |  | ||||||
| extern unsigned int __efi_runtime_start, __efi_runtime_stop; | extern unsigned int __efi_runtime_start, __efi_runtime_stop; | ||||||
| extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; | extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; | ||||||
| @@ -812,6 +814,17 @@ void efi_memcpy_runtime(void *dest, const void *src, size_t n); | |||||||
| /* commonly used helper function */ | /* commonly used helper function */ | ||||||
| u16 *efi_create_indexed_name(u16 *buffer, const char *name, unsigned int index); | u16 *efi_create_indexed_name(u16 *buffer, const char *name, unsigned int index); | ||||||
|  |  | ||||||
|  | /* Capsule update */ | ||||||
|  | efi_status_t EFIAPI efi_update_capsule( | ||||||
|  | 		struct efi_capsule_header **capsule_header_array, | ||||||
|  | 		efi_uintn_t capsule_count, | ||||||
|  | 		u64 scatter_gather_list); | ||||||
|  | efi_status_t EFIAPI efi_query_capsule_caps( | ||||||
|  | 		struct efi_capsule_header **capsule_header_array, | ||||||
|  | 		efi_uintn_t capsule_count, | ||||||
|  | 		u64 *maximum_capsule_size, | ||||||
|  | 		u32 *reset_type); | ||||||
|  |  | ||||||
| #else /* CONFIG_IS_ENABLED(EFI_LOADER) */ | #else /* CONFIG_IS_ENABLED(EFI_LOADER) */ | ||||||
|  |  | ||||||
| /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ | /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ | ||||||
|   | |||||||
| @@ -94,6 +94,17 @@ config EFI_SET_TIME | |||||||
| 	  Provide the SetTime() runtime service at boottime. This service | 	  Provide the SetTime() runtime service at boottime. This service | ||||||
| 	  can be used by an EFI application to adjust the real time clock. | 	  can be used by an EFI application to adjust the real time clock. | ||||||
|  |  | ||||||
|  | config EFI_HAVE_CAPSULE_SUPPORT | ||||||
|  | 	bool | ||||||
|  |  | ||||||
|  | config EFI_RUNTIME_UPDATE_CAPSULE | ||||||
|  | 	bool "UpdateCapsule() runtime service" | ||||||
|  | 	default n | ||||||
|  | 	select EFI_HAVE_CAPSULE_SUPPORT | ||||||
|  | 	help | ||||||
|  | 	  Select this option if you want to use UpdateCapsule and | ||||||
|  | 	  QueryCapsuleCapabilities API's. | ||||||
|  |  | ||||||
| config EFI_DEVICE_PATH_TO_TEXT | config EFI_DEVICE_PATH_TO_TEXT | ||||||
| 	bool "Device path to text protocol" | 	bool "Device path to text protocol" | ||||||
| 	default y | 	default y | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ endif | |||||||
| obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o | obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o | ||||||
| obj-y += efi_bootmgr.o | obj-y += efi_bootmgr.o | ||||||
| obj-y += efi_boottime.o | obj-y += efi_boottime.o | ||||||
|  | obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o | ||||||
| obj-y += efi_console.o | obj-y += efi_console.o | ||||||
| obj-y += efi_device_path.o | obj-y += efi_device_path.o | ||||||
| obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o | obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o | ||||||
|   | |||||||
							
								
								
									
										165
									
								
								lib/efi_loader/efi_capsule.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								lib/efi_loader/efi_capsule.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
|  | /* | ||||||
|  |  *  EFI Capsule | ||||||
|  |  * | ||||||
|  |  *  Copyright (c) 2018 Linaro Limited | ||||||
|  |  *			Author: AKASHI Takahiro | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <common.h> | ||||||
|  | #include <efi_loader.h> | ||||||
|  | #include <efi_variable.h> | ||||||
|  | #include <fs.h> | ||||||
|  | #include <malloc.h> | ||||||
|  | #include <sort.h> | ||||||
|  |  | ||||||
|  | const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * get_last_capsule - get the last capsule index | ||||||
|  |  * | ||||||
|  |  * Retrieve the index of the capsule invoked last time from "CapsuleLast" | ||||||
|  |  * variable. | ||||||
|  |  * | ||||||
|  |  * Return: | ||||||
|  |  * * > 0	- the last capsule index invoked | ||||||
|  |  * * 0xffff	- on error, or no capsule invoked yet | ||||||
|  |  */ | ||||||
|  | static __maybe_unused unsigned int get_last_capsule(void) | ||||||
|  | { | ||||||
|  | 	u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */ | ||||||
|  | 	char value[11], *p; | ||||||
|  | 	efi_uintn_t size; | ||||||
|  | 	unsigned long index = 0xffff; | ||||||
|  | 	efi_status_t ret; | ||||||
|  |  | ||||||
|  | 	size = sizeof(value16); | ||||||
|  | 	ret = efi_get_variable_int(L"CapsuleLast", &efi_guid_capsule_report, | ||||||
|  | 				   NULL, &size, value16, NULL); | ||||||
|  | 	if (ret != EFI_SUCCESS || u16_strncmp(value16, L"Capsule", 7)) | ||||||
|  | 		goto err; | ||||||
|  |  | ||||||
|  | 	p = value; | ||||||
|  | 	utf16_utf8_strcpy(&p, value16); | ||||||
|  | 	strict_strtoul(&value[7], 16, &index); | ||||||
|  | err: | ||||||
|  | 	return index; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * set_capsule_result - set a result variable | ||||||
|  |  * @capsule:		Capsule | ||||||
|  |  * @return_status:	Return status | ||||||
|  |  * | ||||||
|  |  * Create and set a result variable, "CapsuleXXXX", for the capsule, | ||||||
|  |  * @capsule. | ||||||
|  |  */ | ||||||
|  | static __maybe_unused | ||||||
|  | void set_capsule_result(int index, struct efi_capsule_header *capsule, | ||||||
|  | 			efi_status_t return_status) | ||||||
|  | { | ||||||
|  | 	u16 variable_name16[12]; | ||||||
|  | 	struct efi_capsule_result_variable_header result; | ||||||
|  | 	struct efi_time time; | ||||||
|  | 	efi_status_t ret; | ||||||
|  |  | ||||||
|  | 	efi_create_indexed_name(variable_name16, "Capsule", index); | ||||||
|  |  | ||||||
|  | 	result.variable_total_size = sizeof(result); | ||||||
|  | 	result.capsule_guid = capsule->capsule_guid; | ||||||
|  | 	ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL)); | ||||||
|  | 	if (ret == EFI_SUCCESS) | ||||||
|  | 		memcpy(&result.capsule_processed, &time, sizeof(time)); | ||||||
|  | 	else | ||||||
|  | 		memset(&result.capsule_processed, 0, sizeof(time)); | ||||||
|  | 	result.capsule_status = return_status; | ||||||
|  | 	ret = efi_set_variable(variable_name16, &efi_guid_capsule_report, | ||||||
|  | 			       EFI_VARIABLE_NON_VOLATILE | | ||||||
|  | 			       EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||||
|  | 			       EFI_VARIABLE_RUNTIME_ACCESS, | ||||||
|  | 			       sizeof(result), &result); | ||||||
|  | 	if (ret) | ||||||
|  | 		printf("EFI: creating %ls failed\n", variable_name16); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * efi_update_capsule() - process information from operating system | ||||||
|  |  * @capsule_header_array:	Array of virtual address pointers | ||||||
|  |  * @capsule_count:		Number of pointers in capsule_header_array | ||||||
|  |  * @scatter_gather_list:	Array of physical address pointers | ||||||
|  |  * | ||||||
|  |  * This function implements the UpdateCapsule() runtime service. | ||||||
|  |  * | ||||||
|  |  * See the Unified Extensible Firmware Interface (UEFI) specification for | ||||||
|  |  * details. | ||||||
|  |  * | ||||||
|  |  * Return:			status code | ||||||
|  |  */ | ||||||
|  | efi_status_t EFIAPI efi_update_capsule( | ||||||
|  | 		struct efi_capsule_header **capsule_header_array, | ||||||
|  | 		efi_uintn_t capsule_count, | ||||||
|  | 		u64 scatter_gather_list) | ||||||
|  | { | ||||||
|  | 	struct efi_capsule_header *capsule; | ||||||
|  | 	unsigned int i; | ||||||
|  | 	efi_status_t ret; | ||||||
|  |  | ||||||
|  | 	EFI_ENTRY("%p, %lu, %llu\n", capsule_header_array, capsule_count, | ||||||
|  | 		  scatter_gather_list); | ||||||
|  |  | ||||||
|  | 	if (!capsule_count) { | ||||||
|  | 		ret = EFI_INVALID_PARAMETER; | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ret = EFI_UNSUPPORTED; | ||||||
|  | 	for (i = 0, capsule = *capsule_header_array; i < capsule_count; | ||||||
|  | 	     i++, capsule = *(++capsule_header_array)) { | ||||||
|  | 	} | ||||||
|  | out: | ||||||
|  | 	return EFI_EXIT(ret); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * efi_query_capsule_caps() - check if capsule is supported | ||||||
|  |  * @capsule_header_array:	Array of virtual pointers | ||||||
|  |  * @capsule_count:		Number of pointers in capsule_header_array | ||||||
|  |  * @maximum_capsule_size:	Maximum capsule size | ||||||
|  |  * @reset_type:			Type of reset needed for capsule update | ||||||
|  |  * | ||||||
|  |  * This function implements the QueryCapsuleCapabilities() runtime service. | ||||||
|  |  * | ||||||
|  |  * See the Unified Extensible Firmware Interface (UEFI) specification for | ||||||
|  |  * details. | ||||||
|  |  * | ||||||
|  |  * Return:			status code | ||||||
|  |  */ | ||||||
|  | efi_status_t EFIAPI efi_query_capsule_caps( | ||||||
|  | 		struct efi_capsule_header **capsule_header_array, | ||||||
|  | 		efi_uintn_t capsule_count, | ||||||
|  | 		u64 *maximum_capsule_size, | ||||||
|  | 		u32 *reset_type) | ||||||
|  | { | ||||||
|  | 	struct efi_capsule_header *capsule __attribute__((unused)); | ||||||
|  | 	unsigned int i; | ||||||
|  | 	efi_status_t ret; | ||||||
|  |  | ||||||
|  | 	EFI_ENTRY("%p, %lu, %p, %p\n", capsule_header_array, capsule_count, | ||||||
|  | 		  maximum_capsule_size, reset_type); | ||||||
|  |  | ||||||
|  | 	if (!maximum_capsule_size) { | ||||||
|  | 		ret = EFI_INVALID_PARAMETER; | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	*maximum_capsule_size = U64_MAX; | ||||||
|  | 	*reset_type = EFI_RESET_COLD; | ||||||
|  |  | ||||||
|  | 	ret = EFI_SUCCESS; | ||||||
|  | 	for (i = 0, capsule = *capsule_header_array; i < capsule_count; | ||||||
|  | 	     i++, capsule = *(++capsule_header_array)) { | ||||||
|  | 		/* TODO */ | ||||||
|  | 	} | ||||||
|  | out: | ||||||
|  | 	return EFI_EXIT(ret); | ||||||
|  | } | ||||||
| @@ -133,6 +133,10 @@ efi_status_t efi_init_runtime_supported(void) | |||||||
| #ifdef CONFIG_EFI_HAVE_RUNTIME_RESET | #ifdef CONFIG_EFI_HAVE_RUNTIME_RESET | ||||||
| 	rt_table->runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM; | 	rt_table->runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM; | ||||||
| #endif | #endif | ||||||
|  | 	if (IS_ENABLED(CONFIG_EFI_RUNTIME_UPDATE_CAPSULE)) | ||||||
|  | 		rt_table->runtime_services_supported |= | ||||||
|  | 			(EFI_RT_SUPPORTED_UPDATE_CAPSULE | | ||||||
|  | 			 EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES); | ||||||
|  |  | ||||||
| 	ret = efi_install_configuration_table(&efi_rt_properties_table_guid, | 	ret = efi_install_configuration_table(&efi_rt_properties_table_guid, | ||||||
| 					      rt_table); | 					      rt_table); | ||||||
| @@ -448,6 +452,50 @@ efi_status_t __weak __efi_runtime EFIAPI efi_set_time(struct efi_time *time) | |||||||
| 	return EFI_UNSUPPORTED; | 	return EFI_UNSUPPORTED; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * efi_update_capsule_unsupported() - process information from operating system | ||||||
|  |  * | ||||||
|  |  * This function implements the UpdateCapsule() runtime service. | ||||||
|  |  * | ||||||
|  |  * See the Unified Extensible Firmware Interface (UEFI) specification for | ||||||
|  |  * details. | ||||||
|  |  * | ||||||
|  |  * @capsule_header_array:	pointer to array of virtual pointers | ||||||
|  |  * @capsule_count:		number of pointers in capsule_header_array | ||||||
|  |  * @scatter_gather_list:	pointer to array of physical pointers | ||||||
|  |  * Returns:			status code | ||||||
|  |  */ | ||||||
|  | efi_status_t __efi_runtime EFIAPI efi_update_capsule_unsupported( | ||||||
|  | 			struct efi_capsule_header **capsule_header_array, | ||||||
|  | 			efi_uintn_t capsule_count, | ||||||
|  | 			u64 scatter_gather_list) | ||||||
|  | { | ||||||
|  | 	return EFI_UNSUPPORTED; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * efi_query_capsule_caps_unsupported() - check if capsule is supported | ||||||
|  |  * | ||||||
|  |  * This function implements the QueryCapsuleCapabilities() runtime service. | ||||||
|  |  * | ||||||
|  |  * See the Unified Extensible Firmware Interface (UEFI) specification for | ||||||
|  |  * details. | ||||||
|  |  * | ||||||
|  |  * @capsule_header_array:	pointer to array of virtual pointers | ||||||
|  |  * @capsule_count:		number of pointers in capsule_header_array | ||||||
|  |  * @maximum_capsule_size:	maximum capsule size | ||||||
|  |  * @reset_type:			type of reset needed for capsule update | ||||||
|  |  * Returns:			status code | ||||||
|  |  */ | ||||||
|  | efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps_unsupported( | ||||||
|  | 			struct efi_capsule_header **capsule_header_array, | ||||||
|  | 			efi_uintn_t capsule_count, | ||||||
|  | 			u64 *maximum_capsule_size, | ||||||
|  | 			u32 *reset_type) | ||||||
|  | { | ||||||
|  | 	return EFI_UNSUPPORTED; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * efi_is_runtime_service_pointer() - check if pointer points to runtime table |  * efi_is_runtime_service_pointer() - check if pointer points to runtime table | ||||||
|  * |  * | ||||||
| @@ -471,6 +519,13 @@ void efi_runtime_detach(void) | |||||||
| 	efi_runtime_services.reset_system = efi_reset_system; | 	efi_runtime_services.reset_system = efi_reset_system; | ||||||
| 	efi_runtime_services.get_time = efi_get_time; | 	efi_runtime_services.get_time = efi_get_time; | ||||||
| 	efi_runtime_services.set_time = efi_set_time; | 	efi_runtime_services.set_time = efi_set_time; | ||||||
|  | 	if (IS_ENABLED(CONFIG_EFI_RUNTIME_UPDATE_CAPSULE)) { | ||||||
|  | 		/* won't support at runtime */ | ||||||
|  | 		efi_runtime_services.update_capsule = | ||||||
|  | 				efi_update_capsule_unsupported; | ||||||
|  | 		efi_runtime_services.query_capsule_caps = | ||||||
|  | 				efi_query_capsule_caps_unsupported; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/* Update CRC32 */ | 	/* Update CRC32 */ | ||||||
| 	efi_update_table_header_crc32(&efi_runtime_services.hdr); | 	efi_update_table_header_crc32(&efi_runtime_services.hdr); | ||||||
| @@ -879,50 +934,6 @@ static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void) | |||||||
| 	return EFI_UNSUPPORTED; | 	return EFI_UNSUPPORTED; | ||||||
| } | } | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * efi_update_capsule() - process information from operating system |  | ||||||
|  * |  | ||||||
|  * This function implements the UpdateCapsule() runtime service. |  | ||||||
|  * |  | ||||||
|  * See the Unified Extensible Firmware Interface (UEFI) specification for |  | ||||||
|  * details. |  | ||||||
|  * |  | ||||||
|  * @capsule_header_array:	pointer to array of virtual pointers |  | ||||||
|  * @capsule_count:		number of pointers in capsule_header_array |  | ||||||
|  * @scatter_gather_list:	pointer to arry of physical pointers |  | ||||||
|  * Returns:			status code |  | ||||||
|  */ |  | ||||||
| efi_status_t __efi_runtime EFIAPI efi_update_capsule( |  | ||||||
| 			struct efi_capsule_header **capsule_header_array, |  | ||||||
| 			efi_uintn_t capsule_count, |  | ||||||
| 			u64 scatter_gather_list) |  | ||||||
| { |  | ||||||
| 	return EFI_UNSUPPORTED; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * efi_query_capsule_caps() - check if capsule is supported |  | ||||||
|  * |  | ||||||
|  * This function implements the QueryCapsuleCapabilities() runtime service. |  | ||||||
|  * |  | ||||||
|  * See the Unified Extensible Firmware Interface (UEFI) specification for |  | ||||||
|  * details. |  | ||||||
|  * |  | ||||||
|  * @capsule_header_array:	pointer to array of virtual pointers |  | ||||||
|  * @capsule_count:		number of pointers in capsule_header_array |  | ||||||
|  * @maximum_capsule_size:	maximum capsule size |  | ||||||
|  * @reset_type:			type of reset needed for capsule update |  | ||||||
|  * Returns:			status code |  | ||||||
|  */ |  | ||||||
| efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps( |  | ||||||
| 			struct efi_capsule_header **capsule_header_array, |  | ||||||
| 			efi_uintn_t capsule_count, |  | ||||||
| 			u64 *maximum_capsule_size, |  | ||||||
| 			u32 *reset_type) |  | ||||||
| { |  | ||||||
| 	return EFI_UNSUPPORTED; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct efi_runtime_services __efi_runtime_data efi_runtime_services = { | struct efi_runtime_services __efi_runtime_data efi_runtime_services = { | ||||||
| 	.hdr = { | 	.hdr = { | ||||||
| 		.signature = EFI_RUNTIME_SERVICES_SIGNATURE, | 		.signature = EFI_RUNTIME_SERVICES_SIGNATURE, | ||||||
| @@ -940,7 +951,12 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { | |||||||
| 	.set_variable = efi_set_variable, | 	.set_variable = efi_set_variable, | ||||||
| 	.get_next_high_mono_count = (void *)&efi_unimplemented, | 	.get_next_high_mono_count = (void *)&efi_unimplemented, | ||||||
| 	.reset_system = &efi_reset_system_boottime, | 	.reset_system = &efi_reset_system_boottime, | ||||||
|  | #ifdef CONFIG_EFI_RUNTIME_UPDATE_CAPSULE | ||||||
| 	.update_capsule = efi_update_capsule, | 	.update_capsule = efi_update_capsule, | ||||||
| 	.query_capsule_caps = efi_query_capsule_caps, | 	.query_capsule_caps = efi_query_capsule_caps, | ||||||
|  | #else | ||||||
|  | 	.update_capsule = efi_update_capsule_unsupported, | ||||||
|  | 	.query_capsule_caps = efi_query_capsule_caps_unsupported, | ||||||
|  | #endif | ||||||
| 	.query_variable_info = efi_query_variable_info, | 	.query_variable_info = efi_query_variable_info, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -100,9 +100,9 @@ static efi_status_t efi_init_secure_boot(void) | |||||||
|  |  | ||||||
| 	ret = efi_set_variable_int(L"SignatureSupport", | 	ret = efi_set_variable_int(L"SignatureSupport", | ||||||
| 				   &efi_global_variable_guid, | 				   &efi_global_variable_guid, | ||||||
|  | 				   EFI_VARIABLE_READ_ONLY | | ||||||
| 				   EFI_VARIABLE_BOOTSERVICE_ACCESS | | 				   EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||||
| 				   EFI_VARIABLE_RUNTIME_ACCESS | | 				   EFI_VARIABLE_RUNTIME_ACCESS, | ||||||
| 				   EFI_VARIABLE_READ_ONLY, |  | ||||||
| 				   sizeof(signature_types), | 				   sizeof(signature_types), | ||||||
| 				   &signature_types, false); | 				   &signature_types, false); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| @@ -117,6 +117,53 @@ static efi_status_t efi_init_secure_boot(void) | |||||||
| } | } | ||||||
| #endif /* CONFIG_EFI_SECURE_BOOT */ | #endif /* CONFIG_EFI_SECURE_BOOT */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * efi_init_capsule - initialize capsule update state | ||||||
|  |  * | ||||||
|  |  * Return:	status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t efi_init_capsule(void) | ||||||
|  | { | ||||||
|  | 	efi_status_t ret = EFI_SUCCESS; | ||||||
|  |  | ||||||
|  | 	if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_UPDATE)) { | ||||||
|  | 		ret = efi_set_variable_int(L"CapsuleMax", | ||||||
|  | 					   &efi_guid_capsule_report, | ||||||
|  | 					   EFI_VARIABLE_READ_ONLY | | ||||||
|  | 					   EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||||
|  | 					   EFI_VARIABLE_RUNTIME_ACCESS, | ||||||
|  | 					   22, L"CapsuleFFFF", false); | ||||||
|  | 		if (ret != EFI_SUCCESS) | ||||||
|  | 			printf("EFI: cannot initialize CapsuleMax variable\n"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * efi_init_os_indications() - indicate supported features for OS requests | ||||||
|  |  * | ||||||
|  |  * Set the OsIndicationsSupported variable. | ||||||
|  |  * | ||||||
|  |  * Return:	status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t efi_init_os_indications(void) | ||||||
|  | { | ||||||
|  | 	u64 os_indications_supported = 0; | ||||||
|  |  | ||||||
|  | 	if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) | ||||||
|  | 		os_indications_supported |= | ||||||
|  | 			EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED; | ||||||
|  |  | ||||||
|  | 	return efi_set_variable_int(L"OsIndicationsSupported", | ||||||
|  | 				    &efi_global_variable_guid, | ||||||
|  | 				    EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||||||
|  | 				    EFI_VARIABLE_RUNTIME_ACCESS | | ||||||
|  | 				    EFI_VARIABLE_READ_ONLY, | ||||||
|  | 				    sizeof(os_indications_supported), | ||||||
|  | 				    &os_indications_supported, false); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * efi_init_obj_list() - Initialize and populate EFI object list |  * efi_init_obj_list() - Initialize and populate EFI object list | ||||||
|  * |  * | ||||||
| @@ -124,7 +171,6 @@ static efi_status_t efi_init_secure_boot(void) | |||||||
|  */ |  */ | ||||||
| efi_status_t efi_init_obj_list(void) | efi_status_t efi_init_obj_list(void) | ||||||
| { | { | ||||||
| 	u64 os_indications_supported = 0; /* None */ |  | ||||||
| 	efi_status_t ret = EFI_SUCCESS; | 	efi_status_t ret = EFI_SUCCESS; | ||||||
|  |  | ||||||
| 	/* Initialize once only */ | 	/* Initialize once only */ | ||||||
| @@ -168,13 +214,7 @@ efi_status_t efi_init_obj_list(void) | |||||||
| 		goto out; | 		goto out; | ||||||
|  |  | ||||||
| 	/* Indicate supported features */ | 	/* Indicate supported features */ | ||||||
| 	ret = efi_set_variable_int(L"OsIndicationsSupported", | 	ret = efi_init_os_indications(); | ||||||
| 				   &efi_global_variable_guid, |  | ||||||
| 				   EFI_VARIABLE_BOOTSERVICE_ACCESS | |  | ||||||
| 				   EFI_VARIABLE_RUNTIME_ACCESS | |  | ||||||
| 				   EFI_VARIABLE_READ_ONLY, |  | ||||||
| 				   sizeof(os_indications_supported), |  | ||||||
| 				   &os_indications_supported, false); |  | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		goto out; | 		goto out; | ||||||
|  |  | ||||||
| @@ -233,6 +273,10 @@ efi_status_t efi_init_obj_list(void) | |||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		goto out; | 		goto out; | ||||||
|  |  | ||||||
|  | 	ret = efi_init_capsule(); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
| 	/* Initialize EFI runtime services */ | 	/* Initialize EFI runtime services */ | ||||||
| 	ret = efi_reset_system_init(); | 	ret = efi_reset_system_init(); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user