[POWERPC] Move iSeries startup code out of head_64.S
[safe/jmp/linux-2.6] / arch / powerpc / platforms / iseries / exception.S
1 /*
2  *  Low level routines for legacy iSeries support.
3  *
4  *  Extracted from head_64.S
5  *
6  *  PowerPC version
7  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8  *
9  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
10  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
11  *  Adapted for Power Macintosh by Paul Mackerras.
12  *  Low-level exception handlers and MMU support
13  *  rewritten by Paul Mackerras.
14  *    Copyright (C) 1996 Paul Mackerras.
15  *
16  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
17  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
18  *
19  *  This file contains the low-level support and setup for the
20  *  PowerPC-64 platform, including trap and interrupt dispatch.
21  *
22  *  This program is free software; you can redistribute it and/or
23  *  modify it under the terms of the GNU General Public License
24  *  as published by the Free Software Foundation; either version
25  *  2 of the License, or (at your option) any later version.
26  */
27
28 #include <asm/reg.h>
29 #include <asm/ppc_asm.h>
30 #include <asm/asm-offsets.h>
31 #include <asm/thread_info.h>
32 #include <asm/ptrace.h>
33
34         .text
35
36         .globl system_reset_iSeries
37 system_reset_iSeries:
38         mfspr   r13,SPRN_SPRG3          /* Get paca address */
39         mfmsr   r24
40         ori     r24,r24,MSR_RI
41         mtmsrd  r24                     /* RI on */
42         lhz     r24,PACAPACAINDEX(r13)  /* Get processor # */
43         cmpwi   0,r24,0                 /* Are we processor 0? */
44         bne     1f
45         b       .__start_initialization_iSeries /* Start up the first processor */
46 1:      mfspr   r4,SPRN_CTRLF
47         li      r5,CTRL_RUNLATCH        /* Turn off the run light */
48         andc    r4,r4,r5
49         mtspr   SPRN_CTRLT,r4
50
51 1:
52         HMT_LOW
53 #ifdef CONFIG_SMP
54         lbz     r23,PACAPROCSTART(r13)  /* Test if this processor
55                                          * should start */
56         sync
57         LOAD_REG_IMMEDIATE(r3,current_set)
58         sldi    r28,r24,3               /* get current_set[cpu#] */
59         ldx     r3,r3,r28
60         addi    r1,r3,THREAD_SIZE
61         subi    r1,r1,STACK_FRAME_OVERHEAD
62
63         cmpwi   0,r23,0
64         beq     iSeries_secondary_smp_loop      /* Loop until told to go */
65         b       __secondary_start               /* Loop until told to go */
66 iSeries_secondary_smp_loop:
67         /* Let the Hypervisor know we are alive */
68         /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
69         lis     r3,0x8002
70         rldicr  r3,r3,32,15             /* r0 = (r3 << 32) & 0xffff000000000000 */
71 #else /* CONFIG_SMP */
72         /* Yield the processor.  This is required for non-SMP kernels
73                 which are running on multi-threaded machines. */
74         lis     r3,0x8000
75         rldicr  r3,r3,32,15             /* r3 = (r3 << 32) & 0xffff000000000000 */
76         addi    r3,r3,18                /* r3 = 0x8000000000000012 which is "yield" */
77         li      r4,0                    /* "yield timed" */
78         li      r5,-1                   /* "yield forever" */
79 #endif /* CONFIG_SMP */
80         li      r0,-1                   /* r0=-1 indicates a Hypervisor call */
81         sc                              /* Invoke the hypervisor via a system call */
82         mfspr   r13,SPRN_SPRG3          /* Put r13 back ???? */
83         b       1b                      /* If SMP not configured, secondaries
84                                          * loop forever */
85
86 _INIT_STATIC(__start_initialization_iSeries)
87         /* Clear out the BSS */
88         LOAD_REG_IMMEDIATE(r11,__bss_stop)
89         LOAD_REG_IMMEDIATE(r8,__bss_start)
90         sub     r11,r11,r8              /* bss size                     */
91         addi    r11,r11,7               /* round up to an even double word */
92         rldicl. r11,r11,61,3            /* shift right by 3             */
93         beq     4f
94         addi    r8,r8,-8
95         li      r0,0
96         mtctr   r11                     /* zero this many doublewords   */
97 3:      stdu    r0,8(r8)
98         bdnz    3b
99 4:
100         LOAD_REG_IMMEDIATE(r1,init_thread_union)
101         addi    r1,r1,THREAD_SIZE
102         li      r0,0
103         stdu    r0,-STACK_FRAME_OVERHEAD(r1)
104
105         LOAD_REG_IMMEDIATE(r2,__toc_start)
106         addi    r2,r2,0x4000
107         addi    r2,r2,0x4000
108
109         bl      .iSeries_early_setup
110         bl      .early_setup
111
112         /* relocation is on at this point */
113
114         b       .start_here_common