]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/sparc/kernel/head_64.S
Merge tag 'for-linus-20170812' of git://git.infradead.org/linux-mtd
[karo-tx-linux.git] / arch / sparc / kernel / head_64.S
1 /* head.S: Initial boot code for the Sparc64 port of Linux.
2  *
3  * Copyright (C) 1996, 1997, 2007 David S. Miller (davem@davemloft.net)
4  * Copyright (C) 1996 David Sitsky (David.Sitsky@anu.edu.au)
5  * Copyright (C) 1997, 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6  * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
7  */
8
9 #include <linux/version.h>
10 #include <linux/errno.h>
11 #include <linux/threads.h>
12 #include <linux/init.h>
13 #include <linux/linkage.h>
14 #include <asm/thread_info.h>
15 #include <asm/asi.h>
16 #include <asm/pstate.h>
17 #include <asm/ptrace.h>
18 #include <asm/spitfire.h>
19 #include <asm/page.h>
20 #include <asm/pgtable.h>
21 #include <asm/errno.h>
22 #include <asm/signal.h>
23 #include <asm/processor.h>
24 #include <asm/lsu.h>
25 #include <asm/dcr.h>
26 #include <asm/dcu.h>
27 #include <asm/head.h>
28 #include <asm/ttable.h>
29 #include <asm/mmu.h>
30 #include <asm/cpudata.h>
31 #include <asm/pil.h>
32 #include <asm/estate.h>
33 #include <asm/sfafsr.h>
34 #include <asm/unistd.h>
35 #include <asm/export.h>
36
37 /* This section from from _start to sparc64_boot_end should fit into
38  * 0x0000000000404000 to 0x0000000000408000.
39  */
40         .text
41         .globl  start, _start, stext, _stext
42 _start:
43 start:
44 _stext:
45 stext:
46 ! 0x0000000000404000
47         b       sparc64_boot
48          flushw                                 /* Flush register file.      */
49
50 /* This stuff has to be in sync with SILO and other potential boot loaders
51  * Fields should be kept upward compatible and whenever any change is made,
52  * HdrS version should be incremented.
53  */
54         .global root_flags, ram_flags, root_dev
55         .global sparc_ramdisk_image, sparc_ramdisk_size
56         .global sparc_ramdisk_image64
57
58         .ascii  "HdrS"
59         .word   LINUX_VERSION_CODE
60
61         /* History:
62          *
63          * 0x0300 : Supports being located at other than 0x4000
64          * 0x0202 : Supports kernel params string
65          * 0x0201 : Supports reboot_command
66          */
67         .half   0x0301          /* HdrS version */
68
69 root_flags:
70         .half   1
71 root_dev:
72         .half   0
73 ram_flags:
74         .half   0
75 sparc_ramdisk_image:
76         .word   0
77 sparc_ramdisk_size:
78         .word   0
79         .xword  reboot_command
80         .xword  bootstr_info
81 sparc_ramdisk_image64:
82         .xword  0
83         .word   _end
84
85         /* PROM cif handler code address is in %o4.  */
86 sparc64_boot:
87         mov     %o4, %l7
88
89         /* We need to remap the kernel.  Use position independent
90          * code to remap us to KERNBASE.
91          *
92          * SILO can invoke us with 32-bit address masking enabled,
93          * so make sure that's clear.
94          */
95         rdpr    %pstate, %g1
96         andn    %g1, PSTATE_AM, %g1
97         wrpr    %g1, 0x0, %pstate
98         ba,a,pt %xcc, 1f
99          nop
100
101         .globl  prom_finddev_name, prom_chosen_path, prom_root_node
102         .globl  prom_getprop_name, prom_mmu_name, prom_peer_name
103         .globl  prom_callmethod_name, prom_translate_name, prom_root_compatible
104         .globl  prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
105         .globl  prom_boot_mapped_pc, prom_boot_mapping_mode
106         .globl  prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
107         .globl  prom_compatible_name, prom_cpu_path, prom_cpu_compatible
108         .globl  is_sun4v, sun4v_chip_type, prom_set_trap_table_name
109 prom_peer_name:
110         .asciz  "peer"
111 prom_compatible_name:
112         .asciz  "compatible"
113 prom_finddev_name:
114         .asciz  "finddevice"
115 prom_chosen_path:
116         .asciz  "/chosen"
117 prom_cpu_path:
118         .asciz  "/cpu"
119 prom_getprop_name:
120         .asciz  "getprop"
121 prom_mmu_name:
122         .asciz  "mmu"
123 prom_callmethod_name:
124         .asciz  "call-method"
125 prom_translate_name:
126         .asciz  "translate"
127 prom_map_name:
128         .asciz  "map"
129 prom_unmap_name:
130         .asciz  "unmap"
131 prom_set_trap_table_name:
132         .asciz  "SUNW,set-trap-table"
133 prom_sun4v_name:
134         .asciz  "sun4v"
135 prom_niagara_prefix:
136         .asciz  "SUNW,UltraSPARC-T"
137 prom_sparc_prefix:
138         .asciz  "SPARC-"
139 prom_sparc64x_prefix:
140         .asciz  "SPARC64-X"
141         .align  4
142 prom_root_compatible:
143         .skip   64
144 prom_cpu_compatible:
145         .skip   64
146 prom_root_node:
147         .word   0
148 EXPORT_SYMBOL(prom_root_node)
149 prom_mmu_ihandle_cache:
150         .word   0
151 prom_boot_mapped_pc:
152         .word   0
153 prom_boot_mapping_mode:
154         .word   0
155         .align  8
156 prom_boot_mapping_phys_high:
157         .xword  0
158 prom_boot_mapping_phys_low:
159         .xword  0
160 is_sun4v:
161         .word   0
162 sun4v_chip_type:
163         .word   SUN4V_CHIP_INVALID
164 EXPORT_SYMBOL(sun4v_chip_type)
165 1:
166         rd      %pc, %l0
167
168         mov     (1b - prom_peer_name), %l1
169         sub     %l0, %l1, %l1
170         mov     0, %l2
171
172         /* prom_root_node = prom_peer(0) */
173         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "peer"
174         mov     1, %l3
175         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 1
176         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
177         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1, 0
178         stx     %g0, [%sp + 2047 + 128 + 0x20]  ! ret1
179         call    %l7
180          add    %sp, (2047 + 128), %o0          ! argument array
181
182         ldx     [%sp + 2047 + 128 + 0x20], %l4  ! prom root node
183         mov     (1b - prom_root_node), %l1
184         sub     %l0, %l1, %l1
185         stw     %l4, [%l1]
186
187         mov     (1b - prom_getprop_name), %l1
188         mov     (1b - prom_compatible_name), %l2
189         mov     (1b - prom_root_compatible), %l5
190         sub     %l0, %l1, %l1
191         sub     %l0, %l2, %l2
192         sub     %l0, %l5, %l5
193
194         /* prom_getproperty(prom_root_node, "compatible",
195          *                  &prom_root_compatible, 64)
196          */
197         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "getprop"
198         mov     4, %l3
199         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 4
200         mov     1, %l3
201         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
202         stx     %l4, [%sp + 2047 + 128 + 0x18]  ! arg1, prom_root_node
203         stx     %l2, [%sp + 2047 + 128 + 0x20]  ! arg2, "compatible"
204         stx     %l5, [%sp + 2047 + 128 + 0x28]  ! arg3, &prom_root_compatible
205         mov     64, %l3
206         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4, size
207         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! ret1
208         call    %l7
209          add    %sp, (2047 + 128), %o0          ! argument array
210
211         mov     (1b - prom_finddev_name), %l1
212         mov     (1b - prom_chosen_path), %l2
213         mov     (1b - prom_boot_mapped_pc), %l3
214         sub     %l0, %l1, %l1
215         sub     %l0, %l2, %l2
216         sub     %l0, %l3, %l3
217         stw     %l0, [%l3]
218         sub     %sp, (192 + 128), %sp
219
220         /* chosen_node = prom_finddevice("/chosen") */
221         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "finddevice"
222         mov     1, %l3
223         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 1
224         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
225         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1, "/chosen"
226         stx     %g0, [%sp + 2047 + 128 + 0x20]  ! ret1
227         call    %l7
228          add    %sp, (2047 + 128), %o0          ! argument array
229
230         ldx     [%sp + 2047 + 128 + 0x20], %l4  ! chosen device node
231
232         mov     (1b - prom_getprop_name), %l1
233         mov     (1b - prom_mmu_name), %l2
234         mov     (1b - prom_mmu_ihandle_cache), %l5
235         sub     %l0, %l1, %l1
236         sub     %l0, %l2, %l2
237         sub     %l0, %l5, %l5
238
239         /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */
240         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "getprop"
241         mov     4, %l3
242         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 4
243         mov     1, %l3
244         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
245         stx     %l4, [%sp + 2047 + 128 + 0x18]  ! arg1, chosen_node
246         stx     %l2, [%sp + 2047 + 128 + 0x20]  ! arg2, "mmu"
247         stx     %l5, [%sp + 2047 + 128 + 0x28]  ! arg3, &prom_mmu_ihandle_cache
248         mov     4, %l3
249         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4, sizeof(arg3)
250         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! ret1
251         call    %l7
252          add    %sp, (2047 + 128), %o0          ! argument array
253
254         mov     (1b - prom_callmethod_name), %l1
255         mov     (1b - prom_translate_name), %l2
256         sub     %l0, %l1, %l1
257         sub     %l0, %l2, %l2
258         lduw    [%l5], %l5                      ! prom_mmu_ihandle_cache
259
260         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "call-method"
261         mov     3, %l3
262         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 3
263         mov     5, %l3
264         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 5
265         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1: "translate"
266         stx     %l5, [%sp + 2047 + 128 + 0x20]  ! arg2: prom_mmu_ihandle_cache
267         /* PAGE align */
268         srlx    %l0, 13, %l3
269         sllx    %l3, 13, %l3
270         stx     %l3, [%sp + 2047 + 128 + 0x28]  ! arg3: vaddr, our PC
271         stx     %g0, [%sp + 2047 + 128 + 0x30]  ! res1
272         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! res2
273         stx     %g0, [%sp + 2047 + 128 + 0x40]  ! res3
274         stx     %g0, [%sp + 2047 + 128 + 0x48]  ! res4
275         stx     %g0, [%sp + 2047 + 128 + 0x50]  ! res5
276         call    %l7
277          add    %sp, (2047 + 128), %o0          ! argument array
278
279         ldx     [%sp + 2047 + 128 + 0x40], %l1  ! translation mode
280         mov     (1b - prom_boot_mapping_mode), %l4
281         sub     %l0, %l4, %l4
282         stw     %l1, [%l4]
283         mov     (1b - prom_boot_mapping_phys_high), %l4
284         sub     %l0, %l4, %l4
285         ldx     [%sp + 2047 + 128 + 0x48], %l2  ! physaddr high
286         stx     %l2, [%l4 + 0x0]
287         ldx     [%sp + 2047 + 128 + 0x50], %l3  ! physaddr low
288         /* 4MB align */
289         srlx    %l3, ILOG2_4MB, %l3
290         sllx    %l3, ILOG2_4MB, %l3
291         stx     %l3, [%l4 + 0x8]
292
293         /* Leave service as-is, "call-method" */
294         mov     7, %l3
295         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 7
296         mov     1, %l3
297         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
298         mov     (1b - prom_map_name), %l3
299         sub     %l0, %l3, %l3
300         stx     %l3, [%sp + 2047 + 128 + 0x18]  ! arg1: "map"
301         /* Leave arg2 as-is, prom_mmu_ihandle_cache */
302         mov     -1, %l3
303         stx     %l3, [%sp + 2047 + 128 + 0x28]  ! arg3: mode (-1 default)
304         /* 4MB align the kernel image size. */
305         set     (_end - KERNBASE), %l3
306         set     ((4 * 1024 * 1024) - 1), %l4
307         add     %l3, %l4, %l3
308         andn    %l3, %l4, %l3
309         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4: roundup(ksize, 4MB)
310         sethi   %hi(KERNBASE), %l3
311         stx     %l3, [%sp + 2047 + 128 + 0x38]  ! arg5: vaddr (KERNBASE)
312         stx     %g0, [%sp + 2047 + 128 + 0x40]  ! arg6: empty
313         mov     (1b - prom_boot_mapping_phys_low), %l3
314         sub     %l0, %l3, %l3
315         ldx     [%l3], %l3
316         stx     %l3, [%sp + 2047 + 128 + 0x48]  ! arg7: phys addr
317         call    %l7
318          add    %sp, (2047 + 128), %o0          ! argument array
319
320         add     %sp, (192 + 128), %sp
321
322         sethi   %hi(prom_root_compatible), %g1
323         or      %g1, %lo(prom_root_compatible), %g1
324         sethi   %hi(prom_sun4v_name), %g7
325         or      %g7, %lo(prom_sun4v_name), %g7
326         mov     5, %g3
327 90:     ldub    [%g7], %g2
328         ldub    [%g1], %g4
329         cmp     %g2, %g4
330         bne,pn  %icc, 80f
331          add    %g7, 1, %g7
332         subcc   %g3, 1, %g3
333         bne,pt  %xcc, 90b
334          add    %g1, 1, %g1
335
336         sethi   %hi(is_sun4v), %g1
337         or      %g1, %lo(is_sun4v), %g1
338         mov     1, %g7
339         stw     %g7, [%g1]
340
341         /* cpu_node = prom_finddevice("/cpu") */
342         mov     (1b - prom_finddev_name), %l1
343         mov     (1b - prom_cpu_path), %l2
344         sub     %l0, %l1, %l1
345         sub     %l0, %l2, %l2
346         sub     %sp, (192 + 128), %sp
347
348         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "finddevice"
349         mov     1, %l3
350         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 1
351         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
352         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1, "/cpu"
353         stx     %g0, [%sp + 2047 + 128 + 0x20]  ! ret1
354         call    %l7
355          add    %sp, (2047 + 128), %o0          ! argument array
356
357         ldx     [%sp + 2047 + 128 + 0x20], %l4  ! cpu device node
358
359         mov     (1b - prom_getprop_name), %l1
360         mov     (1b - prom_compatible_name), %l2
361         mov     (1b - prom_cpu_compatible), %l5
362         sub     %l0, %l1, %l1
363         sub     %l0, %l2, %l2
364         sub     %l0, %l5, %l5
365
366         /* prom_getproperty(cpu_node, "compatible",
367          *                  &prom_cpu_compatible, 64)
368          */
369         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "getprop"
370         mov     4, %l3
371         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 4
372         mov     1, %l3
373         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
374         stx     %l4, [%sp + 2047 + 128 + 0x18]  ! arg1, cpu_node
375         stx     %l2, [%sp + 2047 + 128 + 0x20]  ! arg2, "compatible"
376         stx     %l5, [%sp + 2047 + 128 + 0x28]  ! arg3, &prom_cpu_compatible
377         mov     64, %l3
378         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4, size
379         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! ret1
380         call    %l7
381          add    %sp, (2047 + 128), %o0          ! argument array
382
383         add     %sp, (192 + 128), %sp
384
385         sethi   %hi(prom_cpu_compatible), %g1
386         or      %g1, %lo(prom_cpu_compatible), %g1
387         sethi   %hi(prom_niagara_prefix), %g7
388         or      %g7, %lo(prom_niagara_prefix), %g7
389         mov     17, %g3
390 90:     ldub    [%g7], %g2
391         ldub    [%g1], %g4
392         cmp     %g2, %g4
393         bne,pn  %icc, 89f
394          add    %g7, 1, %g7
395         subcc   %g3, 1, %g3
396         bne,pt  %xcc, 90b
397          add    %g1, 1, %g1
398         ba,pt   %xcc, 91f
399          nop
400
401 89:     sethi   %hi(prom_cpu_compatible), %g1
402         or      %g1, %lo(prom_cpu_compatible), %g1
403         sethi   %hi(prom_sparc_prefix), %g7
404         or      %g7, %lo(prom_sparc_prefix), %g7
405         mov     6, %g3
406 90:     ldub    [%g7], %g2
407         ldub    [%g1], %g4
408         cmp     %g2, %g4
409         bne,pn  %icc, 4f
410          add    %g7, 1, %g7
411         subcc   %g3, 1, %g3
412         bne,pt  %xcc, 90b
413          add    %g1, 1, %g1
414
415         sethi   %hi(prom_cpu_compatible), %g1
416         or      %g1, %lo(prom_cpu_compatible), %g1
417         ldub    [%g1 + 6], %g2
418         cmp     %g2, 'T'
419         be,pt   %xcc, 70f
420          cmp    %g2, 'M'
421         be,pt   %xcc, 70f
422          cmp    %g2, 'S'
423         bne,pn  %xcc, 49f
424          nop
425
426 70:     ldub    [%g1 + 7], %g2
427         cmp     %g2, CPU_ID_NIAGARA3
428         be,pt   %xcc, 5f
429          mov    SUN4V_CHIP_NIAGARA3, %g4
430         cmp     %g2, CPU_ID_NIAGARA4
431         be,pt   %xcc, 5f
432          mov    SUN4V_CHIP_NIAGARA4, %g4
433         cmp     %g2, CPU_ID_NIAGARA5
434         be,pt   %xcc, 5f
435          mov    SUN4V_CHIP_NIAGARA5, %g4
436         cmp     %g2, CPU_ID_M6
437         be,pt   %xcc, 5f
438          mov    SUN4V_CHIP_SPARC_M6, %g4
439         cmp     %g2, CPU_ID_M7
440         be,pt   %xcc, 5f
441          mov    SUN4V_CHIP_SPARC_M7, %g4
442         cmp     %g2, CPU_ID_M8
443         be,pt   %xcc, 5f
444          mov    SUN4V_CHIP_SPARC_M8, %g4
445         cmp     %g2, CPU_ID_SONOMA1
446         be,pt   %xcc, 5f
447          mov    SUN4V_CHIP_SPARC_SN, %g4
448         ba,pt   %xcc, 49f
449          nop
450
451 91:     sethi   %hi(prom_cpu_compatible), %g1
452         or      %g1, %lo(prom_cpu_compatible), %g1
453         ldub    [%g1 + 17], %g2
454         cmp     %g2, CPU_ID_NIAGARA1
455         be,pt   %xcc, 5f
456          mov    SUN4V_CHIP_NIAGARA1, %g4
457         cmp     %g2, CPU_ID_NIAGARA2
458         be,pt   %xcc, 5f
459          mov    SUN4V_CHIP_NIAGARA2, %g4
460         
461 4:
462         /* Athena */
463         sethi   %hi(prom_cpu_compatible), %g1
464         or      %g1, %lo(prom_cpu_compatible), %g1
465         sethi   %hi(prom_sparc64x_prefix), %g7
466         or      %g7, %lo(prom_sparc64x_prefix), %g7
467         mov     9, %g3
468 41:     ldub    [%g7], %g2
469         ldub    [%g1], %g4
470         cmp     %g2, %g4
471         bne,pn  %icc, 49f
472         add     %g7, 1, %g7
473         subcc   %g3, 1, %g3
474         bne,pt  %xcc, 41b
475         add     %g1, 1, %g1
476         ba,pt   %xcc, 5f
477          mov    SUN4V_CHIP_SPARC64X, %g4
478
479 49:
480         mov     SUN4V_CHIP_UNKNOWN, %g4
481 5:      sethi   %hi(sun4v_chip_type), %g2
482         or      %g2, %lo(sun4v_chip_type), %g2
483         stw     %g4, [%g2]
484
485 80:
486         BRANCH_IF_SUN4V(g1, jump_to_sun4u_init)
487         BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
488         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
489         ba,pt   %xcc, spitfire_boot
490          nop
491
492 cheetah_plus_boot:
493         /* Preserve OBP chosen DCU and DCR register settings.  */
494         ba,pt   %xcc, cheetah_generic_boot
495          nop
496
497 cheetah_boot:
498         mov     DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
499         wr      %g1, %asr18
500
501         sethi   %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7
502         or      %g7, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7
503         sllx    %g7, 32, %g7
504         or      %g7, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g7
505         stxa    %g7, [%g0] ASI_DCU_CONTROL_REG
506         membar  #Sync
507
508 cheetah_generic_boot:
509         mov     TSB_EXTENSION_P, %g3
510         stxa    %g0, [%g3] ASI_DMMU
511         stxa    %g0, [%g3] ASI_IMMU
512         membar  #Sync
513
514         mov     TSB_EXTENSION_S, %g3
515         stxa    %g0, [%g3] ASI_DMMU
516         membar  #Sync
517
518         mov     TSB_EXTENSION_N, %g3
519         stxa    %g0, [%g3] ASI_DMMU
520         stxa    %g0, [%g3] ASI_IMMU
521         membar  #Sync
522
523         ba,a,pt %xcc, jump_to_sun4u_init
524
525 spitfire_boot:
526         /* Typically PROM has already enabled both MMU's and both on-chip
527          * caches, but we do it here anyway just to be paranoid.
528          */
529         mov     (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1
530         stxa    %g1, [%g0] ASI_LSU_CONTROL
531         membar  #Sync
532
533 jump_to_sun4u_init:
534         /*
535          * Make sure we are in privileged mode, have address masking,
536          * using the ordinary globals and have enabled floating
537          * point.
538          *
539          * Again, typically PROM has left %pil at 13 or similar, and
540          * (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE) in %pstate.
541          */
542         wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
543         wr      %g0, 0, %fprs
544
545         set     sun4u_init, %g2
546         jmpl    %g2 + %g0, %g0
547          nop
548
549         __REF
550 sun4u_init:
551         BRANCH_IF_SUN4V(g1, sun4v_init)
552
553         /* Set ctx 0 */
554         mov             PRIMARY_CONTEXT, %g7
555         stxa            %g0, [%g7] ASI_DMMU
556         membar          #Sync
557
558         mov             SECONDARY_CONTEXT, %g7
559         stxa            %g0, [%g7] ASI_DMMU
560         membar  #Sync
561
562         ba,a,pt         %xcc, sun4u_continue
563
564 sun4v_init:
565         /* Set ctx 0 */
566         mov             PRIMARY_CONTEXT, %g7
567         stxa            %g0, [%g7] ASI_MMU
568         membar          #Sync
569
570         mov             SECONDARY_CONTEXT, %g7
571         stxa            %g0, [%g7] ASI_MMU
572         membar          #Sync
573         ba,a,pt         %xcc, niagara_tlb_fixup
574
575 sun4u_continue:
576         BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
577
578         ba,a,pt %xcc, spitfire_tlb_fixup
579
580 niagara_tlb_fixup:
581         mov     3, %g2          /* Set TLB type to hypervisor. */
582         sethi   %hi(tlb_type), %g1
583         stw     %g2, [%g1 + %lo(tlb_type)]
584
585         /* Patch copy/clear ops.  */
586         sethi   %hi(sun4v_chip_type), %g1
587         lduw    [%g1 + %lo(sun4v_chip_type)], %g1
588         cmp     %g1, SUN4V_CHIP_NIAGARA1
589         be,pt   %xcc, niagara_patch
590          cmp    %g1, SUN4V_CHIP_NIAGARA2
591         be,pt   %xcc, niagara2_patch
592          nop
593         cmp     %g1, SUN4V_CHIP_NIAGARA3
594         be,pt   %xcc, niagara2_patch
595          nop
596         cmp     %g1, SUN4V_CHIP_NIAGARA4
597         be,pt   %xcc, niagara4_patch
598          nop
599         cmp     %g1, SUN4V_CHIP_NIAGARA5
600         be,pt   %xcc, niagara4_patch
601          nop
602         cmp     %g1, SUN4V_CHIP_SPARC_M6
603         be,pt   %xcc, niagara4_patch
604          nop
605         cmp     %g1, SUN4V_CHIP_SPARC_M7
606         be,pt   %xcc, niagara4_patch
607          nop
608         cmp     %g1, SUN4V_CHIP_SPARC_M8
609         be,pt   %xcc, niagara4_patch
610          nop
611         cmp     %g1, SUN4V_CHIP_SPARC_SN
612         be,pt   %xcc, niagara4_patch
613          nop
614
615         call    generic_patch_copyops
616          nop
617         call    generic_patch_bzero
618          nop
619         call    generic_patch_pageops
620          nop
621
622         ba,a,pt %xcc, 80f
623          nop
624 niagara4_patch:
625         call    niagara4_patch_copyops
626          nop
627         call    niagara4_patch_bzero
628          nop
629         call    niagara4_patch_pageops
630          nop
631
632         ba,a,pt %xcc, 80f
633          nop
634
635 niagara2_patch:
636         call    niagara2_patch_copyops
637          nop
638         call    niagara_patch_bzero
639          nop
640         call    niagara_patch_pageops
641          nop
642
643         ba,a,pt %xcc, 80f
644          nop
645
646 niagara_patch:
647         call    niagara_patch_copyops
648          nop
649         call    niagara_patch_bzero
650          nop
651         call    niagara_patch_pageops
652          nop
653
654 80:
655         /* Patch TLB/cache ops.  */
656         call    hypervisor_patch_cachetlbops
657          nop
658
659         ba,a,pt %xcc, tlb_fixup_done
660
661 cheetah_tlb_fixup:
662         mov     2, %g2          /* Set TLB type to cheetah+. */
663         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
664
665         mov     1, %g2          /* Set TLB type to cheetah. */
666
667 1:      sethi   %hi(tlb_type), %g1
668         stw     %g2, [%g1 + %lo(tlb_type)]
669
670         /* Patch copy/page operations to cheetah optimized versions. */
671         call    cheetah_patch_copyops
672          nop
673         call    cheetah_patch_copy_page
674          nop
675         call    cheetah_patch_cachetlbops
676          nop
677
678         ba,a,pt %xcc, tlb_fixup_done
679
680 spitfire_tlb_fixup:
681         /* Set TLB type to spitfire. */
682         mov     0, %g2
683         sethi   %hi(tlb_type), %g1
684         stw     %g2, [%g1 + %lo(tlb_type)]
685
686 tlb_fixup_done:
687         sethi   %hi(init_thread_union), %g6
688         or      %g6, %lo(init_thread_union), %g6
689         ldx     [%g6 + TI_TASK], %g4
690
691         wr      %g0, ASI_P, %asi
692         mov     1, %g1
693         sllx    %g1, THREAD_SHIFT, %g1
694         sub     %g1, (STACKFRAME_SZ + STACK_BIAS), %g1
695         add     %g6, %g1, %sp
696
697         /* Set per-cpu pointer initially to zero, this makes
698          * the boot-cpu use the in-kernel-image per-cpu areas
699          * before setup_per_cpu_area() is invoked.
700          */
701         clr     %g5
702
703         wrpr    %g0, 0, %wstate
704         wrpr    %g0, 0x0, %tl
705
706         /* Clear the bss */
707         sethi   %hi(__bss_start), %o0
708         or      %o0, %lo(__bss_start), %o0
709         sethi   %hi(_end), %o1
710         or      %o1, %lo(_end), %o1
711         call    __bzero
712          sub    %o1, %o0, %o1
713
714         call    prom_init
715          mov    %l7, %o0                        ! OpenPROM cif handler
716
717         /* To create a one-register-window buffer between the kernel's
718          * initial stack and the last stack frame we use from the firmware,
719          * do the rest of the boot from a C helper function.
720          */
721         call    start_early_boot
722          nop
723         /* Not reached... */
724
725         .previous
726
727         /* This is meant to allow the sharing of this code between
728          * boot processor invocation (via setup_tba() below) and
729          * secondary processor startup (via trampoline.S).  The
730          * former does use this code, the latter does not yet due
731          * to some complexities.  That should be fixed up at some
732          * point.
733          *
734          * There used to be enormous complexity wrt. transferring
735          * over from the firmware's trap table to the Linux kernel's.
736          * For example, there was a chicken & egg problem wrt. building
737          * the OBP page tables, yet needing to be on the Linux kernel
738          * trap table (to translate PAGE_OFFSET addresses) in order to
739          * do that.
740          *
741          * We now handle OBP tlb misses differently, via linear lookups
742          * into the prom_trans[] array.  So that specific problem no
743          * longer exists.  Yet, unfortunately there are still some issues
744          * preventing trampoline.S from using this code... ho hum.
745          */
746         .globl  setup_trap_table
747 setup_trap_table:
748         save    %sp, -192, %sp
749
750         /* Force interrupts to be disabled. */
751         rdpr    %pstate, %l0
752         andn    %l0, PSTATE_IE, %o1
753         wrpr    %o1, 0x0, %pstate
754         rdpr    %pil, %l1
755         wrpr    %g0, PIL_NORMAL_MAX, %pil
756
757         /* Make the firmware call to jump over to the Linux trap table.  */
758         sethi   %hi(is_sun4v), %o0
759         lduw    [%o0 + %lo(is_sun4v)], %o0
760         brz,pt  %o0, 1f
761          nop
762
763         TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
764         add     %g2, TRAP_PER_CPU_FAULT_INFO, %g2
765         stxa    %g2, [%g0] ASI_SCRATCHPAD
766
767         /* Compute physical address:
768          *
769          * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
770          */
771         sethi   %hi(KERNBASE), %g3
772         sub     %g2, %g3, %g2
773         sethi   %hi(kern_base), %g3
774         ldx     [%g3 + %lo(kern_base)], %g3
775         add     %g2, %g3, %o1
776         sethi   %hi(sparc64_ttable_tl0), %o0
777
778         set     prom_set_trap_table_name, %g2
779         stx     %g2, [%sp + 2047 + 128 + 0x00]
780         mov     2, %g2
781         stx     %g2, [%sp + 2047 + 128 + 0x08]
782         mov     0, %g2
783         stx     %g2, [%sp + 2047 + 128 + 0x10]
784         stx     %o0, [%sp + 2047 + 128 + 0x18]
785         stx     %o1, [%sp + 2047 + 128 + 0x20]
786         sethi   %hi(p1275buf), %g2
787         or      %g2, %lo(p1275buf), %g2
788         ldx     [%g2 + 0x08], %o1
789         call    %o1
790          add    %sp, (2047 + 128), %o0
791
792         ba,a,pt %xcc, 2f
793
794 1:      sethi   %hi(sparc64_ttable_tl0), %o0
795         set     prom_set_trap_table_name, %g2
796         stx     %g2, [%sp + 2047 + 128 + 0x00]
797         mov     1, %g2
798         stx     %g2, [%sp + 2047 + 128 + 0x08]
799         mov     0, %g2
800         stx     %g2, [%sp + 2047 + 128 + 0x10]
801         stx     %o0, [%sp + 2047 + 128 + 0x18]
802         sethi   %hi(p1275buf), %g2
803         or      %g2, %lo(p1275buf), %g2
804         ldx     [%g2 + 0x08], %o1
805         call    %o1
806          add    %sp, (2047 + 128), %o0
807
808         /* Start using proper page size encodings in ctx register.  */
809 2:      sethi   %hi(sparc64_kern_pri_context), %g3
810         ldx     [%g3 + %lo(sparc64_kern_pri_context)], %g2
811
812         mov             PRIMARY_CONTEXT, %g1
813
814 661:    stxa            %g2, [%g1] ASI_DMMU
815         .section        .sun4v_1insn_patch, "ax"
816         .word           661b
817         stxa            %g2, [%g1] ASI_MMU
818         .previous
819
820         membar  #Sync
821
822         BRANCH_IF_SUN4V(o2, 1f)
823
824         /* Kill PROM timer */
825         sethi   %hi(0x80000000), %o2
826         sllx    %o2, 32, %o2
827         wr      %o2, 0, %tick_cmpr
828
829         BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
830
831         ba,a,pt %xcc, 2f
832
833         /* Disable STICK_INT interrupts. */
834 1:
835         sethi   %hi(0x80000000), %o2
836         sllx    %o2, 32, %o2
837         wr      %o2, %asr25
838
839 2:
840         wrpr    %g0, %g0, %wstate
841
842         call    init_irqwork_curcpu
843          nop
844
845         /* Now we can restore interrupt state. */
846         wrpr    %l0, 0, %pstate
847         wrpr    %l1, 0x0, %pil
848
849         ret
850          restore
851
852         .globl  setup_tba
853 setup_tba:
854         save    %sp, -192, %sp
855
856         /* The boot processor is the only cpu which invokes this
857          * routine, the other cpus set things up via trampoline.S.
858          * So save the OBP trap table address here.
859          */
860         rdpr    %tba, %g7
861         sethi   %hi(prom_tba), %o1
862         or      %o1, %lo(prom_tba), %o1
863         stx     %g7, [%o1]
864
865         call    setup_trap_table
866          nop
867
868         ret
869          restore
870 sparc64_boot_end:
871
872 #include "etrap_64.S"
873 #include "rtrap_64.S"
874 #include "winfixup.S"
875 #include "fpu_traps.S"
876 #include "ivec.S"
877 #include "getsetcc.S"
878 #include "utrap.S"
879 #include "spiterrs.S"
880 #include "cherrs.S"
881 #include "misctrap.S"
882 #include "syscalls.S"
883 #include "helpers.S"
884 #include "hvcalls.S"
885 #include "sun4v_tlb_miss.S"
886 #include "sun4v_ivec.S"
887 #include "ktlb.S"
888 #include "tsb.S"
889
890 /*
891  * The following skip makes sure the trap table in ttable.S is aligned
892  * on a 32K boundary as required by the v9 specs for TBA register.
893  *
894  * We align to a 32K boundary, then we have the 32K kernel TSB,
895  * the 64K kernel 4MB TSB, and then the 32K aligned trap table.
896  */
897 1:
898         .skip   0x4000 + _start - 1b
899
900 ! 0x0000000000408000
901
902         .globl  swapper_tsb
903 swapper_tsb:
904         .skip   (32 * 1024)
905
906         .globl  swapper_4m_tsb
907 swapper_4m_tsb:
908         .skip   (64 * 1024)
909
910 ! 0x0000000000420000
911
912         /* Some care needs to be exercised if you try to move the
913          * location of the trap table relative to other things.  For
914          * one thing there are br* instructions in some of the
915          * trap table entires which branch back to code in ktlb.S
916          * Those instructions can only handle a signed 16-bit
917          * displacement.
918          *
919          * There is a binutils bug (bugzilla #4558) which causes
920          * the relocation overflow checks for such instructions to
921          * not be done correctly.  So bintuils will not notice the
922          * error and will instead write junk into the relocation and
923          * you'll have an unbootable kernel.
924          */
925 #include "ttable_64.S"
926
927 ! 0x0000000000428000
928
929 #include "systbls_64.S"
930
931         .data
932         .align  8
933         .globl  prom_tba, tlb_type
934 prom_tba:       .xword  0
935 tlb_type:       .word   0       /* Must NOT end up in BSS */
936 EXPORT_SYMBOL(tlb_type)
937         .section        ".fixup",#alloc,#execinstr
938
939 ENTRY(__retl_efault)
940         retl
941          mov    -EFAULT, %o0
942 ENDPROC(__retl_efault)
943
944 ENTRY(__retl_o1)
945         retl
946          mov    %o1, %o0
947 ENDPROC(__retl_o1)
948
949 ENTRY(__retl_o1_asi)
950         wr      %o5, 0x0, %asi
951         retl
952          mov    %o1, %o0
953 ENDPROC(__retl_o1_asi)