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> | |
15 | #include <generated/compile.h> | |
16 | #include <generated/utsrelease.h> | |
17 | ||
18 | /* | |
19 | * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from | |
20 | * start of kernel and may not cross a 2MiB boundary. We set alignment to | |
21 | * 2MiB so we know it won't cross a 2MiB boundary. | |
22 | */ | |
23 | #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ | |
24 | #define MAX_FDT_OFFSET SZ_512M | |
25 | ||
26 | #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) | |
27 | ||
28 | static void efi_char16_printk(efi_system_table_t *sys_table_arg, | |
29 | efi_char16_t *str); | |
30 | ||
31 | static efi_status_t efi_open_volume(efi_system_table_t *sys_table, | |
32 | void *__image, void **__fh); | |
33 | static efi_status_t efi_file_close(void *handle); | |
34 | ||
35 | static efi_status_t | |
36 | efi_file_read(void *handle, unsigned long *size, void *addr); | |
37 | ||
38 | static efi_status_t | |
39 | efi_file_size(efi_system_table_t *sys_table, void *__fh, | |
40 | efi_char16_t *filename_16, void **handle, u64 *file_sz); | |
41 | ||
42 | /* Include shared EFI stub code */ | |
43 | #include "../../../drivers/firmware/efi/efi-stub-helper.c" | |
44 | #include "../../../drivers/firmware/efi/fdt.c" | |
45 | #include "../../../drivers/firmware/efi/arm-stub.c" | |
46 | ||
47 | ||
48 | static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | |
49 | unsigned long *image_addr, | |
50 | unsigned long *image_size, | |
51 | unsigned long *reserve_addr, | |
52 | unsigned long *reserve_size, | |
53 | unsigned long dram_base, | |
54 | efi_loaded_image_t *image) | |
55 | { | |
56 | efi_status_t status; | |
57 | unsigned long kernel_size, kernel_memsize = 0; | |
58 | ||
59 | /* Relocate the image, if required. */ | |
60 | kernel_size = _edata - _text; | |
61 | if (*image_addr != (dram_base + TEXT_OFFSET)) { | |
62 | kernel_memsize = kernel_size + (_end - _edata); | |
63 | status = efi_relocate_kernel(sys_table, image_addr, | |
64 | kernel_size, kernel_memsize, | |
65 | dram_base + TEXT_OFFSET, | |
66 | PAGE_SIZE); | |
67 | if (status != EFI_SUCCESS) { | |
68 | pr_efi_err(sys_table, "Failed to relocate kernel\n"); | |
69 | return status; | |
70 | } | |
71 | if (*image_addr != (dram_base + TEXT_OFFSET)) { | |
72 | pr_efi_err(sys_table, "Failed to alloc kernel memory\n"); | |
73 | efi_free(sys_table, kernel_memsize, *image_addr); | |
74 | return EFI_ERROR; | |
75 | } | |
76 | *image_size = kernel_memsize; | |
77 | } | |
78 | ||
79 | ||
80 | return EFI_SUCCESS; | |
81 | } |