net: introduce packet capture support
[oweals/u-boot.git] / lib / efi_loader / efi_setup.c
index a908843d87ab50d0fd989c160890fc7354905321..de7b616c6daa75ae2d67b5026c19201e4fb42f08 100644 (file)
  */
 
 #include <common.h>
+#include <bootm.h>
 #include <efi_loader.h>
 
 #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)
+/*
+ * Allow unaligned memory access.
+ *
+ * This routine is overridden by architectures providing this feature.
+ */
+void __weak allow_unaligned(void)
 {
-       efi_status_t ret = EFI_SUCCESS;
+}
+
+/**
+ * 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_uintn_t data_size = 0;
+       char *lang = CONFIG_EFI_PLATFORM_LANG_CODES;
+       char *pos;
 
        /*
-        * On the ARM architecture gd is mapped to a fixed register (r9 or x18).
-        * As this register may be overwritten by an EFI payload we save it here
-        * and restore it on every callback entered.
+        * Variable PlatformLangCodes defines the language codes that the
+        * machine can support.
         */
-       efi_save_gd();
+       ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes",
+                                       &efi_global_variable_guid,
+                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                       EFI_VARIABLE_RUNTIME_ACCESS,
+                                       sizeof(CONFIG_EFI_PLATFORM_LANG_CODES),
+                                       CONFIG_EFI_PLATFORM_LANG_CODES));
+       if (ret != EFI_SUCCESS)
+               goto out;
 
        /*
         * Variable PlatformLang defines the language that the machine has been
         * configured for.
         */
-       ret = EFI_CALL(efi_set_variable(L"PlatformLang",
+       ret = EFI_CALL(efi_get_variable(L"PlatformLang",
                                        &efi_global_variable_guid,
-                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
-                                       EFI_VARIABLE_RUNTIME_ACCESS,
-                                       sizeof(EN_US), EN_US));
-       if (ret != EFI_SUCCESS)
+                                       NULL, &data_size, &pos));
+       if (ret == EFI_BUFFER_TOO_SMALL) {
+               /* The variable is already set. Do not change it. */
+               ret = EFI_SUCCESS;
                goto out;
+       }
 
        /*
-        * Variable PlatformLangCodes defines the language codes that the
-        * machine can support.
+        * The list of supported languages is semicolon separated. Use the first
+        * language to initialize PlatformLang.
         */
-       ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes",
+       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)
+{
+       u64 os_indications_supported = 0; /* None */
+       efi_status_t ret = EFI_SUCCESS;
 
        /* Initialize once only */
        if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
                return efi_obj_list_initialized;
 
+       /* Allow unaligned memory access */
+       allow_unaligned();
+
+       /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
+       switch_to_non_secure_mode();
+
+       /* Initialize variable services */
+       ret = efi_init_variables();
+       if (ret != EFI_SUCCESS)
+               goto out;
+
+       /* Define supported languages */
+       ret = efi_init_platform_lang();
+       if (ret != EFI_SUCCESS)
+               goto out;
+
+       /* Indicate supported features */
+       ret = EFI_CALL(efi_set_variable(L"OsIndicationsSupported",
+                                       &efi_global_variable_guid,
+                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                       EFI_VARIABLE_RUNTIME_ACCESS,
+                                       sizeof(os_indications_supported),
+                                       &os_indications_supported));
+       if (ret != EFI_SUCCESS)
+               goto out;
+
+       /* Indicate supported runtime services */
+       ret = efi_init_runtime_supported();
+       if (ret != EFI_SUCCESS)
+               goto out;
+
        /* Initialize system table */
        ret = efi_initialize_system_table();
        if (ret != EFI_SUCCESS)