1/*
2 * arch/s390/kernel/head31.S
3 *
4 * Copyright (C) IBM Corp. 2005,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	.long	0,0			# IPL_DEVICE
29	.long	0,0			# INITRD_START
30	.long	0,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:	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
41	lctl	%c0,%c15,.Lctl-.LPG1(%r13) # load control registers
42	l	%r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
43					# move IPL device to lowcore
44	mvc	__LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
45#
46# Setup stack
47#
48	l	%r15,.Linittu-.LPG1(%r13)
49	mvc	__LC_CURRENT(4),__TI_task(%r15)
50	ahi	%r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
51	st	%r15,__LC_KERNEL_STACK	# set end of kernel stack
52	ahi	%r15,-96
53	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
54#
55# Save ipl parameters, clear bss memory, initialize storage key for kernel pages,
56# and create a kernel NSS if the SAVESYS= parm is defined
57#
58	l	%r14,.Lstartup_init-.LPG1(%r13)
59	basr	%r14,%r14
60
61	l	%r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
62#
63# find out if we have an IEEE fpu
64#
65	mvc	__LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
66	efpc	%r0,0			# test IEEE extract fpc instruction
67	oi	3(%r12),2		# set IEEE fpu flag
68.Lchkfpu:
69
70#
71# find out if we have the CSP instruction
72#
73       mvc	 __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
74       la	 %r0,0
75       lr	%r1,%r0
76       la	%r2,4
77       csp	%r0,%r2			# Test CSP instruction
78       oi	3(%r12),8		# set CSP flag
79.Lchkcsp:
80
81#
82# find out if we have the MVPG instruction
83#
84       mvc	__LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
85       sr	%r0,%r0
86       la	%r1,0
87       la	%r2,0
88       mvpg	%r1,%r2			# Test CSP instruction
89       oi	3(%r12),16		# set MVPG flag
90.Lchkmvpg:
91
92#
93# find out if we have the IDTE instruction
94#
95	mvc	__LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
96	.long	0xb2b10000		# store facility list
97	tm	0xc8,0x08		# check bit for clearing-by-ASCE
98	bno	.Lchkidte-.LPG1(%r13)
99	lhi	%r1,2094
100	lhi	%r2,0
101	.long	0xb98e2001
102	oi	3(%r12),0x80		# set IDTE flag
103.Lchkidte:
104
105#
106# find out if the diag 0x9c is available
107#
108	mvc	__LC_PGM_NEW_PSW(8),.Lpcdiag9c-.LPG1(%r13)
109	stap	__LC_CPUID+4		# store cpu address
110	lh	%r1,__LC_CPUID+4
111	diag	%r1,0,0x9c		# test diag 0x9c
112	oi	2(%r12),1		# set diag9c flag
113.Lchkdiag9c:
114
115	lpsw  .Lentry-.LPG1(13)		# jump to _stext in primary-space,
116					# virtual and never return ...
117	.align	8
118.Lentry:.long	0x00080000,0x80000000 + _stext
119.Lctl:	.long	0x04b50002		# cr0: various things
120	.long	0			# cr1: primary space segment table
121	.long	.Lduct			# cr2: dispatchable unit control table
122	.long	0			# cr3: instruction authorization
123	.long	0			# cr4: instruction authorization
124	.long	.Lduct			# cr5: primary-aste origin
125	.long	0			# cr6:	I/O interrupts
126	.long	0			# cr7:	secondary space segment table
127	.long	0			# cr8:	access registers translation
128	.long	0			# cr9:	tracing off
129	.long	0			# cr10: tracing off
130	.long	0			# cr11: tracing off
131	.long	0			# cr12: tracing off
132	.long	0			# cr13: home space segment table
133	.long	0xc0000000		# cr14: machine check handling off
134	.long	0			# cr15: linkage stack operations
135.Lpcfpu:.long	0x00080000,0x80000000 + .Lchkfpu
136.Lpccsp:.long	0x00080000,0x80000000 + .Lchkcsp
137.Lpcmvpg:.long	0x00080000,0x80000000 + .Lchkmvpg
138.Lpcidte:.long	0x00080000,0x80000000 + .Lchkidte
139.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c
140.Lmchunk:.long	memory_chunk
141.Lmflags:.long	machine_flags
142.Lbss_bgn:  .long __bss_start
143.Lbss_end:  .long _end
144.Lparmaddr: .long PARMAREA
145.Linittu:   .long init_thread_union
146.Lstartup_init:
147	    .long startup_init
148	.align	64
149.Lduct:	.long	0,0,0,0,.Lduald,0,0,0
150	.long	0,0,0,0,0,0,0,0
151	.align	128
152.Lduald:.rept	8
153	.long	0x80000000,0,0,0	# invalid access-list entries
154	.endr
155
156	.org	0x12000
157	.globl	_ehead
158_ehead:
159#ifdef CONFIG_SHARED_KERNEL
160	.org	0x100000
161#endif
162
163#
164# startup-code, running in absolute addressing mode
165#
166	.globl	_stext
167_stext:	basr	%r13,0			# get base
168.LPG3:
169# check control registers
170	stctl	%c0,%c15,0(%r15)
171	oi	2(%r15),0x40		# enable sigp emergency signal
172	oi	0(%r15),0x10		# switch on low address protection
173	lctl	%c0,%c15,0(%r15)
174
175#
176	lam	0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
177	l	%r14,.Lstart-.LPG3(%r13)
178	basr	%r14,%r14		# call start_kernel
179#
180# We returned from start_kernel ?!? PANIK
181#
182	basr	%r13,0
183	lpsw	.Ldw-.(%r13)		# load disabled wait psw
184#
185	.align	8
186.Ldw:	.long	0x000a0000,0x00000000
187.Lstart:.long	start_kernel
188.Laregs:.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
189