xref: /openbmc/linux/arch/s390/boot/head.S (revision 13b5bd8a)
18282cd64SVasily Gorbik/* SPDX-License-Identifier: GPL-2.0 */
28282cd64SVasily Gorbik/*
38282cd64SVasily Gorbik * Copyright IBM Corp. 1999, 2010
48282cd64SVasily Gorbik *
58282cd64SVasily Gorbik *    Author(s): Hartmut Penner <hp@de.ibm.com>
68282cd64SVasily Gorbik *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
78282cd64SVasily Gorbik *		 Rob van der Heij <rvdhei@iae.nl>
88282cd64SVasily Gorbik *		 Heiko Carstens <heiko.carstens@de.ibm.com>
98282cd64SVasily Gorbik *
108282cd64SVasily Gorbik * There are 5 different IPL methods
118282cd64SVasily Gorbik *  1) load the image directly into ram at address 0 and do an PSW restart
128282cd64SVasily Gorbik *  2) linload will load the image from address 0x10000 to memory 0x10000
138282cd64SVasily Gorbik *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
148282cd64SVasily Gorbik *  3) generate the tape ipl header, store the generated image on a tape
158282cd64SVasily Gorbik *     and ipl from it
168282cd64SVasily Gorbik *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
178282cd64SVasily Gorbik *  4) generate the vm reader ipl header, move the generated image to the
188282cd64SVasily Gorbik *     VM reader (use option NOH!) and do a ipl from reader (VM only)
198282cd64SVasily Gorbik *  5) direct call of start by the SALIPL loader
208282cd64SVasily Gorbik *  We use the cpuid to distinguish between VM and native ipl
218282cd64SVasily Gorbik *  params for kernel are pushed to 0x10400 (see setup.h)
228282cd64SVasily Gorbik *
238282cd64SVasily Gorbik */
248282cd64SVasily Gorbik
258282cd64SVasily Gorbik#include <linux/init.h>
268282cd64SVasily Gorbik#include <linux/linkage.h>
278282cd64SVasily Gorbik#include <asm/asm-offsets.h>
288282cd64SVasily Gorbik#include <asm/thread_info.h>
298282cd64SVasily Gorbik#include <asm/page.h>
308282cd64SVasily Gorbik#include <asm/ptrace.h>
318282cd64SVasily Gorbik
328282cd64SVasily Gorbik#define ARCH_OFFSET	4
338282cd64SVasily Gorbik
348282cd64SVasily Gorbik__HEAD
358282cd64SVasily Gorbik
368282cd64SVasily Gorbik#define IPL_BS	0x730
378282cd64SVasily Gorbik	.org	0
388282cd64SVasily Gorbik	.long	0x00080000,0x80000000+iplstart	# The first 24 bytes are loaded
398282cd64SVasily Gorbik	.long	0x02000018,0x60000050		# by ipl to addresses 0-23.
408282cd64SVasily Gorbik	.long	0x02000068,0x60000050		# (a PSW and two CCWs).
418282cd64SVasily Gorbik	.fill	80-24,1,0x40			# bytes 24-79 are discarded !!
428282cd64SVasily Gorbik	.long	0x020000f0,0x60000050		# The next 160 byte are loaded
438282cd64SVasily Gorbik	.long	0x02000140,0x60000050		# to addresses 0x18-0xb7
448282cd64SVasily Gorbik	.long	0x02000190,0x60000050		# They form the continuation
458282cd64SVasily Gorbik	.long	0x020001e0,0x60000050		# of the CCW program started
468282cd64SVasily Gorbik	.long	0x02000230,0x60000050		# by ipl and load the range
478282cd64SVasily Gorbik	.long	0x02000280,0x60000050		# 0x0f0-0x730 from the image
488282cd64SVasily Gorbik	.long	0x020002d0,0x60000050		# to the range 0x0f0-0x730
498282cd64SVasily Gorbik	.long	0x02000320,0x60000050		# in memory. At the end of
508282cd64SVasily Gorbik	.long	0x02000370,0x60000050		# the channel program the PSW
518282cd64SVasily Gorbik	.long	0x020003c0,0x60000050		# at location 0 is loaded.
528282cd64SVasily Gorbik	.long	0x02000410,0x60000050		# Initial processing starts
538282cd64SVasily Gorbik	.long	0x02000460,0x60000050		# at 0x200 = iplstart.
548282cd64SVasily Gorbik	.long	0x020004b0,0x60000050
558282cd64SVasily Gorbik	.long	0x02000500,0x60000050
568282cd64SVasily Gorbik	.long	0x02000550,0x60000050
578282cd64SVasily Gorbik	.long	0x020005a0,0x60000050
588282cd64SVasily Gorbik	.long	0x020005f0,0x60000050
598282cd64SVasily Gorbik	.long	0x02000640,0x60000050
608282cd64SVasily Gorbik	.long	0x02000690,0x60000050
618282cd64SVasily Gorbik	.long	0x020006e0,0x20000050
628282cd64SVasily Gorbik
63da9ed30dSVasily Gorbik	.org	__LC_RST_NEW_PSW		# 0x1a0
648e5a7627SMartin Schwidefsky	.quad	0,iplstart
65*13b5bd8aSVasily Gorbik	.org	__LC_EXT_NEW_PSW		# 0x1b0
66*13b5bd8aSVasily Gorbik	.quad	0x0002000180000000,0x1b0	# disabled wait
67da9ed30dSVasily Gorbik	.org	__LC_PGM_NEW_PSW		# 0x1d0
68da9ed30dSVasily Gorbik	.quad	0x0000000180000000,startup_pgm_check_handler
69*13b5bd8aSVasily Gorbik	.org	__LC_IO_NEW_PSW			# 0x1f0
70*13b5bd8aSVasily Gorbik	.quad	0x0002000180000000,0x1f0	# disabled wait
718e5a7627SMartin Schwidefsky
728282cd64SVasily Gorbik	.org	0x200
738282cd64SVasily Gorbik
748282cd64SVasily Gorbik#
758282cd64SVasily Gorbik# subroutine to wait for end I/O
768282cd64SVasily Gorbik#
778282cd64SVasily Gorbik.Lirqwait:
788282cd64SVasily Gorbik	mvc	__LC_IO_NEW_PSW(16),.Lnewpsw	# set up IO interrupt psw
798282cd64SVasily Gorbik	lpsw	.Lwaitpsw
808282cd64SVasily Gorbik.Lioint:
818282cd64SVasily Gorbik	br	%r14
828282cd64SVasily Gorbik	.align	8
838282cd64SVasily Gorbik.Lnewpsw:
848282cd64SVasily Gorbik	.quad	0x0000000080000000,.Lioint
858282cd64SVasily Gorbik.Lwaitpsw:
868282cd64SVasily Gorbik	.long	0x020a0000,0x80000000+.Lioint
878282cd64SVasily Gorbik
888282cd64SVasily Gorbik#
898282cd64SVasily Gorbik# subroutine for loading cards from the reader
908282cd64SVasily Gorbik#
918282cd64SVasily Gorbik.Lloader:
928282cd64SVasily Gorbik	la	%r4,0(%r14)
938282cd64SVasily Gorbik	la	%r3,.Lorb		# r2 = address of orb into r2
948282cd64SVasily Gorbik	la	%r5,.Lirb		# r4 = address of irb
958282cd64SVasily Gorbik	la	%r6,.Lccws
968282cd64SVasily Gorbik	la	%r7,20
978282cd64SVasily Gorbik.Linit:
988282cd64SVasily Gorbik	st	%r2,4(%r6)		# initialize CCW data addresses
998282cd64SVasily Gorbik	la	%r2,0x50(%r2)
1008282cd64SVasily Gorbik	la	%r6,8(%r6)
1018282cd64SVasily Gorbik	bct	7,.Linit
1028282cd64SVasily Gorbik
1038282cd64SVasily Gorbik	lctl	%c6,%c6,.Lcr6		# set IO subclass mask
1048282cd64SVasily Gorbik	slr	%r2,%r2
1058282cd64SVasily Gorbik.Lldlp:
1068282cd64SVasily Gorbik	ssch	0(%r3)			# load chunk of 1600 bytes
1078282cd64SVasily Gorbik	bnz	.Llderr
1088282cd64SVasily Gorbik.Lwait4irq:
1098282cd64SVasily Gorbik	bas	%r14,.Lirqwait
1108282cd64SVasily Gorbik	c	%r1,__LC_SUBCHANNEL_ID	# compare subchannel number
1118282cd64SVasily Gorbik	bne	.Lwait4irq
1128282cd64SVasily Gorbik	tsch	0(%r5)
1138282cd64SVasily Gorbik
1148282cd64SVasily Gorbik	slr	%r0,%r0
1158282cd64SVasily Gorbik	ic	%r0,8(%r5)		# get device status
1168282cd64SVasily Gorbik	chi	%r0,8			# channel end ?
1178282cd64SVasily Gorbik	be	.Lcont
1188282cd64SVasily Gorbik	chi	%r0,12			# channel end + device end ?
1198282cd64SVasily Gorbik	be	.Lcont
1208282cd64SVasily Gorbik
1218282cd64SVasily Gorbik	l	%r0,4(%r5)
1228282cd64SVasily Gorbik	s	%r0,8(%r3)		# r0/8 = number of ccws executed
1238282cd64SVasily Gorbik	mhi	%r0,10			# *10 = number of bytes in ccws
1248282cd64SVasily Gorbik	lh	%r3,10(%r5)		# get residual count
1258282cd64SVasily Gorbik	sr	%r0,%r3 		# #ccws*80-residual=#bytes read
1268282cd64SVasily Gorbik	ar	%r2,%r0
1278282cd64SVasily Gorbik
1288282cd64SVasily Gorbik	br	%r4			# r2 contains the total size
1298282cd64SVasily Gorbik
1308282cd64SVasily Gorbik.Lcont:
1318282cd64SVasily Gorbik	ahi	%r2,0x640		# add 0x640 to total size
1328282cd64SVasily Gorbik	la	%r6,.Lccws
1338282cd64SVasily Gorbik	la	%r7,20
1348282cd64SVasily Gorbik.Lincr:
1358282cd64SVasily Gorbik	l	%r0,4(%r6)		# update CCW data addresses
1368282cd64SVasily Gorbik	ahi	%r0,0x640
1378282cd64SVasily Gorbik	st	%r0,4(%r6)
1388282cd64SVasily Gorbik	ahi	%r6,8
1398282cd64SVasily Gorbik	bct	7,.Lincr
1408282cd64SVasily Gorbik
1418282cd64SVasily Gorbik	b	.Lldlp
1428282cd64SVasily Gorbik.Llderr:
1438282cd64SVasily Gorbik	lpsw	.Lcrash
1448282cd64SVasily Gorbik
1458282cd64SVasily Gorbik	.align	8
1468282cd64SVasily Gorbik.Lorb:	.long	0x00000000,0x0080ff00,.Lccws
1478282cd64SVasily Gorbik.Lirb:	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1488282cd64SVasily Gorbik.Lcr6:	.long	0xff000000
1498282cd64SVasily Gorbik.Lloadp:.long	0,0
1508282cd64SVasily Gorbik	.align	8
1518282cd64SVasily Gorbik.Lcrash:.long	0x000a0000,0x00000000
1528282cd64SVasily Gorbik
1538282cd64SVasily Gorbik	.align	8
1548282cd64SVasily Gorbik.Lccws: .rept	19
1558282cd64SVasily Gorbik	.long	0x02600050,0x00000000
1568282cd64SVasily Gorbik	.endr
1578282cd64SVasily Gorbik	.long	0x02200050,0x00000000
1588282cd64SVasily Gorbik
1598282cd64SVasily Gorbikiplstart:
1608282cd64SVasily Gorbik	mvi	__LC_AR_MODE_ID,1	# set esame flag
1618282cd64SVasily Gorbik	slr	%r0,%r0			# set cpuid to zero
1628282cd64SVasily Gorbik	lhi	%r1,2			# mode 2 = esame (dump)
1638282cd64SVasily Gorbik	sigp	%r1,%r0,0x12		# switch to esame mode
1648282cd64SVasily Gorbik	bras	%r13,0f
1658282cd64SVasily Gorbik	.fill	16,4,0x0
1668282cd64SVasily Gorbik0:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
1678282cd64SVasily Gorbik	sam31				# switch to 31 bit addressing mode
1688282cd64SVasily Gorbik	lh	%r1,__LC_SUBCHANNEL_ID	# test if subchannel number
1698282cd64SVasily Gorbik	bct	%r1,.Lnoload		#  is valid
1708282cd64SVasily Gorbik	l	%r1,__LC_SUBCHANNEL_ID	# load ipl subchannel number
1718282cd64SVasily Gorbik	la	%r2,IPL_BS		# load start address
1728282cd64SVasily Gorbik	bas	%r14,.Lloader		# load rest of ipl image
1738282cd64SVasily Gorbik	l	%r12,.Lparm		# pointer to parameter area
1748282cd64SVasily Gorbik	st	%r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
1758282cd64SVasily Gorbik
1768282cd64SVasily Gorbik#
1778282cd64SVasily Gorbik# load parameter file from ipl device
1788282cd64SVasily Gorbik#
1798282cd64SVasily Gorbik.Lagain1:
1808282cd64SVasily Gorbik	l	%r2,.Linitrd		# ramdisk loc. is temp
1818282cd64SVasily Gorbik	bas	%r14,.Lloader		# load parameter file
1828282cd64SVasily Gorbik	ltr	%r2,%r2 		# got anything ?
1838282cd64SVasily Gorbik	bz	.Lnopf
1848282cd64SVasily Gorbik	chi	%r2,895
1858282cd64SVasily Gorbik	bnh	.Lnotrunc
1868282cd64SVasily Gorbik	la	%r2,895
1878282cd64SVasily Gorbik.Lnotrunc:
1888282cd64SVasily Gorbik	l	%r4,.Linitrd
1898282cd64SVasily Gorbik	clc	0(3,%r4),.L_hdr		# if it is HDRx
1908282cd64SVasily Gorbik	bz	.Lagain1		# skip dataset header
1918282cd64SVasily Gorbik	clc	0(3,%r4),.L_eof		# if it is EOFx
1928282cd64SVasily Gorbik	bz	.Lagain1		# skip dateset trailer
1938282cd64SVasily Gorbik	la	%r5,0(%r4,%r2)
1948282cd64SVasily Gorbik	lr	%r3,%r2
1958282cd64SVasily Gorbik	la	%r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
1968282cd64SVasily Gorbik	mvc	0(256,%r3),0(%r4)
1978282cd64SVasily Gorbik	mvc	256(256,%r3),256(%r4)
1988282cd64SVasily Gorbik	mvc	512(256,%r3),512(%r4)
1998282cd64SVasily Gorbik	mvc	768(122,%r3),768(%r4)
2008282cd64SVasily Gorbik	slr	%r0,%r0
2018282cd64SVasily Gorbik	b	.Lcntlp
2028282cd64SVasily Gorbik.Ldelspc:
2038282cd64SVasily Gorbik	ic	%r0,0(%r2,%r3)
2048282cd64SVasily Gorbik	chi	%r0,0x20		# is it a space ?
2058282cd64SVasily Gorbik	be	.Lcntlp
2068282cd64SVasily Gorbik	ahi	%r2,1
2078282cd64SVasily Gorbik	b	.Leolp
2088282cd64SVasily Gorbik.Lcntlp:
2098282cd64SVasily Gorbik	brct	%r2,.Ldelspc
2108282cd64SVasily Gorbik.Leolp:
2118282cd64SVasily Gorbik	slr	%r0,%r0
2128282cd64SVasily Gorbik	stc	%r0,0(%r2,%r3)		# terminate buffer
2138282cd64SVasily Gorbik.Lnopf:
2148282cd64SVasily Gorbik
2158282cd64SVasily Gorbik#
2168282cd64SVasily Gorbik# load ramdisk from ipl device
2178282cd64SVasily Gorbik#
2188282cd64SVasily Gorbik.Lagain2:
2198282cd64SVasily Gorbik	l	%r2,.Linitrd		# addr of ramdisk
2208282cd64SVasily Gorbik	st	%r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
2218282cd64SVasily Gorbik	bas	%r14,.Lloader		# load ramdisk
2228282cd64SVasily Gorbik	st	%r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
2238282cd64SVasily Gorbik	ltr	%r2,%r2
2248282cd64SVasily Gorbik	bnz	.Lrdcont
2258282cd64SVasily Gorbik	st	%r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
2268282cd64SVasily Gorbik.Lrdcont:
2278282cd64SVasily Gorbik	l	%r2,.Linitrd
2288282cd64SVasily Gorbik
2298282cd64SVasily Gorbik	clc	0(3,%r2),.L_hdr		# skip HDRx and EOFx
2308282cd64SVasily Gorbik	bz	.Lagain2
2318282cd64SVasily Gorbik	clc	0(3,%r2),.L_eof
2328282cd64SVasily Gorbik	bz	.Lagain2
2338282cd64SVasily Gorbik
2348282cd64SVasily Gorbik#
2358282cd64SVasily Gorbik# reset files in VM reader
2368282cd64SVasily Gorbik#
2378282cd64SVasily Gorbik	stidp	.Lcpuid			# store cpuid
2388282cd64SVasily Gorbik	tm	.Lcpuid,0xff		# running VM ?
2398282cd64SVasily Gorbik	bno	.Lnoreset
2408282cd64SVasily Gorbik	la	%r2,.Lreset
2418282cd64SVasily Gorbik	lhi	%r3,26
2428282cd64SVasily Gorbik	diag	%r2,%r3,8
2438282cd64SVasily Gorbik	la	%r5,.Lirb
2448282cd64SVasily Gorbik	stsch	0(%r5)			# check if irq is pending
2458282cd64SVasily Gorbik	tm	30(%r5),0x0f		# by verifying if any of the
2468282cd64SVasily Gorbik	bnz	.Lwaitforirq		# activity or status control
2478282cd64SVasily Gorbik	tm	31(%r5),0xff		# bits is set in the schib
2488282cd64SVasily Gorbik	bz	.Lnoreset
2498282cd64SVasily Gorbik.Lwaitforirq:
2508282cd64SVasily Gorbik	bas	%r14,.Lirqwait		# wait for IO interrupt
2518282cd64SVasily Gorbik	c	%r1,__LC_SUBCHANNEL_ID	# compare subchannel number
2528282cd64SVasily Gorbik	bne	.Lwaitforirq
2538282cd64SVasily Gorbik	la	%r5,.Lirb
2548282cd64SVasily Gorbik	tsch	0(%r5)
2558282cd64SVasily Gorbik.Lnoreset:
2568282cd64SVasily Gorbik	b	.Lnoload
2578282cd64SVasily Gorbik
2588282cd64SVasily Gorbik#
2598282cd64SVasily Gorbik# everything loaded, go for it
2608282cd64SVasily Gorbik#
2618282cd64SVasily Gorbik.Lnoload:
2628282cd64SVasily Gorbik	l	%r1,.Lstartup
2638282cd64SVasily Gorbik	br	%r1
2648282cd64SVasily Gorbik
2658282cd64SVasily Gorbik.Linitrd:.long _end			# default address of initrd
2668282cd64SVasily Gorbik.Lparm:	.long  PARMAREA
2678282cd64SVasily Gorbik.Lstartup: .long startup
2688282cd64SVasily Gorbik.Lreset:.byte	0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
2698282cd64SVasily Gorbik	.byte	0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
2708282cd64SVasily Gorbik	.byte	0xc8,0xd6,0xd3,0xc4	# "change rdr all keep nohold"
2718282cd64SVasily Gorbik.L_eof: .long	0xc5d6c600	 /* C'EOF' */
2728282cd64SVasily Gorbik.L_hdr: .long	0xc8c4d900	 /* C'HDR' */
2738282cd64SVasily Gorbik	.align	8
2748282cd64SVasily Gorbik.Lcpuid:.fill	8,1,0
2758282cd64SVasily Gorbik
2768282cd64SVasily Gorbik#
2778282cd64SVasily Gorbik# startup-code at 0x10000, running in absolute addressing mode
2788282cd64SVasily Gorbik# this is called either by the ipl loader or directly by PSW restart
2798282cd64SVasily Gorbik# or linload or SALIPL
2808282cd64SVasily Gorbik#
2818282cd64SVasily Gorbik	.org	0x10000
2828282cd64SVasily GorbikENTRY(startup)
2838282cd64SVasily Gorbik	j	.Lep_startup_normal
284627c9b62SVasily Gorbik	.org	EP_OFFSET
2858282cd64SVasily Gorbik#
2868282cd64SVasily Gorbik# This is a list of s390 kernel entry points. At address 0x1000f the number of
2878282cd64SVasily Gorbik# valid entry points is stored.
2888282cd64SVasily Gorbik#
2898282cd64SVasily Gorbik# IMPORTANT: Do not change this table, it is s390 kernel ABI!
2908282cd64SVasily Gorbik#
291627c9b62SVasily Gorbik	.ascii	EP_STRING
2928282cd64SVasily Gorbik	.byte	0x00,0x01
2938282cd64SVasily Gorbik#
2948282cd64SVasily Gorbik# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
2958282cd64SVasily Gorbik#
2968282cd64SVasily Gorbik	.org	0x10010
2978282cd64SVasily GorbikENTRY(startup_kdump)
2988282cd64SVasily Gorbik	j	.Lep_startup_kdump
2998282cd64SVasily Gorbik.Lep_startup_normal:
3008282cd64SVasily Gorbik	mvi	__LC_AR_MODE_ID,1	# set esame flag
3018282cd64SVasily Gorbik	slr	%r0,%r0 		# set cpuid to zero
3028282cd64SVasily Gorbik	lhi	%r1,2			# mode 2 = esame (dump)
3038282cd64SVasily Gorbik	sigp	%r1,%r0,0x12		# switch to esame mode
3048282cd64SVasily Gorbik	bras	%r13,0f
3058282cd64SVasily Gorbik	.fill	16,4,0x0
3068282cd64SVasily Gorbik0:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
3078282cd64SVasily Gorbik	sam64				# switch to 64 bit addressing mode
3088282cd64SVasily Gorbik	basr	%r13,0			# get base
3098282cd64SVasily Gorbik.LPG0:
310*13b5bd8aSVasily Gorbik	mvc	__LC_EXT_NEW_PSW(16),.Lext_new_psw-.LPG0(%r13)
311*13b5bd8aSVasily Gorbik	mvc	__LC_PGM_NEW_PSW(16),.Lpgm_new_psw-.LPG0(%r13)
312*13b5bd8aSVasily Gorbik	mvc	__LC_IO_NEW_PSW(16),.Lio_new_psw-.LPG0(%r13)
3138282cd64SVasily Gorbik	xc	0x200(256),0x200	# partially clear lowcore
3148282cd64SVasily Gorbik	xc	0x300(256),0x300
3158282cd64SVasily Gorbik	xc	0xe00(256),0xe00
3168282cd64SVasily Gorbik	xc	0xf00(256),0xf00
317a80313ffSGerald Schaefer	lctlg	%c0,%c15,.Lctl-.LPG0(%r13)	# load control registers
3188282cd64SVasily Gorbik	stcke	__LC_BOOT_CLOCK
3198282cd64SVasily Gorbik	mvc	__LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
3208282cd64SVasily Gorbik	spt	6f-.LPG0(%r13)
3218282cd64SVasily Gorbik	mvc	__LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
3228282cd64SVasily Gorbik	l	%r15,.Lstack-.LPG0(%r13)
3238282cd64SVasily Gorbik	brasl	%r14,verify_facilities
3248f75582aSVasily Gorbik	brasl	%r14,startup_kernel
3258282cd64SVasily Gorbik
3268282cd64SVasily Gorbik.Lstack:
32719733fe8SVasily Gorbik	.long	0x8000 + (1<<(PAGE_SHIFT+BOOT_STACK_ORDER)) - STACK_FRAME_OVERHEAD
3288282cd64SVasily Gorbik	.align	8
3298282cd64SVasily Gorbik6:	.long	0x7fffffff,0xffffffff
330*13b5bd8aSVasily Gorbik.Lext_new_psw:
331*13b5bd8aSVasily Gorbik	.quad	0x0002000180000000,0x1b0	# disabled wait
332*13b5bd8aSVasily Gorbik.Lpgm_new_psw:
333*13b5bd8aSVasily Gorbik	.quad	0x0000000180000000,startup_pgm_check_handler
334*13b5bd8aSVasily Gorbik.Lio_new_psw:
335*13b5bd8aSVasily Gorbik	.quad	0x0002000180000000,0x1f0	# disabled wait
336a80313ffSGerald Schaefer.Lctl:	.quad	0x04040000		# cr0: AFP registers & secondary space
337a80313ffSGerald Schaefer	.quad	0			# cr1: primary space segment table
338a80313ffSGerald Schaefer	.quad	.Lduct			# cr2: dispatchable unit control table
339a80313ffSGerald Schaefer	.quad	0			# cr3: instruction authorization
340a80313ffSGerald Schaefer	.quad	0xffff			# cr4: instruction authorization
341a80313ffSGerald Schaefer	.quad	.Lduct			# cr5: primary-aste origin
342a80313ffSGerald Schaefer	.quad	0			# cr6:	I/O interrupts
343a80313ffSGerald Schaefer	.quad	0			# cr7:	secondary space segment table
34417248ea0SSven Schnelle	.quad	0x0000000000008000	# cr8:	access registers translation
345a80313ffSGerald Schaefer	.quad	0			# cr9:	tracing off
346a80313ffSGerald Schaefer	.quad	0			# cr10: tracing off
347a80313ffSGerald Schaefer	.quad	0			# cr11: tracing off
348a80313ffSGerald Schaefer	.quad	0			# cr12: tracing off
349a80313ffSGerald Schaefer	.quad	0			# cr13: home space segment table
350a80313ffSGerald Schaefer	.quad	0xc0000000		# cr14: machine check handling off
351a80313ffSGerald Schaefer	.quad	.Llinkage_stack		# cr15: linkage stack operations
352a80313ffSGerald Schaefer
353a80313ffSGerald Schaefer	.section .dma.data,"aw",@progbits
354a80313ffSGerald Schaefer.Lduct: .long	0,.Laste,.Laste,0,.Lduald,0,0,0
355a80313ffSGerald Schaefer	.long	0,0,0,0,0,0,0,0
356a80313ffSGerald Schaefer.Llinkage_stack:
357a80313ffSGerald Schaefer	.long	0,0,0x89000000,0,0,0,0x8a000000,0
358a80313ffSGerald Schaefer	.align 64
359a80313ffSGerald Schaefer.Laste:	.quad	0,0xffffffffffffffff,0,0,0,0,0,0
360a80313ffSGerald Schaefer	.align	128
361a80313ffSGerald Schaefer.Lduald:.rept	8
362a80313ffSGerald Schaefer	.long	0x80000000,0,0,0	# invalid access-list entries
363a80313ffSGerald Schaefer	.endr
364a80313ffSGerald Schaefer	.previous
365a80313ffSGerald Schaefer
3668282cd64SVasily Gorbik#include "head_kdump.S"
3678282cd64SVasily Gorbik
3688282cd64SVasily Gorbik#
369da9ed30dSVasily Gorbik# This program check is active immediately after kernel start
370da9ed30dSVasily Gorbik# and until early_pgm_check_handler is set in kernel/early.c
371da9ed30dSVasily Gorbik# It simply saves general/control registers and psw in
372da9ed30dSVasily Gorbik# the save area and does disabled wait with a faulty address.
373da9ed30dSVasily Gorbik#
374da9ed30dSVasily GorbikENTRY(startup_pgm_check_handler)
3752835c2eaSVasily Gorbik	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
3762835c2eaSVasily Gorbik	la	%r8,4095
3772835c2eaSVasily Gorbik	stctg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8)
3782835c2eaSVasily Gorbik	stmg	%r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8)
3792835c2eaSVasily Gorbik	mvc	__LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA_SYNC
3802835c2eaSVasily Gorbik	mvc	__LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW
381da9ed30dSVasily Gorbik	mvc	__LC_RETURN_PSW(16),__LC_PGM_OLD_PSW
382da9ed30dSVasily Gorbik	ni	__LC_RETURN_PSW,0xfc	# remove IO and EX bits
383da9ed30dSVasily Gorbik	ni	__LC_RETURN_PSW+1,0xfb	# remove MCHK bit
384da9ed30dSVasily Gorbik	oi	__LC_RETURN_PSW+1,0x2	# set wait state bit
3852835c2eaSVasily Gorbik	larl	%r9,.Lold_psw_disabled_wait
3862835c2eaSVasily Gorbik	stg	%r9,__LC_PGM_NEW_PSW+8
3872835c2eaSVasily Gorbik	l	%r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r9)
388724dc336SVasily Gorbik	brasl	%r14,print_pgm_check_info
389724dc336SVasily Gorbik.Lold_psw_disabled_wait:
3902835c2eaSVasily Gorbik	la	%r8,4095
3912835c2eaSVasily Gorbik	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8)
392da9ed30dSVasily Gorbik	lpswe	__LC_RETURN_PSW		# disabled wait
393724dc336SVasily Gorbik.Ldump_info_stack:
394724dc336SVasily Gorbik	.long	0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD
395da9ed30dSVasily GorbikENDPROC(startup_pgm_check_handler)
396da9ed30dSVasily Gorbik
397da9ed30dSVasily Gorbik#
3988282cd64SVasily Gorbik# params at 10400 (setup.h)
399d0d249d7SPhilipp Rudo# Must be keept in sync with struct parmarea in setup.h
4008282cd64SVasily Gorbik#
4018282cd64SVasily Gorbik	.org	PARMAREA
402d0d249d7SPhilipp Rudo	.quad	0			# IPL_DEVICE
403d0d249d7SPhilipp Rudo	.quad	0			# INITRD_START
404d0d249d7SPhilipp Rudo	.quad	0			# INITRD_SIZE
405d0d249d7SPhilipp Rudo	.quad	0			# OLDMEM_BASE
406d0d249d7SPhilipp Rudo	.quad	0			# OLDMEM_SIZE
4076abe2819SVasily Gorbik	.quad	kernel_version		# points to kernel version string
4088282cd64SVasily Gorbik
4098282cd64SVasily Gorbik	.org	COMMAND_LINE
4108282cd64SVasily Gorbik	.byte	"root=/dev/ram0 ro"
4118282cd64SVasily Gorbik	.byte	0
4128282cd64SVasily Gorbik
413087c4d74SGerald Schaefer	.org	EARLY_SCCB_OFFSET
414087c4d74SGerald Schaefer	.fill	4096
415087c4d74SGerald Schaefer
416087c4d74SGerald Schaefer	.org	HEAD_END
417