]> git.sur5r.net Git - u-boot/blobdiff - lib/efi_loader/efi_image_loader.c
efi_loader: use correct format string for unsigned long
[u-boot] / lib / efi_loader / efi_image_loader.c
index 574b204f23d40dd332e242907010131dff40aebb..849d7ce3777dd1968c5ebe1ebf61840c644d806d 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+const efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
 const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID;
 const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID;
+const efi_guid_t efi_simple_file_system_protocol_guid =
+               EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
+const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
 
-efi_status_t EFIAPI efi_return_handle(void *handle, efi_guid_t *protocol,
-                       void **protocol_interface, void *agent_handle,
-                       void *controller_handle, uint32_t attributes)
-{
-       *protocol_interface = handle;
-       return EFI_SUCCESS;
-}
-
-static void efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
+static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
                        unsigned long rel_size, void *efi_reloc)
 {
        const IMAGE_BASE_RELOCATION *end;
@@ -37,7 +33,7 @@ static void efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
                const uint16_t *relocs = (const uint16_t *)(rel + 1);
                i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t);
                while (i--) {
-                       uint16_t offset = (*relocs & 0xfff) +
+                       uint32_t offset = (uint32_t)(*relocs & 0xfff) +
                                          rel->VirtualAddress;
                        int type = *relocs >> EFI_PAGE_SHIFT;
                        unsigned long delta = (unsigned long)efi_reloc;
@@ -63,11 +59,13 @@ static void efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
                        default:
                                printf("Unknown Relocation off %x type %x\n",
                                       offset, type);
+                               return EFI_LOAD_ERROR;
                        }
                        relocs++;
                }
                rel = (const IMAGE_BASE_RELOCATION *)relocs;
        }
+       return EFI_SUCCESS;
 }
 
 void __weak invalidate_icache_all(void)
@@ -96,6 +94,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
        unsigned long virt_size = 0;
        bool can_run_nt64 = true;
        bool can_run_nt32 = true;
+       uint16_t image_type;
 
 #if defined(CONFIG_ARM64)
        can_run_nt32 = false;
@@ -134,32 +133,53 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
                image_size = opt->SizeOfImage;
                efi_reloc = efi_alloc(virt_size, EFI_LOADER_DATA);
                if (!efi_reloc) {
-                       printf("%s: Could not allocate %ld bytes\n",
-                               __func__, virt_size);
+                       printf("%s: Could not allocate %lu bytes\n",
+                              __func__, virt_size);
                        return NULL;
                }
                entry = efi_reloc + opt->AddressOfEntryPoint;
                rel_size = opt->DataDirectory[rel_idx].Size;
                rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
+               image_type = opt->Subsystem;
        } else if (can_run_nt32 &&
                   (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) {
                IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
                image_size = opt->SizeOfImage;
                efi_reloc = efi_alloc(virt_size, EFI_LOADER_DATA);
                if (!efi_reloc) {
-                       printf("%s: Could not allocate %ld bytes\n",
-                               __func__, virt_size);
+                       printf("%s: Could not allocate %lu bytes\n",
+                              __func__, virt_size);
                        return NULL;
                }
                entry = efi_reloc + opt->AddressOfEntryPoint;
                rel_size = opt->DataDirectory[rel_idx].Size;
                rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
+               image_type = opt->Subsystem;
        } else {
                printf("%s: Invalid optional header magic %x\n", __func__,
                       nt->OptionalHeader.Magic);
                return NULL;
        }
 
+       switch (image_type) {
+       case IMAGE_SUBSYSTEM_EFI_APPLICATION:
+               loaded_image_info->image_code_type = EFI_LOADER_CODE;
+               loaded_image_info->image_data_type = EFI_LOADER_DATA;
+               break;
+       case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+               loaded_image_info->image_code_type = EFI_BOOT_SERVICES_CODE;
+               loaded_image_info->image_data_type = EFI_BOOT_SERVICES_DATA;
+               break;
+       case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+       case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+               loaded_image_info->image_code_type = EFI_RUNTIME_SERVICES_CODE;
+               loaded_image_info->image_data_type = EFI_RUNTIME_SERVICES_DATA;
+               break;
+       default:
+               printf("%s: invalid image type: %u\n", __func__, image_type);
+               break;
+       }
+
        /* Load sections into RAM */
        for (i = num_sections - 1; i >= 0; i--) {
                IMAGE_SECTION_HEADER *sec = &sections[i];
@@ -171,10 +191,15 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
        }
 
        /* Run through relocations */
-       efi_loader_relocate(rel, rel_size, efi_reloc);
+       if (efi_loader_relocate(rel, rel_size, efi_reloc) != EFI_SUCCESS) {
+               efi_free_pages((uintptr_t) efi_reloc,
+                              (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
+               return NULL;
+       }
 
        /* Flush cache */
-       flush_cache((ulong)efi_reloc, virt_size);
+       flush_cache((ulong)efi_reloc,
+                   ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE));
        invalidate_icache_all();
 
        /* Populate the loaded image interface bits */