ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / 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 <asm/thread_info.h>
14 #include <asm/asi.h>
15 #include <asm/pstate.h>
16 #include <asm/ptrace.h>
17 #include <asm/spitfire.h>
18 #include <asm/page.h>
19 #include <asm/pgtable.h>
20 #include <asm/errno.h>
21 #include <asm/signal.h>
22 #include <asm/processor.h>
23 #include <asm/lsu.h>
24 #include <asm/dcr.h>
25 #include <asm/dcu.h>
26 #include <asm/head.h>
27 #include <asm/ttable.h>
28         
29 /* This section from from _start to sparc64_boot_end should fit into
30  * 0x0000.0000.0040.4000 to 0x0000.0000.0040.8000 and will be sharing space
31  * with bootup_user_stack, which is from 0x0000.0000.0040.4000 to
32  * 0x0000.0000.0040.6000 and empty_bad_page, which is from
33  * 0x0000.0000.0040.6000 to 0x0000.0000.0040.8000. 
34  */
35
36         .text
37         .globl  start, _start, stext, _stext
38 _start:
39 start:
40 _stext:
41 stext:
42 bootup_user_stack:
43 ! 0x0000000000404000
44         b       sparc64_boot
45          flushw                                 /* Flush register file.      */
46
47 /* This stuff has to be in sync with SILO and other potential boot loaders
48  * Fields should be kept upward compatible and whenever any change is made,
49  * HdrS version should be incremented.
50  */
51         .global root_flags, ram_flags, root_dev
52         .global sparc_ramdisk_image, sparc_ramdisk_size
53         .globl  silo_args
54
55         .ascii  "HdrS"
56         .word   LINUX_VERSION_CODE
57
58         /* History:
59          *
60          * 0x0300 : Supports being located at other than 0x4000
61          * 0x0202 : Supports kernel params string
62          * 0x0201 : Supports reboot_command
63          */
64         .half   0x0300          /* HdrS version */
65
66 root_flags:
67         .half   1
68 root_dev:
69         .half   0
70 ram_flags:
71         .half   0
72 sparc_ramdisk_image:
73         .word   0
74 sparc_ramdisk_size:
75         .word   0
76         .xword  reboot_command
77         .xword  bootstr_info
78         .word   _end
79
80         /* We must be careful, 32-bit OpenBOOT will get confused if it
81          * tries to save away a register window to a 64-bit kernel
82          * stack address.  Flush all windows, disable interrupts,
83          * remap if necessary, jump onto kernel trap table, then kernel
84          * stack, or else we die.
85          *
86          * PROM entry point is on %o4
87          */
88 sparc64_boot:
89         BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_boot)
90         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_boot)
91         ba,pt   %xcc, spitfire_boot
92          nop
93
94 cheetah_plus_boot:
95         /* Preserve OBP chosen DCU and DCR register settings.  */
96         ba,pt   %xcc, cheetah_generic_boot
97          nop
98
99 cheetah_boot:
100         mov     DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
101         wr      %g1, %asr18
102
103         sethi   %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
104         or      %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
105         sllx    %g5, 32, %g5
106         or      %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
107         stxa    %g5, [%g0] ASI_DCU_CONTROL_REG
108         membar  #Sync
109
110 cheetah_generic_boot:
111         mov     TSB_EXTENSION_P, %g3
112         stxa    %g0, [%g3] ASI_DMMU
113         stxa    %g0, [%g3] ASI_IMMU
114         membar  #Sync
115
116         mov     TSB_EXTENSION_S, %g3
117         stxa    %g0, [%g3] ASI_DMMU
118         membar  #Sync
119
120         mov     TSB_EXTENSION_N, %g3
121         stxa    %g0, [%g3] ASI_DMMU
122         stxa    %g0, [%g3] ASI_IMMU
123         membar  #Sync
124
125         wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
126         wr      %g0, 0, %fprs
127
128         /* Just like for Spitfire, we probe itlb-2 for a mapping which
129          * matches our current %pc.  We take the physical address in
130          * that mapping and use it to make our own.
131          */
132
133         /* %g5 holds the tlb data */
134         sethi   %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
135         sllx    %g5, 32, %g5
136         or      %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
137
138         /* Put PADDR tlb data mask into %g3. */
139         sethi   %uhi(_PAGE_PADDR), %g3
140         or      %g3, %ulo(_PAGE_PADDR), %g3
141         sllx    %g3, 32, %g3
142         sethi   %hi(_PAGE_PADDR), %g7
143         or      %g7, %lo(_PAGE_PADDR), %g7
144         or      %g3, %g7, %g3
145
146         set     2 << 16, %l0            /* TLB entry walker. */
147         set     0x1fff, %l2             /* Page mask. */
148         rd      %pc, %l3
149         andn    %l3, %l2, %g2           /* vaddr comparator */
150
151 1:      ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
152         membar  #Sync
153         andn    %g1, %l2, %g1
154         cmp     %g1, %g2
155         be,pn   %xcc, cheetah_got_tlbentry
156          nop
157         and     %l0, (127 << 3), %g1
158         cmp     %g1, (127 << 3)
159         blu,pt  %xcc, 1b
160          add    %l0, (1 << 3), %l0
161
162         /* Search the small TLB.  OBP never maps us like that but
163          * newer SILO can.
164          */
165         clr     %l0
166
167 1:      ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
168         membar  #Sync
169         andn    %g1, %l2, %g1
170         cmp     %g1, %g2
171         be,pn   %xcc, cheetah_got_tlbentry
172          nop
173         cmp     %l0, (15 << 3)
174         blu,pt  %xcc, 1b
175          add    %l0, (1 << 3), %l0
176
177         /* BUG() if we get here... */
178         ta      0x5
179
180 cheetah_got_tlbentry:
181         ldxa    [%l0] ASI_ITLB_DATA_ACCESS, %g0
182         ldxa    [%l0] ASI_ITLB_DATA_ACCESS, %g1
183         membar  #Sync
184         and     %g1, %g3, %g1
185         set     0x5fff, %l0
186         andn    %g1, %l0, %g1
187         or      %g5, %g1, %g5
188
189         /* Clear out any KERNBASE area entries. */
190         set     2 << 16, %l0
191         sethi   %hi(KERNBASE), %g3
192         sethi   %hi(KERNBASE<<1), %g7
193         mov     TLB_TAG_ACCESS, %l7
194
195         /* First, check ITLB */
196 1:      ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
197         membar  #Sync
198         andn    %g1, %l2, %g1
199         cmp     %g1, %g3
200         blu,pn  %xcc, 2f
201          cmp    %g1, %g7
202         bgeu,pn %xcc, 2f
203          nop
204         stxa    %g0, [%l7] ASI_IMMU
205         membar  #Sync
206         stxa    %g0, [%l0] ASI_ITLB_DATA_ACCESS
207         membar  #Sync
208
209 2:      and     %l0, (127 << 3), %g1
210         cmp     %g1, (127 << 3)
211         blu,pt  %xcc, 1b
212          add    %l0, (1 << 3), %l0
213
214         /* Next, check DTLB */
215         set     2 << 16, %l0
216 1:      ldxa    [%l0] ASI_DTLB_TAG_READ, %g1
217         membar  #Sync
218         andn    %g1, %l2, %g1
219         cmp     %g1, %g3
220         blu,pn  %xcc, 2f
221          cmp    %g1, %g7
222         bgeu,pn %xcc, 2f
223          nop
224         stxa    %g0, [%l7] ASI_DMMU
225         membar  #Sync
226         stxa    %g0, [%l0] ASI_DTLB_DATA_ACCESS
227         membar  #Sync
228         
229 2:      and     %l0, (511 << 3), %g1
230         cmp     %g1, (511 << 3)
231         blu,pt  %xcc, 1b
232          add    %l0, (1 << 3), %l0
233
234         /* On Cheetah+, have to check second DTLB.  */
235         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f)
236         ba,pt   %xcc, 9f
237          nop
238
239 2:      set     3 << 16, %l0
240 1:      ldxa    [%l0] ASI_DTLB_TAG_READ, %g1
241         membar  #Sync
242         andn    %g1, %l2, %g1
243         cmp     %g1, %g3
244         blu,pn  %xcc, 2f
245          cmp    %g1, %g7
246         bgeu,pn %xcc, 2f
247          nop
248         stxa    %g0, [%l7] ASI_DMMU
249         membar  #Sync
250         stxa    %g0, [%l0] ASI_DTLB_DATA_ACCESS
251         membar  #Sync
252         
253 2:      and     %l0, (511 << 3), %g1
254         cmp     %g1, (511 << 3)
255         blu,pt  %xcc, 1b
256          add    %l0, (1 << 3), %l0
257
258 9:
259
260         /* Now lock the TTE we created into ITLB-0 and DTLB-0,
261          * entry 15 (and maybe 14 too).
262          */
263         sethi   %hi(KERNBASE), %g3
264         set     (0 << 16) | (15 << 3), %g7
265         stxa    %g3, [%l7] ASI_DMMU
266         membar  #Sync
267         stxa    %g5, [%g7] ASI_DTLB_DATA_ACCESS
268         membar  #Sync
269         stxa    %g3, [%l7] ASI_IMMU
270         membar  #Sync
271         stxa    %g5, [%g7] ASI_ITLB_DATA_ACCESS
272         membar  #Sync
273         flush   %g3
274         membar  #Sync
275         sethi   %hi(_end), %g3                  /* Check for bigkernel case */
276         or      %g3, %lo(_end), %g3
277         srl     %g3, 23, %g3                    /* Check if _end > 8M */
278         brz,pt  %g3, 1f
279          sethi  %hi(KERNBASE), %g3              /* Restore for fixup code below */
280         sethi   %hi(0x400000), %g3
281         or      %g3, %lo(0x400000), %g3
282         add     %g5, %g3, %g5                   /* New tte data */
283         andn    %g5, (_PAGE_G), %g5
284         sethi   %hi(KERNBASE+0x400000), %g3
285         or      %g3, %lo(KERNBASE+0x400000), %g3
286         set     (0 << 16) | (14 << 3), %g7
287         stxa    %g3, [%l7] ASI_DMMU
288         membar  #Sync
289         stxa    %g5, [%g7] ASI_DTLB_DATA_ACCESS
290         membar  #Sync
291         stxa    %g3, [%l7] ASI_IMMU
292         membar  #Sync
293         stxa    %g5, [%g7] ASI_ITLB_DATA_ACCESS
294         membar  #Sync
295         flush   %g3
296         membar  #Sync
297         sethi   %hi(KERNBASE), %g3              /* Restore for fixup code below */
298         ba,pt   %xcc, 1f
299          nop
300
301 1:      set     sun4u_init, %g2
302         jmpl    %g2 + %g0, %g0
303          nop
304
305 spitfire_boot:
306         /* Typically PROM has already enabled both MMU's and both on-chip
307          * caches, but we do it here anyway just to be paranoid.
308          */
309         mov     (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1
310         stxa    %g1, [%g0] ASI_LSU_CONTROL
311         membar  #Sync
312
313         /*
314          * Make sure we are in privileged mode, have address masking,
315          * using the ordinary globals and have enabled floating
316          * point.
317          *
318          * Again, typically PROM has left %pil at 13 or similar, and
319          * (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE) in %pstate.
320          */
321         wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
322         wr      %g0, 0, %fprs
323
324 spitfire_create_mappings:
325         /* %g5 holds the tlb data */
326         sethi   %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
327         sllx    %g5, 32, %g5
328         or      %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
329
330         /* Base of physical memory cannot reliably be assumed to be
331          * at 0x0!  Figure out where it happens to be. -DaveM
332          */
333
334         /* Put PADDR tlb data mask into %g3. */
335         sethi   %uhi(_PAGE_PADDR_SF), %g3
336         or      %g3, %ulo(_PAGE_PADDR_SF), %g3
337         sllx    %g3, 32, %g3
338         sethi   %hi(_PAGE_PADDR_SF), %g7
339         or      %g7, %lo(_PAGE_PADDR_SF), %g7
340         or      %g3, %g7, %g3
341
342         /* Walk through entire ITLB, looking for entry which maps
343          * our %pc currently, stick PADDR from there into %g5 tlb data.
344          */
345         clr     %l0                     /* TLB entry walker. */
346         set     0x1fff, %l2             /* Page mask. */
347         rd      %pc, %l3
348         andn    %l3, %l2, %g2           /* vaddr comparator */
349 1:
350         /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
351         ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
352         nop
353         nop
354         nop
355         andn    %g1, %l2, %g1           /* Get vaddr */
356         cmp     %g1, %g2
357         be,a,pn %xcc, spitfire_got_tlbentry
358          ldxa   [%l0] ASI_ITLB_DATA_ACCESS, %g1
359         cmp     %l0, (63 << 3)
360         blu,pt  %xcc, 1b
361          add    %l0, (1 << 3), %l0
362
363         /* BUG() if we get here... */
364         ta      0x5
365
366 spitfire_got_tlbentry:
367         /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */
368         nop
369         nop
370         nop
371         and     %g1, %g3, %g1           /* Mask to just get paddr bits.       */
372         set     0x5fff, %l3             /* Mask offset to get phys base.      */
373         andn    %g1, %l3, %g1
374
375         /* NOTE: We hold on to %g1 paddr base as we need it below to lock
376          * NOTE: the PROM cif code into the TLB.
377          */
378
379         or      %g5, %g1, %g5           /* Or it into TAG being built.        */
380
381         clr     %l0                     /* TLB entry walker. */
382         sethi   %hi(KERNBASE), %g3      /* 4M lower limit */
383         sethi   %hi(KERNBASE<<1), %g7   /* 8M upper limit */
384         mov     TLB_TAG_ACCESS, %l7
385 1:
386         /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
387         ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
388         nop
389         nop
390         nop
391         andn    %g1, %l2, %g1           /* Get vaddr */
392         cmp     %g1, %g3
393         blu,pn  %xcc, 2f
394          cmp    %g1, %g7
395         bgeu,pn %xcc, 2f
396          nop
397         stxa    %g0, [%l7] ASI_IMMU
398         stxa    %g0, [%l0] ASI_ITLB_DATA_ACCESS
399         membar  #Sync
400 2:
401         cmp     %l0, (63 << 3)
402         blu,pt  %xcc, 1b
403          add    %l0, (1 << 3), %l0
404
405         nop; nop; nop
406
407         clr     %l0                     /* TLB entry walker. */
408 1:
409         /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
410         ldxa    [%l0] ASI_DTLB_TAG_READ, %g1
411         nop
412         nop
413         nop
414         andn    %g1, %l2, %g1           /* Get vaddr */
415         cmp     %g1, %g3
416         blu,pn  %xcc, 2f
417          cmp    %g1, %g7
418         bgeu,pn %xcc, 2f
419          nop
420         stxa    %g0, [%l7] ASI_DMMU
421         stxa    %g0, [%l0] ASI_DTLB_DATA_ACCESS
422         membar  #Sync
423 2:
424         cmp     %l0, (63 << 3)
425         blu,pt  %xcc, 1b
426          add    %l0, (1 << 3), %l0
427
428         nop; nop; nop
429
430
431         /* PROM never puts any TLB entries into the MMU with the lock bit
432          * set.  So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too.
433          */
434
435         sethi   %hi(KERNBASE), %g3
436         mov     (63 << 3), %g7
437         stxa    %g3, [%l7] ASI_DMMU             /* KERNBASE into TLB TAG        */
438         stxa    %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA            */
439         membar  #Sync
440         stxa    %g3, [%l7] ASI_IMMU             /* KERNBASE into TLB TAG        */
441         stxa    %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA            */
442         membar  #Sync
443         flush   %g3
444         membar  #Sync
445         sethi   %hi(_end), %g3                  /* Check for bigkernel case */
446         or      %g3, %lo(_end), %g3
447         srl     %g3, 23, %g3                    /* Check if _end > 8M */
448         brz,pt  %g3, 2f
449          sethi  %hi(KERNBASE), %g3              /* Restore for fixup code below */
450         sethi   %hi(0x400000), %g3
451         or      %g3, %lo(0x400000), %g3
452         add     %g5, %g3, %g5                   /* New tte data */
453         andn    %g5, (_PAGE_G), %g5
454         sethi   %hi(KERNBASE+0x400000), %g3
455         or      %g3, %lo(KERNBASE+0x400000), %g3
456         mov     (62 << 3), %g7
457         stxa    %g3, [%l7] ASI_DMMU
458         stxa    %g5, [%g7] ASI_DTLB_DATA_ACCESS
459         membar  #Sync
460         stxa    %g3, [%l7] ASI_IMMU
461         stxa    %g5, [%g7] ASI_ITLB_DATA_ACCESS
462         membar  #Sync
463         flush   %g3
464         membar  #Sync
465         sethi   %hi(KERNBASE), %g3              /* Restore for fixup code below */
466 2:      ba,pt   %xcc, 1f
467          nop
468 1:
469         set     sun4u_init, %g2
470         jmpl    %g2 + %g0, %g0
471          nop
472
473 sun4u_init:
474         /* Set ctx 0 */
475         mov     PRIMARY_CONTEXT, %g7
476         stxa    %g0, [%g7] ASI_DMMU
477         membar  #Sync
478
479         mov     SECONDARY_CONTEXT, %g7
480         stxa    %g0, [%g7] ASI_DMMU
481         membar  #Sync
482
483         /* We are now safely (we hope) in Nucleus context (0), rewrite
484          * the KERNBASE TTE's so they no longer have the global bit set.
485          * Don't forget to setup TAG_ACCESS first 8-)
486          */
487         mov     TLB_TAG_ACCESS, %g2
488         stxa    %g3, [%g2] ASI_IMMU
489         stxa    %g3, [%g2] ASI_DMMU
490         membar  #Sync
491
492         BRANCH_IF_ANY_CHEETAH(g1,g5,cheetah_tlb_fixup)
493
494         ba,pt   %xcc, spitfire_tlb_fixup
495          nop
496
497 cheetah_tlb_fixup:
498         set     (0 << 16) | (15 << 3), %g7
499         ldxa    [%g7] ASI_ITLB_DATA_ACCESS, %g0
500         ldxa    [%g7] ASI_ITLB_DATA_ACCESS, %g1
501         andn    %g1, (_PAGE_G), %g1
502         stxa    %g1, [%g7] ASI_ITLB_DATA_ACCESS
503         membar  #Sync
504
505         ldxa    [%g7] ASI_DTLB_DATA_ACCESS, %g0
506         ldxa    [%g7] ASI_DTLB_DATA_ACCESS, %g1
507         andn    %g1, (_PAGE_G), %g1
508         stxa    %g1, [%g7] ASI_DTLB_DATA_ACCESS
509         membar  #Sync
510
511         /* Kill instruction prefetch queues. */
512         flush   %g3
513         membar  #Sync
514
515         mov     2, %g2          /* Set TLB type to cheetah+. */
516         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g5,g7,1f)
517
518         mov     1, %g2          /* Set TLB type to cheetah. */
519
520 1:      sethi   %hi(tlb_type), %g5
521         stw     %g2, [%g5 + %lo(tlb_type)]
522
523         /* Patch copy/page operations to cheetah optimized versions. */
524         call    cheetah_patch_copyops
525          nop
526         call    cheetah_patch_pgcopyops
527          nop
528         call    cheetah_patch_cachetlbops
529          nop
530
531         ba,pt   %xcc, tlb_fixup_done
532          nop
533
534 spitfire_tlb_fixup:
535         mov     (63 << 3), %g7
536         ldxa    [%g7] ASI_ITLB_DATA_ACCESS, %g1
537         andn    %g1, (_PAGE_G), %g1
538         stxa    %g1, [%g7] ASI_ITLB_DATA_ACCESS
539         membar  #Sync
540
541         ldxa    [%g7] ASI_DTLB_DATA_ACCESS, %g1
542         andn    %g1, (_PAGE_G), %g1
543         stxa    %g1, [%g7] ASI_DTLB_DATA_ACCESS
544         membar  #Sync
545
546         /* Kill instruction prefetch queues. */
547         flush   %g3
548         membar  #Sync
549
550         /* Set TLB type to spitfire. */
551         mov     0, %g2
552         sethi   %hi(tlb_type), %g5
553         stw     %g2, [%g5 + %lo(tlb_type)]
554
555 tlb_fixup_done:
556         sethi   %hi(init_thread_union), %g6
557         or      %g6, %lo(init_thread_union), %g6
558         ldx     [%g6 + TI_TASK], %g4
559         mov     %sp, %l6
560         mov     %o4, %l7
561
562 #if 0   /* We don't do it like this anymore, but for historical hack value
563          * I leave this snippet here to show how crazy we can be sometimes. 8-)
564          */
565
566         /* Setup "Linux Current Register", thanks Sun 8-) */
567         wr      %g0, 0x1, %pcr
568
569         /* Blackbird errata workaround.  See commentary in
570          * smp.c:smp_percpu_timer_interrupt() for more
571          * information.
572          */
573         ba,pt   %xcc, 99f
574          nop
575         .align  64
576 99:     wr      %g6, %g0, %pic
577         rd      %pic, %g0
578 #endif
579
580         wr      %g0, ASI_P, %asi
581         mov     1, %g5
582         sllx    %g5, THREAD_SHIFT, %g5
583         sub     %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
584         add     %g6, %g5, %sp
585         mov     0, %fp
586
587         wrpr    %g0, 0, %wstate
588         wrpr    %g0, 0x0, %tl
589
590         /* Clear the bss */
591         sethi   %hi(__bss_start), %o0
592         or      %o0, %lo(__bss_start), %o0
593         sethi   %hi(_end), %o1
594         or      %o1, %lo(_end), %o1
595         call    __bzero
596          sub    %o1, %o0, %o1
597
598         mov     %l6, %o1                        ! OpenPROM stack
599         call    prom_init
600          mov    %l7, %o0                        ! OpenPROM cif handler
601
602         /* Off we go.... */
603         call    start_kernel
604          nop
605         /* Not reached... */
606
607 /* IMPORTANT NOTE: Whenever making changes here, check
608  * trampoline.S as well. -jj */
609         .globl  setup_tba
610 setup_tba:      /* i0 = is_starfire */
611         save    %sp, -160, %sp
612
613         rdpr    %tba, %g7
614         sethi   %hi(prom_tba), %o1
615         or      %o1, %lo(prom_tba), %o1
616         stx     %g7, [%o1]
617
618         /* Setup "Linux" globals 8-) */
619         rdpr    %pstate, %o1
620         mov     %g6, %o2
621         wrpr    %o1, (PSTATE_AG|PSTATE_IE), %pstate
622         sethi   %hi(sparc64_ttable_tl0), %g5
623         wrpr    %g5, %tba
624         mov     %o2, %g6
625
626         /* Set up MMU globals */
627         wrpr    %o1, (PSTATE_MG|PSTATE_IE), %pstate
628
629         /* Set fixed globals used by dTLB miss handler. */
630 #define KERN_HIGHBITS           ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
631 #define KERN_LOWBITS            (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
632
633         mov     TSB_REG, %g1
634         stxa    %g0, [%g1] ASI_DMMU
635         membar  #Sync
636         mov     TLB_SFSR, %g1
637         sethi   %uhi(KERN_HIGHBITS), %g2
638         or      %g2, %ulo(KERN_HIGHBITS), %g2
639         sllx    %g2, 32, %g2
640         or      %g2, KERN_LOWBITS, %g2
641
642         BRANCH_IF_ANY_CHEETAH(g3,g7,cheetah_vpte_base)
643         ba,pt   %xcc, spitfire_vpte_base
644          nop
645
646 cheetah_vpte_base:
647         sethi           %uhi(VPTE_BASE_CHEETAH), %g3
648         or              %g3, %ulo(VPTE_BASE_CHEETAH), %g3
649         ba,pt           %xcc, 2f
650          sllx           %g3, 32, %g3
651
652 spitfire_vpte_base:
653         sethi           %uhi(VPTE_BASE_SPITFIRE), %g3
654         or              %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
655         sllx            %g3, 32, %g3
656
657 2:
658         clr     %g7
659 #undef KERN_HIGHBITS
660 #undef KERN_LOWBITS
661
662         /* Kill PROM timer */
663         sethi   %hi(0x80000000), %o2
664         sllx    %o2, 32, %o2
665         wr      %o2, 0, %tick_cmpr
666
667         BRANCH_IF_ANY_CHEETAH(o2,o3,1f)
668
669         ba,pt   %xcc, 2f
670          nop
671
672         /* Disable STICK_INT interrupts. */
673 1:
674         sethi   %hi(0x80000000), %o2
675         sllx    %o2, 32, %o2
676         wr      %o2, %asr25
677
678         /* Ok, we're done setting up all the state our trap mechanims needs,
679          * now get back into normal globals and let the PROM know what is up.
680          */
681 2:
682         wrpr    %g0, %g0, %wstate
683         wrpr    %o1, PSTATE_IE, %pstate
684
685         call    init_irqwork_curcpu
686          nop
687
688         sethi   %hi(sparc64_ttable_tl0), %g5
689         call    prom_set_trap_table
690          mov    %g5, %o0
691
692         rdpr    %pstate, %o1
693         or      %o1, PSTATE_IE, %o1
694         wrpr    %o1, 0, %pstate
695
696         ret
697          restore
698
699 /*
700  * The following skips make sure the trap table in ttable.S is aligned
701  * on a 32K boundary as required by the v9 specs for TBA register.
702  */
703 sparc64_boot_end:
704         .skip   0x2000 + _start - sparc64_boot_end
705 bootup_user_stack_end:
706         .skip   0x2000
707
708 #ifdef CONFIG_SBUS
709 /* This is just a hack to fool make depend config.h discovering
710    strategy: As the .S files below need config.h, but
711    make depend does not find it for them, we include config.h
712    in head.S */
713 #endif
714
715 ! 0x0000000000408000
716
717 #include "ttable.S"
718 #include "systbls.S"
719
720         .align  1024
721         .globl  swapper_pg_dir
722 swapper_pg_dir:
723         .word   0
724
725 #include "etrap.S"
726 #include "rtrap.S"
727 #include "winfixup.S"
728 #include "entry.S"
729
730         /* This is just anal retentiveness on my part... */
731         .align  16384
732
733         .data
734         .align  8
735         .globl  prom_tba, tlb_type
736 prom_tba:       .xword  0
737 tlb_type:       .word   0       /* Must NOT end up in BSS */
738         .section        ".fixup",#alloc,#execinstr
739         .globl  __ret_efault
740 __ret_efault:
741         ret
742          restore %g0, -EFAULT, %o0
743