s390/facilities: always use lowcore's stfle field for storing facility bits
[deliverable/linux.git] / arch / s390 / kernel / head.S
CommitLineData
1da177e4 1/*
a53c8fab 2 * Copyright IBM Corp. 1999, 2010
0ad775db
HC
3 *
4 * Author(s): Hartmut Penner <hp@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Rob van der Heij <rvdhei@iae.nl>
7 * Heiko Carstens <heiko.carstens@de.ibm.com>
1da177e4
LT
8 *
9 * There are 5 different IPL methods
10 * 1) load the image directly into ram at address 0 and do an PSW restart
11 * 2) linload will load the image from address 0x10000 to memory 0x10000
12 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
13 * 3) generate the tape ipl header, store the generated image on a tape
14 * and ipl from it
15 * In case of SL tape you need to IPL 5 times to get past VOL1 etc
16 * 4) generate the vm reader ipl header, move the generated image to the
17 * VM reader (use option NOH!) and do a ipl from reader (VM only)
18 * 5) direct call of start by the SALIPL loader
19 * We use the cpuid to distinguish between VM and native ipl
20 * params for kernel are pushed to 0x10400 (see setup.h)
0ad775db 21 *
1da177e4
LT
22 */
23
2133bb8d 24#include <linux/init.h>
144d634a 25#include <linux/linkage.h>
0013a854 26#include <asm/asm-offsets.h>
1da177e4
LT
27#include <asm/thread_info.h>
28#include <asm/page.h>
c6eafbf9 29#include <asm/ptrace.h>
1da177e4 30
0ad775db 31#define ARCH_OFFSET 4
0ad775db 32
2133bb8d 33__HEAD
1da177e4 34
25d83cbf
HC
35#define IPL_BS 0x730
36 .org 0
37 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
38 .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
39 .long 0x02000068,0x60000050 # (a PSW and two CCWs).
40 .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
41 .long 0x020000f0,0x60000050 # The next 160 byte are loaded
42 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
43 .long 0x02000190,0x60000050 # They form the continuation
44 .long 0x020001e0,0x60000050 # of the CCW program started
45 .long 0x02000230,0x60000050 # by ipl and load the range
46 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
47 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
48 .long 0x02000320,0x60000050 # in memory. At the end of
49 .long 0x02000370,0x60000050 # the channel program the PSW
50 .long 0x020003c0,0x60000050 # at location 0 is loaded.
51 .long 0x02000410,0x60000050 # Initial processing starts
51eee033 52 .long 0x02000460,0x60000050 # at 0x200 = iplstart.
25d83cbf
HC
53 .long 0x020004b0,0x60000050
54 .long 0x02000500,0x60000050
55 .long 0x02000550,0x60000050
56 .long 0x020005a0,0x60000050
57 .long 0x020005f0,0x60000050
58 .long 0x02000640,0x60000050
59 .long 0x02000690,0x60000050
60 .long 0x020006e0,0x20000050
1da177e4 61
51eee033 62 .org 0x200
51eee033
MS
63
64#
65# subroutine to wait for end I/O
66#
67.Lirqwait:
51eee033
MS
68 mvc 0x1f0(16),.Lnewpsw # set up IO interrupt psw
69 lpsw .Lwaitpsw
70.Lioint:
71 br %r14
72 .align 8
73.Lnewpsw:
74 .quad 0x0000000080000000,.Lioint
51eee033
MS
75.Lwaitpsw:
76 .long 0x020a0000,0x80000000+.Lioint
77
1da177e4
LT
78#
79# subroutine for loading cards from the reader
80#
25d83cbf 81.Lloader:
51eee033 82 la %r4,0(%r14)
25d83cbf
HC
83 la %r3,.Lorb # r2 = address of orb into r2
84 la %r5,.Lirb # r4 = address of irb
85 la %r6,.Lccws
86 la %r7,20
1da177e4 87.Linit:
25d83cbf
HC
88 st %r2,4(%r6) # initialize CCW data addresses
89 la %r2,0x50(%r2)
90 la %r6,8(%r6)
91 bct 7,.Linit
1da177e4 92
25d83cbf
HC
93 lctl %c6,%c6,.Lcr6 # set IO subclass mask
94 slr %r2,%r2
1da177e4 95.Lldlp:
25d83cbf
HC
96 ssch 0(%r3) # load chunk of 1600 bytes
97 bnz .Llderr
1da177e4 98.Lwait4irq:
51eee033 99 bas %r14,.Lirqwait
25d83cbf
HC
100 c %r1,0xb8 # compare subchannel number
101 bne .Lwait4irq
102 tsch 0(%r5)
1da177e4 103
25d83cbf
HC
104 slr %r0,%r0
105 ic %r0,8(%r5) # get device status
106 chi %r0,8 # channel end ?
107 be .Lcont
108 chi %r0,12 # channel end + device end ?
109 be .Lcont
1da177e4 110
25d83cbf
HC
111 l %r0,4(%r5)
112 s %r0,8(%r3) # r0/8 = number of ccws executed
113 mhi %r0,10 # *10 = number of bytes in ccws
114 lh %r3,10(%r5) # get residual count
115 sr %r0,%r3 # #ccws*80-residual=#bytes read
116 ar %r2,%r0
117
51eee033 118 br %r4 # r2 contains the total size
1da177e4
LT
119
120.Lcont:
25d83cbf
HC
121 ahi %r2,0x640 # add 0x640 to total size
122 la %r6,.Lccws
123 la %r7,20
1da177e4 124.Lincr:
25d83cbf
HC
125 l %r0,4(%r6) # update CCW data addresses
126 ahi %r0,0x640
127 st %r0,4(%r6)
128 ahi %r6,8
129 bct 7,.Lincr
1da177e4 130
25d83cbf 131 b .Lldlp
1da177e4 132.Llderr:
25d83cbf 133 lpsw .Lcrash
1da177e4 134
25d83cbf
HC
135 .align 8
136.Lorb: .long 0x00000000,0x0080ff00,.Lccws
137.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
138.Lcr6: .long 0xff000000
139.Lloadp:.long 0,0
140 .align 8
141.Lcrash:.long 0x000a0000,0x00000000
1da177e4 142
25d83cbf
HC
143 .align 8
144.Lccws: .rept 19
145 .long 0x02600050,0x00000000
146 .endr
147 .long 0x02200050,0x00000000
1da177e4
LT
148
149iplstart:
f52c74fe
HC
150 mvi __LC_AR_MODE_ID,1 # set esame flag
151 slr %r0,%r0 # set cpuid to zero
152 lhi %r1,2 # mode 2 = esame (dump)
153 sigp %r1,%r0,0x12 # switch to esame mode
154 bras %r13,0f
155 .fill 16,4,0x0
1560: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
157 sam31 # switch to 31 bit addressing mode
25d83cbf
HC
158 lh %r1,0xb8 # test if subchannel number
159 bct %r1,.Lnoload # is valid
160 l %r1,0xb8 # load ipl subchannel number
161 la %r2,IPL_BS # load start address
162 bas %r14,.Lloader # load rest of ipl image
163 l %r12,.Lparm # pointer to parameter area
164 st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
1da177e4
LT
165
166#
167# load parameter file from ipl device
168#
169.Lagain1:
25d83cbf
HC
170 l %r2,.Linitrd # ramdisk loc. is temp
171 bas %r14,.Lloader # load parameter file
172 ltr %r2,%r2 # got anything ?
173 bz .Lnopf
174 chi %r2,895
175 bnh .Lnotrunc
176 la %r2,895
1da177e4 177.Lnotrunc:
25d83cbf
HC
178 l %r4,.Linitrd
179 clc 0(3,%r4),.L_hdr # if it is HDRx
180 bz .Lagain1 # skip dataset header
181 clc 0(3,%r4),.L_eof # if it is EOFx
182 bz .Lagain1 # skip dateset trailer
183 la %r5,0(%r4,%r2)
184 lr %r3,%r2
61fd330d 185 la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
25d83cbf
HC
186 mvc 0(256,%r3),0(%r4)
187 mvc 256(256,%r3),256(%r4)
188 mvc 512(256,%r3),512(%r4)
189 mvc 768(122,%r3),768(%r4)
190 slr %r0,%r0
191 b .Lcntlp
1da177e4 192.Ldelspc:
25d83cbf
HC
193 ic %r0,0(%r2,%r3)
194 chi %r0,0x20 # is it a space ?
195 be .Lcntlp
196 ahi %r2,1
197 b .Leolp
1da177e4 198.Lcntlp:
25d83cbf 199 brct %r2,.Ldelspc
1da177e4 200.Leolp:
25d83cbf
HC
201 slr %r0,%r0
202 stc %r0,0(%r2,%r3) # terminate buffer
1da177e4
LT
203.Lnopf:
204
205#
206# load ramdisk from ipl device
25d83cbf 207#
1da177e4 208.Lagain2:
25d83cbf
HC
209 l %r2,.Linitrd # addr of ramdisk
210 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
211 bas %r14,.Lloader # load ramdisk
212 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
213 ltr %r2,%r2
214 bnz .Lrdcont
215 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
1da177e4 216.Lrdcont:
25d83cbf 217 l %r2,.Linitrd
1da177e4 218
25d83cbf
HC
219 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
220 bz .Lagain2
221 clc 0(3,%r2),.L_eof
222 bz .Lagain2
1da177e4 223
1da177e4
LT
224#
225# reset files in VM reader
226#
51eee033
MS
227 stidp .Lcpuid # store cpuid
228 tm .Lcpuid,0xff # running VM ?
25d83cbf
HC
229 bno .Lnoreset
230 la %r2,.Lreset
231 lhi %r3,26
232 diag %r2,%r3,8
233 la %r5,.Lirb
234 stsch 0(%r5) # check if irq is pending
235 tm 30(%r5),0x0f # by verifying if any of the
236 bnz .Lwaitforirq # activity or status control
237 tm 31(%r5),0xff # bits is set in the schib
238 bz .Lnoreset
350e3ade 239.Lwaitforirq:
51eee033 240 bas %r14,.Lirqwait # wait for IO interrupt
25d83cbf 241 c %r1,0xb8 # compare subchannel number
51eee033 242 bne .Lwaitforirq
25d83cbf
HC
243 la %r5,.Lirb
244 tsch 0(%r5)
1da177e4 245.Lnoreset:
25d83cbf 246 b .Lnoload
2b071886 247
1da177e4
LT
248#
249# everything loaded, go for it
250#
251.Lnoload:
25d83cbf
HC
252 l %r1,.Lstartup
253 br %r1
1da177e4 254
e033b9a0 255.Linitrd:.long _end # default address of initrd
1da177e4
LT
256.Lparm: .long PARMAREA
257.Lstartup: .long startup
25d83cbf
HC
258.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
259 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
260 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
261.L_eof: .long 0xc5d6c600 /* C'EOF' */
262.L_hdr: .long 0xc8c4d900 /* C'HDR' */
51eee033
MS
263 .align 8
264.Lcpuid:.fill 8,1,0
1da177e4 265
e37f50e1
MS
266#
267# startup-code at 0x10000, running in absolute addressing mode
268# this is called either by the ipl loader or directly by PSW restart
269# or linload or SALIPL
270#
271 .org 0x10000
144d634a 272ENTRY(startup)
60a0c68d
MH
273 j .Lep_startup_normal
274 .org 0x10008
275#
276# This is a list of s390 kernel entry points. At address 0x1000f the number of
277# valid entry points is stored.
278#
279# IMPORTANT: Do not change this table, it is s390 kernel ABI!
280#
281 .ascii "S390EP"
282 .byte 0x00,0x01
283#
284# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
285#
286 .org 0x10010
287ENTRY(startup_kdump)
288 j .Lep_startup_kdump
289.Lep_startup_normal:
51eee033
MS
290 mvi __LC_AR_MODE_ID,1 # set esame flag
291 slr %r0,%r0 # set cpuid to zero
292 lhi %r1,2 # mode 2 = esame (dump)
293 sigp %r1,%r0,0x12 # switch to esame mode
294 bras %r13,0f
295 .fill 16,4,0x0
2960: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
c6eafbf9 297 sam64 # switch to 64 bit addressing mode
1844c9bc 298 basr %r13,0 # get base
e37f50e1 299.LPG0:
866ba284
MS
300 xc 0x200(256),0x200 # partially clear lowcore
301 xc 0x300(256),0x300
60a0c68d 302 xc 0xe00(256),0xe00
76cdd44c 303 xc 0xf00(256),0xf00
22362a0e 304 lctlg %c0,%c15,0x200(%r0) # initialize control registers
1844c9bc 305 stck __LC_LAST_UPDATE_CLOCK
991c1505
HC
306 spt 6f-.LPG0(%r13)
307 mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
9552a66f 308 stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST
76cdd44c
HC
309 mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
310 tm __LC_STFLE_FAC_LIST,0x01 # stfle available ?
8c4caa4f 311 jz 0f
991c1505 312 la %r0,1
76cdd44c 313 .insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
991c1505 314 # verify if all required facilities are supported by the machine
76cdd44c 3150: la %r1,__LC_STFLE_FAC_LIST
991c1505
HC
316 la %r2,3f+8-.LPG0(%r13)
317 l %r3,0(%r2)
3181: l %r0,0(%r1)
319 n %r0,4(%r2)
320 cl %r0,4(%r2)
321 jne 2f
322 la %r1,4(%r1)
323 la %r2,4(%r2)
324 ahi %r3,-1
325 jnz 1b
326 j 4f
3272: l %r15,.Lstack-.LPG0(%r13)
c6eafbf9 328 ahi %r15,-STACK_FRAME_OVERHEAD
d90cbd46
HC
329 la %r2,.Lals_string-.LPG0(%r13)
330 l %r3,.Lsclp_print-.LPG0(%r13)
331 basr %r14,%r3
991c1505 332 lpsw 3f-.LPG0(%r13) # machine type not good enough, crash
d90cbd46
HC
333.Lals_string:
334 .asciz "The Linux kernel requires more recent processor hardware"
335.Lsclp_print:
336 .long _sclp_print_early
337.Lstack:
1844c9bc 338 .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
e37f50e1 339 .align 16
991c1505
HC
3403: .long 0x000a0000,0x8badcccc
341
342# List of facilities that are required. If not all facilities are present
343# the kernel will crash. Format is number of facility words with bits set,
344# followed by the facility words.
345
f8b2dcbd 346#if defined(CONFIG_MARCH_Z13)
a69db2f6 347 .long 2, 0xc100eff2, 0xf46cc800
f8b2dcbd 348#elif defined(CONFIG_MARCH_ZEC12)
a69db2f6 349 .long 2, 0xc100eff2, 0xf46cc800
991c1505 350#elif defined(CONFIG_MARCH_Z196)
4a36b44c 351 .long 2, 0xc100eff2, 0xf46c0000
f861e405 352#elif defined(CONFIG_MARCH_Z10)
4a36b44c 353 .long 2, 0xc100eff2, 0xf0680000
8c4caa4f 354#elif defined(CONFIG_MARCH_Z9_109)
6eb58d9b 355 .long 1, 0xc100efc2
8c4caa4f 356#elif defined(CONFIG_MARCH_Z990)
991c1505 357 .long 1, 0xc0002000
8c4caa4f 358#elif defined(CONFIG_MARCH_Z900)
991c1505 359 .long 1, 0xc0000000
8c4caa4f 360#endif
991c1505 3614:
c6eafbf9 362 /* Continue with startup code in head64.S */
1844c9bc 363 jg startup_continue
51eee033 364
ab96e798 365 .align 8
991c1505 3666: .long 0x7fffffff,0xffffffff
e37f50e1 367
60a0c68d
MH
368#include "head_kdump.S"
369
e37f50e1
MS
370#
371# params at 10400 (setup.h)
372#
373 .org PARMAREA
374 .long 0,0 # IPL_DEVICE
375 .long 0,0 # INITRD_START
376 .long 0,0 # INITRD_SIZE
60a0c68d
MH
377 .long 0,0 # OLDMEM_BASE
378 .long 0,0 # OLDMEM_SIZE
e37f50e1
MS
379
380 .org COMMAND_LINE
381 .byte "root=/dev/ram0 ro"
382 .byte 0
383
1844c9bc 384 .org 0x11000
This page took 0.768554 seconds and 5 git commands to generate.