[U-Boot] [PATCH 1/1] efi_loader: fix setting PlatformLang

AKASHI Takahiro takahiro.akashi at linaro.org
Fri Apr 12 02:49:15 UTC 2019


On Thu, Apr 11, 2019 at 07:23:54PM +0200, Heinrich Schuchardt wrote:
> The UEFI variables PlatformLang and PlatformLangCodes specify the current
> firmware language and the list of all available languages.
> 
> Currently their values are hard coded. With the patch a new configuration
> variable EFI_PLATFORM_LANG_CODES is provided.

Generally speaking, what I expect is that we should have a single place
where arbitrary number of UEFI variables can be configured by default.

> When initializing the UEFI subsystem this configuration variable is used to
> initialize PlatformLangCodes. The value of variable PlatformLang is read.
> If it is not set, the first language specified in EFI_PLATFORM_LANG_CODES
> is used to initialize PlatformLang.
> 
> Suggested-by: Takahiro Akashi <takahiro.akashi at linaro.org>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
>  lib/efi_loader/Kconfig     | 10 ++++++
>  lib/efi_loader/efi_setup.c | 70 ++++++++++++++++++++++++++++++--------
>  2 files changed, 66 insertions(+), 14 deletions(-)
> 
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index a6489ca534..50b050159c 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -26,6 +26,16 @@ config EFI_UNICODE_CAPITALIZATION
>  	  set, only the the correct handling of the letters of the codepage
>  	  used by the FAT file system is ensured.
> 
> +config EFI_PLATFORM_LANG_CODES
> +	string "Language codes supported by firmware"
> +	depends on EFI_LOADER
> +	default "en-US"
> +	help
> +	  This value is used to initialize the PlatformLangCodes variable. Its
> +	  value is a semicolon (;) separated list of language codes in native
> +	  RFC 4646 format, e.g. "en-US;de-DE". The first language code is used
> +	  to initialize the PlatformLang variable.
> +
>  config EFI_LOADER_BOUNCE_BUFFER
>  	bool "EFI Applications use bounce buffers for DMA operations"
>  	depends on EFI_LOADER && ARM64
> diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
> index 6e9d5fe5b7..8f0da35ba4 100644
> --- a/lib/efi_loader/efi_setup.c
> +++ b/lib/efi_loader/efi_setup.c
> @@ -10,37 +10,79 @@
> 
>  #define OBJ_LIST_NOT_INITIALIZED 1
> 
> -/* Language code for American English according to RFC 4646 */
> -#define EN_US L"en-US"
> -
>  static efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
> 
> -/* Initialize and populate EFI object list */
> -efi_status_t efi_init_obj_list(void)
> +/**
> + * efi_init_platform_lang() - define supported languages
> + *
> + * Set the PlatformLangCodes and PlatformLang variables.
> + *
> + * Return:	status code
> + */
> +static efi_status_t efi_init_platform_lang(void)
>  {
> -	efi_status_t ret = EFI_SUCCESS;
> +	efi_status_t ret;
> +	efi_uintn_t data_size = 0;
> +	char *lang = CONFIG_EFI_PLATFORM_LANG_CODES;
> +	char *pos;
> 
>  	/*
> -	 * Variable PlatformLang defines the language that the machine has been
> -	 * configured for.
> +	 * Variable PlatformLangCodes defines the language codes that the
> +	 * machine can support.
>  	 */
> -	ret = EFI_CALL(efi_set_variable(L"PlatformLang",
> +	ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes",
>  					&efi_global_variable_guid,
>  					EFI_VARIABLE_BOOTSERVICE_ACCESS |
>  					EFI_VARIABLE_RUNTIME_ACCESS,
> -					sizeof(EN_US), EN_US));
> +					sizeof(CONFIG_EFI_PLATFORM_LANG_CODES),
> +					CONFIG_EFI_PLATFORM_LANG_CODES));
>  	if (ret != EFI_SUCCESS)
>  		goto out;
> 
>  	/*
> -	 * Variable PlatformLangCodes defines the language codes that the
> -	 * machine can support.
> +	 * Variable PlatformLang defines the language that the machine has been
> +	 * configured for.
>  	 */
> -	ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes",
> +	ret = EFI_CALL(efi_get_variable(L"PlatformLang",
>  					&efi_global_variable_guid,
> +					NULL, &data_size, &pos));
> +	if (ret == EFI_BUFFER_TOO_SMALL) {
> +		/* The variable is already set. Do not change it. */
> +		ret = EFI_SUCCESS;
> +		goto out;
> +	}
> +
> +	/*
> +	 * The list of supported languages is semicolon separated. Use the first
> +	 * language to initialize PlatformLang.
> +	 */
> +	pos = strchr(lang, ';');
> +	if (pos)
> +		*pos = 0;
> +
> +	ret = EFI_CALL(efi_set_variable(L"PlatformLang",
> +					&efi_global_variable_guid,
> +					EFI_VARIABLE_NON_VOLATILE |

Are you going to distinguish non-volatile from volatile from now on?
FYI, I have finished a prototype code with which UEFI variables
are managed separately from U-Boot variables (environment).
This will allow us to implement full semantics of non-volatile
(and authentication in the future) attribute easily.

>  					EFI_VARIABLE_BOOTSERVICE_ACCESS |
>  					EFI_VARIABLE_RUNTIME_ACCESS,
> -					sizeof(EN_US), EN_US));
> +					1 + strlen(lang), lang));
> +out:
> +	if (ret != EFI_SUCCESS)
> +		printf("EFI: cannot initialize platform language settings\n");
> +	return ret;
> +}
> +
> +/**
> + * efi_init_obj_list() - Initialize and populate EFI object list

Well, efi_init_obj_list() is getting bigger and bigger.
The name doesn't reflect its function precisely any more.

-Takahiro Akashi


> + * Return:	status code
> + */
> +efi_status_t efi_init_obj_list(void)
> +{
> +	efi_status_t ret = EFI_SUCCESS;
> +
> +	/* Define supported languages */
> +	ret = efi_init_platform_lang();
>  	if (ret != EFI_SUCCESS)
>  		goto out;
> 
> --
> 2.20.1
> 


More information about the U-Boot mailing list