diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/relocate_kernel.S | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/relocate_kernel.S')
-rw-r--r-- | arch/mips/kernel/relocate_kernel.S | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S new file mode 100644 index 000000000..ac870893b --- /dev/null +++ b/arch/mips/kernel/relocate_kernel.S | |||
@@ -0,0 +1,190 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
2 | /* | ||
3 | * relocate_kernel.S for kexec | ||
4 | * Created by <nschichan@corp.free.fr> on Thu Oct 12 17:49:57 2006 | ||
5 | */ | ||
6 | |||
7 | #include <asm/asm.h> | ||
8 | #include <asm/asmmacro.h> | ||
9 | #include <asm/regdef.h> | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/stackframe.h> | ||
12 | #include <asm/addrspace.h> | ||
13 | |||
14 | LEAF(relocate_new_kernel) | ||
15 | PTR_L a0, arg0 | ||
16 | PTR_L a1, arg1 | ||
17 | PTR_L a2, arg2 | ||
18 | PTR_L a3, arg3 | ||
19 | |||
20 | PTR_L s0, kexec_indirection_page | ||
21 | PTR_L s1, kexec_start_address | ||
22 | |||
23 | process_entry: | ||
24 | PTR_L s2, (s0) | ||
25 | PTR_ADDIU s0, s0, SZREG | ||
26 | |||
27 | /* | ||
28 | * In case of a kdump/crash kernel, the indirection page is not | ||
29 | * populated as the kernel is directly copied to a reserved location | ||
30 | */ | ||
31 | beqz s2, done | ||
32 | |||
33 | /* destination page */ | ||
34 | and s3, s2, 0x1 | ||
35 | beq s3, zero, 1f | ||
36 | and s4, s2, ~0x1 /* store destination addr in s4 */ | ||
37 | b process_entry | ||
38 | |||
39 | 1: | ||
40 | /* indirection page, update s0 */ | ||
41 | and s3, s2, 0x2 | ||
42 | beq s3, zero, 1f | ||
43 | and s0, s2, ~0x2 | ||
44 | b process_entry | ||
45 | |||
46 | 1: | ||
47 | /* done page */ | ||
48 | and s3, s2, 0x4 | ||
49 | beq s3, zero, 1f | ||
50 | b done | ||
51 | 1: | ||
52 | /* source page */ | ||
53 | and s3, s2, 0x8 | ||
54 | beq s3, zero, process_entry | ||
55 | and s2, s2, ~0x8 | ||
56 | li s6, (1 << _PAGE_SHIFT) / SZREG | ||
57 | |||
58 | copy_word: | ||
59 | /* copy page word by word */ | ||
60 | REG_L s5, (s2) | ||
61 | REG_S s5, (s4) | ||
62 | PTR_ADDIU s4, s4, SZREG | ||
63 | PTR_ADDIU s2, s2, SZREG | ||
64 | LONG_ADDIU s6, s6, -1 | ||
65 | beq s6, zero, process_entry | ||
66 | b copy_word | ||
67 | b process_entry | ||
68 | |||
69 | done: | ||
70 | #ifdef CONFIG_SMP | ||
71 | /* kexec_flag reset is signal to other CPUs what kernel | ||
72 | was moved to it's location. Note - we need relocated address | ||
73 | of kexec_flag. */ | ||
74 | |||
75 | bal 1f | ||
76 | 1: move t1,ra; | ||
77 | PTR_LA t2,1b | ||
78 | PTR_LA t0,kexec_flag | ||
79 | PTR_SUB t0,t0,t2; | ||
80 | PTR_ADD t0,t1,t0; | ||
81 | LONG_S zero,(t0) | ||
82 | #endif | ||
83 | |||
84 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | ||
85 | /* We need to flush I-cache before jumping to new kernel. | ||
86 | * Unfortunately, this code is cpu-specific. | ||
87 | */ | ||
88 | .set push | ||
89 | .set noreorder | ||
90 | syncw | ||
91 | syncw | ||
92 | synci 0($0) | ||
93 | .set pop | ||
94 | #else | ||
95 | sync | ||
96 | #endif | ||
97 | /* jump to kexec_start_address */ | ||
98 | j s1 | ||
99 | END(relocate_new_kernel) | ||
100 | |||
101 | #ifdef CONFIG_SMP | ||
102 | /* | ||
103 | * Other CPUs should wait until code is relocated and | ||
104 | * then start at entry (?) point. | ||
105 | */ | ||
106 | LEAF(kexec_smp_wait) | ||
107 | PTR_L a0, s_arg0 | ||
108 | PTR_L a1, s_arg1 | ||
109 | PTR_L a2, s_arg2 | ||
110 | PTR_L a3, s_arg3 | ||
111 | PTR_L s1, kexec_start_address | ||
112 | |||
113 | /* Non-relocated address works for args and kexec_start_address ( old | ||
114 | * kernel is not overwritten). But we need relocated address of | ||
115 | * kexec_flag. | ||
116 | */ | ||
117 | |||
118 | bal 1f | ||
119 | 1: move t1,ra; | ||
120 | PTR_LA t2,1b | ||
121 | PTR_LA t0,kexec_flag | ||
122 | PTR_SUB t0,t0,t2; | ||
123 | PTR_ADD t0,t1,t0; | ||
124 | |||
125 | 1: LONG_L s0, (t0) | ||
126 | bne s0, zero,1b | ||
127 | |||
128 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | ||
129 | .set push | ||
130 | .set noreorder | ||
131 | synci 0($0) | ||
132 | .set pop | ||
133 | #else | ||
134 | sync | ||
135 | #endif | ||
136 | j s1 | ||
137 | END(kexec_smp_wait) | ||
138 | #endif | ||
139 | |||
140 | #ifdef __mips64 | ||
141 | /* all PTR's must be aligned to 8 byte in 64-bit mode */ | ||
142 | .align 3 | ||
143 | #endif | ||
144 | |||
145 | /* All parameters to new kernel are passed in registers a0-a3. | ||
146 | * kexec_args[0..3] are used to prepare register values. | ||
147 | */ | ||
148 | |||
149 | kexec_args: | ||
150 | EXPORT(kexec_args) | ||
151 | arg0: PTR 0x0 | ||
152 | arg1: PTR 0x0 | ||
153 | arg2: PTR 0x0 | ||
154 | arg3: PTR 0x0 | ||
155 | .size kexec_args,PTRSIZE*4 | ||
156 | |||
157 | #ifdef CONFIG_SMP | ||
158 | /* | ||
159 | * Secondary CPUs may have different kernel parameters in | ||
160 | * their registers a0-a3. secondary_kexec_args[0..3] are used | ||
161 | * to prepare register values. | ||
162 | */ | ||
163 | secondary_kexec_args: | ||
164 | EXPORT(secondary_kexec_args) | ||
165 | s_arg0: PTR 0x0 | ||
166 | s_arg1: PTR 0x0 | ||
167 | s_arg2: PTR 0x0 | ||
168 | s_arg3: PTR 0x0 | ||
169 | .size secondary_kexec_args,PTRSIZE*4 | ||
170 | kexec_flag: | ||
171 | LONG 0x1 | ||
172 | |||
173 | #endif | ||
174 | |||
175 | kexec_start_address: | ||
176 | EXPORT(kexec_start_address) | ||
177 | PTR 0x0 | ||
178 | .size kexec_start_address, PTRSIZE | ||
179 | |||
180 | kexec_indirection_page: | ||
181 | EXPORT(kexec_indirection_page) | ||
182 | PTR 0 | ||
183 | .size kexec_indirection_page, PTRSIZE | ||
184 | |||
185 | relocate_new_kernel_end: | ||
186 | |||
187 | relocate_new_kernel_size: | ||
188 | EXPORT(relocate_new_kernel_size) | ||
189 | PTR relocate_new_kernel_end - relocate_new_kernel | ||
190 | .size relocate_new_kernel_size, PTRSIZE | ||