xref: /openbmc/linux/arch/s390/kernel/head64.S (revision ba6e8564)
1/*
2 * arch/s390/kernel/head64.S
3 *
4 * Copyright (C) IBM Corp. 1999,2006
5 *
6 *   Author(s):	Hartmut Penner <hp@de.ibm.com>
7 *		Martin Schwidefsky <schwidefsky@de.ibm.com>
8 *		Rob van der Heij <rvdhei@iae.nl>
9 *		Heiko Carstens <heiko.carstens@de.ibm.com>
10 *
11 */
12
13#
14# startup-code at 0x10000, running in absolute addressing mode
15# this is called either by the ipl loader or directly by PSW restart
16# or linload or SALIPL
17#
18	.org	0x10000
19startup:basr	%r13,0			# get base
20.LPG0:	l	%r13,0f-.LPG0(%r13)
21	b	0(%r13)
220:	.long	startup_continue
23
24#
25# params at 10400 (setup.h)
26#
27	.org	PARMAREA
28	.quad	0			# IPL_DEVICE
29	.quad	0			# INITRD_START
30	.quad	0			# INITRD_SIZE
31
32	.org	COMMAND_LINE
33	.byte	"root=/dev/ram0 ro"
34	.byte	0
35
36	.org	0x11000
37
38startup_continue:
39	basr	%r13,0			# get base
40.LPG1:	sll	%r13,1			# remove high order bit
41	srl	%r13,1
42	lhi	%r1,1			# mode 1 = esame
43	mvi	__LC_AR_MODE_ID,1	# set esame flag
44	slr	%r0,%r0 		# set cpuid to zero
45	sigp	%r1,%r0,0x12		# switch to esame mode
46	sam64				# switch to 64 bit mode
47	lctlg	%c0,%c15,.Lctl-.LPG1(%r13)	# load control registers
48	lg	%r12,.Lparmaddr-.LPG1(%r13)	# pointer to parameter area
49					# move IPL device to lowcore
50	mvc	__LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
51#
52# Setup stack
53#
54	larl	%r15,init_thread_union
55	lg	%r14,__TI_task(%r15)	# cache current in lowcore
56	stg	%r14,__LC_CURRENT
57	aghi	%r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
58	stg	%r15,__LC_KERNEL_STACK	# set end of kernel stack
59	aghi	%r15,-160
60	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
61#
62# Save ipl parameters, clear bss memory, initialize storage key for kernel pages,
63# and create a kernel NSS if the SAVESYS= parm is defined
64#
65	brasl	%r14,startup_init
66					# set program check new psw mask
67	mvc	__LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
68	larl	%r12,machine_flags
69#
70# find out if we have the MVPG instruction
71#
72	la	%r1,0f-.LPG1(%r13)	# set program check address
73	stg	%r1,__LC_PGM_NEW_PSW+8
74	sgr	%r0,%r0
75	lghi	%r1,0
76	lghi	%r2,0
77	mvpg	%r1,%r2 		# test MVPG instruction
78	oi	7(%r12),16		# set MVPG flag
790:
80
81#
82# find out if the diag 0x44 works in 64 bit mode
83#
84	la	%r1,0f-.LPG1(%r13)	# set program check address
85	stg	%r1,__LC_PGM_NEW_PSW+8
86	diag	0,0,0x44		# test diag 0x44
87	oi	7(%r12),32		# set diag44 flag
880:
89
90#
91# find out if we have the IDTE instruction
92#
93	la	%r1,0f-.LPG1(%r13)	# set program check address
94	stg	%r1,__LC_PGM_NEW_PSW+8
95	.long	0xb2b10000		# store facility list
96	tm	0xc8,0x08		# check bit for clearing-by-ASCE
97	bno	0f-.LPG1(%r13)
98	lhi	%r1,2094
99	lhi	%r2,0
100	.long	0xb98e2001
101	oi	7(%r12),0x80		# set IDTE flag
1020:
103
104#
105# find out if the diag 0x9c is available
106#
107	la	%r1,0f-.LPG1(%r13)	# set program check address
108	stg	%r1,__LC_PGM_NEW_PSW+8
109	stap	__LC_CPUID+4		# store cpu address
110	lh	%r1,__LC_CPUID+4
111	diag	%r1,0,0x9c		# test diag 0x9c
112	oi	6(%r12),1		# set diag9c flag
1130:
114
115#
116# find out if we have the MVCOS instruction
117#
118	la	%r1,0f-.LPG1(%r13)	# set program check address
119	stg	%r1,__LC_PGM_NEW_PSW+8
120	.short	0xc800			# mvcos 0(%r0),0(%r0),%r0
121	.short	0x0000
122	.short	0x0000
1230:	tm	0x8f,0x13		# special-operation exception?
124	bno	1f-.LPG1(%r13)		# if yes, MVCOS is present
125	oi	6(%r12),2		# set MVCOS flag
1261:
127
128	lpswe	.Lentry-.LPG1(13)	# jump to _stext in primary-space,
129					# virtual and never return ...
130	.align	16
131.Lentry:.quad	0x0000000180000000,_stext
132.Lctl:	.quad	0x04b50002		# cr0: various things
133	.quad	0			# cr1: primary space segment table
134	.quad	.Lduct			# cr2: dispatchable unit control table
135	.quad	0			# cr3: instruction authorization
136	.quad	0			# cr4: instruction authorization
137	.quad	.Lduct			# cr5: primary-aste origin
138	.quad	0			# cr6:	I/O interrupts
139	.quad	0			# cr7:	secondary space segment table
140	.quad	0			# cr8:	access registers translation
141	.quad	0			# cr9:	tracing off
142	.quad	0			# cr10: tracing off
143	.quad	0			# cr11: tracing off
144	.quad	0			# cr12: tracing off
145	.quad	0			# cr13: home space segment table
146	.quad	0xc0000000		# cr14: machine check handling off
147	.quad	0			# cr15: linkage stack operations
148.Lpcmsk:.quad	0x0000000180000000
149.L4malign:.quad 0xffffffffffc00000
150.Lscan2g:.quad	0x80000000 + 0x20000 - 8	# 2GB + 128K - 8
151.Lnop:	.long	0x07000700
152.Lparmaddr:
153	.quad	PARMAREA
154	.align	64
155.Lduct: .long	0,0,0,0,.Lduald,0,0,0
156	.long	0,0,0,0,0,0,0,0
157	.align	128
158.Lduald:.rept	8
159	.long	0x80000000,0,0,0	# invalid access-list entries
160	.endr
161
162	.org	0x12000
163	.globl	_ehead
164_ehead:
165#ifdef CONFIG_SHARED_KERNEL
166	.org	0x100000
167#endif
168
169#
170# startup-code, running in absolute addressing mode
171#
172	.globl	_stext
173_stext:	basr	%r13,0			# get base
174.LPG3:
175# check control registers
176	stctg	%c0,%c15,0(%r15)
177	oi	6(%r15),0x40		# enable sigp emergency signal
178	oi	4(%r15),0x10		# switch on low address proctection
179	lctlg	%c0,%c15,0(%r15)
180
181	lam	0,15,.Laregs-.LPG3(%r13)	# load acrs needed by uaccess
182	brasl	%r14,start_kernel	# go to C code
183#
184# We returned from start_kernel ?!? PANIK
185#
186	basr	%r13,0
187	lpswe	.Ldw-.(%r13)		# load disabled wait psw
188
189	.align	8
190.Ldw:	.quad	0x0002000180000000,0x0000000000000000
191.Laregs:.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
192