1 /* 2 * Copyright (C) 2013 Linaro Ltd; <roy.franz@linaro.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 */ 9 #include <linux/efi.h> 10 #include <asm/efi.h> 11 12 efi_status_t check_platform_features(efi_system_table_t *sys_table_arg) 13 { 14 int block; 15 16 /* non-LPAE kernels can run anywhere */ 17 if (!IS_ENABLED(CONFIG_ARM_LPAE)) 18 return EFI_SUCCESS; 19 20 /* LPAE kernels need compatible hardware */ 21 block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0); 22 if (block < 5) { 23 pr_efi_err(sys_table_arg, "This LPAE kernel is not supported by your CPU\n"); 24 return EFI_UNSUPPORTED; 25 } 26 return EFI_SUCCESS; 27 } 28 29 efi_status_t handle_kernel_image(efi_system_table_t *sys_table, 30 unsigned long *image_addr, 31 unsigned long *image_size, 32 unsigned long *reserve_addr, 33 unsigned long *reserve_size, 34 unsigned long dram_base, 35 efi_loaded_image_t *image) 36 { 37 unsigned long nr_pages; 38 efi_status_t status; 39 /* Use alloc_addr to tranlsate between types */ 40 efi_physical_addr_t alloc_addr; 41 42 /* 43 * Verify that the DRAM base address is compatible with the ARM 44 * boot protocol, which determines the base of DRAM by masking 45 * off the low 27 bits of the address at which the zImage is 46 * loaded. These assumptions are made by the decompressor, 47 * before any memory map is available. 48 */ 49 dram_base = round_up(dram_base, SZ_128M); 50 51 /* 52 * Reserve memory for the uncompressed kernel image. This is 53 * all that prevents any future allocations from conflicting 54 * with the kernel. Since we can't tell from the compressed 55 * image how much DRAM the kernel actually uses (due to BSS 56 * size uncertainty) we allocate the maximum possible size. 57 * Do this very early, as prints can cause memory allocations 58 * that may conflict with this. 59 */ 60 alloc_addr = dram_base; 61 *reserve_size = MAX_UNCOMP_KERNEL_SIZE; 62 nr_pages = round_up(*reserve_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; 63 status = sys_table->boottime->allocate_pages(EFI_ALLOCATE_ADDRESS, 64 EFI_LOADER_DATA, 65 nr_pages, &alloc_addr); 66 if (status != EFI_SUCCESS) { 67 *reserve_size = 0; 68 pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n"); 69 return status; 70 } 71 *reserve_addr = alloc_addr; 72 73 /* 74 * Relocate the zImage, so that it appears in the lowest 128 MB 75 * memory window. 76 */ 77 *image_size = image->image_size; 78 status = efi_relocate_kernel(sys_table, image_addr, *image_size, 79 *image_size, 80 dram_base + MAX_UNCOMP_KERNEL_SIZE, 0); 81 if (status != EFI_SUCCESS) { 82 pr_efi_err(sys_table, "Failed to relocate kernel.\n"); 83 efi_free(sys_table, *reserve_size, *reserve_addr); 84 *reserve_size = 0; 85 return status; 86 } 87 88 /* 89 * Check to see if we were able to allocate memory low enough 90 * in memory. The kernel determines the base of DRAM from the 91 * address at which the zImage is loaded. 92 */ 93 if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) { 94 pr_efi_err(sys_table, "Failed to relocate kernel, no low memory available.\n"); 95 efi_free(sys_table, *reserve_size, *reserve_addr); 96 *reserve_size = 0; 97 efi_free(sys_table, *image_size, *image_addr); 98 *image_size = 0; 99 return EFI_LOAD_ERROR; 100 } 101 return EFI_SUCCESS; 102 } 103