diff options
author | Tudor Florea <tudor.florea@enea.com> | 2015-10-08 22:42:49 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2015-10-08 22:42:49 +0200 |
commit | 635d320abfa6dc3c0e1d00e3ceae567dd0e55a5b (patch) | |
tree | dcd42fafb9189d3be13ef3d95f9ce6f4f5cfa267 /recipes-kernel/linux/linux-hierofalcon/01-arm64-boot-BE-kernels-from-UEFI.patch | |
download | meta-hierofalcon-635d320abfa6dc3c0e1d00e3ceae567dd0e55a5b.tar.gz |
initial commit for Enea Linux 5.0 arm
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'recipes-kernel/linux/linux-hierofalcon/01-arm64-boot-BE-kernels-from-UEFI.patch')
-rw-r--r-- | recipes-kernel/linux/linux-hierofalcon/01-arm64-boot-BE-kernels-from-UEFI.patch | 995 |
1 files changed, 995 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-hierofalcon/01-arm64-boot-BE-kernels-from-UEFI.patch b/recipes-kernel/linux/linux-hierofalcon/01-arm64-boot-BE-kernels-from-UEFI.patch new file mode 100644 index 0000000..6790315 --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon/01-arm64-boot-BE-kernels-from-UEFI.patch | |||
@@ -0,0 +1,995 @@ | |||
1 | From c55fa726d3e67da11a7ccd16ca367e9094265e4e Mon Sep 17 00:00:00 2001 | ||
2 | From: Adrian Calianu <adrian.calianu@enea.com> | ||
3 | Date: Mon, 16 Feb 2015 13:56:36 +0100 | ||
4 | Subject: [PATCH 1/1] arm64: boot BE kernels from UEFI | ||
5 | |||
6 | Adds support for booting BE kernels from UEFI. As UEFI is defined to | ||
7 | be strictly little endian, some workarounds are required to combine a little | ||
8 | endian EFI stub with a big endian kernel. Also, runtime services need to be | ||
9 | wrapped so they can be executed in little endian mode. | ||
10 | |||
11 | This patch is the resulting of porting on 3.19 kernel of a patch set | ||
12 | ([RFC PATCH 00/10] arm64: boot BE kernels from UEFI) provided by | ||
13 | Ard Biesheuvel ard.biesheuvel at linaro.org for 3.17 kernel. | ||
14 | |||
15 | http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274208.html | ||
16 | |||
17 | Signed-off-by: Adrian Calianu <adrian.calianu@enea.com> | ||
18 | --- | ||
19 | arch/arm64/Kconfig | 10 ++- | ||
20 | arch/arm64/include/asm/assembler.h | 18 +++++ | ||
21 | arch/arm64/include/asm/efi.h | 2 + | ||
22 | arch/arm64/kernel/Makefile | 7 +- | ||
23 | arch/arm64/kernel/efi-be-call.S | 55 +++++++++++++++ | ||
24 | arch/arm64/kernel/efi-be-runtime.c | 104 ++++++++++++++++++++++++++++ | ||
25 | arch/arm64/kernel/efi-entry.S | 43 +++++++++--- | ||
26 | arch/arm64/kernel/efi-stub.c | 10 +-- | ||
27 | arch/arm64/kernel/efi.c | 64 ++++++++++------- | ||
28 | arch/arm64/kernel/efistub-le/Makefile | 52 ++++++++++++++ | ||
29 | arch/arm64/kernel/efistub-le/efi-le-entry.S | 12 ++++ | ||
30 | arch/arm64/kernel/efistub-le/efistub-le.lds | 35 ++++++++++ | ||
31 | arch/arm64/kernel/efistub-le/le.h | 12 ++++ | ||
32 | arch/arm64/kernel/efistub-le/strstr.c | 20 ++++++ | ||
33 | arch/arm64/kernel/head.S | 48 +++++++------ | ||
34 | arch/arm64/kernel/image.h | 16 ++++- | ||
35 | drivers/firmware/efi/efi.c | 26 ++++--- | ||
36 | drivers/firmware/efi/efivars.c | 2 +- | ||
37 | drivers/firmware/efi/libstub/fdt.c | 4 ++ | ||
38 | 19 files changed, 459 insertions(+), 81 deletions(-) | ||
39 | create mode 100644 arch/arm64/kernel/efi-be-call.S | ||
40 | create mode 100644 arch/arm64/kernel/efi-be-runtime.c | ||
41 | create mode 100644 arch/arm64/kernel/efistub-le/Makefile | ||
42 | create mode 100644 arch/arm64/kernel/efistub-le/efi-le-entry.S | ||
43 | create mode 100644 arch/arm64/kernel/efistub-le/efistub-le.lds | ||
44 | create mode 100644 arch/arm64/kernel/efistub-le/le.h | ||
45 | create mode 100644 arch/arm64/kernel/efistub-le/strstr.c | ||
46 | |||
47 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig | ||
48 | index 3f08727..d35a06c 100644 | ||
49 | --- a/arch/arm64/Kconfig | ||
50 | +++ b/arch/arm64/Kconfig | ||
51 | @@ -573,16 +573,20 @@ config CMDLINE_FORCE | ||
52 | config EFI_STUB | ||
53 | bool | ||
54 | |||
55 | +config EFI_LE_STUB | ||
56 | + bool | ||
57 | + | ||
58 | config EFI | ||
59 | bool "UEFI runtime support" | ||
60 | - depends on OF && !CPU_BIG_ENDIAN | ||
61 | + depends on OF | ||
62 | select LIBFDT | ||
63 | select UCS2_STRING | ||
64 | select EFI_PARAMS_FROM_FDT | ||
65 | select EFI_RUNTIME_WRAPPERS | ||
66 | - select EFI_STUB | ||
67 | + select EFI_STUB if !CPU_BIG_ENDIAN | ||
68 | + select EFI_LE_STUB if CPU_BIG_ENDIAN | ||
69 | select EFI_ARMSTUB | ||
70 | - default y | ||
71 | + default y if !CPU_BIG_ENDIAN | ||
72 | help | ||
73 | This option provides support for runtime services provided | ||
74 | by UEFI firmware (such as non-volatile variables, realtime | ||
75 | diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h | ||
76 | index 5901480..ad3aa92 100644 | ||
77 | --- a/arch/arm64/include/asm/assembler.h | ||
78 | +++ b/arch/arm64/include/asm/assembler.h | ||
79 | @@ -155,3 +155,21 @@ lr .req x30 // link register | ||
80 | #endif | ||
81 | orr \rd, \lbits, \hbits, lsl #32 | ||
82 | .endm | ||
83 | + | ||
84 | + /* | ||
85 | + * Define LE constants | ||
86 | + */ | ||
87 | + .macro le16, x | ||
88 | + .byte \x & 0xff | ||
89 | + .byte (\x >> 8) & 0xff | ||
90 | + .endm | ||
91 | + | ||
92 | + .macro le32, x | ||
93 | + le16 \x | ||
94 | + le16 \x >> 16 | ||
95 | + .endm | ||
96 | + | ||
97 | + .macro le64, x | ||
98 | + le32 \x | ||
99 | + le32 \x >> 32 | ||
100 | + .endm | ||
101 | diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h | ||
102 | index a34fd3b..44e642b 100644 | ||
103 | --- a/arch/arm64/include/asm/efi.h | ||
104 | +++ b/arch/arm64/include/asm/efi.h | ||
105 | @@ -44,4 +44,6 @@ extern void efi_idmap_init(void); | ||
106 | |||
107 | #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) | ||
108 | |||
109 | +extern void efi_be_runtime_setup(void); | ||
110 | + | ||
111 | #endif /* _ASM_EFI_H */ | ||
112 | diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile | ||
113 | index 79bdd3b..1ab3ff4 100644 | ||
114 | --- a/arch/arm64/kernel/Makefile | ||
115 | +++ b/arch/arm64/kernel/Makefile | ||
116 | @@ -32,7 +32,12 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o | ||
117 | arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
118 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o | ||
119 | arm64-obj-$(CONFIG_KGDB) += kgdb.o | ||
120 | -arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o | ||
121 | +arm64-efi-obj-y := efi.o | ||
122 | +arm64-efi-obj-$(CONFIG_EFI_STUB) += efi-stub.o efi-entry.o | ||
123 | +arm64-efi-obj-$(CONFIG_EFI_LE_STUB) += efistub-le/ | ||
124 | +arm64-efi-obj-$(CONFIG_CPU_BIG_ENDIAN) += efi-be-runtime.o efi-be-call.o | ||
125 | +arm64-obj-$(CONFIG_EFI) += $(arm64-efi-obj-y) | ||
126 | + | ||
127 | arm64-obj-$(CONFIG_PCI) += pci.o | ||
128 | arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o | ||
129 | arm64-obj-$(CONFIG_ACPI) += acpi.o | ||
130 | diff --git a/arch/arm64/kernel/efi-be-call.S b/arch/arm64/kernel/efi-be-call.S | ||
131 | new file mode 100644 | ||
132 | index 0000000..b395c8c | ||
133 | --- /dev/null | ||
134 | +++ b/arch/arm64/kernel/efi-be-call.S | ||
135 | @@ -0,0 +1,55 @@ | ||
136 | + | ||
137 | +#include <linux/linkage.h> | ||
138 | + | ||
139 | + .text | ||
140 | + .align 3 | ||
141 | +ENTRY(efi_be_phys_call) | ||
142 | + /* | ||
143 | + * Entered at physical address with 1:1 mapping enabled. | ||
144 | + */ | ||
145 | + stp x29, x30, [sp, #-96]! | ||
146 | + mov x29, sp | ||
147 | + str x27, [sp, #16] | ||
148 | + | ||
149 | + ldr x8, =efi_be_phys_call // virt address of this function | ||
150 | + adr x9, efi_be_phys_call // phys address of this function | ||
151 | + sub x9, x8, x9 // calculate virt to phys offset in x9 | ||
152 | + | ||
153 | + /* preserve all inputs */ | ||
154 | + stp x0, x1, [sp, #32] | ||
155 | + stp x2, x3, [sp, #48] | ||
156 | + stp x4, x5, [sp, #64] | ||
157 | + stp x6, x7, [sp, #80] | ||
158 | + | ||
159 | + /* get phys address of stack */ | ||
160 | + sub sp, sp, x9 | ||
161 | + | ||
162 | + /* switch to LE, disable MMU and D-cache but leave I-cache enabled */ | ||
163 | + mrs x27, sctlr_el1 | ||
164 | + bic x8, x27, #1 << 2 // clear SCTLR.C | ||
165 | + msr sctlr_el1, x8 | ||
166 | + | ||
167 | + bl flush_cache_all | ||
168 | + | ||
169 | + /* restore inputs but rotated by 1 register */ | ||
170 | + ldp x7, x0, [sp, #32] | ||
171 | + ldp x1, x2, [sp, #48] | ||
172 | + ldp x3, x4, [sp, #64] | ||
173 | + ldp x5, x6, [sp, #80] | ||
174 | + | ||
175 | + bic x8, x27, #1 << 2 // clear SCTLR.C | ||
176 | + bic x8, x8, #1 << 0 // clear SCTLR.M | ||
177 | + bic x8, x8, #1 << 25 // clear SCTLR.EE | ||
178 | + msr sctlr_el1, x8 | ||
179 | + isb | ||
180 | + | ||
181 | + blr x7 | ||
182 | + | ||
183 | + /* switch back to BE and reenable MMU and D-cache */ | ||
184 | + msr sctlr_el1, x27 | ||
185 | + | ||
186 | + mov sp, x29 | ||
187 | + ldr x27, [sp, #16] | ||
188 | + ldp x29, x30, [sp], #96 | ||
189 | + ret | ||
190 | +ENDPROC(efi_be_phys_call) | ||
191 | diff --git a/arch/arm64/kernel/efi-be-runtime.c b/arch/arm64/kernel/efi-be-runtime.c | ||
192 | new file mode 100644 | ||
193 | index 0000000..28d7406 | ||
194 | --- /dev/null | ||
195 | +++ b/arch/arm64/kernel/efi-be-runtime.c | ||
196 | @@ -0,0 +1,104 @@ | ||
197 | + | ||
198 | +#include <linux/efi.h> | ||
199 | +#include <linux/spinlock.h> | ||
200 | +#include <asm/efi.h> | ||
201 | +#include <asm/neon.h> | ||
202 | +#include <asm/tlbflush.h> | ||
203 | + | ||
204 | +static efi_runtime_services_t *runtime; | ||
205 | +static efi_status_t (*efi_be_call)(phys_addr_t func, ...); | ||
206 | + | ||
207 | +static DEFINE_SPINLOCK(efi_be_rt_lock); | ||
208 | + | ||
209 | +static unsigned long efi_be_call_pre(void) | ||
210 | +{ | ||
211 | + unsigned long flags; | ||
212 | + | ||
213 | + kernel_neon_begin(); | ||
214 | + spin_lock_irqsave(&efi_be_rt_lock, flags); | ||
215 | + cpu_switch_mm(idmap_pg_dir, &init_mm); | ||
216 | + flush_tlb_all(); | ||
217 | + return flags; | ||
218 | +} | ||
219 | + | ||
220 | +static void efi_be_call_post(unsigned long flags) | ||
221 | +{ | ||
222 | + cpu_switch_mm(current, current->active_mm); | ||
223 | + flush_tlb_all(); | ||
224 | + spin_unlock_irqrestore(&efi_be_rt_lock, flags); | ||
225 | + kernel_neon_end(); | ||
226 | +} | ||
227 | + | ||
228 | +static efi_status_t efi_be_get_variable(efi_char16_t *name, | ||
229 | + efi_guid_t *vendor, | ||
230 | + u32 *attr, | ||
231 | + unsigned long *data_size, | ||
232 | + void *data) | ||
233 | +{ | ||
234 | + unsigned long flags; | ||
235 | + efi_status_t status; | ||
236 | + | ||
237 | + *data_size = cpu_to_le64(*data_size); | ||
238 | + flags = efi_be_call_pre(); | ||
239 | + status = efi_be_call(le64_to_cpu(runtime->get_variable), | ||
240 | + virt_to_phys(name), virt_to_phys(vendor), | ||
241 | + virt_to_phys(attr), virt_to_phys(data_size), | ||
242 | + virt_to_phys(data)); | ||
243 | + efi_be_call_post(flags); | ||
244 | + *attr = le32_to_cpu(*attr); | ||
245 | + *data_size = le64_to_cpu(*data_size); | ||
246 | + return status; | ||
247 | +} | ||
248 | + | ||
249 | +static efi_status_t efi_be_get_next_variable(unsigned long *name_size, | ||
250 | + efi_char16_t *name, | ||
251 | + efi_guid_t *vendor) | ||
252 | +{ | ||
253 | + unsigned long flags; | ||
254 | + efi_status_t status; | ||
255 | + | ||
256 | + *name_size = cpu_to_le64(*name_size); | ||
257 | + flags = efi_be_call_pre(); | ||
258 | + status = efi_be_call(le64_to_cpu(runtime->get_next_variable), | ||
259 | + virt_to_phys(name_size), virt_to_phys(name), | ||
260 | + virt_to_phys(vendor)); | ||
261 | + efi_be_call_post(flags); | ||
262 | + *name_size = le64_to_cpu(*name_size); | ||
263 | + return status; | ||
264 | +} | ||
265 | + | ||
266 | +static efi_status_t efi_be_set_variable(efi_char16_t *name, | ||
267 | + efi_guid_t *vendor, | ||
268 | + u32 attr, | ||
269 | + unsigned long data_size, | ||
270 | + void *data) | ||
271 | +{ | ||
272 | + unsigned long flags; | ||
273 | + efi_status_t status; | ||
274 | + | ||
275 | + flags = efi_be_call_pre(); | ||
276 | + status = efi_be_call(le64_to_cpu(runtime->set_variable), | ||
277 | + virt_to_phys(name), virt_to_phys(vendor), | ||
278 | + cpu_to_le32(attr), cpu_to_le64(data_size), | ||
279 | + virt_to_phys(data)); | ||
280 | + efi_be_call_post(flags); | ||
281 | + return status; | ||
282 | +} | ||
283 | + | ||
284 | +void efi_be_runtime_setup(void) | ||
285 | +{ | ||
286 | + extern u8 efi_be_phys_call[]; | ||
287 | + | ||
288 | + runtime = ioremap_cache(le64_to_cpu(efi.systab->runtime), | ||
289 | + sizeof(efi_runtime_services_t)); | ||
290 | + if (!runtime) { | ||
291 | + pr_err("Failed to set up BE wrappers for UEFI Runtime Services!\n"); | ||
292 | + return; | ||
293 | + } | ||
294 | + | ||
295 | + efi_be_call = (void *)virt_to_phys(efi_be_phys_call); | ||
296 | + | ||
297 | + efi.get_variable = efi_be_get_variable; | ||
298 | + efi.get_next_variable = efi_be_get_next_variable; | ||
299 | + efi.set_variable = efi_be_set_variable; | ||
300 | +} | ||
301 | diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S | ||
302 | index 8ce9b05..760fbb5 100644 | ||
303 | --- a/arch/arm64/kernel/efi-entry.S | ||
304 | +++ b/arch/arm64/kernel/efi-entry.S | ||
305 | @@ -34,7 +34,34 @@ ENTRY(efi_stub_entry) | ||
306 | * Create a stack frame to save FP/LR with extra space | ||
307 | * for image_addr variable passed to efi_entry(). | ||
308 | */ | ||
309 | - stp x29, x30, [sp, #-32]! | ||
310 | + stp x29, x30, [sp, #-48]! | ||
311 | + stp x22, x23, [sp, #32] | ||
312 | + | ||
313 | +#ifdef CONFIG_EFI_LE_STUB | ||
314 | + adr x4, efi_stub_entry | ||
315 | + ldp w8, w9, [x4, #-32] | ||
316 | +STUB_BE(rev w8, w8 ) | ||
317 | +STUB_BE(rev w9, w9 ) | ||
318 | + add x8, x4, w8, sxtw // x8: base of Image | ||
319 | + add x9, x4, w9, sxtw // x9: offset of linux_banner | ||
320 | + | ||
321 | + ldp x22, x23, [x4, #-24] // x22: size of Image | ||
322 | +STUB_BE(rev x23, x23 ) // x23: stext offset | ||
323 | + | ||
324 | + /* | ||
325 | + * Get a pointer to linux_banner in the outer image and store it | ||
326 | + * in this image. | ||
327 | + */ | ||
328 | + adrp x4, le_linux_banner | ||
329 | + str x9, [x4, #:lo12:le_linux_banner] | ||
330 | +#else | ||
331 | + adrp x8, _text | ||
332 | + add x8, x8, #:lo12:_text // x8: base of Image | ||
333 | + adrp x9, _edata | ||
334 | + add x9, x9, #:lo12:_edata | ||
335 | + sub x22, x9, x8 // x22: size of Image | ||
336 | + ldr x23, =stext_offset // x23: stext offset | ||
337 | +#endif | ||
338 | |||
339 | /* | ||
340 | * Call efi_entry to do the real work. | ||
341 | @@ -45,8 +72,6 @@ ENTRY(efi_stub_entry) | ||
342 | * efi_system_table_t *sys_table, | ||
343 | * unsigned long *image_addr) ; | ||
344 | */ | ||
345 | - adrp x8, _text | ||
346 | - add x8, x8, #:lo12:_text | ||
347 | add x2, sp, 16 | ||
348 | str x8, [x2] | ||
349 | bl efi_entry | ||
350 | @@ -61,17 +86,12 @@ ENTRY(efi_stub_entry) | ||
351 | */ | ||
352 | mov x20, x0 // DTB address | ||
353 | ldr x0, [sp, #16] // relocated _text address | ||
354 | - ldr x21, =stext_offset | ||
355 | - add x21, x0, x21 | ||
356 | + add x21, x0, x23 | ||
357 | |||
358 | /* | ||
359 | * Calculate size of the kernel Image (same for original and copy). | ||
360 | */ | ||
361 | - adrp x1, _text | ||
362 | - add x1, x1, #:lo12:_text | ||
363 | - adrp x2, _edata | ||
364 | - add x2, x2, #:lo12:_edata | ||
365 | - sub x1, x2, x1 | ||
366 | + mov x1, x22 | ||
367 | |||
368 | /* | ||
369 | * Flush the copied Image to the PoC, and ensure it is not shadowed by | ||
370 | @@ -117,7 +137,8 @@ ENTRY(efi_stub_entry) | ||
371 | |||
372 | efi_load_fail: | ||
373 | mov x0, #EFI_LOAD_ERROR | ||
374 | - ldp x29, x30, [sp], #32 | ||
375 | + ldp x22, x23, [sp, #32] | ||
376 | + ldp x29, x30, [sp], #48 | ||
377 | ret | ||
378 | |||
379 | efi_stub_entry_end: | ||
380 | diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c | ||
381 | index d27dd98..dd6d6bc 100644 | ||
382 | --- a/arch/arm64/kernel/efi-stub.c | ||
383 | +++ b/arch/arm64/kernel/efi-stub.c | ||
384 | @@ -11,7 +11,6 @@ | ||
385 | */ | ||
386 | #include <linux/efi.h> | ||
387 | #include <asm/efi.h> | ||
388 | -#include <asm/sections.h> | ||
389 | |||
390 | efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | ||
391 | unsigned long *image_addr, | ||
392 | @@ -22,22 +21,19 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | ||
393 | efi_loaded_image_t *image) | ||
394 | { | ||
395 | efi_status_t status; | ||
396 | - unsigned long kernel_size, kernel_memsize = 0; | ||
397 | |||
398 | /* Relocate the image, if required. */ | ||
399 | - kernel_size = _edata - _text; | ||
400 | if (*image_addr != (dram_base + TEXT_OFFSET)) { | ||
401 | - kernel_memsize = kernel_size + (_end - _edata); | ||
402 | - status = efi_low_alloc(sys_table, kernel_memsize + TEXT_OFFSET, | ||
403 | + status = efi_low_alloc(sys_table, image->image_size + TEXT_OFFSET, | ||
404 | SZ_2M, reserve_addr); | ||
405 | if (status != EFI_SUCCESS) { | ||
406 | pr_efi_err(sys_table, "Failed to relocate kernel\n"); | ||
407 | return status; | ||
408 | } | ||
409 | memcpy((void *)*reserve_addr + TEXT_OFFSET, (void *)*image_addr, | ||
410 | - kernel_size); | ||
411 | + image->image_size); | ||
412 | *image_addr = *reserve_addr + TEXT_OFFSET; | ||
413 | - *reserve_size = kernel_memsize + TEXT_OFFSET; | ||
414 | + *reserve_size = image->image_size + TEXT_OFFSET; | ||
415 | } | ||
416 | |||
417 | |||
418 | diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c | ||
419 | index 4178e9e..133c599 100644 | ||
420 | --- a/arch/arm64/kernel/efi.c | ||
421 | +++ b/arch/arm64/kernel/efi.c | ||
422 | @@ -43,7 +43,7 @@ early_param("uefi_debug", uefi_debug_setup); | ||
423 | |||
424 | static int __init is_normal_ram(efi_memory_desc_t *md) | ||
425 | { | ||
426 | - if (md->attribute & EFI_MEMORY_WB) | ||
427 | + if (le64_to_cpu(md->attribute) & EFI_MEMORY_WB) | ||
428 | return 1; | ||
429 | return 0; | ||
430 | } | ||
431 | @@ -59,10 +59,10 @@ static void __init efi_setup_idmap(void) | ||
432 | |||
433 | /* map runtime io spaces */ | ||
434 | for_each_efi_memory_desc(&memmap, md) { | ||
435 | - if (!(md->attribute & EFI_MEMORY_RUNTIME) || is_normal_ram(md)) | ||
436 | + if (!(le64_to_cpu(md->attribute) & EFI_MEMORY_RUNTIME) || is_normal_ram(md)) | ||
437 | continue; | ||
438 | - paddr = md->phys_addr; | ||
439 | - npages = md->num_pages; | ||
440 | + paddr = le64_to_cpu(md->phys_addr); | ||
441 | + npages = le64_to_cpu(md->num_pages); | ||
442 | memrange_efi_to_native(&paddr, &npages); | ||
443 | size = npages << PAGE_SHIFT; | ||
444 | create_id_mapping(paddr, size, 1); | ||
445 | @@ -88,29 +88,29 @@ static int __init uefi_init(void) | ||
446 | /* | ||
447 | * Verify the EFI Table | ||
448 | */ | ||
449 | - if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { | ||
450 | + if (le64_to_cpu(efi.systab->hdr.signature) != EFI_SYSTEM_TABLE_SIGNATURE) { | ||
451 | pr_err("System table signature incorrect\n"); | ||
452 | retval = -EINVAL; | ||
453 | goto out; | ||
454 | } | ||
455 | - if ((efi.systab->hdr.revision >> 16) < 2) | ||
456 | + if ((le32_to_cpu(efi.systab->hdr.revision) >> 16) < 2) | ||
457 | pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n", | ||
458 | efi.systab->hdr.revision >> 16, | ||
459 | efi.systab->hdr.revision & 0xffff); | ||
460 | |||
461 | /* Show what we know for posterity */ | ||
462 | - c16 = early_memremap(efi.systab->fw_vendor, | ||
463 | + c16 = early_memremap(le64_to_cpu(efi.systab->fw_vendor), | ||
464 | sizeof(vendor)); | ||
465 | if (c16) { | ||
466 | for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) | ||
467 | - vendor[i] = c16[i]; | ||
468 | + vendor[i] = le16_to_cpu(c16[i]); | ||
469 | vendor[i] = '\0'; | ||
470 | early_memunmap(c16, sizeof(vendor)); | ||
471 | } | ||
472 | |||
473 | pr_info("EFI v%u.%.02u by %s\n", | ||
474 | - efi.systab->hdr.revision >> 16, | ||
475 | - efi.systab->hdr.revision & 0xffff, vendor); | ||
476 | + le32_to_cpu(efi.systab->hdr.revision) >> 16, | ||
477 | + le32_to_cpu(efi.systab->hdr.revision) & 0xffff, vendor); | ||
478 | |||
479 | retval = efi_config_init(NULL); | ||
480 | |||
481 | @@ -124,7 +124,7 @@ out: | ||
482 | */ | ||
483 | static __init int is_reserve_region(efi_memory_desc_t *md) | ||
484 | { | ||
485 | - switch (md->type) { | ||
486 | + switch (le32_to_cpu(md->type)) { | ||
487 | case EFI_LOADER_CODE: | ||
488 | case EFI_LOADER_DATA: | ||
489 | case EFI_BOOT_SERVICES_CODE: | ||
490 | @@ -146,8 +146,9 @@ static __init void reserve_regions(void) | ||
491 | pr_info("Processing EFI memory map:\n"); | ||
492 | |||
493 | for_each_efi_memory_desc(&memmap, md) { | ||
494 | - paddr = md->phys_addr; | ||
495 | - npages = md->num_pages; | ||
496 | + u32 md_type = le32_to_cpu(md->type); | ||
497 | + paddr = le64_to_cpu(md->phys_addr); | ||
498 | + npages = le64_to_cpu(md->num_pages); | ||
499 | |||
500 | if (uefi_debug) { | ||
501 | char buf[64]; | ||
502 | @@ -164,8 +165,8 @@ static __init void reserve_regions(void) | ||
503 | early_init_dt_add_memory_arch(paddr, size); | ||
504 | |||
505 | if (is_reserve_region(md) || | ||
506 | - md->type == EFI_BOOT_SERVICES_CODE || | ||
507 | - md->type == EFI_BOOT_SERVICES_DATA) { | ||
508 | + md_type == EFI_BOOT_SERVICES_CODE || | ||
509 | + md_type == EFI_BOOT_SERVICES_DATA) { | ||
510 | memblock_reserve(paddr, size); | ||
511 | if (uefi_debug) | ||
512 | pr_cont("*"); | ||
513 | @@ -246,17 +247,17 @@ static void __init free_boot_services(void) | ||
514 | */ | ||
515 | if (free_start) { | ||
516 | /* adjust free_end then free region */ | ||
517 | - if (free_end > md->phys_addr) | ||
518 | + if (free_end > le64_to_cpu(md->phys_addr)) | ||
519 | free_end -= PAGE_SIZE; | ||
520 | total_freed += free_region(free_start, free_end); | ||
521 | free_start = 0; | ||
522 | } | ||
523 | - keep_end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); | ||
524 | + keep_end = le64_to_cpu(md->phys_addr) + (le64_to_cpu(md->num_pages) << EFI_PAGE_SHIFT); | ||
525 | continue; | ||
526 | } | ||
527 | |||
528 | - if (md->type != EFI_BOOT_SERVICES_CODE && | ||
529 | - md->type != EFI_BOOT_SERVICES_DATA) { | ||
530 | + if (le32_to_cpu(md->type) != EFI_BOOT_SERVICES_CODE && | ||
531 | + le32_to_cpu(md->type) != EFI_BOOT_SERVICES_DATA) { | ||
532 | /* no need to free this region */ | ||
533 | continue; | ||
534 | } | ||
535 | @@ -264,8 +265,8 @@ static void __init free_boot_services(void) | ||
536 | /* | ||
537 | * We want to free memory from this region. | ||
538 | */ | ||
539 | - paddr = md->phys_addr; | ||
540 | - npages = md->num_pages; | ||
541 | + paddr = le64_to_cpu(md->phys_addr); | ||
542 | + npages = le64_to_cpu(md->num_pages); | ||
543 | memrange_efi_to_native(&paddr, &npages); | ||
544 | size = npages << PAGE_SHIFT; | ||
545 | |||
546 | @@ -333,8 +334,8 @@ static int __init remap_region(efi_memory_desc_t *md, void **new) | ||
547 | { | ||
548 | u64 paddr, vaddr, npages, size; | ||
549 | |||
550 | - paddr = md->phys_addr; | ||
551 | - npages = md->num_pages; | ||
552 | + paddr = le64_to_cpu(md->phys_addr); | ||
553 | + npages = le64_to_cpu(md->num_pages); | ||
554 | memrange_efi_to_native(&paddr, &npages); | ||
555 | size = npages << PAGE_SHIFT; | ||
556 | |||
557 | @@ -350,7 +351,7 @@ static int __init remap_region(efi_memory_desc_t *md, void **new) | ||
558 | } | ||
559 | |||
560 | /* adjust for any rounding when EFI and system pagesize differs */ | ||
561 | - md->virt_addr = vaddr + (md->phys_addr - paddr); | ||
562 | + md->virt_addr = vaddr + (le64_to_cpu(md->phys_addr) - paddr); | ||
563 | |||
564 | if (uefi_debug) | ||
565 | pr_info(" EFI remap 0x%012llx => %p\n", | ||
566 | @@ -395,6 +396,21 @@ static int __init arm64_enter_virtual_mode(void) | ||
567 | |||
568 | efi.memmap = &memmap; | ||
569 | |||
570 | + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) { | ||
571 | + efi.systab = ioremap_cache(efi_system_table, | ||
572 | + sizeof(efi_system_table_t)); | ||
573 | + if (!efi.systab) { | ||
574 | + pr_err("Failed to remap EFI system table!\n"); | ||
575 | + return -1; | ||
576 | + } | ||
577 | + free_boot_services(); | ||
578 | + efi_be_runtime_setup(); | ||
579 | + | ||
580 | + set_bit(EFI_SYSTEM_TABLES, &efi.flags); | ||
581 | + set_bit(EFI_RUNTIME_SERVICES, &efi.flags); | ||
582 | + return 0; | ||
583 | + } | ||
584 | + | ||
585 | /* Map the runtime regions */ | ||
586 | virtmap = kmalloc(mapsize, GFP_KERNEL); | ||
587 | if (!virtmap) { | ||
588 | diff --git a/arch/arm64/kernel/efistub-le/Makefile b/arch/arm64/kernel/efistub-le/Makefile | ||
589 | new file mode 100644 | ||
590 | index 0000000..8a1c2a8 | ||
591 | --- /dev/null | ||
592 | +++ b/arch/arm64/kernel/efistub-le/Makefile | ||
593 | @@ -0,0 +1,52 @@ | ||
594 | + | ||
595 | +# | ||
596 | +# Build a little endian EFI stub and wrap it into a single .o | ||
597 | +# | ||
598 | + | ||
599 | +# the LE objects making up the LE efi stub | ||
600 | +le-objs := efi-entry.o efi-stub.o strstr.o cache.o \ | ||
601 | + lib-memchr.o lib-memcmp.o lib-memcpy.o lib-memmove.o \ | ||
602 | + lib-memset.o lib-strchr.o lib-strlen.o lib-strncmp.o \ | ||
603 | + fdt-fdt.o fdt-fdt_ro.o fdt-fdt_rw.o fdt-fdt_sw.o \ | ||
604 | + fdt-fdt_wip.o fdt-fdt_empty_tree.o \ | ||
605 | + libstub-fdt.o libstub-arm-stub.o libstub-efi-stub-helper.o | ||
606 | + | ||
607 | +extra-y := efi-le-stub.bin efi-le-stub.elf $(le-objs) | ||
608 | + | ||
609 | +KBUILD_CFLAGS := $(subst -pg,,$(KBUILD_CFLAGS)) -fno-stack-protector \ | ||
610 | + -mlittle-endian -I$(srctree)/scripts/dtc/libfdt | ||
611 | + | ||
612 | +le-targets := $(addprefix $(obj)/, $(le-objs)) | ||
613 | +$(le-targets): KBUILD_AFLAGS += -mlittle-endian -include $(srctree)/$(src)/le.h | ||
614 | + | ||
615 | +$(obj)/efi-entry.o: $(obj)/../efi-entry.S FORCE | ||
616 | + $(call if_changed_dep,as_o_S) | ||
617 | + | ||
618 | +CFLAGS_efi-stub.o += -DTEXT_OFFSET=$(TEXT_OFFSET) | ||
619 | +$(obj)/efi-stub.o: $(obj)/../efi-stub.c FORCE | ||
620 | + $(call if_changed_dep,cc_o_c) | ||
621 | + | ||
622 | +$(obj)/cache.o: $(src)/../../mm/cache.S FORCE | ||
623 | + $(call if_changed_dep,as_o_S) | ||
624 | + | ||
625 | +$(obj)/lib-%.o: $(src)/../../lib/%.S FORCE | ||
626 | + $(call if_changed_dep,as_o_S) | ||
627 | + | ||
628 | +$(obj)/fdt-%.o: $(srctree)/lib/%.c FORCE | ||
629 | + $(call if_changed_dep,cc_o_c) | ||
630 | + | ||
631 | +$(obj)/libstub-%.o: $(srctree)/drivers/firmware/efi/libstub/%.c FORCE | ||
632 | + $(call if_changed_dep,cc_o_c) | ||
633 | + | ||
634 | +$(obj)/efi-le-stub.elf: LDFLAGS=-EL -Map $@.map -T | ||
635 | +$(obj)/efi-le-stub.elf: $(src)/efistub-le.lds $(le-targets) FORCE | ||
636 | + $(call if_changed,ld) | ||
637 | + | ||
638 | +$(obj)/efi-le-stub.bin: OBJCOPYFLAGS=-O binary | ||
639 | +$(obj)/efi-le-stub.bin: $(obj)/efi-le-stub.elf FORCE | ||
640 | + $(call if_changed,objcopy) | ||
641 | + | ||
642 | +# the BE object containing the entire LE stub | ||
643 | +obj-y := efi-le-entry.o | ||
644 | + | ||
645 | +$(obj)/efi-le-entry.o: $(obj)/efi-le-stub.bin | ||
646 | diff --git a/arch/arm64/kernel/efistub-le/efi-le-entry.S b/arch/arm64/kernel/efistub-le/efi-le-entry.S | ||
647 | new file mode 100644 | ||
648 | index 0000000..755364c | ||
649 | --- /dev/null | ||
650 | +++ b/arch/arm64/kernel/efistub-le/efi-le-entry.S | ||
651 | @@ -0,0 +1,12 @@ | ||
652 | +#include <linux/linkage.h> | ||
653 | + | ||
654 | + .text | ||
655 | + .align 12 | ||
656 | + .long _text - efi_stub_entry | ||
657 | + .long linux_banner - efi_stub_entry | ||
658 | + .quad _kernel_size_le | ||
659 | + .quad stext_offset | ||
660 | + .quad 0 | ||
661 | +ENTRY(efi_stub_entry) | ||
662 | + .incbin "arch/arm64/kernel/efistub-le/efi-le-stub.bin" | ||
663 | +ENDPROC(efi_stub_entry) | ||
664 | diff --git a/arch/arm64/kernel/efistub-le/efistub-le.lds b/arch/arm64/kernel/efistub-le/efistub-le.lds | ||
665 | new file mode 100644 | ||
666 | index 0000000..f64d542 | ||
667 | --- /dev/null | ||
668 | +++ b/arch/arm64/kernel/efistub-le/efistub-le.lds | ||
669 | @@ -0,0 +1,35 @@ | ||
670 | + | ||
671 | +ENTRY(efi_stub_entry) | ||
672 | + | ||
673 | +SECTIONS { | ||
674 | + /* | ||
675 | + * The inner and outer alignment of this chunk of code need to be the | ||
676 | + * same so that PC relative references using adrp/add or adrp/ldr pairs | ||
677 | + * will work correctly. | ||
678 | + * Skip 32 bytes here, so we can put the binary blob at an offset of | ||
679 | + * 4k + 0x20 in the outer image, and use the gap to share constants | ||
680 | + * emitted by the outer linker but required in the stub. | ||
681 | + */ | ||
682 | + .text 0x20 : { | ||
683 | + arch/arm64/kernel/efistub-le/efi-entry.o(.init.text) | ||
684 | + *(.init.text) | ||
685 | + *(.text) | ||
686 | + *(.text*) | ||
687 | + } | ||
688 | + .rodata : { | ||
689 | + . = ALIGN(16); | ||
690 | + *(.rodata) | ||
691 | + *(.rodata*) | ||
692 | + *(.init.rodata) | ||
693 | + } | ||
694 | + .data : { | ||
695 | + . = ALIGN(16); | ||
696 | + *(.data) | ||
697 | + *(.data*) | ||
698 | + le_linux_banner = .; | ||
699 | + . += 8; | ||
700 | + } | ||
701 | + /DISCARD/ : { | ||
702 | + *(__ex_table) | ||
703 | + } | ||
704 | +} | ||
705 | diff --git a/arch/arm64/kernel/efistub-le/le.h b/arch/arm64/kernel/efistub-le/le.h | ||
706 | new file mode 100644 | ||
707 | index 0000000..a9f6dfc | ||
708 | --- /dev/null | ||
709 | +++ b/arch/arm64/kernel/efistub-le/le.h | ||
710 | @@ -0,0 +1,12 @@ | ||
711 | + | ||
712 | +/* | ||
713 | + * This is a bit of a hack, but it is necessary to correctly compile .S files | ||
714 | + * that contain CPU_LE()/CPU_BE() statements, as these are defined to depend on | ||
715 | + * CONFIG_ symbols and not on the endianness of the compiler. | ||
716 | + */ | ||
717 | +#ifdef CONFIG_CPU_BIG_ENDIAN | ||
718 | +#define STUB_BE(code...) code | ||
719 | +#else | ||
720 | +#define STUB_BE(code...) | ||
721 | +#endif | ||
722 | +#undef CONFIG_CPU_BIG_ENDIAN | ||
723 | diff --git a/arch/arm64/kernel/efistub-le/strstr.c b/arch/arm64/kernel/efistub-le/strstr.c | ||
724 | new file mode 100644 | ||
725 | index 0000000..bd16094 | ||
726 | --- /dev/null | ||
727 | +++ b/arch/arm64/kernel/efistub-le/strstr.c | ||
728 | @@ -0,0 +1,20 @@ | ||
729 | + | ||
730 | +#include <linux/types.h> | ||
731 | +#include <linux/string.h> | ||
732 | + | ||
733 | +char *strstr(const char *s1, const char *s2) | ||
734 | +{ | ||
735 | + size_t l1, l2; | ||
736 | + | ||
737 | + l2 = strlen(s2); | ||
738 | + if (!l2) | ||
739 | + return (char *)s1; | ||
740 | + l1 = strlen(s1); | ||
741 | + while (l1 >= l2) { | ||
742 | + l1--; | ||
743 | + if (!memcmp(s1, s2, l2)) | ||
744 | + return (char *)s1; | ||
745 | + s1++; | ||
746 | + } | ||
747 | + return NULL; | ||
748 | +} | ||
749 | diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S | ||
750 | index 8ce88e0..8b1eba5 100644 | ||
751 | --- a/arch/arm64/kernel/head.S | ||
752 | +++ b/arch/arm64/kernel/head.S | ||
753 | @@ -126,7 +126,10 @@ efi_head: | ||
754 | .byte 0x4d | ||
755 | .byte 0x64 | ||
756 | #ifdef CONFIG_EFI | ||
757 | - .long pe_header - efi_head // Offset to the PE header. | ||
758 | + .byte pe_header - efi_head // Offset to the PE header. | ||
759 | + .byte 0 | ||
760 | + .byte 0 | ||
761 | + .byte 0 | ||
762 | #else | ||
763 | .word 0 // reserved | ||
764 | #endif | ||
765 | @@ -139,30 +142,31 @@ pe_header: | ||
766 | .ascii "PE" | ||
767 | .short 0 | ||
768 | coff_header: | ||
769 | - .short 0xaa64 // AArch64 | ||
770 | - .short 2 // nr_sections | ||
771 | + le16 0xaa64 // AArch64 | ||
772 | + le16 2 // nr_sections | ||
773 | .long 0 // TimeDateStamp | ||
774 | .long 0 // PointerToSymbolTable | ||
775 | - .long 1 // NumberOfSymbols | ||
776 | - .short section_table - optional_header // SizeOfOptionalHeader | ||
777 | - .short 0x206 // Characteristics. | ||
778 | + le32 1 // NumberOfSymbols | ||
779 | + .byte section_table - optional_header // SizeOfOptionalHeader | ||
780 | + .byte 0 | ||
781 | + le16 0x206 // Characteristics. | ||
782 | // IMAGE_FILE_DEBUG_STRIPPED | | ||
783 | // IMAGE_FILE_EXECUTABLE_IMAGE | | ||
784 | // IMAGE_FILE_LINE_NUMS_STRIPPED | ||
785 | optional_header: | ||
786 | - .short 0x20b // PE32+ format | ||
787 | + le16 0x20b // PE32+ format | ||
788 | .byte 0x02 // MajorLinkerVersion | ||
789 | .byte 0x14 // MinorLinkerVersion | ||
790 | - .long _end - stext // SizeOfCode | ||
791 | + .long _efi_code_virtsize_le // SizeOfCode | ||
792 | .long 0 // SizeOfInitializedData | ||
793 | .long 0 // SizeOfUninitializedData | ||
794 | - .long efi_stub_entry - efi_head // AddressOfEntryPoint | ||
795 | - .long stext_offset // BaseOfCode | ||
796 | + .long _efi_entry_point_le // AddressOfEntryPoint | ||
797 | + .long _efi_stext_offset_le // BaseOfCode | ||
798 | |||
799 | extra_header_fields: | ||
800 | .quad 0 // ImageBase | ||
801 | - .long 0x1000 // SectionAlignment | ||
802 | - .long PECOFF_FILE_ALIGNMENT // FileAlignment | ||
803 | + le32 0x1000 // SectionAlignment | ||
804 | + le32 0x200 // FileAlignment | ||
805 | .short 0 // MajorOperatingSystemVersion | ||
806 | .short 0 // MinorOperatingSystemVersion | ||
807 | .short 0 // MajorImageVersion | ||
808 | @@ -171,19 +175,19 @@ extra_header_fields: | ||
809 | .short 0 // MinorSubsystemVersion | ||
810 | .long 0 // Win32VersionValue | ||
811 | |||
812 | - .long _end - efi_head // SizeOfImage | ||
813 | + .long _efi_image_size_le // SizeOfImage | ||
814 | |||
815 | // Everything before the kernel image is considered part of the header | ||
816 | - .long stext_offset // SizeOfHeaders | ||
817 | + .long _efi_stext_offset_le // SizeOfHeaders | ||
818 | .long 0 // CheckSum | ||
819 | - .short 0xa // Subsystem (EFI application) | ||
820 | + le16 0xa // Subsystem (EFI application) | ||
821 | .short 0 // DllCharacteristics | ||
822 | .quad 0 // SizeOfStackReserve | ||
823 | .quad 0 // SizeOfStackCommit | ||
824 | .quad 0 // SizeOfHeapReserve | ||
825 | .quad 0 // SizeOfHeapCommit | ||
826 | .long 0 // LoaderFlags | ||
827 | - .long 0x6 // NumberOfRvaAndSizes | ||
828 | + le32 0x6 // NumberOfRvaAndSizes | ||
829 | |||
830 | .quad 0 // ExportTable | ||
831 | .quad 0 // ImportTable | ||
832 | @@ -211,23 +215,23 @@ section_table: | ||
833 | .long 0 // PointerToLineNumbers | ||
834 | .short 0 // NumberOfRelocations | ||
835 | .short 0 // NumberOfLineNumbers | ||
836 | - .long 0x42100040 // Characteristics (section flags) | ||
837 | + le32 0x42100040 // Characteristics (section flags) | ||
838 | |||
839 | |||
840 | .ascii ".text" | ||
841 | .byte 0 | ||
842 | .byte 0 | ||
843 | .byte 0 // end of 0 padding of section name | ||
844 | - .long _end - stext // VirtualSize | ||
845 | - .long stext_offset // VirtualAddress | ||
846 | - .long _edata - stext // SizeOfRawData | ||
847 | - .long stext_offset // PointerToRawData | ||
848 | + .long _efi_code_virtsize_le // VirtualSize | ||
849 | + .long _efi_stext_offset_le // VirtualAddress | ||
850 | + .long _efi_code_rawsize_le // SizeOfRawData | ||
851 | + .long _efi_stext_offset_le // PointerToRawData | ||
852 | |||
853 | .long 0 // PointerToRelocations (0 for executables) | ||
854 | .long 0 // PointerToLineNumbers (0 for executables) | ||
855 | .short 0 // NumberOfRelocations (0 for executables) | ||
856 | .short 0 // NumberOfLineNumbers (0 for executables) | ||
857 | - .long 0xe0500020 // Characteristics (section flags) | ||
858 | + le32 0xe0500020 // Characteristics (section flags) | ||
859 | |||
860 | /* | ||
861 | * EFI will load stext onwards at the 4k section alignment | ||
862 | diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h | ||
863 | index 8fae075..d08ce56 100644 | ||
864 | --- a/arch/arm64/kernel/image.h | ||
865 | +++ b/arch/arm64/kernel/image.h | ||
866 | @@ -37,8 +37,10 @@ | ||
867 | (((data) & 0x0000ff0000000000) >> 24) | \ | ||
868 | (((data) & 0x00ff000000000000) >> 40) | \ | ||
869 | (((data) & 0xff00000000000000) >> 56)) | ||
870 | +#define DATA_LE32(data) (DATA_LE64(data) >> 32) | ||
871 | #else | ||
872 | #define DATA_LE64(data) ((data) & 0xffffffffffffffff) | ||
873 | +#define DATA_LE32(data) ((data) & 0xffffffff) | ||
874 | #endif | ||
875 | |||
876 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
877 | @@ -57,6 +59,18 @@ | ||
878 | #define HEAD_SYMBOLS \ | ||
879 | _kernel_size_le = DATA_LE64(_end - _text); \ | ||
880 | _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \ | ||
881 | - _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); | ||
882 | + _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); \ | ||
883 | + EFI_HEAD_SYMBOLS | ||
884 | + | ||
885 | +#ifdef CONFIG_EFI | ||
886 | +#define EFI_HEAD_SYMBOLS \ | ||
887 | + _efi_stext_offset_le = DATA_LE32(stext_offset); \ | ||
888 | + _efi_code_virtsize_le = DATA_LE32(_end - _text - stext_offset); \ | ||
889 | + _efi_code_rawsize_le = DATA_LE32(_edata - _text - stext_offset); \ | ||
890 | + _efi_image_size_le = DATA_LE32(_end - _text); \ | ||
891 | + _efi_entry_point_le = DATA_LE32(efi_stub_entry - _text); | ||
892 | +#else | ||
893 | +#define EFI_HEAD_SYMBOLS | ||
894 | +#endif | ||
895 | |||
896 | #endif /* __ASM_IMAGE_H */ | ||
897 | diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c | ||
898 | index 9035c1b..4e98daa 100644 | ||
899 | --- a/drivers/firmware/efi/efi.c | ||
900 | +++ b/drivers/firmware/efi/efi.c | ||
901 | @@ -296,18 +296,23 @@ static __init int match_config_table(efi_guid_t *guid, | ||
902 | int __init efi_config_init(efi_config_table_type_t *arch_tables) | ||
903 | { | ||
904 | void *config_tables, *tablep; | ||
905 | - int i, sz; | ||
906 | + unsigned long __tables; | ||
907 | + int i, sz, nr_tables; | ||
908 | |||
909 | - if (efi_enabled(EFI_64BIT)) | ||
910 | + if (efi_enabled(EFI_64BIT)) { | ||
911 | sz = sizeof(efi_config_table_64_t); | ||
912 | - else | ||
913 | + nr_tables = le64_to_cpu((__force __le64)efi.systab->nr_tables); | ||
914 | + __tables = le64_to_cpu((__force __le64)efi.systab->tables); | ||
915 | + } else { | ||
916 | sz = sizeof(efi_config_table_32_t); | ||
917 | + nr_tables = le32_to_cpu((__force __le32)efi.systab->nr_tables); | ||
918 | + __tables = le32_to_cpu((__force __le32)efi.systab->tables); | ||
919 | + } | ||
920 | |||
921 | /* | ||
922 | * Let's see what config tables the firmware passed to us. | ||
923 | */ | ||
924 | - config_tables = early_memremap(efi.systab->tables, | ||
925 | - efi.systab->nr_tables * sz); | ||
926 | + config_tables = early_memremap(__tables, nr_tables * sz); | ||
927 | if (config_tables == NULL) { | ||
928 | pr_err("Could not map Configuration table!\n"); | ||
929 | return -ENOMEM; | ||
930 | @@ -315,21 +320,20 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) | ||
931 | |||
932 | tablep = config_tables; | ||
933 | pr_info(""); | ||
934 | - for (i = 0; i < efi.systab->nr_tables; i++) { | ||
935 | + for (i = 0; i < nr_tables; i++) { | ||
936 | efi_guid_t guid; | ||
937 | unsigned long table; | ||
938 | |||
939 | if (efi_enabled(EFI_64BIT)) { | ||
940 | u64 table64; | ||
941 | guid = ((efi_config_table_64_t *)tablep)->guid; | ||
942 | - table64 = ((efi_config_table_64_t *)tablep)->table; | ||
943 | - table = table64; | ||
944 | + table = table64 = le64_to_cpu((__force __le64) | ||
945 | + ((efi_config_table_64_t *)tablep)->table); | ||
946 | #ifndef CONFIG_64BIT | ||
947 | if (table64 >> 32) { | ||
948 | pr_cont("\n"); | ||
949 | pr_err("Table located above 4GB, disabling EFI.\n"); | ||
950 | - early_memunmap(config_tables, | ||
951 | - efi.systab->nr_tables * sz); | ||
952 | + early_memunmap(config_tables, nr_tables * sz); | ||
953 | return -EINVAL; | ||
954 | } | ||
955 | #endif | ||
956 | @@ -344,7 +348,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) | ||
957 | tablep += sz; | ||
958 | } | ||
959 | pr_cont("\n"); | ||
960 | - early_memunmap(config_tables, efi.systab->nr_tables * sz); | ||
961 | + early_memunmap(config_tables, nr_tables * sz); | ||
962 | |||
963 | set_bit(EFI_CONFIG_TABLES, &efi.flags); | ||
964 | |||
965 | diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c | ||
966 | index f256ecd..2b1c8be 100644 | ||
967 | --- a/drivers/firmware/efi/efivars.c | ||
968 | +++ b/drivers/firmware/efi/efivars.c | ||
969 | @@ -563,7 +563,7 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var) | ||
970 | /* Convert Unicode to normal chars (assume top bits are 0), | ||
971 | ala UTF-8 */ | ||
972 | for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) { | ||
973 | - short_name[i] = variable_name[i] & 0xFF; | ||
974 | + short_name[i] = le16_to_cpu((__force __le16)variable_name[i]); | ||
975 | } | ||
976 | /* This is ugly, but necessary to separate one vendor's | ||
977 | private variables from another's. */ | ||
978 | diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c | ||
979 | index c846a96..f0f9d54 100644 | ||
980 | --- a/drivers/firmware/efi/libstub/fdt.c | ||
981 | +++ b/drivers/firmware/efi/libstub/fdt.c | ||
982 | @@ -22,6 +22,10 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, | ||
983 | unsigned long map_size, unsigned long desc_size, | ||
984 | u32 desc_ver) | ||
985 | { | ||
986 | +#ifdef CONFIG_EFI_LE_STUB | ||
987 | + extern char const *le_linux_banner; | ||
988 | + char const *linux_banner = le_linux_banner; | ||
989 | +#endif | ||
990 | int node, prev, num_rsv; | ||
991 | int status; | ||
992 | u32 fdt_val32; | ||
993 | -- | ||
994 | 1.9.1 | ||
995 | |||