2 * Copyright IBM Corp. 1999, 2010
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>
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
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)
24 #include <linux/init.h>
25 #include <linux/linkage.h>
26 #include <asm/asm-offsets.h>
27 #include <asm/thread_info.h>
40 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
41 .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
42 .long 0x02000068,0x60000050 # (a PSW and two CCWs).
43 .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
44 .long 0x020000f0,0x60000050 # The next 160 byte are loaded
45 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
46 .long 0x02000190,0x60000050 # They form the continuation
47 .long 0x020001e0,0x60000050 # of the CCW program started
48 .long 0x02000230,0x60000050 # by ipl and load the range
49 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
50 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
51 .long 0x02000320,0x60000050 # in memory. At the end of
52 .long 0x02000370,0x60000050 # the channel program the PSW
53 .long 0x020003c0,0x60000050 # at location 0 is loaded.
54 .long 0x02000410,0x60000050 # Initial processing starts
55 .long 0x02000460,0x60000050 # at 0xf0 = iplstart.
56 .long 0x020004b0,0x60000050
57 .long 0x02000500,0x60000050
58 .long 0x02000550,0x60000050
59 .long 0x020005a0,0x60000050
60 .long 0x020005f0,0x60000050
61 .long 0x02000640,0x60000050
62 .long 0x02000690,0x60000050
63 .long 0x020006e0,0x20000050
67 # subroutine for loading cards from the reader
70 la %r3,.Lorb # r2 = address of orb into r2
71 la %r5,.Lirb # r4 = address of irb
75 st %r2,4(%r6) # initialize CCW data addresses
80 lctl %c6,%c6,.Lcr6 # set IO subclass mask
83 ssch 0(%r3) # load chunk of 1600 bytes
86 mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
89 c %r1,0xb8 # compare subchannel number
94 ic %r0,8(%r5) # get device status
95 chi %r0,8 # channel end ?
97 chi %r0,12 # channel end + device end ?
101 s %r0,8(%r3) # r0/8 = number of ccws executed
102 mhi %r0,10 # *10 = number of bytes in ccws
103 lh %r3,10(%r5) # get residual count
104 sr %r0,%r3 # #ccws*80-residual=#bytes read
107 br %r14 # r2 contains the total size
110 ahi %r2,0x640 # add 0x640 to total size
114 l %r0,4(%r6) # update CCW data addresses
125 .Lorb: .long 0x00000000,0x0080ff00,.Lccws
126 .Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
127 .Lcr6: .long 0xff000000
130 .Lcrash:.long 0x000a0000,0x00000000
132 .long 0x00080000,0x80000000+.Lioint
134 .long 0x020a0000,0x80000000+.Lioint
138 .long 0x02600050,0x00000000
140 .long 0x02200050,0x00000000
143 lh %r1,0xb8 # test if subchannel number
144 bct %r1,.Lnoload # is valid
145 l %r1,0xb8 # load ipl subchannel number
146 la %r2,IPL_BS # load start address
147 bas %r14,.Lloader # load rest of ipl image
148 l %r12,.Lparm # pointer to parameter area
149 st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
152 # load parameter file from ipl device
155 l %r2,.Linitrd # ramdisk loc. is temp
156 bas %r14,.Lloader # load parameter file
157 ltr %r2,%r2 # got anything ?
164 clc 0(3,%r4),.L_hdr # if it is HDRx
165 bz .Lagain1 # skip dataset header
166 clc 0(3,%r4),.L_eof # if it is EOFx
167 bz .Lagain1 # skip dateset trailer
170 la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
171 mvc 0(256,%r3),0(%r4)
172 mvc 256(256,%r3),256(%r4)
173 mvc 512(256,%r3),512(%r4)
174 mvc 768(122,%r3),768(%r4)
179 chi %r0,0x20 # is it a space ?
187 stc %r0,0(%r2,%r3) # terminate buffer
191 # load ramdisk from ipl device
194 l %r2,.Linitrd # addr of ramdisk
195 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
196 bas %r14,.Lloader # load ramdisk
197 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
200 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
204 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
210 # reset files in VM reader
212 stidp __LC_SAVE_AREA_SYNC # store cpuid
213 tm __LC_SAVE_AREA_SYNC,0xff# running VM ?
219 stsch 0(%r5) # check if irq is pending
220 tm 30(%r5),0x0f # by verifying if any of the
221 bnz .Lwaitforirq # activity or status control
222 tm 31(%r5),0xff # bits is set in the schib
225 mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
229 c %r1,0xb8 # compare subchannel number
238 .long 0x00080000,0x80000000+.Lrdrint
240 .long 0x020a0000,0x80000000+.Lrdrint
243 # everything loaded, go for it
249 .Linitrd:.long _end # default address of initrd
250 .Lparm: .long PARMAREA
251 .Lstartup: .long startup
252 .Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
253 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
254 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
255 .L_eof: .long 0xc5d6c600 /* C'EOF' */
256 .L_hdr: .long 0xc8c4d900 /* C'HDR' */
259 # SALIPL loader support. Based on a patch by Rob van der Heij.
260 # This entry point is called directly from the SALIPL loader and
261 # doesn't need a builtin ipl record.
265 stm %r0,%r15,0x07b0 # store registers
269 l %r8,.cmd # pointer to command buffer
271 ltr %r9,%r9 # do we have SALIPL parameters?
274 mvc 0(64,%r8),0x00b0 # copy saved registers
275 xc 64(240-64,%r8),0(%r8) # remainder of buffer
276 tr 0(64,%r8),.lowcase
279 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
282 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
283 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
284 j startup # continue with startup
285 .cmd: .long COMMAND_LINE # address of command line buffer
286 .parm: .long PARMAREA
288 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
289 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
290 .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
291 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
292 .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
293 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
294 .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
295 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
296 .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
297 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
298 .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
299 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
300 .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
301 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
302 .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
303 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
305 .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
306 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
307 .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
308 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
309 .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
310 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
311 .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
312 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
313 .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
314 .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
315 .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
316 .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr
317 .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx
318 .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz
319 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
320 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
323 # startup-code at 0x10000, running in absolute addressing mode
324 # this is called either by the ipl loader or directly by PSW restart
325 # or linload or SALIPL
329 j .Lep_startup_normal
332 # This is a list of s390 kernel entry points. At address 0x1000f the number of
333 # valid entry points is stored.
335 # IMPORTANT: Do not change this table, it is s390 kernel ABI!
340 # kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
346 basr %r13,0 # get base
348 xc 0x200(256),0x200 # partially clear lowcore
351 stck __LC_LAST_UPDATE_CLOCK
353 mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
354 xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
355 #ifndef CONFIG_MARCH_G5
356 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
357 .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
358 tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
361 .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended
362 0: l %r0,__LC_STFL_FAC_LIST
363 n %r0,2f+8-.LPG0(%r13)
364 cl %r0,2f+8-.LPG0(%r13)
366 l %r0,__LC_STFL_FAC_LIST+4
367 n %r0,2f+12-.LPG0(%r13)
368 cl %r0,2f+12-.LPG0(%r13)
370 1: l %r15,.Lstack-.LPG0(%r13)
372 la %r2,.Lals_string-.LPG0(%r13)
373 l %r3,.Lsclp_print-.LPG0(%r13)
375 lpsw 2f-.LPG0(%r13) # machine type not good enough, crash
377 .asciz "The Linux kernel requires more recent processor hardware"
379 .long _sclp_print_early
381 .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
383 2: .long 0x000a0000,0x8badcccc
384 #if defined(CONFIG_64BIT)
385 #if defined(CONFIG_MARCH_Z196)
386 .long 0xc100efe3, 0xf46c0000
387 #elif defined(CONFIG_MARCH_Z10)
388 .long 0xc100efe3, 0xf0680000
389 #elif defined(CONFIG_MARCH_Z9_109)
390 .long 0xc100efc3, 0x00000000
391 #elif defined(CONFIG_MARCH_Z990)
392 .long 0xc0002000, 0x00000000
393 #elif defined(CONFIG_MARCH_Z900)
394 .long 0xc0000000, 0x00000000
397 #if defined(CONFIG_MARCH_Z196)
398 .long 0x8100c880, 0x00000000
399 #elif defined(CONFIG_MARCH_Z10)
400 .long 0x8100c880, 0x00000000
401 #elif defined(CONFIG_MARCH_Z9_109)
402 .long 0x8100c880, 0x00000000
403 #elif defined(CONFIG_MARCH_Z990)
404 .long 0x80002000, 0x00000000
405 #elif defined(CONFIG_MARCH_Z900)
406 .long 0x80000000, 0x00000000
413 mvi __LC_AR_MODE_ID,1 # set esame flag
414 slr %r0,%r0 # set cpuid to zero
415 lhi %r1,2 # mode 2 = esame (dump)
416 sigp %r1,%r0,0x12 # switch to esame mode
417 sam64 # switch to 64 bit mode
419 lmh %r0,%r15,0(%r13) # clear high-order half
423 mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
424 l %r13,4f-.LPG0(%r13)
427 4: .long startup_continue
430 5: .long 0x7fffffff,0xffffffff
432 #include "head_kdump.S"
435 # params at 10400 (setup.h)
438 .long 0,0 # IPL_DEVICE
439 .long 0,0 # INITRD_START
440 .long 0,0 # INITRD_SIZE
441 .long 0,0 # OLDMEM_BASE
442 .long 0,0 # OLDMEM_SIZE
445 .byte "root=/dev/ram0 ro"