1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org>
5 * This file implements the EFI boot stub for the arm64 kernel.
6 * Adapted from ARM version by Mark Salter <msalter@redhat.com>
10 #include <linux/efi.h>
12 #include <asm/memory.h>
13 #include <asm/sections.h>
14 #include <asm/sysreg.h>
18 efi_status_t
check_platform_features(void)
22 /* UEFI mandates support for 4 KB granularity, no need to check */
23 if (IS_ENABLED(CONFIG_ARM64_4K_PAGES
))
26 tg
= (read_cpuid(ID_AA64MMFR0_EL1
) >> ID_AA64MMFR0_TGRAN_SHIFT
) & 0xf;
27 if (tg
!= ID_AA64MMFR0_TGRAN_SUPPORTED
) {
28 if (IS_ENABLED(CONFIG_ARM64_64K_PAGES
))
29 efi_err("This 64 KB granular kernel is not supported by your CPU\n");
31 efi_err("This 16 KB granular kernel is not supported by your CPU\n");
32 return EFI_UNSUPPORTED
;
38 * Relocatable kernels can fix up the misalignment with respect to
39 * MIN_KIMG_ALIGN, so they only require a minimum alignment of EFI_KIMG_ALIGN
40 * (which accounts for the alignment of statically allocated objects such as
43 static const u64 min_kimg_align
= IS_ENABLED(CONFIG_RELOCATABLE
) ? EFI_KIMG_ALIGN
46 efi_status_t
handle_kernel_image(unsigned long *image_addr
,
47 unsigned long *image_size
,
48 unsigned long *reserve_addr
,
49 unsigned long *reserve_size
,
50 unsigned long dram_base
,
51 efi_loaded_image_t
*image
)
54 unsigned long kernel_size
, kernel_memsize
= 0;
57 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE
)) {
59 status
= efi_get_random_bytes(sizeof(phys_seed
),
61 if (status
== EFI_NOT_FOUND
) {
62 efi_info("EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
63 } else if (status
!= EFI_SUCCESS
) {
64 efi_err("efi_get_random_bytes() failed\n");
68 efi_info("KASLR disabled on kernel command line\n");
72 if (image
->image_base
!= _text
)
73 efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n");
75 kernel_size
= _edata
- _text
;
76 kernel_memsize
= kernel_size
+ (_end
- _edata
);
77 *reserve_size
= kernel_memsize
+ TEXT_OFFSET
% min_kimg_align
;
79 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE
) && phys_seed
!= 0) {
81 * If KASLR is enabled, and we have some randomness available,
82 * locate the kernel at a randomized offset in physical memory.
84 status
= efi_random_alloc(*reserve_size
, min_kimg_align
,
85 reserve_addr
, phys_seed
);
87 status
= EFI_OUT_OF_RESOURCES
;
90 if (status
!= EFI_SUCCESS
) {
91 if (IS_ALIGNED((u64
)_text
- TEXT_OFFSET
, min_kimg_align
)) {
93 * Just execute from wherever we were loaded by the
94 * UEFI PE/COFF loader if the alignment is suitable.
96 *image_addr
= (u64
)_text
;
101 status
= efi_allocate_pages_aligned(*reserve_size
, reserve_addr
,
102 ULONG_MAX
, min_kimg_align
);
104 if (status
!= EFI_SUCCESS
) {
105 efi_err("Failed to relocate kernel\n");
111 *image_addr
= *reserve_addr
+ TEXT_OFFSET
% min_kimg_align
;
112 memcpy((void *)*image_addr
, _text
, kernel_size
);