Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/s390/kernel/head.S
10819 views
1
/*
2
* Copyright IBM Corp. 1999,2010
3
*
4
* Author(s): Hartmut Penner <[email protected]>
5
* Martin Schwidefsky <[email protected]>
6
* Rob van der Heij <[email protected]>
7
* Heiko Carstens <[email protected]>
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
260
iplstart:
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
387
start:
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
452
startup:
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
.insn s,0xb2b10000,__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
468
0: 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
476
1: 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
489
2: .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
515
3:
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
527
4: .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
533
4: .long startup_continue
534
#endif
535
.align 8
536
5: .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
552