Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq
[linux-2.6] / arch / sparc64 / kernel / head.S
1 /* $Id: head.S,v 1.87 2002/02/09 19:49:31 davem Exp $
2  * head.S: Initial boot code for the Sparc64 port of Linux.
3  *
4  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
5  * Copyright (C) 1996 David Sitsky (David.Sitsky@anu.edu.au)
6  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7  * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
8  */
9
10 #include <linux/config.h>
11 #include <linux/version.h>
12 #include <linux/errno.h>
13 #include <linux/threads.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         
32 /* This section from from _start to sparc64_boot_end should fit into
33  * 0x0000000000404000 to 0x0000000000408000.
34  */
35         .text
36         .globl  start, _start, stext, _stext
37 _start:
38 start:
39 _stext:
40 stext:
41 ! 0x0000000000404000
42         b       sparc64_boot
43          flushw                                 /* Flush register file.      */
44
45 /* This stuff has to be in sync with SILO and other potential boot loaders
46  * Fields should be kept upward compatible and whenever any change is made,
47  * HdrS version should be incremented.
48  */
49         .global root_flags, ram_flags, root_dev
50         .global sparc_ramdisk_image, sparc_ramdisk_size
51         .global sparc_ramdisk_image64
52
53         .ascii  "HdrS"
54         .word   LINUX_VERSION_CODE
55
56         /* History:
57          *
58          * 0x0300 : Supports being located at other than 0x4000
59          * 0x0202 : Supports kernel params string
60          * 0x0201 : Supports reboot_command
61          */
62         .half   0x0301          /* HdrS version */
63
64 root_flags:
65         .half   1
66 root_dev:
67         .half   0
68 ram_flags:
69         .half   0
70 sparc_ramdisk_image:
71         .word   0
72 sparc_ramdisk_size:
73         .word   0
74         .xword  reboot_command
75         .xword  bootstr_info
76 sparc_ramdisk_image64:
77         .xword  0
78         .word   _end
79
80         /* PROM cif handler code address is in %o4.  */
81 sparc64_boot:
82 1:      rd      %pc, %g7
83         set     1b, %g1
84         cmp     %g1, %g7
85         be,pn   %xcc, sparc64_boot_after_remap
86          mov    %o4, %l7
87
88         /* We need to remap the kernel.  Use position independant
89          * code to remap us to KERNBASE.
90          *
91          * SILO can invoke us with 32-bit address masking enabled,
92          * so make sure that's clear.
93          */
94         rdpr    %pstate, %g1
95         andn    %g1, PSTATE_AM, %g1
96         wrpr    %g1, 0x0, %pstate
97         ba,a,pt %xcc, 1f
98
99         .globl  prom_finddev_name, prom_chosen_path, prom_root_node
100         .globl  prom_getprop_name, prom_mmu_name, prom_peer_name
101         .globl  prom_callmethod_name, prom_translate_name, prom_root_compatible
102         .globl  prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
103         .globl  prom_boot_mapped_pc, prom_boot_mapping_mode
104         .globl  prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
105         .globl  is_sun4v
106 prom_peer_name:
107         .asciz  "peer"
108 prom_compatible_name:
109         .asciz  "compatible"
110 prom_finddev_name:
111         .asciz  "finddevice"
112 prom_chosen_path:
113         .asciz  "/chosen"
114 prom_getprop_name:
115         .asciz  "getprop"
116 prom_mmu_name:
117         .asciz  "mmu"
118 prom_callmethod_name:
119         .asciz  "call-method"
120 prom_translate_name:
121         .asciz  "translate"
122 prom_map_name:
123         .asciz  "map"
124 prom_unmap_name:
125         .asciz  "unmap"
126 prom_sun4v_name:
127         .asciz  "sun4v"
128         .align  4
129 prom_root_compatible:
130         .skip   64
131 prom_root_node:
132         .word   0
133 prom_mmu_ihandle_cache:
134         .word   0
135 prom_boot_mapped_pc:
136         .word   0
137 prom_boot_mapping_mode:
138         .word   0
139         .align  8
140 prom_boot_mapping_phys_high:
141         .xword  0
142 prom_boot_mapping_phys_low:
143         .xword  0
144 is_sun4v:
145         .word   0
146 1:
147         rd      %pc, %l0
148
149         mov     (1b - prom_peer_name), %l1
150         sub     %l0, %l1, %l1
151         mov     0, %l2
152
153         /* prom_root_node = prom_peer(0) */
154         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "peer"
155         mov     1, %l3
156         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 1
157         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
158         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1, 0
159         stx     %g0, [%sp + 2047 + 128 + 0x20]  ! ret1
160         call    %l7
161          add    %sp, (2047 + 128), %o0          ! argument array
162
163         ldx     [%sp + 2047 + 128 + 0x20], %l4  ! prom root node
164         mov     (1b - prom_root_node), %l1
165         sub     %l0, %l1, %l1
166         stw     %l4, [%l1]
167
168         mov     (1b - prom_getprop_name), %l1
169         mov     (1b - prom_compatible_name), %l2
170         mov     (1b - prom_root_compatible), %l5
171         sub     %l0, %l1, %l1
172         sub     %l0, %l2, %l2
173         sub     %l0, %l5, %l5
174
175         /* prom_getproperty(prom_root_node, "compatible",
176          *                  &prom_root_compatible, 64)
177          */
178         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "getprop"
179         mov     4, %l3
180         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 4
181         mov     1, %l3
182         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
183         stx     %l4, [%sp + 2047 + 128 + 0x18]  ! arg1, prom_root_node
184         stx     %l2, [%sp + 2047 + 128 + 0x20]  ! arg2, "compatible"
185         stx     %l5, [%sp + 2047 + 128 + 0x28]  ! arg3, &prom_root_compatible
186         mov     64, %l3
187         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4, size
188         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! ret1
189         call    %l7
190          add    %sp, (2047 + 128), %o0          ! argument array
191
192         mov     (1b - prom_finddev_name), %l1
193         mov     (1b - prom_chosen_path), %l2
194         mov     (1b - prom_boot_mapped_pc), %l3
195         sub     %l0, %l1, %l1
196         sub     %l0, %l2, %l2
197         sub     %l0, %l3, %l3
198         stw     %l0, [%l3]
199         sub     %sp, (192 + 128), %sp
200
201         /* chosen_node = prom_finddevice("/chosen") */
202         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "finddevice"
203         mov     1, %l3
204         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 1
205         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
206         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1, "/chosen"
207         stx     %g0, [%sp + 2047 + 128 + 0x20]  ! ret1
208         call    %l7
209          add    %sp, (2047 + 128), %o0          ! argument array
210
211         ldx     [%sp + 2047 + 128 + 0x20], %l4  ! chosen device node
212
213         mov     (1b - prom_getprop_name), %l1
214         mov     (1b - prom_mmu_name), %l2
215         mov     (1b - prom_mmu_ihandle_cache), %l5
216         sub     %l0, %l1, %l1
217         sub     %l0, %l2, %l2
218         sub     %l0, %l5, %l5
219
220         /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */
221         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "getprop"
222         mov     4, %l3
223         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 4
224         mov     1, %l3
225         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
226         stx     %l4, [%sp + 2047 + 128 + 0x18]  ! arg1, chosen_node
227         stx     %l2, [%sp + 2047 + 128 + 0x20]  ! arg2, "mmu"
228         stx     %l5, [%sp + 2047 + 128 + 0x28]  ! arg3, &prom_mmu_ihandle_cache
229         mov     4, %l3
230         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4, sizeof(arg3)
231         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! ret1
232         call    %l7
233          add    %sp, (2047 + 128), %o0          ! argument array
234
235         mov     (1b - prom_callmethod_name), %l1
236         mov     (1b - prom_translate_name), %l2
237         sub     %l0, %l1, %l1
238         sub     %l0, %l2, %l2
239         lduw    [%l5], %l5                      ! prom_mmu_ihandle_cache
240
241         stx     %l1, [%sp + 2047 + 128 + 0x00]  ! service, "call-method"
242         mov     3, %l3
243         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 3
244         mov     5, %l3
245         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 5
246         stx     %l2, [%sp + 2047 + 128 + 0x18]  ! arg1: "translate"
247         stx     %l5, [%sp + 2047 + 128 + 0x20]  ! arg2: prom_mmu_ihandle_cache
248         /* PAGE align */
249         srlx    %l0, 13, %l3
250         sllx    %l3, 13, %l3
251         stx     %l3, [%sp + 2047 + 128 + 0x28]  ! arg3: vaddr, our PC
252         stx     %g0, [%sp + 2047 + 128 + 0x30]  ! res1
253         stx     %g0, [%sp + 2047 + 128 + 0x38]  ! res2
254         stx     %g0, [%sp + 2047 + 128 + 0x40]  ! res3
255         stx     %g0, [%sp + 2047 + 128 + 0x48]  ! res4
256         stx     %g0, [%sp + 2047 + 128 + 0x50]  ! res5
257         call    %l7
258          add    %sp, (2047 + 128), %o0          ! argument array
259
260         ldx     [%sp + 2047 + 128 + 0x40], %l1  ! translation mode
261         mov     (1b - prom_boot_mapping_mode), %l4
262         sub     %l0, %l4, %l4
263         stw     %l1, [%l4]
264         mov     (1b - prom_boot_mapping_phys_high), %l4
265         sub     %l0, %l4, %l4
266         ldx     [%sp + 2047 + 128 + 0x48], %l2  ! physaddr high
267         stx     %l2, [%l4 + 0x0]
268         ldx     [%sp + 2047 + 128 + 0x50], %l3  ! physaddr low
269         /* 4MB align */
270         srlx    %l3, 22, %l3
271         sllx    %l3, 22, %l3
272         stx     %l3, [%l4 + 0x8]
273
274         /* Leave service as-is, "call-method" */
275         mov     7, %l3
276         stx     %l3, [%sp + 2047 + 128 + 0x08]  ! num_args, 7
277         mov     1, %l3
278         stx     %l3, [%sp + 2047 + 128 + 0x10]  ! num_rets, 1
279         mov     (1b - prom_map_name), %l3
280         sub     %l0, %l3, %l3
281         stx     %l3, [%sp + 2047 + 128 + 0x18]  ! arg1: "map"
282         /* Leave arg2 as-is, prom_mmu_ihandle_cache */
283         mov     -1, %l3
284         stx     %l3, [%sp + 2047 + 128 + 0x28]  ! arg3: mode (-1 default)
285         sethi   %hi(8 * 1024 * 1024), %l3
286         stx     %l3, [%sp + 2047 + 128 + 0x30]  ! arg4: size (8MB)
287         sethi   %hi(KERNBASE), %l3
288         stx     %l3, [%sp + 2047 + 128 + 0x38]  ! arg5: vaddr (KERNBASE)
289         stx     %g0, [%sp + 2047 + 128 + 0x40]  ! arg6: empty
290         mov     (1b - prom_boot_mapping_phys_low), %l3
291         sub     %l0, %l3, %l3
292         ldx     [%l3], %l3
293         stx     %l3, [%sp + 2047 + 128 + 0x48]  ! arg7: phys addr
294         call    %l7
295          add    %sp, (2047 + 128), %o0          ! argument array
296
297         add     %sp, (192 + 128), %sp
298
299 sparc64_boot_after_remap:
300         sethi   %hi(prom_root_compatible), %g1
301         or      %g1, %lo(prom_root_compatible), %g1
302         sethi   %hi(prom_sun4v_name), %g7
303         or      %g7, %lo(prom_sun4v_name), %g7
304         mov     5, %g3
305 1:      ldub    [%g7], %g2
306         ldub    [%g1], %g4
307         cmp     %g2, %g4
308         bne,pn  %icc, 2f
309          add    %g7, 1, %g7
310         subcc   %g3, 1, %g3
311         bne,pt  %xcc, 1b
312          add    %g1, 1, %g1
313
314         sethi   %hi(is_sun4v), %g1
315         or      %g1, %lo(is_sun4v), %g1
316         mov     1, %g7
317         stw     %g7, [%g1]
318
319 2:
320         BRANCH_IF_SUN4V(g1, jump_to_sun4u_init)
321         BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
322         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
323         ba,pt   %xcc, spitfire_boot
324          nop
325
326 cheetah_plus_boot:
327         /* Preserve OBP chosen DCU and DCR register settings.  */
328         ba,pt   %xcc, cheetah_generic_boot
329          nop
330
331 cheetah_boot:
332         mov     DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
333         wr      %g1, %asr18
334
335         sethi   %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7
336         or      %g7, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7
337         sllx    %g7, 32, %g7
338         or      %g7, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g7
339         stxa    %g7, [%g0] ASI_DCU_CONTROL_REG
340         membar  #Sync
341
342 cheetah_generic_boot:
343         mov     TSB_EXTENSION_P, %g3
344         stxa    %g0, [%g3] ASI_DMMU
345         stxa    %g0, [%g3] ASI_IMMU
346         membar  #Sync
347
348         mov     TSB_EXTENSION_S, %g3
349         stxa    %g0, [%g3] ASI_DMMU
350         membar  #Sync
351
352         mov     TSB_EXTENSION_N, %g3
353         stxa    %g0, [%g3] ASI_DMMU
354         stxa    %g0, [%g3] ASI_IMMU
355         membar  #Sync
356
357         ba,a,pt %xcc, jump_to_sun4u_init
358
359 spitfire_boot:
360         /* Typically PROM has already enabled both MMU's and both on-chip
361          * caches, but we do it here anyway just to be paranoid.
362          */
363         mov     (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1
364         stxa    %g1, [%g0] ASI_LSU_CONTROL
365         membar  #Sync
366
367 jump_to_sun4u_init:
368         /*
369          * Make sure we are in privileged mode, have address masking,
370          * using the ordinary globals and have enabled floating
371          * point.
372          *
373          * Again, typically PROM has left %pil at 13 or similar, and
374          * (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE) in %pstate.
375          */
376         wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
377         wr      %g0, 0, %fprs
378
379         set     sun4u_init, %g2
380         jmpl    %g2 + %g0, %g0
381          nop
382
383 sun4u_init:
384         BRANCH_IF_SUN4V(g1, sun4v_init)
385
386         /* Set ctx 0 */
387         mov             PRIMARY_CONTEXT, %g7
388         stxa            %g0, [%g7] ASI_DMMU
389         membar          #Sync
390
391         mov             SECONDARY_CONTEXT, %g7
392         stxa            %g0, [%g7] ASI_DMMU
393         membar  #Sync
394
395         ba,pt           %xcc, sun4u_continue
396          nop
397
398 sun4v_init:
399         /* Set ctx 0 */
400         mov             PRIMARY_CONTEXT, %g7
401         stxa            %g0, [%g7] ASI_MMU
402         membar          #Sync
403
404         mov             SECONDARY_CONTEXT, %g7
405         stxa            %g0, [%g7] ASI_MMU
406         membar          #Sync
407         ba,pt           %xcc, niagara_tlb_fixup
408          nop
409
410 sun4u_continue:
411         BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
412
413         ba,pt   %xcc, spitfire_tlb_fixup
414          nop
415
416 niagara_tlb_fixup:
417         mov     3, %g2          /* Set TLB type to hypervisor. */
418         sethi   %hi(tlb_type), %g1
419         stw     %g2, [%g1 + %lo(tlb_type)]
420
421         /* Patch copy/clear ops.  */
422         call    niagara_patch_copyops
423          nop
424         call    niagara_patch_bzero
425          nop
426         call    niagara_patch_pageops
427          nop
428
429         /* Patch TLB/cache ops.  */
430         call    hypervisor_patch_cachetlbops
431          nop
432
433         ba,pt   %xcc, tlb_fixup_done
434          nop
435
436 cheetah_tlb_fixup:
437         mov     2, %g2          /* Set TLB type to cheetah+. */
438         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
439
440         mov     1, %g2          /* Set TLB type to cheetah. */
441
442 1:      sethi   %hi(tlb_type), %g1
443         stw     %g2, [%g1 + %lo(tlb_type)]
444
445         /* Patch copy/page operations to cheetah optimized versions. */
446         call    cheetah_patch_copyops
447          nop
448         call    cheetah_patch_copy_page
449          nop
450         call    cheetah_patch_cachetlbops
451          nop
452
453         ba,pt   %xcc, tlb_fixup_done
454          nop
455
456 spitfire_tlb_fixup:
457         /* Set TLB type to spitfire. */
458         mov     0, %g2
459         sethi   %hi(tlb_type), %g1
460         stw     %g2, [%g1 + %lo(tlb_type)]
461
462 tlb_fixup_done:
463         sethi   %hi(init_thread_union), %g6
464         or      %g6, %lo(init_thread_union), %g6
465         ldx     [%g6 + TI_TASK], %g4
466         mov     %sp, %l6
467         mov     %o4, %l7
468
469         wr      %g0, ASI_P, %asi
470         mov     1, %g1
471         sllx    %g1, THREAD_SHIFT, %g1
472         sub     %g1, (STACKFRAME_SZ + STACK_BIAS), %g1
473         add     %g6, %g1, %sp
474         mov     0, %fp
475
476         /* Set per-cpu pointer initially to zero, this makes
477          * the boot-cpu use the in-kernel-image per-cpu areas
478          * before setup_per_cpu_area() is invoked.
479          */
480         clr     %g5
481
482         wrpr    %g0, 0, %wstate
483         wrpr    %g0, 0x0, %tl
484
485         /* Clear the bss */
486         sethi   %hi(__bss_start), %o0
487         or      %o0, %lo(__bss_start), %o0
488         sethi   %hi(_end), %o1
489         or      %o1, %lo(_end), %o1
490         call    __bzero
491          sub    %o1, %o0, %o1
492
493         mov     %l6, %o1                        ! OpenPROM stack
494         call    prom_init
495          mov    %l7, %o0                        ! OpenPROM cif handler
496
497         /* Initialize current_thread_info()->cpu as early as possible.
498          * In order to do that accurately we have to patch up the get_cpuid()
499          * assembler sequences.  And that, in turn, requires that we know
500          * if we are on a Starfire box or not.  While we're here, patch up
501          * the sun4v sequences as well.
502          */
503         call    check_if_starfire
504          nop
505         call    per_cpu_patch
506          nop
507         call    sun4v_patch
508          nop
509
510 #ifdef CONFIG_SMP
511         call    hard_smp_processor_id
512          nop
513         cmp     %o0, NR_CPUS
514         blu,pt  %xcc, 1f
515          nop
516         call    boot_cpu_id_too_large
517          nop
518         /* Not reached... */
519
520 1:
521 #else
522         mov     0, %o0
523 #endif
524         stb     %o0, [%g6 + TI_CPU]
525
526         /* Off we go.... */
527         call    start_kernel
528          nop
529         /* Not reached... */
530
531         /* This is meant to allow the sharing of this code between
532          * boot processor invocation (via setup_tba() below) and
533          * secondary processor startup (via trampoline.S).  The
534          * former does use this code, the latter does not yet due
535          * to some complexities.  That should be fixed up at some
536          * point.
537          *
538          * There used to be enormous complexity wrt. transferring
539          * over from the firwmare's trap table to the Linux kernel's.
540          * For example, there was a chicken & egg problem wrt. building
541          * the OBP page tables, yet needing to be on the Linux kernel
542          * trap table (to translate PAGE_OFFSET addresses) in order to
543          * do that.
544          *
545          * We now handle OBP tlb misses differently, via linear lookups
546          * into the prom_trans[] array.  So that specific problem no
547          * longer exists.  Yet, unfortunately there are still some issues
548          * preventing trampoline.S from using this code... ho hum.
549          */
550         .globl  setup_trap_table
551 setup_trap_table:
552         save    %sp, -192, %sp
553
554         /* Force interrupts to be disabled. */
555         rdpr    %pstate, %o1
556         andn    %o1, PSTATE_IE, %o1
557         wrpr    %o1, 0x0, %pstate
558         wrpr    %g0, 15, %pil
559
560         /* Make the firmware call to jump over to the Linux trap table.  */
561         sethi   %hi(is_sun4v), %o0
562         lduw    [%o0 + %lo(is_sun4v)], %o0
563         brz,pt  %o0, 1f
564          nop
565
566         TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
567         add     %g2, TRAP_PER_CPU_FAULT_INFO, %g2
568         stxa    %g2, [%g0] ASI_SCRATCHPAD
569
570         /* Compute physical address:
571          *
572          * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
573          */
574         sethi   %hi(KERNBASE), %g3
575         sub     %g2, %g3, %g2
576         sethi   %hi(kern_base), %g3
577         ldx     [%g3 + %lo(kern_base)], %g3
578         add     %g2, %g3, %o1
579
580         call    prom_set_trap_table_sun4v
581          sethi  %hi(sparc64_ttable_tl0), %o0
582
583         ba,pt   %xcc, 2f
584          nop
585
586 1:      call    prom_set_trap_table
587          sethi  %hi(sparc64_ttable_tl0), %o0
588
589         /* Start using proper page size encodings in ctx register.  */
590 2:      sethi   %hi(sparc64_kern_pri_context), %g3
591         ldx     [%g3 + %lo(sparc64_kern_pri_context)], %g2
592
593         mov             PRIMARY_CONTEXT, %g1
594
595 661:    stxa            %g2, [%g1] ASI_DMMU
596         .section        .sun4v_1insn_patch, "ax"
597         .word           661b
598         stxa            %g2, [%g1] ASI_MMU
599         .previous
600
601         membar  #Sync
602
603         /* Kill PROM timer */
604         sethi   %hi(0x80000000), %o2
605         sllx    %o2, 32, %o2
606         wr      %o2, 0, %tick_cmpr
607
608         BRANCH_IF_SUN4V(o2, 1f)
609         BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
610
611         ba,pt   %xcc, 2f
612          nop
613
614         /* Disable STICK_INT interrupts. */
615 1:
616         sethi   %hi(0x80000000), %o2
617         sllx    %o2, 32, %o2
618         wr      %o2, %asr25
619
620 2:
621         wrpr    %g0, %g0, %wstate
622
623         call    init_irqwork_curcpu
624          nop
625
626         /* Now we can turn interrupts back on. */
627         rdpr    %pstate, %o1
628         or      %o1, PSTATE_IE, %o1
629         wrpr    %o1, 0, %pstate
630         wrpr    %g0, 0x0, %pil
631
632         ret
633          restore
634
635         .globl  setup_tba
636 setup_tba:
637         save    %sp, -192, %sp
638
639         /* The boot processor is the only cpu which invokes this
640          * routine, the other cpus set things up via trampoline.S.
641          * So save the OBP trap table address here.
642          */
643         rdpr    %tba, %g7
644         sethi   %hi(prom_tba), %o1
645         or      %o1, %lo(prom_tba), %o1
646         stx     %g7, [%o1]
647
648         call    setup_trap_table
649          nop
650
651         ret
652          restore
653 sparc64_boot_end:
654
655 #include "ktlb.S"
656 #include "tsb.S"
657 #include "etrap.S"
658 #include "rtrap.S"
659 #include "winfixup.S"
660 #include "entry.S"
661 #include "sun4v_tlb_miss.S"
662 #include "sun4v_ivec.S"
663
664 /*
665  * The following skip makes sure the trap table in ttable.S is aligned
666  * on a 32K boundary as required by the v9 specs for TBA register.
667  *
668  * We align to a 32K boundary, then we have the 32K kernel TSB,
669  * then the 32K aligned trap table.
670  */
671 1:
672         .skip   0x4000 + _start - 1b
673
674         .globl  swapper_tsb
675 swapper_tsb:
676         .skip   (32 * 1024)
677
678 ! 0x0000000000408000
679
680 #include "ttable.S"
681
682 #include "systbls.S"
683
684         .data
685         .align  8
686         .globl  prom_tba, tlb_type
687 prom_tba:       .xword  0
688 tlb_type:       .word   0       /* Must NOT end up in BSS */
689         .section        ".fixup",#alloc,#execinstr
690
691         .globl  __ret_efault, __retl_efault
692 __ret_efault:
693         ret
694          restore %g0, -EFAULT, %o0
695 __retl_efault:
696         retl
697          mov    -EFAULT, %o0