Commit | Line | Data |
---|---|---|
3c7f2550 MS |
1 | /* |
2 | * Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org> | |
3 | * | |
4 | * This file implements the EFI boot stub for the arm64 kernel. | |
5 | * Adapted from ARM version by Mark Salter <msalter@redhat.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | */ | |
12 | #include <linux/efi.h> | |
13 | #include <linux/libfdt.h> | |
14 | #include <asm/sections.h> | |
3c7f2550 MS |
15 | |
16 | /* | |
17 | * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from | |
18 | * start of kernel and may not cross a 2MiB boundary. We set alignment to | |
19 | * 2MiB so we know it won't cross a 2MiB boundary. | |
20 | */ | |
21 | #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ | |
22 | #define MAX_FDT_OFFSET SZ_512M | |
23 | ||
24 | #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) | |
25 | ||
26 | static void efi_char16_printk(efi_system_table_t *sys_table_arg, | |
27 | efi_char16_t *str); | |
28 | ||
29 | static efi_status_t efi_open_volume(efi_system_table_t *sys_table, | |
30 | void *__image, void **__fh); | |
31 | static efi_status_t efi_file_close(void *handle); | |
32 | ||
33 | static efi_status_t | |
34 | efi_file_read(void *handle, unsigned long *size, void *addr); | |
35 | ||
36 | static efi_status_t | |
37 | efi_file_size(efi_system_table_t *sys_table, void *__fh, | |
38 | efi_char16_t *filename_16, void **handle, u64 *file_sz); | |
39 | ||
40 | /* Include shared EFI stub code */ | |
41 | #include "../../../drivers/firmware/efi/efi-stub-helper.c" | |
42 | #include "../../../drivers/firmware/efi/fdt.c" | |
43 | #include "../../../drivers/firmware/efi/arm-stub.c" | |
44 | ||
45 | ||
46 | static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | |
47 | unsigned long *image_addr, | |
48 | unsigned long *image_size, | |
49 | unsigned long *reserve_addr, | |
50 | unsigned long *reserve_size, | |
51 | unsigned long dram_base, | |
52 | efi_loaded_image_t *image) | |
53 | { | |
54 | efi_status_t status; | |
55 | unsigned long kernel_size, kernel_memsize = 0; | |
56 | ||
57 | /* Relocate the image, if required. */ | |
58 | kernel_size = _edata - _text; | |
59 | if (*image_addr != (dram_base + TEXT_OFFSET)) { | |
60 | kernel_memsize = kernel_size + (_end - _edata); | |
61 | status = efi_relocate_kernel(sys_table, image_addr, | |
62 | kernel_size, kernel_memsize, | |
63 | dram_base + TEXT_OFFSET, | |
64 | PAGE_SIZE); | |
65 | if (status != EFI_SUCCESS) { | |
66 | pr_efi_err(sys_table, "Failed to relocate kernel\n"); | |
67 | return status; | |
68 | } | |
69 | if (*image_addr != (dram_base + TEXT_OFFSET)) { | |
70 | pr_efi_err(sys_table, "Failed to alloc kernel memory\n"); | |
71 | efi_free(sys_table, kernel_memsize, *image_addr); | |
72 | return EFI_ERROR; | |
73 | } | |
74 | *image_size = kernel_memsize; | |
75 | } | |
76 | ||
77 | ||
78 | return EFI_SUCCESS; | |
79 | } |