xref: /openbmc/linux/arch/s390/boot/head.S (revision e1e38ea1)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright IBM Corp. 1999, 2010
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>
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)
22 *
23 */
24
25#include <linux/init.h>
26#include <linux/linkage.h>
27#include <asm/asm-offsets.h>
28#include <asm/thread_info.h>
29#include <asm/page.h>
30#include <asm/ptrace.h>
31
32#define ARCH_OFFSET	4
33
34__HEAD
35
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
53	.long	0x02000460,0x60000050		# at 0x200 = iplstart.
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
62
63	.org	0x200
64
65#
66# subroutine to wait for end I/O
67#
68.Lirqwait:
69	mvc	__LC_IO_NEW_PSW(16),.Lnewpsw	# set up IO interrupt psw
70	lpsw	.Lwaitpsw
71.Lioint:
72	br	%r14
73	.align	8
74.Lnewpsw:
75	.quad	0x0000000080000000,.Lioint
76.Lwaitpsw:
77	.long	0x020a0000,0x80000000+.Lioint
78
79#
80# subroutine for loading cards from the reader
81#
82.Lloader:
83	la	%r4,0(%r14)
84	la	%r3,.Lorb		# r2 = address of orb into r2
85	la	%r5,.Lirb		# r4 = address of irb
86	la	%r6,.Lccws
87	la	%r7,20
88.Linit:
89	st	%r2,4(%r6)		# initialize CCW data addresses
90	la	%r2,0x50(%r2)
91	la	%r6,8(%r6)
92	bct	7,.Linit
93
94	lctl	%c6,%c6,.Lcr6		# set IO subclass mask
95	slr	%r2,%r2
96.Lldlp:
97	ssch	0(%r3)			# load chunk of 1600 bytes
98	bnz	.Llderr
99.Lwait4irq:
100	bas	%r14,.Lirqwait
101	c	%r1,__LC_SUBCHANNEL_ID	# compare subchannel number
102	bne	.Lwait4irq
103	tsch	0(%r5)
104
105	slr	%r0,%r0
106	ic	%r0,8(%r5)		# get device status
107	chi	%r0,8			# channel end ?
108	be	.Lcont
109	chi	%r0,12			# channel end + device end ?
110	be	.Lcont
111
112	l	%r0,4(%r5)
113	s	%r0,8(%r3)		# r0/8 = number of ccws executed
114	mhi	%r0,10			# *10 = number of bytes in ccws
115	lh	%r3,10(%r5)		# get residual count
116	sr	%r0,%r3 		# #ccws*80-residual=#bytes read
117	ar	%r2,%r0
118
119	br	%r4			# r2 contains the total size
120
121.Lcont:
122	ahi	%r2,0x640		# add 0x640 to total size
123	la	%r6,.Lccws
124	la	%r7,20
125.Lincr:
126	l	%r0,4(%r6)		# update CCW data addresses
127	ahi	%r0,0x640
128	st	%r0,4(%r6)
129	ahi	%r6,8
130	bct	7,.Lincr
131
132	b	.Lldlp
133.Llderr:
134	lpsw	.Lcrash
135
136	.align	8
137.Lorb:	.long	0x00000000,0x0080ff00,.Lccws
138.Lirb:	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
139.Lcr6:	.long	0xff000000
140.Lloadp:.long	0,0
141	.align	8
142.Lcrash:.long	0x000a0000,0x00000000
143
144	.align	8
145.Lccws: .rept	19
146	.long	0x02600050,0x00000000
147	.endr
148	.long	0x02200050,0x00000000
149
150iplstart:
151	mvi	__LC_AR_MODE_ID,1	# set esame flag
152	slr	%r0,%r0			# set cpuid to zero
153	lhi	%r1,2			# mode 2 = esame (dump)
154	sigp	%r1,%r0,0x12		# switch to esame mode
155	bras	%r13,0f
156	.fill	16,4,0x0
1570:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
158	sam31				# switch to 31 bit addressing mode
159	lh	%r1,__LC_SUBCHANNEL_ID	# test if subchannel number
160	bct	%r1,.Lnoload		#  is valid
161	l	%r1,__LC_SUBCHANNEL_ID	# load ipl subchannel number
162	la	%r2,IPL_BS		# load start address
163	bas	%r14,.Lloader		# load rest of ipl image
164	l	%r12,.Lparm		# pointer to parameter area
165	st	%r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
166
167#
168# load parameter file from ipl device
169#
170.Lagain1:
171	l	%r2,.Linitrd		# ramdisk loc. is temp
172	bas	%r14,.Lloader		# load parameter file
173	ltr	%r2,%r2 		# got anything ?
174	bz	.Lnopf
175	chi	%r2,895
176	bnh	.Lnotrunc
177	la	%r2,895
178.Lnotrunc:
179	l	%r4,.Linitrd
180	clc	0(3,%r4),.L_hdr		# if it is HDRx
181	bz	.Lagain1		# skip dataset header
182	clc	0(3,%r4),.L_eof		# if it is EOFx
183	bz	.Lagain1		# skip dateset trailer
184	la	%r5,0(%r4,%r2)
185	lr	%r3,%r2
186	la	%r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
187	mvc	0(256,%r3),0(%r4)
188	mvc	256(256,%r3),256(%r4)
189	mvc	512(256,%r3),512(%r4)
190	mvc	768(122,%r3),768(%r4)
191	slr	%r0,%r0
192	b	.Lcntlp
193.Ldelspc:
194	ic	%r0,0(%r2,%r3)
195	chi	%r0,0x20		# is it a space ?
196	be	.Lcntlp
197	ahi	%r2,1
198	b	.Leolp
199.Lcntlp:
200	brct	%r2,.Ldelspc
201.Leolp:
202	slr	%r0,%r0
203	stc	%r0,0(%r2,%r3)		# terminate buffer
204.Lnopf:
205
206#
207# load ramdisk from ipl device
208#
209.Lagain2:
210	l	%r2,.Linitrd		# addr of ramdisk
211	st	%r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
212	bas	%r14,.Lloader		# load ramdisk
213	st	%r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
214	ltr	%r2,%r2
215	bnz	.Lrdcont
216	st	%r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
217.Lrdcont:
218	l	%r2,.Linitrd
219
220	clc	0(3,%r2),.L_hdr		# skip HDRx and EOFx
221	bz	.Lagain2
222	clc	0(3,%r2),.L_eof
223	bz	.Lagain2
224
225#
226# reset files in VM reader
227#
228	stidp	.Lcpuid			# store cpuid
229	tm	.Lcpuid,0xff		# running VM ?
230	bno	.Lnoreset
231	la	%r2,.Lreset
232	lhi	%r3,26
233	diag	%r2,%r3,8
234	la	%r5,.Lirb
235	stsch	0(%r5)			# check if irq is pending
236	tm	30(%r5),0x0f		# by verifying if any of the
237	bnz	.Lwaitforirq		# activity or status control
238	tm	31(%r5),0xff		# bits is set in the schib
239	bz	.Lnoreset
240.Lwaitforirq:
241	bas	%r14,.Lirqwait		# wait for IO interrupt
242	c	%r1,__LC_SUBCHANNEL_ID	# compare subchannel number
243	bne	.Lwaitforirq
244	la	%r5,.Lirb
245	tsch	0(%r5)
246.Lnoreset:
247	b	.Lnoload
248
249#
250# everything loaded, go for it
251#
252.Lnoload:
253	l	%r1,.Lstartup
254	br	%r1
255
256.Linitrd:.long _end			# default address of initrd
257.Lparm:	.long  PARMAREA
258.Lstartup: .long startup
259.Lreset:.byte	0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
260	.byte	0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
261	.byte	0xc8,0xd6,0xd3,0xc4	# "change rdr all keep nohold"
262.L_eof: .long	0xc5d6c600	 /* C'EOF' */
263.L_hdr: .long	0xc8c4d900	 /* C'HDR' */
264	.align	8
265.Lcpuid:.fill	8,1,0
266
267#
268# startup-code at 0x10000, running in absolute addressing mode
269# this is called either by the ipl loader or directly by PSW restart
270# or linload or SALIPL
271#
272	.org	0x10000
273ENTRY(startup)
274	j	.Lep_startup_normal
275	.org	EP_OFFSET
276#
277# This is a list of s390 kernel entry points. At address 0x1000f the number of
278# valid entry points is stored.
279#
280# IMPORTANT: Do not change this table, it is s390 kernel ABI!
281#
282	.ascii	EP_STRING
283	.byte	0x00,0x01
284#
285# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
286#
287	.org	0x10010
288ENTRY(startup_kdump)
289	j	.Lep_startup_kdump
290.Lep_startup_normal:
291	mvi	__LC_AR_MODE_ID,1	# set esame flag
292	slr	%r0,%r0 		# set cpuid to zero
293	lhi	%r1,2			# mode 2 = esame (dump)
294	sigp	%r1,%r0,0x12		# switch to esame mode
295	bras	%r13,0f
296	.fill	16,4,0x0
2970:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
298	sam64				# switch to 64 bit addressing mode
299	basr	%r13,0			# get base
300.LPG0:
301	xc	0x200(256),0x200	# partially clear lowcore
302	xc	0x300(256),0x300
303	xc	0xe00(256),0xe00
304	xc	0xf00(256),0xf00
305	lctlg	%c0,%c15,0x200(%r0)	# initialize control registers
306	stcke	__LC_BOOT_CLOCK
307	mvc	__LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
308	spt	6f-.LPG0(%r13)
309	mvc	__LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
310	l	%r15,.Lstack-.LPG0(%r13)
311	ahi	%r15,-STACK_FRAME_OVERHEAD
312	brasl	%r14,verify_facilities
313#ifdef CONFIG_KERNEL_UNCOMPRESSED
314	jg	startup_continue
315#else
316	jg	startup_decompressor
317#endif
318
319.Lstack:
320	.long	0x8000 + (1<<(PAGE_SHIFT+THREAD_SIZE_ORDER))
321	.align	8
3226:	.long	0x7fffffff,0xffffffff
323
324#include "head_kdump.S"
325
326#
327# params at 10400 (setup.h)
328#
329	.org	PARMAREA
330	.long	0,0			# IPL_DEVICE
331	.long	0,0			# INITRD_START
332	.long	0,0			# INITRD_SIZE
333	.long	0,0			# OLDMEM_BASE
334	.long	0,0			# OLDMEM_SIZE
335
336	.org	COMMAND_LINE
337	.byte	"root=/dev/ram0 ro"
338	.byte	0
339
340	.org	0x11000
341