aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig19
-rw-r--r--arch/arm64/Kconfig.debug9
-rw-r--r--arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi2
-rw-r--r--arch/arm64/include/asm/atomic.h5
-rw-r--r--arch/arm64/include/asm/barrier.h3
-rw-r--r--arch/arm64/include/asm/bitops.h9
-rw-r--r--arch/arm64/include/asm/cpu_ops.h2
-rw-r--r--arch/arm64/include/asm/cputype.h1
-rw-r--r--arch/arm64/include/asm/efi.h14
-rw-r--r--arch/arm64/include/asm/kvm_host.h2
-rw-r--r--arch/arm64/include/asm/kvm_psci.h6
-rw-r--r--arch/arm64/include/asm/mmu.h2
-rw-r--r--arch/arm64/include/asm/pgtable.h2
-rw-r--r--arch/arm64/include/asm/psci.h2
-rw-r--r--arch/arm64/include/asm/thread_info.h2
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h13
-rw-r--r--arch/arm64/kernel/Makefile4
-rw-r--r--arch/arm64/kernel/early_printk.c156
-rw-r--r--arch/arm64/kernel/efi-entry.S109
-rw-r--r--arch/arm64/kernel/efi-stub.c81
-rw-r--r--arch/arm64/kernel/efi.c469
-rw-r--r--arch/arm64/kernel/head.S112
-rw-r--r--arch/arm64/kernel/psci.c231
-rw-r--r--arch/arm64/kernel/setup.c5
-rw-r--r--arch/arm64/kernel/smp.c22
-rw-r--r--arch/arm64/kvm/guest.c2
-rw-r--r--arch/arm64/kvm/handle_exit.c10
-rw-r--r--arch/arm64/kvm/sys_regs_generic_v8.c2
-rw-r--r--arch/arm64/mm/hugetlbpage.c5
-rw-r--r--arch/arm64/mm/init.c21
-rw-r--r--arch/arm64/mm/mmu.c65
-rw-r--r--arch/arm64/xen/hypercall.S1
32 files changed, 1112 insertions, 276 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e759af5d7098..e384ab9b3862 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -112,6 +112,9 @@ config IOMMU_HELPER
112config KERNEL_MODE_NEON 112config KERNEL_MODE_NEON
113 def_bool y 113 def_bool y
114 114
115config FIX_EARLYCON_MEM
116 def_bool y
117
115source "init/Kconfig" 118source "init/Kconfig"
116 119
117source "kernel/Kconfig.freezer" 120source "kernel/Kconfig.freezer"
@@ -280,6 +283,20 @@ config CMDLINE_FORCE
280 This is useful if you cannot or don't want to change the 283 This is useful if you cannot or don't want to change the
281 command-line options your boot loader passes to the kernel. 284 command-line options your boot loader passes to the kernel.
282 285
286config EFI
287 bool "UEFI runtime support"
288 depends on OF && !CPU_BIG_ENDIAN
289 select LIBFDT
290 select UCS2_STRING
291 select EFI_PARAMS_FROM_FDT
292 default y
293 help
294 This option provides support for runtime services provided
295 by UEFI firmware (such as non-volatile variables, realtime
296 clock, and platform reset). A UEFI stub is also provided to
297 allow the kernel to be booted as an EFI application. This
298 is only useful on systems that have UEFI firmware.
299
283endmenu 300endmenu
284 301
285menu "Userspace binary formats" 302menu "Userspace binary formats"
@@ -331,6 +348,8 @@ source "net/Kconfig"
331 348
332source "drivers/Kconfig" 349source "drivers/Kconfig"
333 350
351source "drivers/firmware/Kconfig"
352
334source "fs/Kconfig" 353source "fs/Kconfig"
335 354
336source "arch/arm64/kvm/Kconfig" 355source "arch/arm64/kvm/Kconfig"
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index d10ec334c93b..1c1b75629842 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -20,15 +20,6 @@ config STRICT_DEVMEM
20 20
21 If in doubt, say Y. 21 If in doubt, say Y.
22 22
23config EARLY_PRINTK
24 bool "Early printk support"
25 default y
26 help
27 Say Y here if you want to have an early console using the
28 earlyprintk=<name>[,<addr>][,<options>] kernel parameter. It
29 is assumed that the early console device has been initialised
30 by the boot loader prior to starting the Linux kernel.
31
32config PID_IN_CONTEXTIDR 23config PID_IN_CONTEXTIDR
33 bool "Write the current PID to the CONTEXTIDR register" 24 bool "Write the current PID to the CONTEXTIDR register"
34 help 25 help
diff --git a/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
index 2f2ecd217363..ac2cb2418025 100644
--- a/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
@@ -200,7 +200,7 @@
200 }; 200 };
201 201
202 mcc { 202 mcc {
203 compatible = "arm,vexpress,config-bus", "simple-bus"; 203 compatible = "arm,vexpress,config-bus";
204 arm,vexpress,config-bridge = <&v2m_sysreg>; 204 arm,vexpress,config-bridge = <&v2m_sysreg>;
205 205
206 v2m_oscclk1: osc@1 { 206 v2m_oscclk1: osc@1 {
diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
index 0237f0867e37..57e8cb49824c 100644
--- a/arch/arm64/include/asm/atomic.h
+++ b/arch/arm64/include/asm/atomic.h
@@ -152,11 +152,6 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
152 152
153#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0) 153#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
154 154
155#define smp_mb__before_atomic_dec() smp_mb()
156#define smp_mb__after_atomic_dec() smp_mb()
157#define smp_mb__before_atomic_inc() smp_mb()
158#define smp_mb__after_atomic_inc() smp_mb()
159
160/* 155/*
161 * 64-bit atomic operations. 156 * 64-bit atomic operations.
162 */ 157 */
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 66eb7648043b..48b9e704af7c 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -98,6 +98,9 @@ do { \
98#define set_mb(var, value) do { var = value; smp_mb(); } while (0) 98#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
99#define nop() asm volatile("nop"); 99#define nop() asm volatile("nop");
100 100
101#define smp_mb__before_atomic() smp_mb()
102#define smp_mb__after_atomic() smp_mb()
103
101#endif /* __ASSEMBLY__ */ 104#endif /* __ASSEMBLY__ */
102 105
103#endif /* __ASM_BARRIER_H */ 106#endif /* __ASM_BARRIER_H */
diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h
index aa5b59d6ba43..9c19594ce7cb 100644
--- a/arch/arm64/include/asm/bitops.h
+++ b/arch/arm64/include/asm/bitops.h
@@ -17,17 +17,8 @@
17#define __ASM_BITOPS_H 17#define __ASM_BITOPS_H
18 18
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20
21#include <asm/barrier.h> 20#include <asm/barrier.h>
22 21
23/*
24 * clear_bit may not imply a memory barrier
25 */
26#ifndef smp_mb__before_clear_bit
27#define smp_mb__before_clear_bit() smp_mb()
28#define smp_mb__after_clear_bit() smp_mb()
29#endif
30
31#ifndef _LINUX_BITOPS_H 22#ifndef _LINUX_BITOPS_H
32#error only <linux/bitops.h> can be included directly 23#error only <linux/bitops.h> can be included directly
33#endif 24#endif
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index 152413076503..d7b4b38a8e86 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -39,6 +39,7 @@ struct device_node;
39 * from the cpu to be killed. 39 * from the cpu to be killed.
40 * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the 40 * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
41 * cpu being killed. 41 * cpu being killed.
42 * @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu.
42 * @cpu_suspend: Suspends a cpu and saves the required context. May fail owing 43 * @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
43 * to wrong parameters or error conditions. Called from the 44 * to wrong parameters or error conditions. Called from the
44 * CPU being suspended. Must be called with IRQs disabled. 45 * CPU being suspended. Must be called with IRQs disabled.
@@ -52,6 +53,7 @@ struct cpu_operations {
52#ifdef CONFIG_HOTPLUG_CPU 53#ifdef CONFIG_HOTPLUG_CPU
53 int (*cpu_disable)(unsigned int cpu); 54 int (*cpu_disable)(unsigned int cpu);
54 void (*cpu_die)(unsigned int cpu); 55 void (*cpu_die)(unsigned int cpu);
56 int (*cpu_kill)(unsigned int cpu);
55#endif 57#endif
56#ifdef CONFIG_ARM64_CPU_SUSPEND 58#ifdef CONFIG_ARM64_CPU_SUSPEND
57 int (*cpu_suspend)(unsigned long); 59 int (*cpu_suspend)(unsigned long);
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index c404fb0df3a6..27f54a7cc81b 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -41,6 +41,7 @@
41 41
42#define ARM_CPU_PART_AEM_V8 0xD0F0 42#define ARM_CPU_PART_AEM_V8 0xD0F0
43#define ARM_CPU_PART_FOUNDATION 0xD000 43#define ARM_CPU_PART_FOUNDATION 0xD000
44#define ARM_CPU_PART_CORTEX_A53 0xD030
44#define ARM_CPU_PART_CORTEX_A57 0xD070 45#define ARM_CPU_PART_CORTEX_A57 0xD070
45 46
46#define APM_CPU_PART_POTENZA 0x0000 47#define APM_CPU_PART_POTENZA 0x0000
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
new file mode 100644
index 000000000000..5a46c4e7f539
--- /dev/null
+++ b/arch/arm64/include/asm/efi.h
@@ -0,0 +1,14 @@
1#ifndef _ASM_EFI_H
2#define _ASM_EFI_H
3
4#include <asm/io.h>
5
6#ifdef CONFIG_EFI
7extern void efi_init(void);
8extern void efi_idmap_init(void);
9#else
10#define efi_init()
11#define efi_idmap_init()
12#endif
13
14#endif /* _ASM_EFI_H */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0a1d69751562..92242ce06309 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -39,7 +39,7 @@
39#include <kvm/arm_vgic.h> 39#include <kvm/arm_vgic.h>
40#include <kvm/arm_arch_timer.h> 40#include <kvm/arm_arch_timer.h>
41 41
42#define KVM_VCPU_MAX_FEATURES 2 42#define KVM_VCPU_MAX_FEATURES 3
43 43
44struct kvm_vcpu; 44struct kvm_vcpu;
45int kvm_target_cpu(void); 45int kvm_target_cpu(void);
diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h
index e301a4816355..bc39e557c56c 100644
--- a/arch/arm64/include/asm/kvm_psci.h
+++ b/arch/arm64/include/asm/kvm_psci.h
@@ -18,6 +18,10 @@
18#ifndef __ARM64_KVM_PSCI_H__ 18#ifndef __ARM64_KVM_PSCI_H__
19#define __ARM64_KVM_PSCI_H__ 19#define __ARM64_KVM_PSCI_H__
20 20
21bool kvm_psci_call(struct kvm_vcpu *vcpu); 21#define KVM_ARM_PSCI_0_1 1
22#define KVM_ARM_PSCI_0_2 2
23
24int kvm_psci_version(struct kvm_vcpu *vcpu);
25int kvm_psci_call(struct kvm_vcpu *vcpu);
22 26
23#endif /* __ARM64_KVM_PSCI_H__ */ 27#endif /* __ARM64_KVM_PSCI_H__ */
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index aff0292c8f4d..c2f006c48bdb 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -31,5 +31,7 @@ extern void paging_init(void);
31extern void setup_mm_for_reboot(void); 31extern void setup_mm_for_reboot(void);
32extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt); 32extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
33extern void init_mem_pgprot(void); 33extern void init_mem_pgprot(void);
34/* create an identity mapping for memory (or io if map_io is true) */
35extern void create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io);
34 36
35#endif 37#endif
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7b1c67a0b485..e2f96748859b 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -406,7 +406,7 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
406 406
407/* 407/*
408 * Ensure that there are not more swap files than can be encoded in the kernel 408 * Ensure that there are not more swap files than can be encoded in the kernel
409 * the PTEs. 409 * PTEs.
410 */ 410 */
411#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS) 411#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
412 412
diff --git a/arch/arm64/include/asm/psci.h b/arch/arm64/include/asm/psci.h
index d15ab8b46336..e5312ea0ec1a 100644
--- a/arch/arm64/include/asm/psci.h
+++ b/arch/arm64/include/asm/psci.h
@@ -14,6 +14,6 @@
14#ifndef __ASM_PSCI_H 14#ifndef __ASM_PSCI_H
15#define __ASM_PSCI_H 15#define __ASM_PSCI_H
16 16
17void psci_init(void); 17int psci_init(void);
18 18
19#endif /* __ASM_PSCI_H */ 19#endif /* __ASM_PSCI_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 720e70b66ffd..7b8e3a2a00fb 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -95,13 +95,11 @@ static inline struct thread_info *current_thread_info(void)
95 * TIF_NEED_RESCHED - rescheduling necessary 95 * TIF_NEED_RESCHED - rescheduling necessary
96 * TIF_NOTIFY_RESUME - callback before returning to user 96 * TIF_NOTIFY_RESUME - callback before returning to user
97 * TIF_USEDFPU - FPU was used by this task this quantum (SMP) 97 * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
98 * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
99 */ 98 */
100#define TIF_SIGPENDING 0 99#define TIF_SIGPENDING 0
101#define TIF_NEED_RESCHED 1 100#define TIF_NEED_RESCHED 1
102#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ 101#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
103#define TIF_SYSCALL_TRACE 8 102#define TIF_SYSCALL_TRACE 8
104#define TIF_POLLING_NRFLAG 16
105#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ 103#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
106#define TIF_FREEZE 19 104#define TIF_FREEZE 19
107#define TIF_RESTORE_SIGMASK 20 105#define TIF_RESTORE_SIGMASK 20
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index eaf54a30bedc..e633ff8cdec8 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -31,6 +31,7 @@
31#define KVM_NR_SPSR 5 31#define KVM_NR_SPSR 5
32 32
33#ifndef __ASSEMBLY__ 33#ifndef __ASSEMBLY__
34#include <linux/psci.h>
34#include <asm/types.h> 35#include <asm/types.h>
35#include <asm/ptrace.h> 36#include <asm/ptrace.h>
36 37
@@ -56,8 +57,9 @@ struct kvm_regs {
56#define KVM_ARM_TARGET_FOUNDATION_V8 1 57#define KVM_ARM_TARGET_FOUNDATION_V8 1
57#define KVM_ARM_TARGET_CORTEX_A57 2 58#define KVM_ARM_TARGET_CORTEX_A57 2
58#define KVM_ARM_TARGET_XGENE_POTENZA 3 59#define KVM_ARM_TARGET_XGENE_POTENZA 3
60#define KVM_ARM_TARGET_CORTEX_A53 4
59 61
60#define KVM_ARM_NUM_TARGETS 4 62#define KVM_ARM_NUM_TARGETS 5
61 63
62/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ 64/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
63#define KVM_ARM_DEVICE_TYPE_SHIFT 0 65#define KVM_ARM_DEVICE_TYPE_SHIFT 0
@@ -77,6 +79,7 @@ struct kvm_regs {
77 79
78#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ 80#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
79#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */ 81#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
82#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
80 83
81struct kvm_vcpu_init { 84struct kvm_vcpu_init {
82 __u32 target; 85 __u32 target;
@@ -186,10 +189,10 @@ struct kvm_arch_memory_slot {
186#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2) 189#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
187#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3) 190#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
188 191
189#define KVM_PSCI_RET_SUCCESS 0 192#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
190#define KVM_PSCI_RET_NI ((unsigned long)-1) 193#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
191#define KVM_PSCI_RET_INVAL ((unsigned long)-2) 194#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
192#define KVM_PSCI_RET_DENIED ((unsigned long)-3) 195#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
193 196
194#endif 197#endif
195 198
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 7d811d9522bc..ba5e17a522d5 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -4,6 +4,8 @@
4 4
5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) 5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) 6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
7CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) \
8 -I$(src)/../../../scripts/dtc/libfdt
7 9
8# Object file lists. 10# Object file lists.
9arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ 11arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
@@ -18,10 +20,10 @@ arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o
18arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o 20arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
19arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o 21arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
20arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 22arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
21arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
22arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o 23arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
23arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o 24arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
24arm64-obj-$(CONFIG_KGDB) += kgdb.o 25arm64-obj-$(CONFIG_KGDB) += kgdb.o
26arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o
25 27
26obj-y += $(arm64-obj-y) vdso/ 28obj-y += $(arm64-obj-y) vdso/
27obj-m += $(arm64-obj-m) 29obj-m += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/early_printk.c b/arch/arm64/kernel/early_printk.c
deleted file mode 100644
index 2dc36d00addf..000000000000
--- a/arch/arm64/kernel/early_printk.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/*
2 * Earlyprintk support.
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.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 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#include <linux/kernel.h>
20#include <linux/console.h>
21#include <linux/init.h>
22#include <linux/string.h>
23#include <linux/mm.h>
24#include <linux/io.h>
25
26#include <linux/amba/serial.h>
27#include <linux/serial_reg.h>
28
29#include <asm/fixmap.h>
30
31static void __iomem *early_base;
32static void (*printch)(char ch);
33
34/*
35 * PL011 single character TX.
36 */
37static void pl011_printch(char ch)
38{
39 while (readl_relaxed(early_base + UART01x_FR) & UART01x_FR_TXFF)
40 ;
41 writeb_relaxed(ch, early_base + UART01x_DR);
42 while (readl_relaxed(early_base + UART01x_FR) & UART01x_FR_BUSY)
43 ;
44}
45
46/*
47 * Semihosting-based debug console
48 */
49static void smh_printch(char ch)
50{
51 asm volatile("mov x1, %0\n"
52 "mov x0, #3\n"
53 "hlt 0xf000\n"
54 : : "r" (&ch) : "x0", "x1", "memory");
55}
56
57/*
58 * 8250/16550 (8-bit aligned registers) single character TX.
59 */
60static void uart8250_8bit_printch(char ch)
61{
62 while (!(readb_relaxed(early_base + UART_LSR) & UART_LSR_THRE))
63 ;
64 writeb_relaxed(ch, early_base + UART_TX);
65}
66
67/*
68 * 8250/16550 (32-bit aligned registers) single character TX.
69 */
70static void uart8250_32bit_printch(char ch)
71{
72 while (!(readl_relaxed(early_base + (UART_LSR << 2)) & UART_LSR_THRE))
73 ;
74 writel_relaxed(ch, early_base + (UART_TX << 2));
75}
76
77struct earlycon_match {
78 const char *name;
79 void (*printch)(char ch);
80};
81
82static const struct earlycon_match earlycon_match[] __initconst = {
83 { .name = "pl011", .printch = pl011_printch, },
84 { .name = "smh", .printch = smh_printch, },
85 { .name = "uart8250-8bit", .printch = uart8250_8bit_printch, },
86 { .name = "uart8250-32bit", .printch = uart8250_32bit_printch, },
87 {}
88};
89
90static void early_write(struct console *con, const char *s, unsigned n)
91{
92 while (n-- > 0) {
93 if (*s == '\n')
94 printch('\r');
95 printch(*s);
96 s++;
97 }
98}
99
100static struct console early_console_dev = {
101 .name = "earlycon",
102 .write = early_write,
103 .flags = CON_PRINTBUFFER | CON_BOOT,
104 .index = -1,
105};
106
107/*
108 * Parse earlyprintk=... parameter in the format:
109 *
110 * <name>[,<addr>][,<options>]
111 *
112 * and register the early console. It is assumed that the UART has been
113 * initialised by the bootloader already.
114 */
115static int __init setup_early_printk(char *buf)
116{
117 const struct earlycon_match *match = earlycon_match;
118 phys_addr_t paddr = 0;
119
120 if (!buf) {
121 pr_warning("No earlyprintk arguments passed.\n");
122 return 0;
123 }
124
125 while (match->name) {
126 size_t len = strlen(match->name);
127 if (!strncmp(buf, match->name, len)) {
128 buf += len;
129 break;
130 }
131 match++;
132 }
133 if (!match->name) {
134 pr_warning("Unknown earlyprintk arguments: %s\n", buf);
135 return 0;
136 }
137
138 /* I/O address */
139 if (!strncmp(buf, ",0x", 3)) {
140 char *e;
141 paddr = simple_strtoul(buf + 1, &e, 16);
142 buf = e;
143 }
144 /* no options parsing yet */
145
146 if (paddr)
147 early_base = (void __iomem *)set_fixmap_offset_io(FIX_EARLYCON_MEM_BASE, paddr);
148
149 printch = match->printch;
150 early_console = &early_console_dev;
151 register_console(&early_console_dev);
152
153 return 0;
154}
155
156early_param("earlyprintk", setup_early_printk);
diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
new file mode 100644
index 000000000000..66716c9b9e5f
--- /dev/null
+++ b/arch/arm64/kernel/efi-entry.S
@@ -0,0 +1,109 @@
1/*
2 * EFI entry point.
3 *
4 * Copyright (C) 2013, 2014 Red Hat, Inc.
5 * Author: 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/linkage.h>
13#include <linux/init.h>
14
15#include <asm/assembler.h>
16
17#define EFI_LOAD_ERROR 0x8000000000000001
18
19 __INIT
20
21 /*
22 * We arrive here from the EFI boot manager with:
23 *
24 * * CPU in little-endian mode
25 * * MMU on with identity-mapped RAM
26 * * Icache and Dcache on
27 *
28 * We will most likely be running from some place other than where
29 * we want to be. The kernel image wants to be placed at TEXT_OFFSET
30 * from start of RAM.
31 */
32ENTRY(efi_stub_entry)
33 /*
34 * Create a stack frame to save FP/LR with extra space
35 * for image_addr variable passed to efi_entry().
36 */
37 stp x29, x30, [sp, #-32]!
38
39 /*
40 * Call efi_entry to do the real work.
41 * x0 and x1 are already set up by firmware. Current runtime
42 * address of image is calculated and passed via *image_addr.
43 *
44 * unsigned long efi_entry(void *handle,
45 * efi_system_table_t *sys_table,
46 * unsigned long *image_addr) ;
47 */
48 adrp x8, _text
49 add x8, x8, #:lo12:_text
50 add x2, sp, 16
51 str x8, [x2]
52 bl efi_entry
53 cmn x0, #1
54 b.eq efi_load_fail
55
56 /*
57 * efi_entry() will have relocated the kernel image if necessary
58 * and we return here with device tree address in x0 and the kernel
59 * entry point stored at *image_addr. Save those values in registers
60 * which are callee preserved.
61 */
62 mov x20, x0 // DTB address
63 ldr x0, [sp, #16] // relocated _text address
64 mov x21, x0
65
66 /*
67 * Flush dcache covering current runtime addresses
68 * of kernel text/data. Then flush all of icache.
69 */
70 adrp x1, _text
71 add x1, x1, #:lo12:_text
72 adrp x2, _edata
73 add x2, x2, #:lo12:_edata
74 sub x1, x2, x1
75
76 bl __flush_dcache_area
77 ic ialluis
78
79 /* Turn off Dcache and MMU */
80 mrs x0, CurrentEL
81 cmp x0, #PSR_MODE_EL2t
82 ccmp x0, #PSR_MODE_EL2h, #0x4, ne
83 b.ne 1f
84 mrs x0, sctlr_el2
85 bic x0, x0, #1 << 0 // clear SCTLR.M
86 bic x0, x0, #1 << 2 // clear SCTLR.C
87 msr sctlr_el2, x0
88 isb
89 b 2f
901:
91 mrs x0, sctlr_el1
92 bic x0, x0, #1 << 0 // clear SCTLR.M
93 bic x0, x0, #1 << 2 // clear SCTLR.C
94 msr sctlr_el1, x0
95 isb
962:
97 /* Jump to kernel entry point */
98 mov x0, x20
99 mov x1, xzr
100 mov x2, xzr
101 mov x3, xzr
102 br x21
103
104efi_load_fail:
105 mov x0, #EFI_LOAD_ERROR
106 ldp x29, x30, [sp], #32
107 ret
108
109ENDPROC(efi_stub_entry)
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
new file mode 100644
index 000000000000..60e98a639ac5
--- /dev/null
+++ b/arch/arm64/kernel/efi-stub.c
@@ -0,0 +1,81 @@
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
28static void efi_char16_printk(efi_system_table_t *sys_table_arg,
29 efi_char16_t *str);
30
31static efi_status_t efi_open_volume(efi_system_table_t *sys_table,
32 void *__image, void **__fh);
33static efi_status_t efi_file_close(void *handle);
34
35static efi_status_t
36efi_file_read(void *handle, unsigned long *size, void *addr);
37
38static efi_status_t
39efi_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
48static 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}
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
new file mode 100644
index 000000000000..14db1f6e8d7f
--- /dev/null
+++ b/arch/arm64/kernel/efi.c
@@ -0,0 +1,469 @@
1/*
2 * Extensible Firmware Interface
3 *
4 * Based on Extensible Firmware Interface Specification version 2.4
5 *
6 * Copyright (C) 2013, 2014 Linaro Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/efi.h>
15#include <linux/export.h>
16#include <linux/memblock.h>
17#include <linux/bootmem.h>
18#include <linux/of.h>
19#include <linux/of_fdt.h>
20#include <linux/sched.h>
21#include <linux/slab.h>
22
23#include <asm/cacheflush.h>
24#include <asm/efi.h>
25#include <asm/tlbflush.h>
26#include <asm/mmu_context.h>
27
28struct efi_memory_map memmap;
29
30static efi_runtime_services_t *runtime;
31
32static u64 efi_system_table;
33
34static int uefi_debug __initdata;
35static int __init uefi_debug_setup(char *str)
36{
37 uefi_debug = 1;
38
39 return 0;
40}
41early_param("uefi_debug", uefi_debug_setup);
42
43static int __init is_normal_ram(efi_memory_desc_t *md)
44{
45 if (md->attribute & EFI_MEMORY_WB)
46 return 1;
47 return 0;
48}
49
50static void __init efi_setup_idmap(void)
51{
52 struct memblock_region *r;
53 efi_memory_desc_t *md;
54 u64 paddr, npages, size;
55
56 for_each_memblock(memory, r)
57 create_id_mapping(r->base, r->size, 0);
58
59 /* map runtime io spaces */
60 for_each_efi_memory_desc(&memmap, md) {
61 if (!(md->attribute & EFI_MEMORY_RUNTIME) || is_normal_ram(md))
62 continue;
63 paddr = md->phys_addr;
64 npages = md->num_pages;
65 memrange_efi_to_native(&paddr, &npages);
66 size = npages << PAGE_SHIFT;
67 create_id_mapping(paddr, size, 1);
68 }
69}
70
71static int __init uefi_init(void)
72{
73 efi_char16_t *c16;
74 char vendor[100] = "unknown";
75 int i, retval;
76
77 efi.systab = early_memremap(efi_system_table,
78 sizeof(efi_system_table_t));
79 if (efi.systab == NULL) {
80 pr_warn("Unable to map EFI system table.\n");
81 return -ENOMEM;
82 }
83
84 set_bit(EFI_BOOT, &efi.flags);
85 set_bit(EFI_64BIT, &efi.flags);
86
87 /*
88 * Verify the EFI Table
89 */
90 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
91 pr_err("System table signature incorrect\n");
92 return -EINVAL;
93 }
94 if ((efi.systab->hdr.revision >> 16) < 2)
95 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
96 efi.systab->hdr.revision >> 16,
97 efi.systab->hdr.revision & 0xffff);
98
99 /* Show what we know for posterity */
100 c16 = early_memremap(efi.systab->fw_vendor,
101 sizeof(vendor));
102 if (c16) {
103 for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
104 vendor[i] = c16[i];
105 vendor[i] = '\0';
106 }
107
108 pr_info("EFI v%u.%.02u by %s\n",
109 efi.systab->hdr.revision >> 16,
110 efi.systab->hdr.revision & 0xffff, vendor);
111
112 retval = efi_config_init(NULL);
113 if (retval == 0)
114 set_bit(EFI_CONFIG_TABLES, &efi.flags);
115
116 early_memunmap(c16, sizeof(vendor));
117 early_memunmap(efi.systab, sizeof(efi_system_table_t));
118
119 return retval;
120}
121
122static __initdata char memory_type_name[][32] = {
123 {"Reserved"},
124 {"Loader Code"},
125 {"Loader Data"},
126 {"Boot Code"},
127 {"Boot Data"},
128 {"Runtime Code"},
129 {"Runtime Data"},
130 {"Conventional Memory"},
131 {"Unusable Memory"},
132 {"ACPI Reclaim Memory"},
133 {"ACPI Memory NVS"},
134 {"Memory Mapped I/O"},
135 {"MMIO Port Space"},
136 {"PAL Code"},
137};
138
139/*
140 * Return true for RAM regions we want to permanently reserve.
141 */
142static __init int is_reserve_region(efi_memory_desc_t *md)
143{
144 if (!is_normal_ram(md))
145 return 0;
146
147 if (md->attribute & EFI_MEMORY_RUNTIME)
148 return 1;
149
150 if (md->type == EFI_ACPI_RECLAIM_MEMORY ||
151 md->type == EFI_RESERVED_TYPE)
152 return 1;
153
154 return 0;
155}
156
157static __init void reserve_regions(void)
158{
159 efi_memory_desc_t *md;
160 u64 paddr, npages, size;
161
162 if (uefi_debug)
163 pr_info("Processing EFI memory map:\n");
164
165 for_each_efi_memory_desc(&memmap, md) {
166 paddr = md->phys_addr;
167 npages = md->num_pages;
168
169 if (uefi_debug)
170 pr_info(" 0x%012llx-0x%012llx [%s]",
171 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
172 memory_type_name[md->type]);
173
174 memrange_efi_to_native(&paddr, &npages);
175 size = npages << PAGE_SHIFT;
176
177 if (is_normal_ram(md))
178 early_init_dt_add_memory_arch(paddr, size);
179
180 if (is_reserve_region(md) ||
181 md->type == EFI_BOOT_SERVICES_CODE ||
182 md->type == EFI_BOOT_SERVICES_DATA) {
183 memblock_reserve(paddr, size);
184 if (uefi_debug)
185 pr_cont("*");
186 }
187
188 if (uefi_debug)
189 pr_cont("\n");
190 }
191}
192
193
194static u64 __init free_one_region(u64 start, u64 end)
195{
196 u64 size = end - start;
197
198 if (uefi_debug)
199 pr_info(" EFI freeing: 0x%012llx-0x%012llx\n", start, end - 1);
200
201 free_bootmem_late(start, size);
202 return size;
203}
204
205static u64 __init free_region(u64 start, u64 end)
206{
207 u64 map_start, map_end, total = 0;
208
209 if (end <= start)
210 return total;
211
212 map_start = (u64)memmap.phys_map;
213 map_end = PAGE_ALIGN(map_start + (memmap.map_end - memmap.map));
214 map_start &= PAGE_MASK;
215
216 if (start < map_end && end > map_start) {
217 /* region overlaps UEFI memmap */
218 if (start < map_start)
219 total += free_one_region(start, map_start);
220
221 if (map_end < end)
222 total += free_one_region(map_end, end);
223 } else
224 total += free_one_region(start, end);
225
226 return total;
227}
228
229static void __init free_boot_services(void)
230{
231 u64 total_freed = 0;
232 u64 keep_end, free_start, free_end;
233 efi_memory_desc_t *md;
234
235 /*
236 * If kernel uses larger pages than UEFI, we have to be careful
237 * not to inadvertantly free memory we want to keep if there is
238 * overlap at the kernel page size alignment. We do not want to
239 * free is_reserve_region() memory nor the UEFI memmap itself.
240 *
241 * The memory map is sorted, so we keep track of the end of
242 * any previous region we want to keep, remember any region
243 * we want to free and defer freeing it until we encounter
244 * the next region we want to keep. This way, before freeing
245 * it, we can clip it as needed to avoid freeing memory we
246 * want to keep for UEFI.
247 */
248
249 keep_end = 0;
250 free_start = 0;
251
252 for_each_efi_memory_desc(&memmap, md) {
253 u64 paddr, npages, size;
254
255 if (is_reserve_region(md)) {
256 /*
257 * We don't want to free any memory from this region.
258 */
259 if (free_start) {
260 /* adjust free_end then free region */
261 if (free_end > md->phys_addr)
262 free_end -= PAGE_SIZE;
263 total_freed += free_region(free_start, free_end);
264 free_start = 0;
265 }
266 keep_end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
267 continue;
268 }
269
270 if (md->type != EFI_BOOT_SERVICES_CODE &&
271 md->type != EFI_BOOT_SERVICES_DATA) {
272 /* no need to free this region */
273 continue;
274 }
275
276 /*
277 * We want to free memory from this region.
278 */
279 paddr = md->phys_addr;
280 npages = md->num_pages;
281 memrange_efi_to_native(&paddr, &npages);
282 size = npages << PAGE_SHIFT;
283
284 if (free_start) {
285 if (paddr <= free_end)
286 free_end = paddr + size;
287 else {
288 total_freed += free_region(free_start, free_end);
289 free_start = paddr;
290 free_end = paddr + size;
291 }
292 } else {
293 free_start = paddr;
294 free_end = paddr + size;
295 }
296 if (free_start < keep_end) {
297 free_start += PAGE_SIZE;
298 if (free_start >= free_end)
299 free_start = 0;
300 }
301 }
302 if (free_start)
303 total_freed += free_region(free_start, free_end);
304
305 if (total_freed)
306 pr_info("Freed 0x%llx bytes of EFI boot services memory",
307 total_freed);
308}
309
310void __init efi_init(void)
311{
312 struct efi_fdt_params params;
313
314 /* Grab UEFI information placed in FDT by stub */
315 if (!efi_get_fdt_params(&params, uefi_debug))
316 return;
317
318 efi_system_table = params.system_table;
319
320 memblock_reserve(params.mmap & PAGE_MASK,
321 PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK)));
322 memmap.phys_map = (void *)params.mmap;
323 memmap.map = early_memremap(params.mmap, params.mmap_size);
324 memmap.map_end = memmap.map + params.mmap_size;
325 memmap.desc_size = params.desc_size;
326 memmap.desc_version = params.desc_ver;
327
328 if (uefi_init() < 0)
329 return;
330
331 reserve_regions();
332}
333
334void __init efi_idmap_init(void)
335{
336 if (!efi_enabled(EFI_BOOT))
337 return;
338
339 /* boot time idmap_pg_dir is incomplete, so fill in missing parts */
340 efi_setup_idmap();
341}
342
343static int __init remap_region(efi_memory_desc_t *md, void **new)
344{
345 u64 paddr, vaddr, npages, size;
346
347 paddr = md->phys_addr;
348 npages = md->num_pages;
349 memrange_efi_to_native(&paddr, &npages);
350 size = npages << PAGE_SHIFT;
351
352 if (is_normal_ram(md))
353 vaddr = (__force u64)ioremap_cache(paddr, size);
354 else
355 vaddr = (__force u64)ioremap(paddr, size);
356
357 if (!vaddr) {
358 pr_err("Unable to remap 0x%llx pages @ %p\n",
359 npages, (void *)paddr);
360 return 0;
361 }
362
363 /* adjust for any rounding when EFI and system pagesize differs */
364 md->virt_addr = vaddr + (md->phys_addr - paddr);
365
366 if (uefi_debug)
367 pr_info(" EFI remap 0x%012llx => %p\n",
368 md->phys_addr, (void *)md->virt_addr);
369
370 memcpy(*new, md, memmap.desc_size);
371 *new += memmap.desc_size;
372
373 return 1;
374}
375
376/*
377 * Switch UEFI from an identity map to a kernel virtual map
378 */
379static int __init arm64_enter_virtual_mode(void)
380{
381 efi_memory_desc_t *md;
382 phys_addr_t virtmap_phys;
383 void *virtmap, *virt_md;
384 efi_status_t status;
385 u64 mapsize;
386 int count = 0;
387 unsigned long flags;
388
389 if (!efi_enabled(EFI_BOOT)) {
390 pr_info("EFI services will not be available.\n");
391 return -1;
392 }
393
394 pr_info("Remapping and enabling EFI services.\n");
395
396 /* replace early memmap mapping with permanent mapping */
397 mapsize = memmap.map_end - memmap.map;
398 early_memunmap(memmap.map, mapsize);
399 memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
400 mapsize);
401 memmap.map_end = memmap.map + mapsize;
402
403 efi.memmap = &memmap;
404
405 /* Map the runtime regions */
406 virtmap = kmalloc(mapsize, GFP_KERNEL);
407 if (!virtmap) {
408 pr_err("Failed to allocate EFI virtual memmap\n");
409 return -1;
410 }
411 virtmap_phys = virt_to_phys(virtmap);
412 virt_md = virtmap;
413
414 for_each_efi_memory_desc(&memmap, md) {
415 if (!(md->attribute & EFI_MEMORY_RUNTIME))
416 continue;
417 if (remap_region(md, &virt_md))
418 ++count;
419 }
420
421 efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table);
422 if (efi.systab)
423 set_bit(EFI_SYSTEM_TABLES, &efi.flags);
424
425 local_irq_save(flags);
426 cpu_switch_mm(idmap_pg_dir, &init_mm);
427
428 /* Call SetVirtualAddressMap with the physical address of the map */
429 runtime = efi.systab->runtime;
430 efi.set_virtual_address_map = runtime->set_virtual_address_map;
431
432 status = efi.set_virtual_address_map(count * memmap.desc_size,
433 memmap.desc_size,
434 memmap.desc_version,
435 (efi_memory_desc_t *)virtmap_phys);
436 cpu_set_reserved_ttbr0();
437 flush_tlb_all();
438 local_irq_restore(flags);
439
440 kfree(virtmap);
441
442 free_boot_services();
443
444 if (status != EFI_SUCCESS) {
445 pr_err("Failed to set EFI virtual address map! [%lx]\n",
446 status);
447 return -1;
448 }
449
450 /* Set up runtime services function pointers */
451 runtime = efi.systab->runtime;
452 efi.get_time = runtime->get_time;
453 efi.set_time = runtime->set_time;
454 efi.get_wakeup_time = runtime->get_wakeup_time;
455 efi.set_wakeup_time = runtime->set_wakeup_time;
456 efi.get_variable = runtime->get_variable;
457 efi.get_next_variable = runtime->get_next_variable;
458 efi.set_variable = runtime->set_variable;
459 efi.query_variable_info = runtime->query_variable_info;
460 efi.update_capsule = runtime->update_capsule;
461 efi.query_capsule_caps = runtime->query_capsule_caps;
462 efi.get_next_high_mono_count = runtime->get_next_high_mono_count;
463 efi.reset_system = runtime->reset_system;
464
465 set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
466
467 return 0;
468}
469early_initcall(arm64_enter_virtual_mode);
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 0fd565000772..738291b5be29 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -108,8 +108,18 @@
108 /* 108 /*
109 * DO NOT MODIFY. Image header expected by Linux boot-loaders. 109 * DO NOT MODIFY. Image header expected by Linux boot-loaders.
110 */ 110 */
111#ifdef CONFIG_EFI
112efi_head:
113 /*
114 * This add instruction has no meaningful effect except that
115 * its opcode forms the magic "MZ" signature required by UEFI.
116 */
117 add x13, x18, #0x16
118 b stext
119#else
111 b stext // branch to kernel start, magic 120 b stext // branch to kernel start, magic
112 .long 0 // reserved 121 .long 0 // reserved
122#endif
113 .quad TEXT_OFFSET // Image load offset from start of RAM 123 .quad TEXT_OFFSET // Image load offset from start of RAM
114 .quad 0 // reserved 124 .quad 0 // reserved
115 .quad 0 // reserved 125 .quad 0 // reserved
@@ -120,7 +130,109 @@
120 .byte 0x52 130 .byte 0x52
121 .byte 0x4d 131 .byte 0x4d
122 .byte 0x64 132 .byte 0x64
133#ifdef CONFIG_EFI
134 .long pe_header - efi_head // Offset to the PE header.
135#else
123 .word 0 // reserved 136 .word 0 // reserved
137#endif
138
139#ifdef CONFIG_EFI
140 .align 3
141pe_header:
142 .ascii "PE"
143 .short 0
144coff_header:
145 .short 0xaa64 // AArch64
146 .short 2 // nr_sections
147 .long 0 // TimeDateStamp
148 .long 0 // PointerToSymbolTable
149 .long 1 // NumberOfSymbols
150 .short section_table - optional_header // SizeOfOptionalHeader
151 .short 0x206 // Characteristics.
152 // IMAGE_FILE_DEBUG_STRIPPED |
153 // IMAGE_FILE_EXECUTABLE_IMAGE |
154 // IMAGE_FILE_LINE_NUMS_STRIPPED
155optional_header:
156 .short 0x20b // PE32+ format
157 .byte 0x02 // MajorLinkerVersion
158 .byte 0x14 // MinorLinkerVersion
159 .long _edata - stext // SizeOfCode
160 .long 0 // SizeOfInitializedData
161 .long 0 // SizeOfUninitializedData
162 .long efi_stub_entry - efi_head // AddressOfEntryPoint
163 .long stext - efi_head // BaseOfCode
164
165extra_header_fields:
166 .quad 0 // ImageBase
167 .long 0x20 // SectionAlignment
168 .long 0x8 // FileAlignment
169 .short 0 // MajorOperatingSystemVersion
170 .short 0 // MinorOperatingSystemVersion
171 .short 0 // MajorImageVersion
172 .short 0 // MinorImageVersion
173 .short 0 // MajorSubsystemVersion
174 .short 0 // MinorSubsystemVersion
175 .long 0 // Win32VersionValue
176
177 .long _edata - efi_head // SizeOfImage
178
179 // Everything before the kernel image is considered part of the header
180 .long stext - efi_head // SizeOfHeaders
181 .long 0 // CheckSum
182 .short 0xa // Subsystem (EFI application)
183 .short 0 // DllCharacteristics
184 .quad 0 // SizeOfStackReserve
185 .quad 0 // SizeOfStackCommit
186 .quad 0 // SizeOfHeapReserve
187 .quad 0 // SizeOfHeapCommit
188 .long 0 // LoaderFlags
189 .long 0x6 // NumberOfRvaAndSizes
190
191 .quad 0 // ExportTable
192 .quad 0 // ImportTable
193 .quad 0 // ResourceTable
194 .quad 0 // ExceptionTable
195 .quad 0 // CertificationTable
196 .quad 0 // BaseRelocationTable
197
198 // Section table
199section_table:
200
201 /*
202 * The EFI application loader requires a relocation section
203 * because EFI applications must be relocatable. This is a
204 * dummy section as far as we are concerned.
205 */
206 .ascii ".reloc"
207 .byte 0
208 .byte 0 // end of 0 padding of section name
209 .long 0
210 .long 0
211 .long 0 // SizeOfRawData
212 .long 0 // PointerToRawData
213 .long 0 // PointerToRelocations
214 .long 0 // PointerToLineNumbers
215 .short 0 // NumberOfRelocations
216 .short 0 // NumberOfLineNumbers
217 .long 0x42100040 // Characteristics (section flags)
218
219
220 .ascii ".text"
221 .byte 0
222 .byte 0
223 .byte 0 // end of 0 padding of section name
224 .long _edata - stext // VirtualSize
225 .long stext - efi_head // VirtualAddress
226 .long _edata - stext // SizeOfRawData
227 .long stext - efi_head // PointerToRawData
228
229 .long 0 // PointerToRelocations (0 for executables)
230 .long 0 // PointerToLineNumbers (0 for executables)
231 .short 0 // NumberOfRelocations (0 for executables)
232 .short 0 // NumberOfLineNumbers (0 for executables)
233 .long 0xe0500020 // Characteristics (section flags)
234 .align 5
235#endif
124 236
125ENTRY(stext) 237ENTRY(stext)
126 mov x21, x0 // x21=FDT 238 mov x21, x0 // x21=FDT
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index ea4828a4aa96..9e9798f91172 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -18,12 +18,17 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/smp.h> 20#include <linux/smp.h>
21#include <linux/reboot.h>
22#include <linux/pm.h>
23#include <linux/delay.h>
24#include <uapi/linux/psci.h>
21 25
22#include <asm/compiler.h> 26#include <asm/compiler.h>
23#include <asm/cpu_ops.h> 27#include <asm/cpu_ops.h>
24#include <asm/errno.h> 28#include <asm/errno.h>
25#include <asm/psci.h> 29#include <asm/psci.h>
26#include <asm/smp_plat.h> 30#include <asm/smp_plat.h>
31#include <asm/system_misc.h>
27 32
28#define PSCI_POWER_STATE_TYPE_STANDBY 0 33#define PSCI_POWER_STATE_TYPE_STANDBY 0
29#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1 34#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
@@ -40,58 +45,52 @@ struct psci_operations {
40 int (*cpu_off)(struct psci_power_state state); 45 int (*cpu_off)(struct psci_power_state state);
41 int (*cpu_on)(unsigned long cpuid, unsigned long entry_point); 46 int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
42 int (*migrate)(unsigned long cpuid); 47 int (*migrate)(unsigned long cpuid);
48 int (*affinity_info)(unsigned long target_affinity,
49 unsigned long lowest_affinity_level);
50 int (*migrate_info_type)(void);
43}; 51};
44 52
45static struct psci_operations psci_ops; 53static struct psci_operations psci_ops;
46 54
47static int (*invoke_psci_fn)(u64, u64, u64, u64); 55static int (*invoke_psci_fn)(u64, u64, u64, u64);
56typedef int (*psci_initcall_t)(const struct device_node *);
48 57
49enum psci_function { 58enum psci_function {
50 PSCI_FN_CPU_SUSPEND, 59 PSCI_FN_CPU_SUSPEND,
51 PSCI_FN_CPU_ON, 60 PSCI_FN_CPU_ON,
52 PSCI_FN_CPU_OFF, 61 PSCI_FN_CPU_OFF,
53 PSCI_FN_MIGRATE, 62 PSCI_FN_MIGRATE,
63 PSCI_FN_AFFINITY_INFO,
64 PSCI_FN_MIGRATE_INFO_TYPE,
54 PSCI_FN_MAX, 65 PSCI_FN_MAX,
55}; 66};
56 67
57static u32 psci_function_id[PSCI_FN_MAX]; 68static u32 psci_function_id[PSCI_FN_MAX];
58 69
59#define PSCI_RET_SUCCESS 0
60#define PSCI_RET_EOPNOTSUPP -1
61#define PSCI_RET_EINVAL -2
62#define PSCI_RET_EPERM -3
63
64static int psci_to_linux_errno(int errno) 70static int psci_to_linux_errno(int errno)
65{ 71{
66 switch (errno) { 72 switch (errno) {
67 case PSCI_RET_SUCCESS: 73 case PSCI_RET_SUCCESS:
68 return 0; 74 return 0;
69 case PSCI_RET_EOPNOTSUPP: 75 case PSCI_RET_NOT_SUPPORTED:
70 return -EOPNOTSUPP; 76 return -EOPNOTSUPP;
71 case PSCI_RET_EINVAL: 77 case PSCI_RET_INVALID_PARAMS:
72 return -EINVAL; 78 return -EINVAL;
73 case PSCI_RET_EPERM: 79 case PSCI_RET_DENIED:
74 return -EPERM; 80 return -EPERM;
75 }; 81 };
76 82
77 return -EINVAL; 83 return -EINVAL;
78} 84}
79 85
80#define PSCI_POWER_STATE_ID_MASK 0xffff
81#define PSCI_POWER_STATE_ID_SHIFT 0
82#define PSCI_POWER_STATE_TYPE_MASK 0x1
83#define PSCI_POWER_STATE_TYPE_SHIFT 16
84#define PSCI_POWER_STATE_AFFL_MASK 0x3
85#define PSCI_POWER_STATE_AFFL_SHIFT 24
86
87static u32 psci_power_state_pack(struct psci_power_state state) 86static u32 psci_power_state_pack(struct psci_power_state state)
88{ 87{
89 return ((state.id & PSCI_POWER_STATE_ID_MASK) 88 return ((state.id << PSCI_0_2_POWER_STATE_ID_SHIFT)
90 << PSCI_POWER_STATE_ID_SHIFT) | 89 & PSCI_0_2_POWER_STATE_ID_MASK) |
91 ((state.type & PSCI_POWER_STATE_TYPE_MASK) 90 ((state.type << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
92 << PSCI_POWER_STATE_TYPE_SHIFT) | 91 & PSCI_0_2_POWER_STATE_TYPE_MASK) |
93 ((state.affinity_level & PSCI_POWER_STATE_AFFL_MASK) 92 ((state.affinity_level << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
94 << PSCI_POWER_STATE_AFFL_SHIFT); 93 & PSCI_0_2_POWER_STATE_AFFL_MASK);
95} 94}
96 95
97/* 96/*
@@ -128,6 +127,14 @@ static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
128 return function_id; 127 return function_id;
129} 128}
130 129
130static int psci_get_version(void)
131{
132 int err;
133
134 err = invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
135 return err;
136}
137
131static int psci_cpu_suspend(struct psci_power_state state, 138static int psci_cpu_suspend(struct psci_power_state state,
132 unsigned long entry_point) 139 unsigned long entry_point)
133{ 140{
@@ -171,26 +178,36 @@ static int psci_migrate(unsigned long cpuid)
171 return psci_to_linux_errno(err); 178 return psci_to_linux_errno(err);
172} 179}
173 180
174static const struct of_device_id psci_of_match[] __initconst = { 181static int psci_affinity_info(unsigned long target_affinity,
175 { .compatible = "arm,psci", }, 182 unsigned long lowest_affinity_level)
176 {}, 183{
177}; 184 int err;
185 u32 fn;
186
187 fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
188 err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
189 return err;
190}
178 191
179void __init psci_init(void) 192static int psci_migrate_info_type(void)
180{ 193{
181 struct device_node *np; 194 int err;
182 const char *method; 195 u32 fn;
183 u32 id;
184 196
185 np = of_find_matching_node(NULL, psci_of_match); 197 fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
186 if (!np) 198 err = invoke_psci_fn(fn, 0, 0, 0);
187 return; 199 return err;
200}
188 201
189 pr_info("probing function IDs from device-tree\n"); 202static int get_set_conduit_method(struct device_node *np)
203{
204 const char *method;
205
206 pr_info("probing for conduit method from DT.\n");
190 207
191 if (of_property_read_string(np, "method", &method)) { 208 if (of_property_read_string(np, "method", &method)) {
192 pr_warning("missing \"method\" property\n"); 209 pr_warn("missing \"method\" property\n");
193 goto out_put_node; 210 return -ENXIO;
194 } 211 }
195 212
196 if (!strcmp("hvc", method)) { 213 if (!strcmp("hvc", method)) {
@@ -198,10 +215,99 @@ void __init psci_init(void)
198 } else if (!strcmp("smc", method)) { 215 } else if (!strcmp("smc", method)) {
199 invoke_psci_fn = __invoke_psci_fn_smc; 216 invoke_psci_fn = __invoke_psci_fn_smc;
200 } else { 217 } else {
201 pr_warning("invalid \"method\" property: %s\n", method); 218 pr_warn("invalid \"method\" property: %s\n", method);
219 return -EINVAL;
220 }
221 return 0;
222}
223
224static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
225{
226 invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
227}
228
229static void psci_sys_poweroff(void)
230{
231 invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
232}
233
234/*
235 * PSCI Function IDs for v0.2+ are well defined so use
236 * standard values.
237 */
238static int psci_0_2_init(struct device_node *np)
239{
240 int err, ver;
241
242 err = get_set_conduit_method(np);
243
244 if (err)
245 goto out_put_node;
246
247 ver = psci_get_version();
248
249 if (ver == PSCI_RET_NOT_SUPPORTED) {
250 /* PSCI v0.2 mandates implementation of PSCI_ID_VERSION. */
251 pr_err("PSCI firmware does not comply with the v0.2 spec.\n");
252 err = -EOPNOTSUPP;
202 goto out_put_node; 253 goto out_put_node;
254 } else {
255 pr_info("PSCIv%d.%d detected in firmware.\n",
256 PSCI_VERSION_MAJOR(ver),
257 PSCI_VERSION_MINOR(ver));
258
259 if (PSCI_VERSION_MAJOR(ver) == 0 &&
260 PSCI_VERSION_MINOR(ver) < 2) {
261 err = -EINVAL;
262 pr_err("Conflicting PSCI version detected.\n");
263 goto out_put_node;
264 }
203 } 265 }
204 266
267 pr_info("Using standard PSCI v0.2 function IDs\n");
268 psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
269 psci_ops.cpu_suspend = psci_cpu_suspend;
270
271 psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
272 psci_ops.cpu_off = psci_cpu_off;
273
274 psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
275 psci_ops.cpu_on = psci_cpu_on;
276
277 psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
278 psci_ops.migrate = psci_migrate;
279
280 psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
281 psci_ops.affinity_info = psci_affinity_info;
282
283 psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
284 PSCI_0_2_FN_MIGRATE_INFO_TYPE;
285 psci_ops.migrate_info_type = psci_migrate_info_type;
286
287 arm_pm_restart = psci_sys_reset;
288
289 pm_power_off = psci_sys_poweroff;
290
291out_put_node:
292 of_node_put(np);
293 return err;
294}
295
296/*
297 * PSCI < v0.2 get PSCI Function IDs via DT.
298 */
299static int psci_0_1_init(struct device_node *np)
300{
301 u32 id;
302 int err;
303
304 err = get_set_conduit_method(np);
305
306 if (err)
307 goto out_put_node;
308
309 pr_info("Using PSCI v0.1 Function IDs from DT\n");
310
205 if (!of_property_read_u32(np, "cpu_suspend", &id)) { 311 if (!of_property_read_u32(np, "cpu_suspend", &id)) {
206 psci_function_id[PSCI_FN_CPU_SUSPEND] = id; 312 psci_function_id[PSCI_FN_CPU_SUSPEND] = id;
207 psci_ops.cpu_suspend = psci_cpu_suspend; 313 psci_ops.cpu_suspend = psci_cpu_suspend;
@@ -224,7 +330,28 @@ void __init psci_init(void)
224 330
225out_put_node: 331out_put_node:
226 of_node_put(np); 332 of_node_put(np);
227 return; 333 return err;
334}
335
336static const struct of_device_id psci_of_match[] __initconst = {
337 { .compatible = "arm,psci", .data = psci_0_1_init},
338 { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
339 {},
340};
341
342int __init psci_init(void)
343{
344 struct device_node *np;
345 const struct of_device_id *matched_np;
346 psci_initcall_t init_fn;
347
348 np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
349
350 if (!np)
351 return -ENODEV;
352
353 init_fn = (psci_initcall_t)matched_np->data;
354 return init_fn(np);
228} 355}
229 356
230#ifdef CONFIG_SMP 357#ifdef CONFIG_SMP
@@ -277,6 +404,35 @@ static void cpu_psci_cpu_die(unsigned int cpu)
277 404
278 pr_crit("unable to power off CPU%u (%d)\n", cpu, ret); 405 pr_crit("unable to power off CPU%u (%d)\n", cpu, ret);
279} 406}
407
408static int cpu_psci_cpu_kill(unsigned int cpu)
409{
410 int err, i;
411
412 if (!psci_ops.affinity_info)
413 return 1;
414 /*
415 * cpu_kill could race with cpu_die and we can
416 * potentially end up declaring this cpu undead
417 * while it is dying. So, try again a few times.
418 */
419
420 for (i = 0; i < 10; i++) {
421 err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
422 if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
423 pr_info("CPU%d killed.\n", cpu);
424 return 1;
425 }
426
427 msleep(10);
428 pr_info("Retrying again to check for CPU kill\n");
429 }
430
431 pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n",
432 cpu, err);
433 /* Make op_cpu_kill() fail. */
434 return 0;
435}
280#endif 436#endif
281 437
282const struct cpu_operations cpu_psci_ops = { 438const struct cpu_operations cpu_psci_ops = {
@@ -287,6 +443,7 @@ const struct cpu_operations cpu_psci_ops = {
287#ifdef CONFIG_HOTPLUG_CPU 443#ifdef CONFIG_HOTPLUG_CPU
288 .cpu_disable = cpu_psci_cpu_disable, 444 .cpu_disable = cpu_psci_cpu_disable,
289 .cpu_die = cpu_psci_cpu_die, 445 .cpu_die = cpu_psci_cpu_die,
446 .cpu_kill = cpu_psci_cpu_kill,
290#endif 447#endif
291}; 448};
292 449
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 7ec784653b29..e578171b22ff 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -41,6 +41,7 @@
41#include <linux/memblock.h> 41#include <linux/memblock.h>
42#include <linux/of_fdt.h> 42#include <linux/of_fdt.h>
43#include <linux/of_platform.h> 43#include <linux/of_platform.h>
44#include <linux/efi.h>
44 45
45#include <asm/fixmap.h> 46#include <asm/fixmap.h>
46#include <asm/cputype.h> 47#include <asm/cputype.h>
@@ -55,6 +56,7 @@
55#include <asm/traps.h> 56#include <asm/traps.h>
56#include <asm/memblock.h> 57#include <asm/memblock.h>
57#include <asm/psci.h> 58#include <asm/psci.h>
59#include <asm/efi.h>
58 60
59unsigned int processor_id; 61unsigned int processor_id;
60EXPORT_SYMBOL(processor_id); 62EXPORT_SYMBOL(processor_id);
@@ -366,11 +368,14 @@ void __init setup_arch(char **cmdline_p)
366 368
367 parse_early_param(); 369 parse_early_param();
368 370
371 efi_init();
369 arm64_memblock_init(); 372 arm64_memblock_init();
370 373
371 paging_init(); 374 paging_init();
372 request_standard_resources(); 375 request_standard_resources();
373 376
377 efi_idmap_init();
378
374 unflatten_device_tree(); 379 unflatten_device_tree();
375 380
376 psci_init(); 381 psci_init();
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index f0a141dd5655..c3cb160edc69 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -228,6 +228,19 @@ int __cpu_disable(void)
228 return 0; 228 return 0;
229} 229}
230 230
231static int op_cpu_kill(unsigned int cpu)
232{
233 /*
234 * If we have no means of synchronising with the dying CPU, then assume
235 * that it is really dead. We can only wait for an arbitrary length of
236 * time and hope that it's dead, so let's skip the wait and just hope.
237 */
238 if (!cpu_ops[cpu]->cpu_kill)
239 return 1;
240
241 return cpu_ops[cpu]->cpu_kill(cpu);
242}
243
231static DECLARE_COMPLETION(cpu_died); 244static DECLARE_COMPLETION(cpu_died);
232 245
233/* 246/*
@@ -241,6 +254,15 @@ void __cpu_die(unsigned int cpu)
241 return; 254 return;
242 } 255 }
243 pr_notice("CPU%u: shutdown\n", cpu); 256 pr_notice("CPU%u: shutdown\n", cpu);
257
258 /*
259 * Now that the dying CPU is beyond the point of no return w.r.t.
260 * in-kernel synchronisation, try to get the firwmare to help us to
261 * verify that it has really left the kernel before we consider
262 * clobbering anything it might still be using.
263 */
264 if (!op_cpu_kill(cpu))
265 pr_warn("CPU%d may not have shut down cleanly\n", cpu);
244} 266}
245 267
246/* 268/*
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 08745578d54d..60b5c31f3c10 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -214,6 +214,8 @@ int __attribute_const__ kvm_target_cpu(void)
214 return KVM_ARM_TARGET_AEM_V8; 214 return KVM_ARM_TARGET_AEM_V8;
215 case ARM_CPU_PART_FOUNDATION: 215 case ARM_CPU_PART_FOUNDATION:
216 return KVM_ARM_TARGET_FOUNDATION_V8; 216 return KVM_ARM_TARGET_FOUNDATION_V8;
217 case ARM_CPU_PART_CORTEX_A53:
218 return KVM_ARM_TARGET_CORTEX_A53;
217 case ARM_CPU_PART_CORTEX_A57: 219 case ARM_CPU_PART_CORTEX_A57:
218 return KVM_ARM_TARGET_CORTEX_A57; 220 return KVM_ARM_TARGET_CORTEX_A57;
219 }; 221 };
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7bc41eab4c64..182415e1a952 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -30,11 +30,15 @@ typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
30 30
31static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) 31static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
32{ 32{
33 if (kvm_psci_call(vcpu)) 33 int ret;
34
35 ret = kvm_psci_call(vcpu);
36 if (ret < 0) {
37 kvm_inject_undefined(vcpu);
34 return 1; 38 return 1;
39 }
35 40
36 kvm_inject_undefined(vcpu); 41 return ret;
37 return 1;
38} 42}
39 43
40static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) 44static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c b/arch/arm64/kvm/sys_regs_generic_v8.c
index 8fe6f76b0edc..475fd2929310 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -88,6 +88,8 @@ static int __init sys_reg_genericv8_init(void)
88 &genericv8_target_table); 88 &genericv8_target_table);
89 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_FOUNDATION_V8, 89 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_FOUNDATION_V8,
90 &genericv8_target_table); 90 &genericv8_target_table);
91 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A53,
92 &genericv8_target_table);
91 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A57, 93 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A57,
92 &genericv8_target_table); 94 &genericv8_target_table);
93 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_XGENE_POTENZA, 95 kvm_register_target_sys_reg_table(KVM_ARM_TARGET_XGENE_POTENZA,
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 31eb959e9aa8..023747bf4dd7 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -58,11 +58,6 @@ int pud_huge(pud_t pud)
58#endif 58#endif
59} 59}
60 60
61int pmd_huge_support(void)
62{
63 return 1;
64}
65
66static __init int setup_hugepagesz(char *opt) 61static __init int setup_hugepagesz(char *opt)
67{ 62{
68 unsigned long ps = memparse(opt, &opt); 63 unsigned long ps = memparse(opt, &opt);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 51d5352e6ad5..091d428d64ac 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -126,8 +126,6 @@ static void arm64_memory_present(void)
126 126
127void __init arm64_memblock_init(void) 127void __init arm64_memblock_init(void)
128{ 128{
129 u64 *reserve_map, base, size;
130
131 /* Register the kernel text, kernel data and initrd with memblock */ 129 /* Register the kernel text, kernel data and initrd with memblock */
132 memblock_reserve(__pa(_text), _end - _text); 130 memblock_reserve(__pa(_text), _end - _text);
133#ifdef CONFIG_BLK_DEV_INITRD 131#ifdef CONFIG_BLK_DEV_INITRD
@@ -142,25 +140,6 @@ void __init arm64_memblock_init(void)
142 memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE); 140 memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE);
143 memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE); 141 memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE);
144 142
145 /* Reserve the dtb region */
146 memblock_reserve(virt_to_phys(initial_boot_params),
147 be32_to_cpu(initial_boot_params->totalsize));
148
149 /*
150 * Process the reserve map. This will probably overlap the initrd
151 * and dtb locations which are already reserved, but overlapping
152 * doesn't hurt anything
153 */
154 reserve_map = ((void*)initial_boot_params) +
155 be32_to_cpu(initial_boot_params->off_mem_rsvmap);
156 while (1) {
157 base = be64_to_cpup(reserve_map++);
158 size = be64_to_cpup(reserve_map++);
159 if (!size)
160 break;
161 memblock_reserve(base, size);
162 }
163
164 early_init_fdt_scan_reserved_mem(); 143 early_init_fdt_scan_reserved_mem();
165 dma_contiguous_reserve(0); 144 dma_contiguous_reserve(0);
166 145
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 0a472c41a67f..4a829a210bb6 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -168,7 +168,8 @@ static void __init *early_alloc(unsigned long sz)
168} 168}
169 169
170static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, 170static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
171 unsigned long end, unsigned long pfn) 171 unsigned long end, unsigned long pfn,
172 pgprot_t prot)
172{ 173{
173 pte_t *pte; 174 pte_t *pte;
174 175
@@ -180,16 +181,28 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
180 181
181 pte = pte_offset_kernel(pmd, addr); 182 pte = pte_offset_kernel(pmd, addr);
182 do { 183 do {
183 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); 184 set_pte(pte, pfn_pte(pfn, prot));
184 pfn++; 185 pfn++;
185 } while (pte++, addr += PAGE_SIZE, addr != end); 186 } while (pte++, addr += PAGE_SIZE, addr != end);
186} 187}
187 188
188static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, 189static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
189 unsigned long end, phys_addr_t phys) 190 unsigned long end, phys_addr_t phys,
191 int map_io)
190{ 192{
191 pmd_t *pmd; 193 pmd_t *pmd;
192 unsigned long next; 194 unsigned long next;
195 pmdval_t prot_sect;
196 pgprot_t prot_pte;
197
198 if (map_io) {
199 prot_sect = PMD_TYPE_SECT | PMD_SECT_AF |
200 PMD_ATTRINDX(MT_DEVICE_nGnRE);
201 prot_pte = __pgprot(PROT_DEVICE_nGnRE);
202 } else {
203 prot_sect = prot_sect_kernel;
204 prot_pte = PAGE_KERNEL_EXEC;
205 }
193 206
194 /* 207 /*
195 * Check for initial section mappings in the pgd/pud and remove them. 208 * Check for initial section mappings in the pgd/pud and remove them.
@@ -205,7 +218,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
205 /* try section mapping first */ 218 /* try section mapping first */
206 if (((addr | next | phys) & ~SECTION_MASK) == 0) { 219 if (((addr | next | phys) & ~SECTION_MASK) == 0) {
207 pmd_t old_pmd =*pmd; 220 pmd_t old_pmd =*pmd;
208 set_pmd(pmd, __pmd(phys | prot_sect_kernel)); 221 set_pmd(pmd, __pmd(phys | prot_sect));
209 /* 222 /*
210 * Check for previous table entries created during 223 * Check for previous table entries created during
211 * boot (__create_page_tables) and flush them. 224 * boot (__create_page_tables) and flush them.
@@ -213,21 +226,23 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
213 if (!pmd_none(old_pmd)) 226 if (!pmd_none(old_pmd))
214 flush_tlb_all(); 227 flush_tlb_all();
215 } else { 228 } else {
216 alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys)); 229 alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
230 prot_pte);
217 } 231 }
218 phys += next - addr; 232 phys += next - addr;
219 } while (pmd++, addr = next, addr != end); 233 } while (pmd++, addr = next, addr != end);
220} 234}
221 235
222static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, 236static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
223 unsigned long end, unsigned long phys) 237 unsigned long end, unsigned long phys,
238 int map_io)
224{ 239{
225 pud_t *pud = pud_offset(pgd, addr); 240 pud_t *pud = pud_offset(pgd, addr);
226 unsigned long next; 241 unsigned long next;
227 242
228 do { 243 do {
229 next = pud_addr_end(addr, end); 244 next = pud_addr_end(addr, end);
230 alloc_init_pmd(pud, addr, next, phys); 245 alloc_init_pmd(pud, addr, next, phys, map_io);
231 phys += next - addr; 246 phys += next - addr;
232 } while (pud++, addr = next, addr != end); 247 } while (pud++, addr = next, addr != end);
233} 248}
@@ -236,30 +251,44 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
236 * Create the page directory entries and any necessary page tables for the 251 * Create the page directory entries and any necessary page tables for the
237 * mapping specified by 'md'. 252 * mapping specified by 'md'.
238 */ 253 */
239static void __init create_mapping(phys_addr_t phys, unsigned long virt, 254static void __init __create_mapping(pgd_t *pgd, phys_addr_t phys,
240 phys_addr_t size) 255 unsigned long virt, phys_addr_t size,
256 int map_io)
241{ 257{
242 unsigned long addr, length, end, next; 258 unsigned long addr, length, end, next;
243 pgd_t *pgd;
244
245 if (virt < VMALLOC_START) {
246 pr_warning("BUG: not creating mapping for 0x%016llx at 0x%016lx - outside kernel range\n",
247 phys, virt);
248 return;
249 }
250 259
251 addr = virt & PAGE_MASK; 260 addr = virt & PAGE_MASK;
252 length = PAGE_ALIGN(size + (virt & ~PAGE_MASK)); 261 length = PAGE_ALIGN(size + (virt & ~PAGE_MASK));
253 262
254 pgd = pgd_offset_k(addr);
255 end = addr + length; 263 end = addr + length;
256 do { 264 do {
257 next = pgd_addr_end(addr, end); 265 next = pgd_addr_end(addr, end);
258 alloc_init_pud(pgd, addr, next, phys); 266 alloc_init_pud(pgd, addr, next, phys, map_io);
259 phys += next - addr; 267 phys += next - addr;
260 } while (pgd++, addr = next, addr != end); 268 } while (pgd++, addr = next, addr != end);
261} 269}
262 270
271static void __init create_mapping(phys_addr_t phys, unsigned long virt,
272 phys_addr_t size)
273{
274 if (virt < VMALLOC_START) {
275 pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
276 &phys, virt);
277 return;
278 }
279 __create_mapping(pgd_offset_k(virt & PAGE_MASK), phys, virt, size, 0);
280}
281
282void __init create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io)
283{
284 if ((addr >> PGDIR_SHIFT) >= ARRAY_SIZE(idmap_pg_dir)) {
285 pr_warn("BUG: not creating id mapping for %pa\n", &addr);
286 return;
287 }
288 __create_mapping(&idmap_pg_dir[pgd_index(addr)],
289 addr, addr, size, map_io);
290}
291
263static void __init map_mem(void) 292static void __init map_mem(void)
264{ 293{
265 struct memblock_region *reg; 294 struct memblock_region *reg;
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
index 531342ec4bcf..8bbe9401f4f0 100644
--- a/arch/arm64/xen/hypercall.S
+++ b/arch/arm64/xen/hypercall.S
@@ -80,6 +80,7 @@ HYPERCALL2(memory_op);
80HYPERCALL2(physdev_op); 80HYPERCALL2(physdev_op);
81HYPERCALL3(vcpu_op); 81HYPERCALL3(vcpu_op);
82HYPERCALL1(tmem_op); 82HYPERCALL1(tmem_op);
83HYPERCALL2(multicall);
83 84
84ENTRY(privcmd_call) 85ENTRY(privcmd_call)
85 mov x16, x0 86 mov x16, x0