• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/s390/kernel/
1/*
2 * Copyright IBM Corp. 1999,2010
3 *
4 *    Author(s): Hartmut Penner <hp@de.ibm.com>
5 *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
6 *		 Rob van der Heij <rvdhei@iae.nl>
7 *		 Heiko Carstens <heiko.carstens@de.ibm.com>
8 *
9 * There are 5 different IPL methods
10 *  1) load the image directly into ram at address 0 and do an PSW restart
11 *  2) linload will load the image from address 0x10000 to memory 0x10000
12 *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
13 *  3) generate the tape ipl header, store the generated image on a tape
14 *     and ipl from it
15 *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
16 *  4) generate the vm reader ipl header, move the generated image to the
17 *     VM reader (use option NOH!) and do a ipl from reader (VM only)
18 *  5) direct call of start by the SALIPL loader
19 *  We use the cpuid to distinguish between VM and native ipl
20 *  params for kernel are pushed to 0x10400 (see setup.h)
21 *
22 */
23
24#include <linux/init.h>
25#include <asm/asm-offsets.h>
26#include <asm/thread_info.h>
27#include <asm/page.h>
28
29#ifdef CONFIG_64BIT
30#define ARCH_OFFSET	4
31#else
32#define ARCH_OFFSET	0
33#endif
34
35__HEAD
36#ifndef CONFIG_IPL
37	.org   0
38	.long  0x00080000,0x80000000+startup	# Just a restart PSW
39#else
40#ifdef CONFIG_IPL_TAPE
41#define IPL_BS 1024
42	.org   0
43	.long  0x00080000,0x80000000+iplstart	# The first 24 bytes are loaded
44	.long  0x27000000,0x60000001		# by ipl to addresses 0-23.
45	.long  0x02000000,0x20000000+IPL_BS	# (a PSW and two CCWs).
46	.long  0x00000000,0x00000000		# external old psw
47	.long  0x00000000,0x00000000		# svc old psw
48	.long  0x00000000,0x00000000		# program check old psw
49	.long  0x00000000,0x00000000		# machine check old psw
50	.long  0x00000000,0x00000000		# io old psw
51	.long  0x00000000,0x00000000
52	.long  0x00000000,0x00000000
53	.long  0x00000000,0x00000000
54	.long  0x000a0000,0x00000058		# external new psw
55	.long  0x000a0000,0x00000060		# svc new psw
56	.long  0x000a0000,0x00000068		# program check new psw
57	.long  0x000a0000,0x00000070		# machine check new psw
58	.long  0x00080000,0x80000000+.Lioint	# io new psw
59
60	.org   0x100
61#
62# subroutine for loading from tape
63# Parameters:
64#  R1 = device number
65#  R2 = load address
66.Lloader:
67	st	%r14,.Lldret
68	la	%r3,.Lorbread		# r3 = address of orb
69	la	%r5,.Lirb		# r5 = address of irb
70	st	%r2,.Lccwread+4 	# initialize CCW data addresses
71	lctl	%c6,%c6,.Lcr6
72	slr	%r2,%r2
73.Lldlp:
74	la	%r6,3			# 3 retries
75.Lssch:
76	ssch	0(%r3)			# load chunk of IPL_BS bytes
77	bnz	.Llderr
78.Lw4end:
79	bas	%r14,.Lwait4io
80	tm	8(%r5),0x82		# do we have a problem ?
81	bnz	.Lrecov
82	slr	%r7,%r7
83	icm	%r7,3,10(%r5)		# get residual count
84	lcr	%r7,%r7
85	la	%r7,IPL_BS(%r7) 	# IPL_BS-residual=#bytes read
86	ar	%r2,%r7 		# add to total size
87	tm	8(%r5),0x01		# found a tape mark ?
88	bnz	.Ldone
89	l	%r0,.Lccwread+4 	# update CCW data addresses
90	ar	%r0,%r7
91	st	%r0,.Lccwread+4
92	b	.Lldlp
93.Ldone:
94	l	%r14,.Lldret
95	br	%r14			# r2 contains the total size
96.Lrecov:
97	bas	%r14,.Lsense		# do the sensing
98	bct	%r6,.Lssch		# dec. retry count & branch
99	b	.Llderr
100#
101# Sense subroutine
102#
103.Lsense:
104	st	%r14,.Lsnsret
105	la	%r7,.Lorbsense
106	ssch	0(%r7)			# start sense command
107	bnz	.Llderr
108	bas	%r14,.Lwait4io
109	l	%r14,.Lsnsret
110	tm	8(%r5),0x82		# do we have a problem ?
111	bnz	.Llderr
112	br	%r14
113#
114# Wait for interrupt subroutine
115#
116.Lwait4io:
117	lpsw	.Lwaitpsw
118.Lioint:
119	c	%r1,0xb8		# compare subchannel number
120	bne	.Lwait4io
121	tsch	0(%r5)
122	slr	%r0,%r0
123	tm	8(%r5),0x82		# do we have a problem ?
124	bnz	.Lwtexit
125	tm	8(%r5),0x04		# got device end ?
126	bz	.Lwait4io
127.Lwtexit:
128	br	%r14
129.Llderr:
130	lpsw	.Lcrash
131
132	.align	8
133.Lorbread:
134	.long	0x00000000,0x0080ff00,.Lccwread
135	.align	8
136.Lorbsense:
137	.long	0x00000000,0x0080ff00,.Lccwsense
138	.align	8
139.Lccwread:
140	.long	0x02200000+IPL_BS,0x00000000
141.Lccwsense:
142	.long	0x04200001,0x00000000
143.Lwaitpsw:
144	.long	0x020a0000,0x80000000+.Lioint
145
146.Lirb:	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
147.Lcr6:	.long	0xff000000
148	.align	8
149.Lcrash:.long	0x000a0000,0x00000000
150.Lldret:.long	0
151.Lsnsret: .long 0
152#endif	/* CONFIG_IPL_TAPE */
153
154#ifdef CONFIG_IPL_VM
155#define IPL_BS	0x730
156	.org	0
157	.long	0x00080000,0x80000000+iplstart	# The first 24 bytes are loaded
158	.long	0x02000018,0x60000050		# by ipl to addresses 0-23.
159	.long	0x02000068,0x60000050		# (a PSW and two CCWs).
160	.fill	80-24,1,0x40			# bytes 24-79 are discarded !!
161	.long	0x020000f0,0x60000050		# The next 160 byte are loaded
162	.long	0x02000140,0x60000050		# to addresses 0x18-0xb7
163	.long	0x02000190,0x60000050		# They form the continuation
164	.long	0x020001e0,0x60000050		# of the CCW program started
165	.long	0x02000230,0x60000050		# by ipl and load the range
166	.long	0x02000280,0x60000050		# 0x0f0-0x730 from the image
167	.long	0x020002d0,0x60000050		# to the range 0x0f0-0x730
168	.long	0x02000320,0x60000050		# in memory. At the end of
169	.long	0x02000370,0x60000050		# the channel program the PSW
170	.long	0x020003c0,0x60000050		# at location 0 is loaded.
171	.long	0x02000410,0x60000050		# Initial processing starts
172	.long	0x02000460,0x60000050		# at 0xf0 = iplstart.
173	.long	0x020004b0,0x60000050
174	.long	0x02000500,0x60000050
175	.long	0x02000550,0x60000050
176	.long	0x020005a0,0x60000050
177	.long	0x020005f0,0x60000050
178	.long	0x02000640,0x60000050
179	.long	0x02000690,0x60000050
180	.long	0x020006e0,0x20000050
181
182	.org	0xf0
183#
184# subroutine for loading cards from the reader
185#
186.Lloader:
187	la	%r3,.Lorb		# r2 = address of orb into r2
188	la	%r5,.Lirb		# r4 = address of irb
189	la	%r6,.Lccws
190	la	%r7,20
191.Linit:
192	st	%r2,4(%r6)		# initialize CCW data addresses
193	la	%r2,0x50(%r2)
194	la	%r6,8(%r6)
195	bct	7,.Linit
196
197	lctl	%c6,%c6,.Lcr6		# set IO subclass mask
198	slr	%r2,%r2
199.Lldlp:
200	ssch	0(%r3)			# load chunk of 1600 bytes
201	bnz	.Llderr
202.Lwait4irq:
203	mvc	0x78(8),.Lnewpsw	# set up IO interrupt psw
204	lpsw	.Lwaitpsw
205.Lioint:
206	c	%r1,0xb8		# compare subchannel number
207	bne	.Lwait4irq
208	tsch	0(%r5)
209
210	slr	%r0,%r0
211	ic	%r0,8(%r5)		# get device status
212	chi	%r0,8			# channel end ?
213	be	.Lcont
214	chi	%r0,12			# channel end + device end ?
215	be	.Lcont
216
217	l	%r0,4(%r5)
218	s	%r0,8(%r3)		# r0/8 = number of ccws executed
219	mhi	%r0,10			# *10 = number of bytes in ccws
220	lh	%r3,10(%r5)		# get residual count
221	sr	%r0,%r3 		# #ccws*80-residual=#bytes read
222	ar	%r2,%r0
223
224	br	%r14			# r2 contains the total size
225
226.Lcont:
227	ahi	%r2,0x640		# add 0x640 to total size
228	la	%r6,.Lccws
229	la	%r7,20
230.Lincr:
231	l	%r0,4(%r6)		# update CCW data addresses
232	ahi	%r0,0x640
233	st	%r0,4(%r6)
234	ahi	%r6,8
235	bct	7,.Lincr
236
237	b	.Lldlp
238.Llderr:
239	lpsw	.Lcrash
240
241	.align	8
242.Lorb:	.long	0x00000000,0x0080ff00,.Lccws
243.Lirb:	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
244.Lcr6:	.long	0xff000000
245.Lloadp:.long	0,0
246	.align	8
247.Lcrash:.long	0x000a0000,0x00000000
248.Lnewpsw:
249	.long	0x00080000,0x80000000+.Lioint
250.Lwaitpsw:
251	.long	0x020a0000,0x80000000+.Lioint
252
253	.align	8
254.Lccws: .rept	19
255	.long	0x02600050,0x00000000
256	.endr
257	.long	0x02200050,0x00000000
258#endif	/* CONFIG_IPL_VM */
259
260iplstart:
261	lh	%r1,0xb8		# test if subchannel number
262	bct	%r1,.Lnoload		#  is valid
263	l	%r1,0xb8		# load ipl subchannel number
264	la	%r2,IPL_BS		# load start address
265	bas	%r14,.Lloader		# load rest of ipl image
266	l	%r12,.Lparm		# pointer to parameter area
267	st	%r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
268
269#
270# load parameter file from ipl device
271#
272.Lagain1:
273	l	%r2,.Linitrd		# ramdisk loc. is temp
274	bas	%r14,.Lloader		# load parameter file
275	ltr	%r2,%r2 		# got anything ?
276	bz	.Lnopf
277	chi	%r2,895
278	bnh	.Lnotrunc
279	la	%r2,895
280.Lnotrunc:
281	l	%r4,.Linitrd
282	clc	0(3,%r4),.L_hdr		# if it is HDRx
283	bz	.Lagain1		# skip dataset header
284	clc	0(3,%r4),.L_eof		# if it is EOFx
285	bz	.Lagain1		# skip dateset trailer
286	la	%r5,0(%r4,%r2)
287	lr	%r3,%r2
288	la	%r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
289	mvc	0(256,%r3),0(%r4)
290	mvc	256(256,%r3),256(%r4)
291	mvc	512(256,%r3),512(%r4)
292	mvc	768(122,%r3),768(%r4)
293	slr	%r0,%r0
294	b	.Lcntlp
295.Ldelspc:
296	ic	%r0,0(%r2,%r3)
297	chi	%r0,0x20		# is it a space ?
298	be	.Lcntlp
299	ahi	%r2,1
300	b	.Leolp
301.Lcntlp:
302	brct	%r2,.Ldelspc
303.Leolp:
304	slr	%r0,%r0
305	stc	%r0,0(%r2,%r3)		# terminate buffer
306.Lnopf:
307
308#
309# load ramdisk from ipl device
310#
311.Lagain2:
312	l	%r2,.Linitrd		# addr of ramdisk
313	st	%r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
314	bas	%r14,.Lloader		# load ramdisk
315	st	%r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
316	ltr	%r2,%r2
317	bnz	.Lrdcont
318	st	%r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
319.Lrdcont:
320	l	%r2,.Linitrd
321
322	clc	0(3,%r2),.L_hdr		# skip HDRx and EOFx
323	bz	.Lagain2
324	clc	0(3,%r2),.L_eof
325	bz	.Lagain2
326
327#ifdef CONFIG_IPL_VM
328#
329# reset files in VM reader
330#
331	stidp	__LC_SAVE_AREA		# store cpuid
332	tm	__LC_SAVE_AREA,0xff	# running VM ?
333	bno	.Lnoreset
334	la	%r2,.Lreset
335	lhi	%r3,26
336	diag	%r2,%r3,8
337	la	%r5,.Lirb
338	stsch	0(%r5)			# check if irq is pending
339	tm	30(%r5),0x0f		# by verifying if any of the
340	bnz	.Lwaitforirq		# activity or status control
341	tm	31(%r5),0xff		# bits is set in the schib
342	bz	.Lnoreset
343.Lwaitforirq:
344	mvc	0x78(8),.Lrdrnewpsw	# set up IO interrupt psw
345.Lwaitrdrirq:
346	lpsw	.Lrdrwaitpsw
347.Lrdrint:
348	c	%r1,0xb8		# compare subchannel number
349	bne	.Lwaitrdrirq
350	la	%r5,.Lirb
351	tsch	0(%r5)
352.Lnoreset:
353	b	.Lnoload
354
355	.align	8
356.Lrdrnewpsw:
357	.long	0x00080000,0x80000000+.Lrdrint
358.Lrdrwaitpsw:
359	.long	0x020a0000,0x80000000+.Lrdrint
360#endif
361
362#
363# everything loaded, go for it
364#
365.Lnoload:
366	l	%r1,.Lstartup
367	br	%r1
368
369.Linitrd:.long _end			# default address of initrd
370.Lparm:	.long  PARMAREA
371.Lstartup: .long startup
372.Lreset:.byte	0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
373	.byte	0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
374	.byte	0xc8,0xd6,0xd3,0xc4	# "change rdr all keep nohold"
375.L_eof: .long	0xc5d6c600	 /* C'EOF' */
376.L_hdr: .long	0xc8c4d900	 /* C'HDR' */
377
378#endif	/* CONFIG_IPL */
379
380#
381# SALIPL loader support. Based on a patch by Rob van der Heij.
382# This entry point is called directly from the SALIPL loader and
383# doesn't need a builtin ipl record.
384#
385	.org	0x800
386	.globl	start
387start:
388	stm	%r0,%r15,0x07b0		# store registers
389	basr	%r12,%r0
390.base:
391	l	%r11,.parm
392	l	%r8,.cmd		# pointer to command buffer
393
394	ltr	%r9,%r9			# do we have SALIPL parameters?
395	bp	.sk8x8
396
397	mvc	0(64,%r8),0x00b0	# copy saved registers
398	xc	64(240-64,%r8),0(%r8)	# remainder of buffer
399	tr	0(64,%r8),.lowcase
400	b	.gotr
401.sk8x8:
402	mvc	0(240,%r8),0(%r9)	# copy iplparms into buffer
403.gotr:
404	slr	%r0,%r0
405	st	%r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
406	st	%r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
407	j	startup 		# continue with startup
408.cmd:	.long	COMMAND_LINE		# address of command line buffer
409.parm:	.long	PARMAREA
410.lowcase:
411	.byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
412	.byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
413	.byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
414	.byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
415	.byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
416	.byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
417	.byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
418	.byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
419	.byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
420	.byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
421	.byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
422	.byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
423	.byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
424	.byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
425	.byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
426	.byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
427
428	.byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
429	.byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
430	.byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
431	.byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
432	.byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
433	.byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
434	.byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
435	.byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
436	.byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87	# .abcdefg
437	.byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf	# hi
438	.byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97	# .jklmnop
439	.byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf	# qr
440	.byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7	# ..stuvwx
441	.byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef	# yz
442	.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
443	.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
444
445#
446# startup-code at 0x10000, running in absolute addressing mode
447# this is called either by the ipl loader or directly by PSW restart
448# or linload or SALIPL
449#
450	.org	0x10000
451	.globl	startup
452startup:
453	basr	%r13,0			# get base
454.LPG0:
455	xc	0x200(256),0x200	# partially clear lowcore
456	xc	0x300(256),0x300
457	stck	__LC_LAST_UPDATE_CLOCK
458	spt	5f-.LPG0(%r13)
459	mvc	__LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
460#ifndef CONFIG_MARCH_G5
461	# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
462	xc	__LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
463	stfl	__LC_STFL_FAC_LIST	# store facility list
464	tm	__LC_STFL_FAC_LIST,0x01	# stfle available ?
465	jz	0f
466	la	%r0,0
467	.insn	s,0xb2b00000,__LC_STFL_FAC_LIST	# store facility list extended
4680:	l	%r0,__LC_STFL_FAC_LIST
469	n	%r0,2f+8-.LPG0(%r13)
470	cl	%r0,2f+8-.LPG0(%r13)
471	jne	1f
472	l	%r0,__LC_STFL_FAC_LIST+4
473	n	%r0,2f+12-.LPG0(%r13)
474	cl	%r0,2f+12-.LPG0(%r13)
475	je	3f
4761:	l	%r15,.Lstack-.LPG0(%r13)
477	ahi	%r15,-96
478	la	%r2,.Lals_string-.LPG0(%r13)
479	l	%r3,.Lsclp_print-.LPG0(%r13)
480	basr	%r14,%r3
481	lpsw	2f-.LPG0(%r13)		# machine type not good enough, crash
482.Lals_string:
483	.asciz	"The Linux kernel requires more recent processor hardware"
484.Lsclp_print:
485	.long	_sclp_print_early
486.Lstack:
487	.long	0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
488	.align 16
4892:	.long	0x000a0000,0x8badcccc
490#if defined(CONFIG_64BIT)
491#if defined(CONFIG_MARCH_Z10)
492	.long 0xc100efe3, 0xf0680000
493#elif defined(CONFIG_MARCH_Z9_109)
494	.long 0xc100efc3, 0x00000000
495#elif defined(CONFIG_MARCH_Z990)
496	.long 0xc0002000, 0x00000000
497#elif defined(CONFIG_MARCH_Z900)
498	.long 0xc0000000, 0x00000000
499#endif
500#else
501#if defined(CONFIG_MARCH_Z10)
502	.long 0x8100c880, 0x00000000
503#elif defined(CONFIG_MARCH_Z9_109)
504	.long 0x8100c880, 0x00000000
505#elif defined(CONFIG_MARCH_Z990)
506	.long 0x80002000, 0x00000000
507#elif defined(CONFIG_MARCH_Z900)
508	.long 0x80000000, 0x00000000
509#endif
510#endif
5113:
512#endif
513
514#ifdef CONFIG_64BIT
515	mvi	__LC_AR_MODE_ID,1	# set esame flag
516	slr	%r0,%r0 		# set cpuid to zero
517	lhi	%r1,2			# mode 2 = esame (dump)
518	sigp	%r1,%r0,0x12		# switch to esame mode
519	sam64				# switch to 64 bit mode
520	larl	%r13,4f
521	lmh	%r0,%r15,0(%r13)	# clear high-order half
522	jg	startup_continue
5234:	.fill	16,4,0x0
524#else
525	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
526	l	%r13,4f-.LPG0(%r13)
527	b	0(%r13)
528	.align	8
5294:	.long	startup_continue
530#endif
531	.align	8
5325:	.long	0x7fffffff,0xffffffff
533
534#
535# params at 10400 (setup.h)
536#
537	.org	PARMAREA
538	.long	0,0			# IPL_DEVICE
539	.long	0,0			# INITRD_START
540	.long	0,0			# INITRD_SIZE
541
542	.org	COMMAND_LINE
543	.byte	"root=/dev/ram0 ro"
544	.byte	0
545
546	.org	0x11000
547