| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Heiko Carstens | 0ad775d | 2005-11-07 00:59:12 -0800 | [diff] [blame] | 2 |  * arch/s390/kernel/head64.S | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 |  * | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 4 |  * Copyright (C) IBM Corp. 1999,2006 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 5 |  * | 
| Heiko Carstens | 0ad775d | 2005-11-07 00:59:12 -0800 | [diff] [blame] | 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 |  * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 |  */ | 
 | 12 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 13 | # | 
| Heiko Carstens | 0ad775d | 2005-11-07 00:59:12 -0800 | [diff] [blame] | 14 | # startup-code at 0x10000, running in absolute addressing mode | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 | # this is called either by the ipl loader or directly by PSW restart | 
 | 16 | # or linload or SALIPL | 
 | 17 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 18 | 	.org	0x10000 | 
 | 19 | startup:basr	%r13,0			# get base | 
 | 20 | .LPG0:	l	%r13,0f-.LPG0(%r13) | 
 | 21 | 	b	0(%r13) | 
 | 22 | 0:	.long	startup_continue | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 23 |  | 
 | 24 | # | 
 | 25 | # params at 10400 (setup.h) | 
 | 26 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 27 | 	.org	PARMAREA | 
 | 28 | 	.quad	0			# IPL_DEVICE | 
 | 29 | 	.quad	0			# INITRD_START | 
 | 30 | 	.quad	0			# INITRD_SIZE | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 31 |  | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 32 | 	.org	COMMAND_LINE | 
 | 33 | 	.byte	"root=/dev/ram0 ro" | 
 | 34 | 	.byte	0 | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 35 |  | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 36 | 	.org	0x11000 | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 37 |  | 
 | 38 | startup_continue: | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 39 | 	basr	%r13,0			# get base | 
 | 40 | .LPG1:	sll	%r13,1			# remove high order bit | 
 | 41 | 	srl	%r13,1 | 
| Michael Holzheu | 411ed32 | 2007-04-27 16:01:49 +0200 | [diff] [blame] | 42 |  | 
 | 43 | #ifdef CONFIG_ZFCPDUMP | 
 | 44 |  | 
 | 45 | 	# check if we have been ipled using zfcp dump: | 
 | 46 |  | 
 | 47 | 	tm	0xb9,0x01		# test if subchannel is enabled | 
 | 48 | 	jno	.nodump			# subchannel disabled | 
 | 49 | 	l	%r1,0xb8 | 
 | 50 | 	la	%r5,.Lipl_schib-.LPG1(%r13) | 
 | 51 | 	stsch	0(%r5)			# get schib of subchannel | 
 | 52 | 	jne	.nodump			# schib not available | 
 | 53 | 	tm	5(%r5),0x01		# devno valid? | 
 | 54 | 	jno	.nodump | 
 | 55 | 	tm	4(%r5),0x80		# qdio capable device? | 
 | 56 | 	jno	.nodump | 
 | 57 | 	l	%r2,20(%r0)		# address of ipl parameter block | 
 | 58 | 	lhi	%r3,0 | 
 | 59 | 	ic	%r3,0x148(%r2)		# get opt field | 
 | 60 | 	chi	%r3,0x20		# load with dump? | 
 | 61 | 	jne	.nodump | 
 | 62 |  | 
 | 63 | 	# store all prefix registers in case of load with dump: | 
 | 64 |  | 
 | 65 | 	la	%r7,0			# base register for 0 page | 
 | 66 | 	la	%r8,0			# first cpu | 
 | 67 | 	l	%r11,.Lpref_arr_ptr-.LPG1(%r13)	# address of prefix array | 
 | 68 | 	ahi	%r11,4			# skip boot cpu | 
 | 69 | 	lr	%r12,%r11 | 
 | 70 | 	ahi	%r12,(CONFIG_NR_CPUS*4)	# end of prefix array | 
 | 71 | 	stap	.Lcurrent_cpu+2-.LPG1(%r13)	# store current cpu addr | 
 | 72 | 1: | 
 | 73 | 	cl	%r8,.Lcurrent_cpu-.LPG1(%r13)	# is ipl cpu ? | 
 | 74 | 	je	4f				# if yes get next cpu | 
 | 75 | 2: | 
 | 76 | 	lr	%r9,%r7 | 
 | 77 | 	sigp	%r9,%r8,0x9		# stop & store status of cpu | 
 | 78 | 	brc	8,3f			# accepted | 
 | 79 | 	brc	4,4f			# status stored: next cpu | 
 | 80 | 	brc	2,2b			# busy: 	 try again | 
 | 81 | 	brc	1,4f			# not op:	 next cpu | 
 | 82 | 3: | 
 | 83 | 	mvc	0(4,%r11),264(%r7)	# copy prefix register to prefix array | 
 | 84 | 	ahi	%r11,4			# next element in prefix array | 
 | 85 | 	clr	%r11,%r12 | 
 | 86 | 	je	5f			# no more space in prefix array | 
 | 87 | 4: | 
 | 88 | 	ahi	%r8,1				# next cpu (r8 += 1) | 
 | 89 | 	cl	%r8,.Llast_cpu-.LPG1(%r13)	# is last possible cpu ? | 
 | 90 | 	jl	1b				# jump if not last cpu | 
 | 91 | 5: | 
 | 92 | 	lhi	%r1,2			# mode 2 = esame (dump) | 
 | 93 | 	j	6f | 
 | 94 | 	.align 4 | 
 | 95 | .Lipl_schib: | 
 | 96 | 	.rept 13 | 
 | 97 | 	.long 0 | 
 | 98 | 	.endr | 
 | 99 | .nodump: | 
 | 100 | 	lhi	%r1,1			# mode 1 = esame (normal ipl) | 
 | 101 | 6: | 
 | 102 | #else | 
 | 103 | 	lhi	%r1,1			# mode 1 = esame (normal ipl) | 
 | 104 | #endif /* CONFIG_ZFCPDUMP */ | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 105 | 	mvi	__LC_AR_MODE_ID,1	# set esame flag | 
 | 106 | 	slr	%r0,%r0 		# set cpuid to zero | 
 | 107 | 	sigp	%r1,%r0,0x12		# switch to esame mode | 
 | 108 | 	sam64				# switch to 64 bit mode | 
 | 109 | 	lctlg	%c0,%c15,.Lctl-.LPG1(%r13)	# load control registers | 
 | 110 | 	lg	%r12,.Lparmaddr-.LPG1(%r13)	# pointer to parameter area | 
 | 111 | 					# move IPL device to lowcore | 
 | 112 | 	mvc	__LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) | 
| Heiko Carstens | e87bfe5 | 2006-09-20 15:59:15 +0200 | [diff] [blame] | 113 | # | 
 | 114 | # Setup stack | 
 | 115 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 116 | 	larl	%r15,init_thread_union | 
 | 117 | 	lg	%r14,__TI_task(%r15)	# cache current in lowcore | 
 | 118 | 	stg	%r14,__LC_CURRENT | 
 | 119 | 	aghi	%r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE | 
 | 120 | 	stg	%r15,__LC_KERNEL_STACK	# set end of kernel stack | 
 | 121 | 	aghi	%r15,-160 | 
 | 122 | 	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 123 | # | 
| Hongjie Yang | fe355b7 | 2007-02-05 21:18:24 +0100 | [diff] [blame] | 124 | # Save ipl parameters, clear bss memory, initialize storage key for kernel pages, | 
 | 125 | # and create a kernel NSS if the SAVESYS= parm is defined | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 | # | 
| Hongjie Yang | fe355b7 | 2007-02-05 21:18:24 +0100 | [diff] [blame] | 127 | 	brasl	%r14,startup_init | 
| Heiko Carstens | d57de5a | 2006-12-04 15:40:42 +0100 | [diff] [blame] | 128 | 					# set program check new psw mask | 
 | 129 | 	mvc	__LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 130 | 	larl	%r12,machine_flags | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 131 | # | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 132 | # find out if we have the MVPG instruction | 
 | 133 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 134 | 	la	%r1,0f-.LPG1(%r13)	# set program check address | 
 | 135 | 	stg	%r1,__LC_PGM_NEW_PSW+8 | 
 | 136 | 	sgr	%r0,%r0 | 
 | 137 | 	lghi	%r1,0 | 
 | 138 | 	lghi	%r2,0 | 
 | 139 | 	mvpg	%r1,%r2 		# test MVPG instruction | 
 | 140 | 	oi	7(%r12),16		# set MVPG flag | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 141 | 0: | 
 | 142 |  | 
 | 143 | # | 
 | 144 | # find out if the diag 0x44 works in 64 bit mode | 
 | 145 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 146 | 	la	%r1,0f-.LPG1(%r13)	# set program check address | 
 | 147 | 	stg	%r1,__LC_PGM_NEW_PSW+8 | 
 | 148 | 	diag	0,0,0x44		# test diag 0x44 | 
 | 149 | 	oi	7(%r12),32		# set diag44 flag | 
 | 150 | 0: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 151 |  | 
 | 152 | # | 
 | 153 | # find out if we have the IDTE instruction | 
 | 154 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 155 | 	la	%r1,0f-.LPG1(%r13)	# set program check address | 
 | 156 | 	stg	%r1,__LC_PGM_NEW_PSW+8 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 157 | 	.long	0xb2b10000		# store facility list | 
 | 158 | 	tm	0xc8,0x08		# check bit for clearing-by-ASCE | 
 | 159 | 	bno	0f-.LPG1(%r13) | 
| Martin Schwidefsky | 6f457e1 | 2008-01-26 14:10:58 +0100 | [diff] [blame] | 160 | 	lhi	%r1,2048 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 161 | 	lhi	%r2,0 | 
 | 162 | 	.long	0xb98e2001 | 
 | 163 | 	oi	7(%r12),0x80		# set IDTE flag | 
 | 164 | 0: | 
 | 165 |  | 
| Gerald Schaefer | 6c2a9e6 | 2006-09-20 15:59:44 +0200 | [diff] [blame] | 166 | # | 
| Martin Schwidefsky | 3c1fcfe | 2006-09-30 23:27:45 -0700 | [diff] [blame] | 167 | # find out if the diag 0x9c is available | 
 | 168 | # | 
| Heiko Carstens | cb601d4 | 2006-10-04 20:02:15 +0200 | [diff] [blame] | 169 | 	la	%r1,0f-.LPG1(%r13)	# set program check address | 
 | 170 | 	stg	%r1,__LC_PGM_NEW_PSW+8 | 
 | 171 | 	stap	__LC_CPUID+4		# store cpu address | 
 | 172 | 	lh	%r1,__LC_CPUID+4 | 
 | 173 | 	diag	%r1,0,0x9c		# test diag 0x9c | 
 | 174 | 	oi	6(%r12),1		# set diag9c flag | 
| Martin Schwidefsky | 3c1fcfe | 2006-09-30 23:27:45 -0700 | [diff] [blame] | 175 | 0: | 
 | 176 |  | 
 | 177 | # | 
| Gerald Schaefer | 6c2a9e6 | 2006-09-20 15:59:44 +0200 | [diff] [blame] | 178 | # find out if we have the MVCOS instruction | 
 | 179 | # | 
 | 180 | 	la	%r1,0f-.LPG1(%r13)	# set program check address | 
 | 181 | 	stg	%r1,__LC_PGM_NEW_PSW+8 | 
 | 182 | 	.short	0xc800			# mvcos 0(%r0),0(%r0),%r0 | 
 | 183 | 	.short	0x0000 | 
 | 184 | 	.short	0x0000 | 
 | 185 | 0:	tm	0x8f,0x13		# special-operation exception? | 
 | 186 | 	bno	1f-.LPG1(%r13)		# if yes, MVCOS is present | 
 | 187 | 	oi	6(%r12),2		# set MVCOS flag | 
 | 188 | 1: | 
 | 189 |  | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 190 | 	lpswe	.Lentry-.LPG1(13)	# jump to _stext in primary-space, | 
 | 191 | 					# virtual and never return ... | 
 | 192 | 	.align	16 | 
 | 193 | .Lentry:.quad	0x0000000180000000,_stext | 
 | 194 | .Lctl:	.quad	0x04b50002		# cr0: various things | 
 | 195 | 	.quad	0			# cr1: primary space segment table | 
 | 196 | 	.quad	.Lduct			# cr2: dispatchable unit control table | 
 | 197 | 	.quad	0			# cr3: instruction authorization | 
 | 198 | 	.quad	0			# cr4: instruction authorization | 
| Gerald Schaefer | 482b05d | 2007-03-05 23:35:54 +0100 | [diff] [blame] | 199 | 	.quad	.Lduct			# cr5: primary-aste origin | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 200 | 	.quad	0			# cr6:	I/O interrupts | 
 | 201 | 	.quad	0			# cr7:	secondary space segment table | 
 | 202 | 	.quad	0			# cr8:	access registers translation | 
 | 203 | 	.quad	0			# cr9:	tracing off | 
 | 204 | 	.quad	0			# cr10: tracing off | 
 | 205 | 	.quad	0			# cr11: tracing off | 
 | 206 | 	.quad	0			# cr12: tracing off | 
 | 207 | 	.quad	0			# cr13: home space segment table | 
 | 208 | 	.quad	0xc0000000		# cr14: machine check handling off | 
 | 209 | 	.quad	0			# cr15: linkage stack operations | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 210 | .Lpcmsk:.quad	0x0000000180000000 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 211 | .L4malign:.quad 0xffffffffffc00000 | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 212 | .Lscan2g:.quad	0x80000000 + 0x20000 - 8	# 2GB + 128K - 8 | 
 | 213 | .Lnop:	.long	0x07000700 | 
| Michael Holzheu | 411ed32 | 2007-04-27 16:01:49 +0200 | [diff] [blame] | 214 | #ifdef CONFIG_ZFCPDUMP | 
 | 215 | .Lcurrent_cpu: | 
 | 216 | 	.long 0x0 | 
 | 217 | .Llast_cpu: | 
 | 218 | 	.long 0x0000ffff | 
 | 219 | .Lpref_arr_ptr: | 
 | 220 | 	.long zfcpdump_prefix_array | 
 | 221 | #endif /* CONFIG_ZFCPDUMP */ | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 222 | .Lparmaddr: | 
 | 223 | 	.quad	PARMAREA | 
| Gerald Schaefer | 482b05d | 2007-03-05 23:35:54 +0100 | [diff] [blame] | 224 | 	.align	64 | 
 | 225 | .Lduct: .long	0,0,0,0,.Lduald,0,0,0 | 
 | 226 | 	.long	0,0,0,0,0,0,0,0 | 
 | 227 | 	.align	128 | 
 | 228 | .Lduald:.rept	8 | 
 | 229 | 	.long	0x80000000,0,0,0	# invalid access-list entries | 
 | 230 | 	.endr | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 231 |  | 
| Heiko Carstens | dc8f5d2 | 2006-07-18 13:44:57 +0200 | [diff] [blame] | 232 | 	.org	0x12000 | 
| Heiko Carstens | 615b04b | 2007-02-21 10:55:37 +0100 | [diff] [blame] | 233 | 	.globl	_ehead | 
 | 234 | _ehead: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 235 | #ifdef CONFIG_SHARED_KERNEL | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 236 | 	.org	0x100000 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 237 | #endif | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 238 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 239 | # | 
| Heiko Carstens | b1b7030 | 2006-06-29 14:58:17 +0200 | [diff] [blame] | 240 | # startup-code, running in absolute addressing mode | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 241 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 242 | 	.globl	_stext | 
 | 243 | _stext:	basr	%r13,0			# get base | 
| Heiko Carstens | 1e8e338 | 2005-10-30 15:00:11 -0800 | [diff] [blame] | 244 | .LPG3: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 245 | # check control registers | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 246 | 	stctg	%c0,%c15,0(%r15) | 
 | 247 | 	oi	6(%r15),0x40		# enable sigp emergency signal | 
 | 248 | 	oi	4(%r15),0x10		# switch on low address proctection | 
 | 249 | 	lctlg	%c0,%c15,0(%r15) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 250 |  | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 251 | 	lam	0,15,.Laregs-.LPG3(%r13)	# load acrs needed by uaccess | 
 | 252 | 	brasl	%r14,start_kernel	# go to C code | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 253 | # | 
 | 254 | # We returned from start_kernel ?!? PANIK | 
 | 255 | # | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 256 | 	basr	%r13,0 | 
 | 257 | 	lpswe	.Ldw-.(%r13)		# load disabled wait psw | 
| Heiko Carstens | e87bfe5 | 2006-09-20 15:59:15 +0200 | [diff] [blame] | 258 |  | 
| Heiko Carstens | 25d83cb | 2006-09-28 16:56:37 +0200 | [diff] [blame] | 259 | 	.align	8 | 
 | 260 | .Ldw:	.quad	0x0002000180000000,0x0000000000000000 | 
 | 261 | .Laregs:.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |