Root/arch/s390/kernel/head.S

1/*
2 * Copyright IBM Corp. 1999,2010
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>
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)
21 *
22 */
23
24#include <linux/init.h>
25#include <asm/asm-offsets.h>
26#include <asm/thread_info.h>
27#include <asm/page.h>
28
29#ifdef CONFIG_64BIT
30#define ARCH_OFFSET 4
31#else
32#define ARCH_OFFSET 0
33#endif
34
35__HEAD
36#ifndef CONFIG_IPL
37    .org 0
38    .long 0x00080000,0x80000000+startup # Just a restart PSW
39#else
40#ifdef CONFIG_IPL_TAPE
41#define IPL_BS 1024
42    .org 0
43    .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
44    .long 0x27000000,0x60000001 # by ipl to addresses 0-23.
45    .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs).
46    .long 0x00000000,0x00000000 # external old psw
47    .long 0x00000000,0x00000000 # svc old psw
48    .long 0x00000000,0x00000000 # program check old psw
49    .long 0x00000000,0x00000000 # machine check old psw
50    .long 0x00000000,0x00000000 # io old psw
51    .long 0x00000000,0x00000000
52    .long 0x00000000,0x00000000
53    .long 0x00000000,0x00000000
54    .long 0x000a0000,0x00000058 # external new psw
55    .long 0x000a0000,0x00000060 # svc new psw
56    .long 0x000a0000,0x00000068 # program check new psw
57    .long 0x000a0000,0x00000070 # machine check new psw
58    .long 0x00080000,0x80000000+.Lioint # io new psw
59
60    .org 0x100
61#
62# subroutine for loading from tape
63# Parameters:
64# R1 = device number
65# R2 = load address
66.Lloader:
67    st %r14,.Lldret
68    la %r3,.Lorbread # r3 = address of orb
69    la %r5,.Lirb # r5 = address of irb
70    st %r2,.Lccwread+4 # initialize CCW data addresses
71    lctl %c6,%c6,.Lcr6
72    slr %r2,%r2
73.Lldlp:
74    la %r6,3 # 3 retries
75.Lssch:
76    ssch 0(%r3) # load chunk of IPL_BS bytes
77    bnz .Llderr
78.Lw4end:
79    bas %r14,.Lwait4io
80    tm 8(%r5),0x82 # do we have a problem ?
81    bnz .Lrecov
82    slr %r7,%r7
83    icm %r7,3,10(%r5) # get residual count
84    lcr %r7,%r7
85    la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read
86    ar %r2,%r7 # add to total size
87    tm 8(%r5),0x01 # found a tape mark ?
88    bnz .Ldone
89    l %r0,.Lccwread+4 # update CCW data addresses
90    ar %r0,%r7
91    st %r0,.Lccwread+4
92    b .Lldlp
93.Ldone:
94    l %r14,.Lldret
95    br %r14 # r2 contains the total size
96.Lrecov:
97    bas %r14,.Lsense # do the sensing
98    bct %r6,.Lssch # dec. retry count & branch
99    b .Llderr
100#
101# Sense subroutine
102#
103.Lsense:
104    st %r14,.Lsnsret
105    la %r7,.Lorbsense
106    ssch 0(%r7) # start sense command
107    bnz .Llderr
108    bas %r14,.Lwait4io
109    l %r14,.Lsnsret
110    tm 8(%r5),0x82 # do we have a problem ?
111    bnz .Llderr
112    br %r14
113#
114# Wait for interrupt subroutine
115#
116.Lwait4io:
117    lpsw .Lwaitpsw
118.Lioint:
119    c %r1,0xb8 # compare subchannel number
120    bne .Lwait4io
121    tsch 0(%r5)
122    slr %r0,%r0
123    tm 8(%r5),0x82 # do we have a problem ?
124    bnz .Lwtexit
125    tm 8(%r5),0x04 # got device end ?
126    bz .Lwait4io
127.Lwtexit:
128    br %r14
129.Llderr:
130    lpsw .Lcrash
131
132    .align 8
133.Lorbread:
134    .long 0x00000000,0x0080ff00,.Lccwread
135    .align 8
136.Lorbsense:
137    .long 0x00000000,0x0080ff00,.Lccwsense
138    .align 8
139.Lccwread:
140    .long 0x02200000+IPL_BS,0x00000000
141.Lccwsense:
142    .long 0x04200001,0x00000000
143.Lwaitpsw:
144    .long 0x020a0000,0x80000000+.Lioint
145
146.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
147.Lcr6: .long 0xff000000
148    .align 8
149.Lcrash:.long 0x000a0000,0x00000000
150.Lldret:.long 0
151.Lsnsret: .long 0
152#endif /* CONFIG_IPL_TAPE */
153
154#ifdef CONFIG_IPL_VM
155#define IPL_BS 0x730
156    .org 0
157    .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
158    .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
159    .long 0x02000068,0x60000050 # (a PSW and two CCWs).
160    .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
161    .long 0x020000f0,0x60000050 # The next 160 byte are loaded
162    .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
163    .long 0x02000190,0x60000050 # They form the continuation
164    .long 0x020001e0,0x60000050 # of the CCW program started
165    .long 0x02000230,0x60000050 # by ipl and load the range
166    .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
167    .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
168    .long 0x02000320,0x60000050 # in memory. At the end of
169    .long 0x02000370,0x60000050 # the channel program the PSW
170    .long 0x020003c0,0x60000050 # at location 0 is loaded.
171    .long 0x02000410,0x60000050 # Initial processing starts
172    .long 0x02000460,0x60000050 # at 0xf0 = iplstart.
173    .long 0x020004b0,0x60000050
174    .long 0x02000500,0x60000050
175    .long 0x02000550,0x60000050
176    .long 0x020005a0,0x60000050
177    .long 0x020005f0,0x60000050
178    .long 0x02000640,0x60000050
179    .long 0x02000690,0x60000050
180    .long 0x020006e0,0x20000050
181
182    .org 0xf0
183#
184# subroutine for loading cards from the reader
185#
186.Lloader:
187    la %r3,.Lorb # r2 = address of orb into r2
188    la %r5,.Lirb # r4 = address of irb
189    la %r6,.Lccws
190    la %r7,20
191.Linit:
192    st %r2,4(%r6) # initialize CCW data addresses
193    la %r2,0x50(%r2)
194    la %r6,8(%r6)
195    bct 7,.Linit
196
197    lctl %c6,%c6,.Lcr6 # set IO subclass mask
198    slr %r2,%r2
199.Lldlp:
200    ssch 0(%r3) # load chunk of 1600 bytes
201    bnz .Llderr
202.Lwait4irq:
203    mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
204    lpsw .Lwaitpsw
205.Lioint:
206    c %r1,0xb8 # compare subchannel number
207    bne .Lwait4irq
208    tsch 0(%r5)
209
210    slr %r0,%r0
211    ic %r0,8(%r5) # get device status
212    chi %r0,8 # channel end ?
213    be .Lcont
214    chi %r0,12 # channel end + device end ?
215    be .Lcont
216
217    l %r0,4(%r5)
218    s %r0,8(%r3) # r0/8 = number of ccws executed
219    mhi %r0,10 # *10 = number of bytes in ccws
220    lh %r3,10(%r5) # get residual count
221    sr %r0,%r3 # #ccws*80-residual=#bytes read
222    ar %r2,%r0
223
224    br %r14 # r2 contains the total size
225
226.Lcont:
227    ahi %r2,0x640 # add 0x640 to total size
228    la %r6,.Lccws
229    la %r7,20
230.Lincr:
231    l %r0,4(%r6) # update CCW data addresses
232    ahi %r0,0x640
233    st %r0,4(%r6)
234    ahi %r6,8
235    bct 7,.Lincr
236
237    b .Lldlp
238.Llderr:
239    lpsw .Lcrash
240
241    .align 8
242.Lorb: .long 0x00000000,0x0080ff00,.Lccws
243.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
244.Lcr6: .long 0xff000000
245.Lloadp:.long 0,0
246    .align 8
247.Lcrash:.long 0x000a0000,0x00000000
248.Lnewpsw:
249    .long 0x00080000,0x80000000+.Lioint
250.Lwaitpsw:
251    .long 0x020a0000,0x80000000+.Lioint
252
253    .align 8
254.Lccws: .rept 19
255    .long 0x02600050,0x00000000
256    .endr
257    .long 0x02200050,0x00000000
258#endif /* CONFIG_IPL_VM */
259
260iplstart:
261    lh %r1,0xb8 # test if subchannel number
262    bct %r1,.Lnoload # is valid
263    l %r1,0xb8 # load ipl subchannel number
264    la %r2,IPL_BS # load start address
265    bas %r14,.Lloader # load rest of ipl image
266    l %r12,.Lparm # pointer to parameter area
267    st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
268
269#
270# load parameter file from ipl device
271#
272.Lagain1:
273    l %r2,.Linitrd # ramdisk loc. is temp
274    bas %r14,.Lloader # load parameter file
275    ltr %r2,%r2 # got anything ?
276    bz .Lnopf
277    chi %r2,895
278    bnh .Lnotrunc
279    la %r2,895
280.Lnotrunc:
281    l %r4,.Linitrd
282    clc 0(3,%r4),.L_hdr # if it is HDRx
283    bz .Lagain1 # skip dataset header
284    clc 0(3,%r4),.L_eof # if it is EOFx
285    bz .Lagain1 # skip dateset trailer
286    la %r5,0(%r4,%r2)
287    lr %r3,%r2
288    la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
289    mvc 0(256,%r3),0(%r4)
290    mvc 256(256,%r3),256(%r4)
291    mvc 512(256,%r3),512(%r4)
292    mvc 768(122,%r3),768(%r4)
293    slr %r0,%r0
294    b .Lcntlp
295.Ldelspc:
296    ic %r0,0(%r2,%r3)
297    chi %r0,0x20 # is it a space ?
298    be .Lcntlp
299    ahi %r2,1
300    b .Leolp
301.Lcntlp:
302    brct %r2,.Ldelspc
303.Leolp:
304    slr %r0,%r0
305    stc %r0,0(%r2,%r3) # terminate buffer
306.Lnopf:
307
308#
309# load ramdisk from ipl device
310#
311.Lagain2:
312    l %r2,.Linitrd # addr of ramdisk
313    st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
314    bas %r14,.Lloader # load ramdisk
315    st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
316    ltr %r2,%r2
317    bnz .Lrdcont
318    st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
319.Lrdcont:
320    l %r2,.Linitrd
321
322    clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
323    bz .Lagain2
324    clc 0(3,%r2),.L_eof
325    bz .Lagain2
326
327#ifdef CONFIG_IPL_VM
328#
329# reset files in VM reader
330#
331    stidp __LC_SAVE_AREA # store cpuid
332    tm __LC_SAVE_AREA,0xff # running VM ?
333    bno .Lnoreset
334    la %r2,.Lreset
335    lhi %r3,26
336    diag %r2,%r3,8
337    la %r5,.Lirb
338    stsch 0(%r5) # check if irq is pending
339    tm 30(%r5),0x0f # by verifying if any of the
340    bnz .Lwaitforirq # activity or status control
341    tm 31(%r5),0xff # bits is set in the schib
342    bz .Lnoreset
343.Lwaitforirq:
344    mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
345.Lwaitrdrirq:
346    lpsw .Lrdrwaitpsw
347.Lrdrint:
348    c %r1,0xb8 # compare subchannel number
349    bne .Lwaitrdrirq
350    la %r5,.Lirb
351    tsch 0(%r5)
352.Lnoreset:
353    b .Lnoload
354
355    .align 8
356.Lrdrnewpsw:
357    .long 0x00080000,0x80000000+.Lrdrint
358.Lrdrwaitpsw:
359    .long 0x020a0000,0x80000000+.Lrdrint
360#endif
361
362#
363# everything loaded, go for it
364#
365.Lnoload:
366    l %r1,.Lstartup
367    br %r1
368
369.Linitrd:.long _end # default address of initrd
370.Lparm: .long PARMAREA
371.Lstartup: .long startup
372.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
373    .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
374    .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
375.L_eof: .long 0xc5d6c600 /* C'EOF' */
376.L_hdr: .long 0xc8c4d900 /* C'HDR' */
377
378#endif /* CONFIG_IPL */
379
380#
381# SALIPL loader support. Based on a patch by Rob van der Heij.
382# This entry point is called directly from the SALIPL loader and
383# doesn't need a builtin ipl record.
384#
385    .org 0x800
386    .globl start
387start:
388    stm %r0,%r15,0x07b0 # store registers
389    basr %r12,%r0
390.base:
391    l %r11,.parm
392    l %r8,.cmd # pointer to command buffer
393
394    ltr %r9,%r9 # do we have SALIPL parameters?
395    bp .sk8x8
396
397    mvc 0(64,%r8),0x00b0 # copy saved registers
398    xc 64(240-64,%r8),0(%r8) # remainder of buffer
399    tr 0(64,%r8),.lowcase
400    b .gotr
401.sk8x8:
402    mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
403.gotr:
404    slr %r0,%r0
405    st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
406    st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
407    j startup # continue with startup
408.cmd: .long COMMAND_LINE # address of command line buffer
409.parm: .long PARMAREA
410.lowcase:
411    .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
412    .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
413    .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
414    .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
415    .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
416    .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
417    .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
418    .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
419    .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
420    .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
421    .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
422    .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
423    .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
424    .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
425    .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
426    .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
427
428    .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
429    .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
430    .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
431    .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
432    .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
433    .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
434    .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
435    .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
436    .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
437    .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
438    .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
439    .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr
440    .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx
441    .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz
442    .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
443    .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
444
445#
446# startup-code at 0x10000, running in absolute addressing mode
447# this is called either by the ipl loader or directly by PSW restart
448# or linload or SALIPL
449#
450    .org 0x10000
451    .globl startup
452startup:
453    basr %r13,0 # get base
454.LPG0:
455    xc 0x200(256),0x200 # partially clear lowcore
456    xc 0x300(256),0x300
457    stck __LC_LAST_UPDATE_CLOCK
458    spt 5f-.LPG0(%r13)
459    mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
460#ifndef CONFIG_MARCH_G5
461    # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
462    xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
463    stfl __LC_STFL_FAC_LIST # store facility list
464    tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
465    jz 0f
466    la %r0,0
467    .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended
4680: l %r0,__LC_STFL_FAC_LIST
469    n %r0,2f+8-.LPG0(%r13)
470    cl %r0,2f+8-.LPG0(%r13)
471    jne 1f
472    l %r0,__LC_STFL_FAC_LIST+4
473    n %r0,2f+12-.LPG0(%r13)
474    cl %r0,2f+12-.LPG0(%r13)
475    je 3f
4761: l %r15,.Lstack-.LPG0(%r13)
477    ahi %r15,-96
478    la %r2,.Lals_string-.LPG0(%r13)
479    l %r3,.Lsclp_print-.LPG0(%r13)
480    basr %r14,%r3
481    lpsw 2f-.LPG0(%r13) # machine type not good enough, crash
482.Lals_string:
483    .asciz "The Linux kernel requires more recent processor hardware"
484.Lsclp_print:
485    .long _sclp_print_early
486.Lstack:
487    .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
488    .align 16
4892: .long 0x000a0000,0x8badcccc
490#if defined(CONFIG_64BIT)
491#if defined(CONFIG_MARCH_Z196)
492    .long 0xc100efe3, 0xf46c0000
493#elif defined(CONFIG_MARCH_Z10)
494    .long 0xc100efe3, 0xf0680000
495#elif defined(CONFIG_MARCH_Z9_109)
496    .long 0xc100efc3, 0x00000000
497#elif defined(CONFIG_MARCH_Z990)
498    .long 0xc0002000, 0x00000000
499#elif defined(CONFIG_MARCH_Z900)
500    .long 0xc0000000, 0x00000000
501#endif
502#else
503#if defined(CONFIG_MARCH_Z196)
504    .long 0x8100c880, 0x00000000
505#elif defined(CONFIG_MARCH_Z10)
506    .long 0x8100c880, 0x00000000
507#elif defined(CONFIG_MARCH_Z9_109)
508    .long 0x8100c880, 0x00000000
509#elif defined(CONFIG_MARCH_Z990)
510    .long 0x80002000, 0x00000000
511#elif defined(CONFIG_MARCH_Z900)
512    .long 0x80000000, 0x00000000
513#endif
514#endif
5153:
516#endif
517
518#ifdef CONFIG_64BIT
519    mvi __LC_AR_MODE_ID,1 # set esame flag
520    slr %r0,%r0 # set cpuid to zero
521    lhi %r1,2 # mode 2 = esame (dump)
522    sigp %r1,%r0,0x12 # switch to esame mode
523    sam64 # switch to 64 bit mode
524    larl %r13,4f
525    lmh %r0,%r15,0(%r13) # clear high-order half
526    jg startup_continue
5274: .fill 16,4,0x0
528#else
529    mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
530    l %r13,4f-.LPG0(%r13)
531    b 0(%r13)
532    .align 8
5334: .long startup_continue
534#endif
535    .align 8
5365: .long 0x7fffffff,0xffffffff
537
538#
539# params at 10400 (setup.h)
540#
541    .org PARMAREA
542    .long 0,0 # IPL_DEVICE
543    .long 0,0 # INITRD_START
544    .long 0,0 # INITRD_SIZE
545
546    .org COMMAND_LINE
547    .byte "root=/dev/ram0 ro"
548    .byte 0
549
550    .org 0x11000
551

Archive Download this file



interactive