aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 15:39:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 15:39:07 -0500
commit01e9d22638f387b5413163d1030169b6478c09c5 (patch)
treef36991611954663429f2ed36ec19145dd0c9ec4f /drivers/firmware
parent541d284be0fcca3d3990e6dd89b091aec66849c6 (diff)
parent6660800fb7fd0f66faecb3c550fe59709220ade5 (diff)
Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King: - UEFI boot and runtime services support for ARM from Ard Biesheuvel and Roy Franz. - DT compatibility with old atags booting protocol for Nokia N900 devices from Ivaylo Dimitrov. - PSCI firmware interface using new arm-smc calling convention from Jens Wiklander. - Runtime patching for udiv/sdiv instructions for ARMv7 CPUs that support these instructions from Nicolas Pitre. - L2x0 cache updates from Dirk B and Linus Walleij. - Randconfig fixes from Arnd Bergmann. - ARMv7M (nommu) updates from Ezequiel Garcia * 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (34 commits) ARM: 8481/2: drivers: psci: replace psci firmware calls ARM: 8480/2: arm64: add implementation for arm-smccc ARM: 8479/2: add implementation for arm-smccc ARM: 8478/2: arm/arm64: add arm-smccc ARM: 8494/1: mm: Enable PXN when running non-LPAE kernel on LPAE processor ARM: 8496/1: OMAP: RX51: save ATAGS data in the early boot stage ARM: 8495/1: ATAGS: move save_atags() to arch/arm/include/asm/setup.h ARM: 8452/3: PJ4: make coprocessor access sequences buildable in Thumb2 mode ARM: 8482/1: l2x0: make it possible to disable outer sync from DT ARM: 8488/1: Make IPI_CPU_BACKTRACE a "non-secure" SGI ARM: 8487/1: Remove IPI_CALL_FUNC_SINGLE ARM: 8485/1: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook ARM: 8484/1: Documentation: l2c2x0: Mention separate controllers explicitly ARM: 8483/1: Documentation: l2c: Rename l2cc to l2c2x0 ARM: 8477/1: runtime patch udiv/sdiv instructions into __aeabi_{u}idiv() ARM: 8476/1: VDSO: use PTR_ERR_OR_ZERO for vma check ARM: 8453/2: proc-v7.S: don't locate temporary stack space in .text section ARM: add UEFI stub support ARM: wire up UEFI init and runtime support ARM: only consider memblocks with NOMAP cleared for linear mapping ...
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/Kconfig3
-rw-r--r--drivers/firmware/efi/Makefile1
-rw-r--r--drivers/firmware/efi/libstub/Makefile9
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c4
-rw-r--r--drivers/firmware/efi/libstub/arm32-stub.c85
-rw-r--r--drivers/firmware/psci.c23
6 files changed, 122 insertions, 3 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index cf478fe6b335..49a3a1185bb6 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -173,6 +173,9 @@ config QCOM_SCM_64
173 def_bool y 173 def_bool y
174 depends on QCOM_SCM && ARM64 174 depends on QCOM_SCM && ARM64
175 175
176config HAVE_ARM_SMCCC
177 bool
178
176source "drivers/firmware/broadcom/Kconfig" 179source "drivers/firmware/broadcom/Kconfig"
177source "drivers/firmware/google/Kconfig" 180source "drivers/firmware/google/Kconfig"
178source "drivers/firmware/efi/Kconfig" 181source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index f292917b00e7..62e654f255f4 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -20,4 +20,5 @@ obj-$(CONFIG_EFI_STUB) += libstub/
20obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o 20obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
21 21
22arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o 22arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o
23obj-$(CONFIG_ARM) += $(arm-obj-y)
23obj-$(CONFIG_ARM64) += $(arm-obj-y) 24obj-$(CONFIG_ARM64) += $(arm-obj-y)
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index c0ddd1b8dca3..9c12e18031d5 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -34,6 +34,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
34lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o \ 34lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o \
35 $(patsubst %.c,lib-%.o,$(arm-deps)) 35 $(patsubst %.c,lib-%.o,$(arm-deps))
36 36
37lib-$(CONFIG_ARM) += arm32-stub.o
37lib-$(CONFIG_ARM64) += arm64-stub.o 38lib-$(CONFIG_ARM64) += arm64-stub.o
38CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) 39CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
39 40
@@ -67,3 +68,11 @@ quiet_cmd_stubcopy = STUBCPY $@
67 $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y) \ 68 $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y) \
68 && (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \ 69 && (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \
69 rm -f $@; /bin/false); else /bin/false; fi 70 rm -f $@; /bin/false); else /bin/false; fi
71
72#
73# ARM discards the .data section because it disallows r/w data in the
74# decompressor. So move our .data to .data.efistub, which is preserved
75# explicitly by the decompressor linker script.
76#
77STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub
78STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 950c87f5d279..3397902e4040 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -303,8 +303,10 @@ fail:
303 * The value chosen is the largest non-zero power of 2 suitable for this purpose 303 * The value chosen is the largest non-zero power of 2 suitable for this purpose
304 * both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can 304 * both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can
305 * be mapped efficiently. 305 * be mapped efficiently.
306 * Since 32-bit ARM could potentially execute with a 1G/3G user/kernel split,
307 * map everything below 1 GB.
306 */ 308 */
307#define EFI_RT_VIRTUAL_BASE 0x40000000 309#define EFI_RT_VIRTUAL_BASE SZ_512M
308 310
309static int cmp_mem_desc(const void *l, const void *r) 311static int cmp_mem_desc(const void *l, const void *r)
310{ 312{
diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c
new file mode 100644
index 000000000000..495ebd657e38
--- /dev/null
+++ b/drivers/firmware/efi/libstub/arm32-stub.c
@@ -0,0 +1,85 @@
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
12efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
13 unsigned long *image_addr,
14 unsigned long *image_size,
15 unsigned long *reserve_addr,
16 unsigned long *reserve_size,
17 unsigned long dram_base,
18 efi_loaded_image_t *image)
19{
20 unsigned long nr_pages;
21 efi_status_t status;
22 /* Use alloc_addr to tranlsate between types */
23 efi_physical_addr_t alloc_addr;
24
25 /*
26 * Verify that the DRAM base address is compatible with the ARM
27 * boot protocol, which determines the base of DRAM by masking
28 * off the low 27 bits of the address at which the zImage is
29 * loaded. These assumptions are made by the decompressor,
30 * before any memory map is available.
31 */
32 dram_base = round_up(dram_base, SZ_128M);
33
34 /*
35 * Reserve memory for the uncompressed kernel image. This is
36 * all that prevents any future allocations from conflicting
37 * with the kernel. Since we can't tell from the compressed
38 * image how much DRAM the kernel actually uses (due to BSS
39 * size uncertainty) we allocate the maximum possible size.
40 * Do this very early, as prints can cause memory allocations
41 * that may conflict with this.
42 */
43 alloc_addr = dram_base;
44 *reserve_size = MAX_UNCOMP_KERNEL_SIZE;
45 nr_pages = round_up(*reserve_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
46 status = sys_table->boottime->allocate_pages(EFI_ALLOCATE_ADDRESS,
47 EFI_LOADER_DATA,
48 nr_pages, &alloc_addr);
49 if (status != EFI_SUCCESS) {
50 *reserve_size = 0;
51 pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n");
52 return status;
53 }
54 *reserve_addr = alloc_addr;
55
56 /*
57 * Relocate the zImage, so that it appears in the lowest 128 MB
58 * memory window.
59 */
60 *image_size = image->image_size;
61 status = efi_relocate_kernel(sys_table, image_addr, *image_size,
62 *image_size,
63 dram_base + MAX_UNCOMP_KERNEL_SIZE, 0);
64 if (status != EFI_SUCCESS) {
65 pr_efi_err(sys_table, "Failed to relocate kernel.\n");
66 efi_free(sys_table, *reserve_size, *reserve_addr);
67 *reserve_size = 0;
68 return status;
69 }
70
71 /*
72 * Check to see if we were able to allocate memory low enough
73 * in memory. The kernel determines the base of DRAM from the
74 * address at which the zImage is loaded.
75 */
76 if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
77 pr_efi_err(sys_table, "Failed to relocate kernel, no low memory available.\n");
78 efi_free(sys_table, *reserve_size, *reserve_addr);
79 *reserve_size = 0;
80 efi_free(sys_table, *image_size, *image_addr);
81 *image_size = 0;
82 return EFI_LOAD_ERROR;
83 }
84 return EFI_SUCCESS;
85}
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index d24f35d74b27..f25cd79c8a79 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -13,6 +13,7 @@
13 13
14#define pr_fmt(fmt) "psci: " fmt 14#define pr_fmt(fmt) "psci: " fmt
15 15
16#include <linux/arm-smccc.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/linkage.h> 18#include <linux/linkage.h>
18#include <linux/of.h> 19#include <linux/of.h>
@@ -58,8 +59,6 @@ struct psci_operations psci_ops;
58 59
59typedef unsigned long (psci_fn)(unsigned long, unsigned long, 60typedef unsigned long (psci_fn)(unsigned long, unsigned long,
60 unsigned long, unsigned long); 61 unsigned long, unsigned long);
61asmlinkage psci_fn __invoke_psci_fn_hvc;
62asmlinkage psci_fn __invoke_psci_fn_smc;
63static psci_fn *invoke_psci_fn; 62static psci_fn *invoke_psci_fn;
64 63
65enum psci_function { 64enum psci_function {
@@ -107,6 +106,26 @@ bool psci_power_state_is_valid(u32 state)
107 return !(state & ~valid_mask); 106 return !(state & ~valid_mask);
108} 107}
109 108
109static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
110 unsigned long arg0, unsigned long arg1,
111 unsigned long arg2)
112{
113 struct arm_smccc_res res;
114
115 arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
116 return res.a0;
117}
118
119static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
120 unsigned long arg0, unsigned long arg1,
121 unsigned long arg2)
122{
123 struct arm_smccc_res res;
124
125 arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
126 return res.a0;
127}
128
110static int psci_to_linux_errno(int errno) 129static int psci_to_linux_errno(int errno)
111{ 130{
112 switch (errno) { 131 switch (errno) {