source: mainline/kernel/arch/sparc64/src/sun4v/start.S

Last change on this file was 26f5bdf, checked in by Jakub Jermar <jakub@…>, 7 years ago

Use aligned addresses to take over the MMU

Commit cfdeedc55a55b7c1fc8de8b3faea55104ff3f641 made the kernel image
start address unaligned, which broke the MMU takeover on sun4v. Use
kernel load address, which is still aligned.

  • Property mode set to 100644
File size: 9.0 KB
Line 
1#
2# Copyright (c) 2005 Jakub Jermar
3# Copyright (c) 2008 Pavel Rimsky
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29
30#include <abi/asmtool.h>
31#include <arch/arch.h>
32#include <arch/stack.h>
33#include <arch/regdef.h>
34#include <arch/context_struct.h>
35#include <arch/sun4v/regdef.h>
36#include <arch/sun4v/hypercall.h>
37#include <arch/sun4v/arch.h>
38#include <arch/sun4v/cpu.h>
39#include <arch/mm/pagesize.h>
40#include <arch/mm/sun4v/tte.h>
41#include <arch/mm/sun4v/mmu.h>
42#include <arch/mm/sun4v/tlb.h>
43
44.register %g2, #scratch
45.register %g3, #scratch
46
47.section K_TEXT_START, "ax"
48
49#define BSP_FLAG 1
50#define PHYSMEM_ADDR_SIZE 56
51
52/*
53 * Flags set in the TTE data entry mapping the kernel.
54 */
55#ifdef CONFIG_VIRT_IDX_DCACHE
56 #define TTE_FLAGS \
57 (1 << TTE_V_SHIFT) \
58 | (1 << TTE_EP_SHIFT) \
59 | (1 << TTE_CP_SHIFT) \
60 | (1 << TTE_CV_SHIFT) \
61 | (1 << TTE_P_SHIFT) \
62 | (1 << TTE_W_SHIFT)
63#else
64 #define TTE_FLAGS \
65 (1 << TTE_V_SHIFT) \
66 | (1 << TTE_EP_SHIFT) \
67 | (1 << TTE_CP_SHIFT) \
68 | (1 << TTE_P_SHIFT) \
69 | (1 << TTE_W_SHIFT)
70#endif
71
72
73/*
74 * Fills a register with a TTE Data item. The item will map the given virtual
75 * address to a real address which will be computed by adding the starting
76 * address of the physical memory to the virtual address.
77 *
78 * parameters:
79 * addr: virtual address to be mapped
80 * rphysmem_start: register containing the starting address
81 * of the physical memory
82 * rtmp1: a register to be used as temporary
83 * rtmp2: a register to be used as temporary
84 * rd: register where the result will be saved
85 *
86 */
87#define TTE_DATA(addr, rphysmem_start, rtmp1, rtmp2, rd) \
88 setx TTE_FLAGS | PAGESIZE_4M, rtmp1, rd; \
89 add rd, rphysmem_start, rd; \
90 setx (addr), rtmp1, rtmp2; \
91 add rd, rtmp2, rd;
92
93/*
94 * Here is where the kernel is passed control from the boot loader.
95 *
96 * The registers are expected to be in this state:
97 * - %o0 starting address of physical memory
98 * + bootstrap processor flag
99 * bits 63...1: physical memory starting address / 2
100 * bit 0: non-zero on BSP processor, zero on AP processors
101 * - %o1 bootinfo structure address (BSP only)
102 *
103 *
104 * Moreover, we depend on boot having established the following environment:
105 * - TLBs are on
106 * - identity mapping for the kernel image
107 *
108 */
109SYMBOL(kernel_image_start)
110 mov BSP_FLAG, %l0
111 and %o0, %l0, %l7 ! l7 <= bootstrap processor?
112 andn %o0, %l0, %l6 ! l6 <= start of physical memory
113 or %o1, %g0, %l1
114
115 ! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
116 srlx %l6, 13, %l5
117
118 ! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
119 sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
120 srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5
121
122 /*
123 * Setup basic runtime environment.
124 */
125 wrpr %g0, NWINDOWS - 2, %cansave ! set maximum saveable windows
126 wrpr %g0, 0, %canrestore ! get rid of windows we will
127 ! never need again
128 wrpr %g0, 0, %otherwin ! make sure the window state is
129 ! consistent
130 wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window
131 ! traps for kernel
132
133 wrpr %g0, 0, %wstate ! use default spill/fill trap
134
135 wrpr %g0, 0, %tl ! TL = 0, primary context
136 ! register is used
137 wrpr %g0, 0, %gl
138
139 wrpr %g0, PSTATE_PRIV_BIT, %pstate ! disable interrupts and disable
140 ! 32-bit address masking
141
142 wrpr %g0, 0, %pil ! intialize %pil
143
144 /*
145 * Switch to kernel trap table.
146 */
147 sethi %hi(trap_table), %g1
148 wrpr %g1, %lo(trap_table), %tba
149
150 /* Explicitly switch to hypervisor API 1.1. */
151 mov 1, %o0
152 mov 1, %o1
153 mov 1, %o2
154 mov 0, %o3
155 mov 0, %o4
156 mov 0, %o5
157 ta 0xff
158
159 /*
160 * Take over the MMU.
161 */
162
163 ! map kernel in context 1
164 set kernel_load_address, %o0 ! virt. address
165 set 1, %o1 ! context
166 TTE_DATA(kernel_load_address, %l5, %g2, %g3, %o2) ! TTE data
167 set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3 ! MMU flags
168 __HYPERCALL_HYPERFAST(MMU_MAP_ADDR)
169
170 ! switch to context 1
171 set 1, %o0
172 set VA_PRIMARY_CONTEXT_REG, %o1
173 stxa %o0, [%o1] ASI_PRIMARY_CONTEXT_REG
174
175 ! demap all in context 0
176 set 0, %o0 ! reserved
177 set 0, %o1 ! reserved
178 set 0, %o2 ! context
179 set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3 ! MMU flags
180 __HYPERCALL_FAST(MMU_DEMAP_CTX)
181
182 ! install permanent mapping for kernel in context 0
183 set kernel_load_address, %o0 ! virtual address
184 set 0, %o1 ! context
185 TTE_DATA(kernel_load_address, %l5, %g2, %g3, %o2) ! TTE data
186 set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3 ! MMU flags
187 __HYPERCALL_FAST(MMU_MAP_PERM_ADDR)
188
189 ! switch to context 0
190 mov 0, %o0
191 set VA_PRIMARY_CONTEXT_REG, %o1
192 stxa %o0, [%o1] ASI_PRIMARY_CONTEXT_REG
193
194 ! demap all in context 1 (cleanup)
195 set 0, %o0 ! reserved
196 set 0, %o1 ! reserved
197 set 1, %o2 ! context
198 set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3 ! MMU flags
199 __HYPERCALL_FAST(MMU_DEMAP_CTX)
200
201 /*
202 * Set CPUID.
203 */
204 __HYPERCALL_FAST(CPU_MYID)
205 mov SCRATCHPAD_CPUID, %g1
206 stxa %o1, [%g1] ASI_SCRATCHPAD
207
208 /*
209 * Set MMU fault status area for the current CPU.
210 */
211 set mmu_fsas, %o0 ! o0 <= addr. of fault status areas array
212 add %o0, %l6, %o0 ! kernel address to real address
213 mulx %o1, MMU_FSA_SIZE, %g1 ! g1 <= offset of current CPU's fault status area
214 add %g1, %o0, %o0 ! o0 <= FSA of the current CPU
215 mov SCRATCHPAD_MMU_FSA, %g1
216 stxa %o0, [%g1] ASI_SCRATCHPAD ! remember MMU fault status area to speed up miss handler
217 __HYPERCALL_FAST(MMU_FAULT_AREA_CONF)
218
219 ! on APs skip executing the following code
220 cmp %l7, 0
221 be %xcc, 1f
222 nop
223
224 /*
225 * Save physmem_base for use by the mm subsystem.
226 * %l6 contains starting physical address
227 */
228 sethi %hi(physmem_base), %l4
229 stx %l6, [%l4 + %lo(physmem_base)]
230
231 /*
232 * Store a template of a TTE Data entry for kernel mappings.
233 * This template will be used from the kernel MMU miss handler.
234 */
235 !TTE_DATA(0, %l5, %g2, %g3, %g1)
236 setx TTE_FLAGS | PAGESIZE_8K, %g2, %g1; \
237 add %g1, %l5, %g1; \
238 set kernel_8k_tlb_data_template, %g4
239 stx %g1, [%g4]
240
241 /*
242 * So far, we have not touched the stack.
243 * It is a good idea to set the kernel stack to a known state now.
244 */
245 sethi %hi(temporary_boot_stack), %sp
246 or %sp, %lo(temporary_boot_stack), %sp
247 sub %sp, STACK_BIAS, %sp
248
249 /*
250 * Call sparc64_pre_main(bootinfo)
251 */
252 call sparc64_pre_main
253 or %l1, %g0, %o0
254
255 /*
256 * Create the first stack frame.
257 */
258 save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
259 flushw
260 add %g0, -STACK_BIAS, %fp
261
262 call main_bsp
263 nop
264
265 /* Not reached. */
266
2670:
268 ba,a %xcc, 0b
269
2701:
271
272#ifdef CONFIG_SMP
273
274 /*
275 * Configure stack for the AP.
276 * The AP is expected to use the stack saved
277 * in the ctx global variable.
278 */
279
280 mov 1, %o0 ! MMU enable flag
281 set mmu_enabled, %o1
282 mov MMU_ENABLE, %o5 ! MMU enable HV call
283 ta 0x80 ! call HV
284
285 mmu_enabled:
286
287 /*
288 * Configure stack for the AP.
289 * The AP is expected to use the stack saved
290 * in the ctx global variable.
291 */
292 set ctx, %g1
293 add %g1, CONTEXT_OFFSET_SP, %g1
294 ldx [%g1], %o6
295
296 /*
297 * Create the first stack frame.
298 */
299 save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
300 flushw
301 add %g0, -STACK_BIAS, %fp
302
303 call main_ap
304 nop
305#endif
306
307 /* Not reached. */
3080:
309 ba,a %xcc, 0b
310
311.section K_DATA_START, "aw", @progbits
312
313#define INITIAL_STACK_SIZE 1024
314
315.align STACK_ALIGNMENT
316 .space INITIAL_STACK_SIZE
317.align STACK_ALIGNMENT
318temporary_boot_stack:
319 .space STACK_WINDOW_SAVE_AREA_SIZE
320
321
322.data
323
324.align 8
325SYMBOL(physmem_base) ! copy of the physical memory base address
326 .quad 0
327
328/*
329 * This variable is used by the fast_data_access_MMU_miss trap handler.
330 * In runtime, it is modified to contain the address of the end of physical
331 * memory.
332 */
333SYMBOL(end_of_identity)
334 .quad -1
335
336SYMBOL(kernel_8k_tlb_data_template)
337 .quad 0
338
339/* MMU fault status areas for all CPUs */
340.align MMU_FSA_ALIGNMENT
341SYMBOL(mmu_fsas)
342 .space (MMU_FSA_SIZE * MAX_NUM_STRANDS)
Note: See TracBrowser for help on using the repository browser.