diff options
-rw-r--r-- | lib/efi_loader/Kconfig | 10 | ||||
-rw-r--r-- | lib/efi_loader/efi_setup.c | 72 |
2 files changed, 67 insertions, 15 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index a6489ca5343..50b050159c3 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 6e9d5fe5b7a..b32a7b3f934 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -10,44 +10,86 @@ #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 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(EN_US), EN_US)); + 1 + strlen(lang), lang)); +out: if (ret != EFI_SUCCESS) - goto out; + printf("EFI: cannot initialize platform language settings\n"); + return ret; +} + +/** + * efi_init_obj_list() - Initialize and populate EFI object list + * + * Return: status code + */ +efi_status_t efi_init_obj_list(void) +{ + efi_status_t ret = EFI_SUCCESS; /* Initialize once only */ if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) return efi_obj_list_initialized; + /* Define supported languages */ + ret = efi_init_platform_lang(); + if (ret != EFI_SUCCESS) + goto out; + /* Initialize system table */ ret = efi_initialize_system_table(); if (ret != EFI_SUCCESS) |