Merge remote branch 'nouveau/for-airlied' into drm-linus
[pandora-kernel.git] / arch / s390 / kernel / head64.S
1 /*
2  * arch/s390/kernel/head64.S
3  *
4  * Copyright (C) IBM Corp. 1999,2006
5  *
6  *   Author(s): Hartmut Penner <hp@de.ibm.com>
7  *              Martin Schwidefsky <schwidefsky@de.ibm.com>
8  *              Rob van der Heij <rvdhei@iae.nl>
9  *              Heiko Carstens <heiko.carstens@de.ibm.com>
10  *
11  */
12
13         .org    0x11000
14
15 startup_continue:
16         basr    %r13,0                  # get base
17 .LPG1:  sll     %r13,1                  # remove high order bit
18         srl     %r13,1
19
20 #ifdef CONFIG_ZFCPDUMP
21
22         # check if we have been ipled using zfcp dump:
23
24         tm      0xb9,0x01               # test if subchannel is enabled
25         jno     .nodump                 # subchannel disabled
26         l       %r1,0xb8
27         la      %r5,.Lipl_schib-.LPG1(%r13)
28         stsch   0(%r5)                  # get schib of subchannel
29         jne     .nodump                 # schib not available
30         tm      5(%r5),0x01             # devno valid?
31         jno     .nodump
32         tm      4(%r5),0x80             # qdio capable device?
33         jno     .nodump
34         l       %r2,20(%r0)             # address of ipl parameter block
35         lhi     %r3,0
36         ic      %r3,0x148(%r2)          # get opt field
37         chi     %r3,0x20                # load with dump?
38         jne     .nodump
39
40         # store all prefix registers in case of load with dump:
41
42         la      %r7,0                   # base register for 0 page
43         la      %r8,0                   # first cpu
44         l       %r11,.Lpref_arr_ptr-.LPG1(%r13) # address of prefix array
45         ahi     %r11,4                  # skip boot cpu
46         lr      %r12,%r11
47         ahi     %r12,(CONFIG_NR_CPUS*4) # end of prefix array
48         stap    .Lcurrent_cpu+2-.LPG1(%r13)     # store current cpu addr
49 1:
50         cl      %r8,.Lcurrent_cpu-.LPG1(%r13)   # is ipl cpu ?
51         je      4f                              # if yes get next cpu
52 2:
53         lr      %r9,%r7
54         sigp    %r9,%r8,0x9             # stop & store status of cpu
55         brc     8,3f                    # accepted
56         brc     4,4f                    # status stored: next cpu
57         brc     2,2b                    # busy:          try again
58         brc     1,4f                    # not op:        next cpu
59 3:
60         mvc     0(4,%r11),264(%r7)      # copy prefix register to prefix array
61         ahi     %r11,4                  # next element in prefix array
62         clr     %r11,%r12
63         je      5f                      # no more space in prefix array
64 4:
65         ahi     %r8,1                   # next cpu (r8 += 1)
66         chi     %r8,MAX_CPU_ADDRESS     # is last possible cpu ?
67         jle     1b                      # jump if not last cpu
68 5:
69         lhi     %r1,2                   # mode 2 = esame (dump)
70         j       6f
71         .align 4
72 .Lipl_schib:
73         .rept 13
74         .long 0
75         .endr
76 .nodump:
77         lhi     %r1,1                   # mode 1 = esame (normal ipl)
78 6:
79 #else
80         lhi     %r1,1                   # mode 1 = esame (normal ipl)
81 #endif /* CONFIG_ZFCPDUMP */
82         mvi     __LC_AR_MODE_ID,1       # set esame flag
83         slr     %r0,%r0                 # set cpuid to zero
84         sigp    %r1,%r0,0x12            # switch to esame mode
85         sam64                           # switch to 64 bit mode
86         llgfr   %r13,%r13               # clear high-order half of base reg
87         lmh     %r0,%r15,.Lzero64-.LPG1(%r13)   # clear high-order half
88         lctlg   %c0,%c15,.Lctl-.LPG1(%r13)      # load control registers
89         lg      %r12,.Lparmaddr-.LPG1(%r13)     # pointer to parameter area
90                                         # move IPL device to lowcore
91         lghi    %r0,__LC_PASTE
92         stg     %r0,__LC_VDSO_PER_CPU
93 #
94 # Setup stack
95 #
96         larl    %r15,init_thread_union
97         stg     %r15,__LC_THREAD_INFO   # cache thread info in lowcore
98         lg      %r14,__TI_task(%r15)    # cache current in lowcore
99         stg     %r14,__LC_CURRENT
100         aghi    %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
101         stg     %r15,__LC_KERNEL_STACK  # set end of kernel stack
102         aghi    %r15,-160
103 #
104 # Save ipl parameters, clear bss memory, initialize storage key for kernel pages,
105 # and create a kernel NSS if the SAVESYS= parm is defined
106 #
107         brasl   %r14,startup_init
108         lpswe   .Lentry-.LPG1(13)       # jump to _stext in primary-space,
109                                         # virtual and never return ...
110         .align  16
111 .Lentry:.quad   0x0000000180000000,_stext
112 .Lctl:  .quad   0x04350002              # cr0: various things
113         .quad   0                       # cr1: primary space segment table
114         .quad   .Lduct                  # cr2: dispatchable unit control table
115         .quad   0                       # cr3: instruction authorization
116         .quad   0                       # cr4: instruction authorization
117         .quad   .Lduct                  # cr5: primary-aste origin
118         .quad   0                       # cr6:  I/O interrupts
119         .quad   0                       # cr7:  secondary space segment table
120         .quad   0                       # cr8:  access registers translation
121         .quad   0                       # cr9:  tracing off
122         .quad   0                       # cr10: tracing off
123         .quad   0                       # cr11: tracing off
124         .quad   0                       # cr12: tracing off
125         .quad   0                       # cr13: home space segment table
126         .quad   0xc0000000              # cr14: machine check handling off
127         .quad   0                       # cr15: linkage stack operations
128 .Lpcmsk:.quad   0x0000000180000000
129 .L4malign:.quad 0xffffffffffc00000
130 .Lscan2g:.quad  0x80000000 + 0x20000 - 8        # 2GB + 128K - 8
131 .Lnop:  .long   0x07000700
132 .Lzero64:.fill  16,4,0x0
133 #ifdef CONFIG_ZFCPDUMP
134 .Lcurrent_cpu:
135         .long 0x0
136 .Lpref_arr_ptr:
137         .long zfcpdump_prefix_array
138 #endif /* CONFIG_ZFCPDUMP */
139 .Lparmaddr:
140         .quad   PARMAREA
141         .align  64
142 .Lduct: .long   0,0,0,0,.Lduald,0,0,0
143         .long   0,0,0,0,0,0,0,0
144         .align  128
145 .Lduald:.rept   8
146         .long   0x80000000,0,0,0        # invalid access-list entries
147         .endr
148
149         .org    0x12000
150         .globl  _ehead
151 _ehead:
152 #ifdef CONFIG_SHARED_KERNEL
153         .org    0x100000
154 #endif
155
156 #
157 # startup-code, running in absolute addressing mode
158 #
159         .globl  _stext
160 _stext: basr    %r13,0                  # get base
161 .LPG3:
162 # check control registers
163         stctg   %c0,%c15,0(%r15)
164         oi      6(%r15),0x40            # enable sigp emergency signal
165         oi      4(%r15),0x10            # switch on low address proctection
166         lctlg   %c0,%c15,0(%r15)
167
168         lam     0,15,.Laregs-.LPG3(%r13)        # load acrs needed by uaccess
169         brasl   %r14,start_kernel       # go to C code
170 #
171 # We returned from start_kernel ?!? PANIK
172 #
173         basr    %r13,0
174         lpswe   .Ldw-.(%r13)            # load disabled wait psw
175
176         .align  8
177 .Ldw:   .quad   0x0002000180000000,0x0000000000000000
178 .Laregs:.long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0