]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/s390/boot/head.S
Merge tag 'sound-5.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[mirror_ubuntu-jammy-kernel.git] / arch / s390 / boot / head.S
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
1da177e4 2/*
a53c8fab 3 * Copyright IBM Corp. 1999, 2010
0ad775db
HC
4 *
5 * Author(s): Hartmut Penner <hp@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Rob van der Heij <rvdhei@iae.nl>
8 * Heiko Carstens <heiko.carstens@de.ibm.com>
1da177e4
LT
9 *
10 * There are 5 different IPL methods
11 * 1) load the image directly into ram at address 0 and do an PSW restart
12 * 2) linload will load the image from address 0x10000 to memory 0x10000
13 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
14 * 3) generate the tape ipl header, store the generated image on a tape
15 * and ipl from it
16 * In case of SL tape you need to IPL 5 times to get past VOL1 etc
17 * 4) generate the vm reader ipl header, move the generated image to the
18 * VM reader (use option NOH!) and do a ipl from reader (VM only)
19 * 5) direct call of start by the SALIPL loader
20 * We use the cpuid to distinguish between VM and native ipl
21 * params for kernel are pushed to 0x10400 (see setup.h)
0ad775db 22 *
1da177e4
LT
23 */
24
2133bb8d 25#include <linux/init.h>
144d634a 26#include <linux/linkage.h>
0013a854 27#include <asm/asm-offsets.h>
1da177e4
LT
28#include <asm/thread_info.h>
29#include <asm/page.h>
c6eafbf9 30#include <asm/ptrace.h>
1da177e4 31
0ad775db 32#define ARCH_OFFSET 4
0ad775db 33
2133bb8d 34__HEAD
1da177e4 35
25d83cbf
HC
36#define IPL_BS 0x730
37 .org 0
38 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
39 .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
40 .long 0x02000068,0x60000050 # (a PSW and two CCWs).
41 .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
42 .long 0x020000f0,0x60000050 # The next 160 byte are loaded
43 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
44 .long 0x02000190,0x60000050 # They form the continuation
45 .long 0x020001e0,0x60000050 # of the CCW program started
46 .long 0x02000230,0x60000050 # by ipl and load the range
47 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
48 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
49 .long 0x02000320,0x60000050 # in memory. At the end of
50 .long 0x02000370,0x60000050 # the channel program the PSW
51 .long 0x020003c0,0x60000050 # at location 0 is loaded.
52 .long 0x02000410,0x60000050 # Initial processing starts
51eee033 53 .long 0x02000460,0x60000050 # at 0x200 = iplstart.
25d83cbf
HC
54 .long 0x020004b0,0x60000050
55 .long 0x02000500,0x60000050
56 .long 0x02000550,0x60000050
57 .long 0x020005a0,0x60000050
58 .long 0x020005f0,0x60000050
59 .long 0x02000640,0x60000050
60 .long 0x02000690,0x60000050
61 .long 0x020006e0,0x20000050
1da177e4 62
da9ed30d 63 .org __LC_RST_NEW_PSW # 0x1a0
8e5a7627 64 .quad 0,iplstart
da9ed30d
VG
65 .org __LC_PGM_NEW_PSW # 0x1d0
66 .quad 0x0000000180000000,startup_pgm_check_handler
8e5a7627 67
51eee033 68 .org 0x200
51eee033
MS
69
70#
71# subroutine to wait for end I/O
72#
73.Lirqwait:
34ba2450 74 mvc __LC_IO_NEW_PSW(16),.Lnewpsw # set up IO interrupt psw
51eee033
MS
75 lpsw .Lwaitpsw
76.Lioint:
77 br %r14
78 .align 8
79.Lnewpsw:
80 .quad 0x0000000080000000,.Lioint
51eee033
MS
81.Lwaitpsw:
82 .long 0x020a0000,0x80000000+.Lioint
83
1da177e4
LT
84#
85# subroutine for loading cards from the reader
86#
25d83cbf 87.Lloader:
51eee033 88 la %r4,0(%r14)
25d83cbf
HC
89 la %r3,.Lorb # r2 = address of orb into r2
90 la %r5,.Lirb # r4 = address of irb
91 la %r6,.Lccws
92 la %r7,20
1da177e4 93.Linit:
25d83cbf
HC
94 st %r2,4(%r6) # initialize CCW data addresses
95 la %r2,0x50(%r2)
96 la %r6,8(%r6)
97 bct 7,.Linit
1da177e4 98
25d83cbf
HC
99 lctl %c6,%c6,.Lcr6 # set IO subclass mask
100 slr %r2,%r2
1da177e4 101.Lldlp:
25d83cbf
HC
102 ssch 0(%r3) # load chunk of 1600 bytes
103 bnz .Llderr
1da177e4 104.Lwait4irq:
51eee033 105 bas %r14,.Lirqwait
34ba2450 106 c %r1,__LC_SUBCHANNEL_ID # compare subchannel number
25d83cbf
HC
107 bne .Lwait4irq
108 tsch 0(%r5)
1da177e4 109
25d83cbf
HC
110 slr %r0,%r0
111 ic %r0,8(%r5) # get device status
112 chi %r0,8 # channel end ?
113 be .Lcont
114 chi %r0,12 # channel end + device end ?
115 be .Lcont
1da177e4 116
25d83cbf
HC
117 l %r0,4(%r5)
118 s %r0,8(%r3) # r0/8 = number of ccws executed
119 mhi %r0,10 # *10 = number of bytes in ccws
120 lh %r3,10(%r5) # get residual count
121 sr %r0,%r3 # #ccws*80-residual=#bytes read
122 ar %r2,%r0
123
51eee033 124 br %r4 # r2 contains the total size
1da177e4
LT
125
126.Lcont:
25d83cbf
HC
127 ahi %r2,0x640 # add 0x640 to total size
128 la %r6,.Lccws
129 la %r7,20
1da177e4 130.Lincr:
25d83cbf
HC
131 l %r0,4(%r6) # update CCW data addresses
132 ahi %r0,0x640
133 st %r0,4(%r6)
134 ahi %r6,8
135 bct 7,.Lincr
1da177e4 136
25d83cbf 137 b .Lldlp
1da177e4 138.Llderr:
25d83cbf 139 lpsw .Lcrash
1da177e4 140
25d83cbf
HC
141 .align 8
142.Lorb: .long 0x00000000,0x0080ff00,.Lccws
143.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
144.Lcr6: .long 0xff000000
145.Lloadp:.long 0,0
146 .align 8
147.Lcrash:.long 0x000a0000,0x00000000
1da177e4 148
25d83cbf
HC
149 .align 8
150.Lccws: .rept 19
151 .long 0x02600050,0x00000000
152 .endr
153 .long 0x02200050,0x00000000
1da177e4
LT
154
155iplstart:
f52c74fe
HC
156 mvi __LC_AR_MODE_ID,1 # set esame flag
157 slr %r0,%r0 # set cpuid to zero
158 lhi %r1,2 # mode 2 = esame (dump)
159 sigp %r1,%r0,0x12 # switch to esame mode
160 bras %r13,0f
161 .fill 16,4,0x0
1620: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
163 sam31 # switch to 31 bit addressing mode
34ba2450 164 lh %r1,__LC_SUBCHANNEL_ID # test if subchannel number
25d83cbf 165 bct %r1,.Lnoload # is valid
34ba2450 166 l %r1,__LC_SUBCHANNEL_ID # load ipl subchannel number
25d83cbf
HC
167 la %r2,IPL_BS # load start address
168 bas %r14,.Lloader # load rest of ipl image
169 l %r12,.Lparm # pointer to parameter area
170 st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
1da177e4
LT
171
172#
173# load parameter file from ipl device
174#
175.Lagain1:
25d83cbf
HC
176 l %r2,.Linitrd # ramdisk loc. is temp
177 bas %r14,.Lloader # load parameter file
178 ltr %r2,%r2 # got anything ?
179 bz .Lnopf
180 chi %r2,895
181 bnh .Lnotrunc
182 la %r2,895
1da177e4 183.Lnotrunc:
25d83cbf
HC
184 l %r4,.Linitrd
185 clc 0(3,%r4),.L_hdr # if it is HDRx
186 bz .Lagain1 # skip dataset header
187 clc 0(3,%r4),.L_eof # if it is EOFx
188 bz .Lagain1 # skip dateset trailer
189 la %r5,0(%r4,%r2)
190 lr %r3,%r2
61fd330d 191 la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
25d83cbf
HC
192 mvc 0(256,%r3),0(%r4)
193 mvc 256(256,%r3),256(%r4)
194 mvc 512(256,%r3),512(%r4)
195 mvc 768(122,%r3),768(%r4)
196 slr %r0,%r0
197 b .Lcntlp
1da177e4 198.Ldelspc:
25d83cbf
HC
199 ic %r0,0(%r2,%r3)
200 chi %r0,0x20 # is it a space ?
201 be .Lcntlp
202 ahi %r2,1
203 b .Leolp
1da177e4 204.Lcntlp:
25d83cbf 205 brct %r2,.Ldelspc
1da177e4 206.Leolp:
25d83cbf
HC
207 slr %r0,%r0
208 stc %r0,0(%r2,%r3) # terminate buffer
1da177e4
LT
209.Lnopf:
210
211#
212# load ramdisk from ipl device
25d83cbf 213#
1da177e4 214.Lagain2:
25d83cbf
HC
215 l %r2,.Linitrd # addr of ramdisk
216 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
217 bas %r14,.Lloader # load ramdisk
218 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
219 ltr %r2,%r2
220 bnz .Lrdcont
221 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
1da177e4 222.Lrdcont:
25d83cbf 223 l %r2,.Linitrd
1da177e4 224
25d83cbf
HC
225 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
226 bz .Lagain2
227 clc 0(3,%r2),.L_eof
228 bz .Lagain2
1da177e4 229
1da177e4
LT
230#
231# reset files in VM reader
232#
51eee033
MS
233 stidp .Lcpuid # store cpuid
234 tm .Lcpuid,0xff # running VM ?
25d83cbf
HC
235 bno .Lnoreset
236 la %r2,.Lreset
237 lhi %r3,26
238 diag %r2,%r3,8
239 la %r5,.Lirb
240 stsch 0(%r5) # check if irq is pending
241 tm 30(%r5),0x0f # by verifying if any of the
242 bnz .Lwaitforirq # activity or status control
243 tm 31(%r5),0xff # bits is set in the schib
244 bz .Lnoreset
350e3ade 245.Lwaitforirq:
51eee033 246 bas %r14,.Lirqwait # wait for IO interrupt
34ba2450 247 c %r1,__LC_SUBCHANNEL_ID # compare subchannel number
51eee033 248 bne .Lwaitforirq
25d83cbf
HC
249 la %r5,.Lirb
250 tsch 0(%r5)
1da177e4 251.Lnoreset:
25d83cbf 252 b .Lnoload
2b071886 253
1da177e4
LT
254#
255# everything loaded, go for it
256#
257.Lnoload:
25d83cbf
HC
258 l %r1,.Lstartup
259 br %r1
1da177e4 260
e033b9a0 261.Linitrd:.long _end # default address of initrd
1da177e4
LT
262.Lparm: .long PARMAREA
263.Lstartup: .long startup
25d83cbf
HC
264.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
265 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
266 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
267.L_eof: .long 0xc5d6c600 /* C'EOF' */
268.L_hdr: .long 0xc8c4d900 /* C'HDR' */
51eee033
MS
269 .align 8
270.Lcpuid:.fill 8,1,0
1da177e4 271
e37f50e1
MS
272#
273# startup-code at 0x10000, running in absolute addressing mode
274# this is called either by the ipl loader or directly by PSW restart
275# or linload or SALIPL
276#
277 .org 0x10000
144d634a 278ENTRY(startup)
60a0c68d 279 j .Lep_startup_normal
627c9b62 280 .org EP_OFFSET
60a0c68d
MH
281#
282# This is a list of s390 kernel entry points. At address 0x1000f the number of
283# valid entry points is stored.
284#
285# IMPORTANT: Do not change this table, it is s390 kernel ABI!
286#
627c9b62 287 .ascii EP_STRING
60a0c68d
MH
288 .byte 0x00,0x01
289#
290# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
291#
292 .org 0x10010
293ENTRY(startup_kdump)
294 j .Lep_startup_kdump
295.Lep_startup_normal:
51eee033
MS
296 mvi __LC_AR_MODE_ID,1 # set esame flag
297 slr %r0,%r0 # set cpuid to zero
298 lhi %r1,2 # mode 2 = esame (dump)
299 sigp %r1,%r0,0x12 # switch to esame mode
300 bras %r13,0f
301 .fill 16,4,0x0
3020: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
c6eafbf9 303 sam64 # switch to 64 bit addressing mode
1844c9bc 304 basr %r13,0 # get base
e37f50e1 305.LPG0:
866ba284
MS
306 xc 0x200(256),0x200 # partially clear lowcore
307 xc 0x300(256),0x300
60a0c68d 308 xc 0xe00(256),0xe00
76cdd44c 309 xc 0xf00(256),0xf00
a80313ff 310 lctlg %c0,%c15,.Lctl-.LPG0(%r13) # load control registers
6e2ef5e4
MS
311 stcke __LC_BOOT_CLOCK
312 mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
991c1505
HC
313 spt 6f-.LPG0(%r13)
314 mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
be2412c2 315 l %r15,.Lstack-.LPG0(%r13)
be2412c2 316 brasl %r14,verify_facilities
8f75582a 317 brasl %r14,startup_kernel
51eee033 318
be2412c2 319.Lstack:
19733fe8 320 .long 0x8000 + (1<<(PAGE_SHIFT+BOOT_STACK_ORDER)) - STACK_FRAME_OVERHEAD
ab96e798 321 .align 8
991c1505 3226: .long 0x7fffffff,0xffffffff
e37f50e1 323
a80313ff
GS
324.Lctl: .quad 0x04040000 # cr0: AFP registers & secondary space
325 .quad 0 # cr1: primary space segment table
326 .quad .Lduct # cr2: dispatchable unit control table
327 .quad 0 # cr3: instruction authorization
328 .quad 0xffff # cr4: instruction authorization
329 .quad .Lduct # cr5: primary-aste origin
330 .quad 0 # cr6: I/O interrupts
331 .quad 0 # cr7: secondary space segment table
17248ea0 332 .quad 0x0000000000008000 # cr8: access registers translation
a80313ff
GS
333 .quad 0 # cr9: tracing off
334 .quad 0 # cr10: tracing off
335 .quad 0 # cr11: tracing off
336 .quad 0 # cr12: tracing off
337 .quad 0 # cr13: home space segment table
338 .quad 0xc0000000 # cr14: machine check handling off
339 .quad .Llinkage_stack # cr15: linkage stack operations
340
341 .section .dma.data,"aw",@progbits
342.Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0
343 .long 0,0,0,0,0,0,0,0
344.Llinkage_stack:
345 .long 0,0,0x89000000,0,0,0,0x8a000000,0
346 .align 64
347.Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0
348 .align 128
349.Lduald:.rept 8
350 .long 0x80000000,0,0,0 # invalid access-list entries
351 .endr
352 .previous
353
60a0c68d
MH
354#include "head_kdump.S"
355
da9ed30d
VG
356#
357# This program check is active immediately after kernel start
358# and until early_pgm_check_handler is set in kernel/early.c
359# It simply saves general/control registers and psw in
360# the save area and does disabled wait with a faulty address.
361#
362ENTRY(startup_pgm_check_handler)
363 stmg %r0,%r15,__LC_SAVE_AREA_SYNC
364 la %r1,4095
365 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1)
366 mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC
367 mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW
da9ed30d
VG
368 mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW
369 ni __LC_RETURN_PSW,0xfc # remove IO and EX bits
370 ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit
371 oi __LC_RETURN_PSW+1,0x2 # set wait state bit
724dc336
VG
372 larl %r2,.Lold_psw_disabled_wait
373 stg %r2,__LC_PGM_NEW_PSW+8
374 l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r2)
375 brasl %r14,print_pgm_check_info
376.Lold_psw_disabled_wait:
377 la %r1,4095
378 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
da9ed30d 379 lpswe __LC_RETURN_PSW # disabled wait
724dc336
VG
380.Ldump_info_stack:
381 .long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD
da9ed30d
VG
382ENDPROC(startup_pgm_check_handler)
383
e37f50e1
MS
384#
385# params at 10400 (setup.h)
d0d249d7 386# Must be keept in sync with struct parmarea in setup.h
e37f50e1
MS
387#
388 .org PARMAREA
d0d249d7
PR
389 .quad 0 # IPL_DEVICE
390 .quad 0 # INITRD_START
391 .quad 0 # INITRD_SIZE
392 .quad 0 # OLDMEM_BASE
393 .quad 0 # OLDMEM_SIZE
6abe2819 394 .quad kernel_version # points to kernel version string
e37f50e1
MS
395
396 .org COMMAND_LINE
397 .byte "root=/dev/ram0 ro"
398 .byte 0
399
087c4d74
GS
400 .org EARLY_SCCB_OFFSET
401 .fill 4096
402
403 .org HEAD_END