1
2
3
4
5
6
7
8
9 #include <linux/kexec.h>
10 #include <linux/linkage.h>
11
12 #include <asm/assembler.h>
13 #include <asm/kexec.h>
14 #include <asm/page.h>
15 #include <asm/sysreg.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29 ENTRY(arm64_relocate_new_kernel)
30
31
32 mov x18, x2
33 mov x17, x1
34 mov x16, x0
35 raw_dcache_line_size x15, x0
36 mov x14, xzr
37 mov x13, xzr
38
39
40 mrs x0, CurrentEL
41 cmp x0, #CurrentEL_EL2
42 b.ne 1f
43 mrs x0, sctlr_el2
44 ldr x1, =SCTLR_ELx_FLAGS
45 bic x0, x0, x1
46 pre_disable_mmu_workaround
47 msr sctlr_el2, x0
48 isb
49 1:
50
51
52 tbnz x16, IND_DONE_BIT, .Ldone
53
54 .Lloop:
55 and x12, x16, PAGE_MASK
56
57
58 .Ltest_source:
59 tbz x16, IND_SOURCE_BIT, .Ltest_indirection
60
61
62 mov x0, x13
63 add x20, x0, #PAGE_SIZE
64 sub x1, x15, #1
65 bic x0, x0, x1
66 2: dc ivac, x0
67 add x0, x0, x15
68 cmp x0, x20
69 b.lo 2b
70 dsb sy
71
72 mov x20, x13
73 mov x21, x12
74 copy_page x20, x21, x0, x1, x2, x3, x4, x5, x6, x7
75
76
77 add x13, x13, PAGE_SIZE
78 b .Lnext
79
80 .Ltest_indirection:
81 tbz x16, IND_INDIRECTION_BIT, .Ltest_destination
82
83
84 mov x14, x12
85 b .Lnext
86
87 .Ltest_destination:
88 tbz x16, IND_DESTINATION_BIT, .Lnext
89
90
91 mov x13, x12
92
93 .Lnext:
94
95 ldr x16, [x14], #8
96
97
98 tbz x16, IND_DONE_BIT, .Lloop
99
100 .Ldone:
101
102 dsb nsh
103 ic iallu
104 dsb nsh
105 isb
106
107
108 mov x0, x18
109 mov x1, xzr
110 mov x2, xzr
111 mov x3, xzr
112 br x17
113
114 ENDPROC(arm64_relocate_new_kernel)
115
116 .ltorg
117
118 .align 3
119
120 .Lcopy_end:
121 .org KEXEC_CONTROL_PAGE_SIZE
122
123
124
125
126
127 .globl arm64_relocate_new_kernel_size
128 arm64_relocate_new_kernel_size:
129 .quad .Lcopy_end - arm64_relocate_new_kernel