blob: 22596d70fc2e8961f1e29dc80305248b20028c79 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * arch/s390/kernel/head.S
3 *
Heiko Carstensb1b70302006-06-29 14:58:17 +02004 * Copyright (C) IBM Corp. 1999,2006
Heiko Carstens0ad775d2005-11-07 00:59:12 -08005 *
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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 *
11 * There are 5 different IPL methods
12 * 1) load the image directly into ram at address 0 and do an PSW restart
13 * 2) linload will load the image from address 0x10000 to memory 0x10000
14 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
15 * 3) generate the tape ipl header, store the generated image on a tape
16 * and ipl from it
17 * In case of SL tape you need to IPL 5 times to get past VOL1 etc
18 * 4) generate the vm reader ipl header, move the generated image to the
19 * VM reader (use option NOH!) and do a ipl from reader (VM only)
20 * 5) direct call of start by the SALIPL loader
21 * We use the cpuid to distinguish between VM and native ipl
22 * params for kernel are pushed to 0x10400 (see setup.h)
Heiko Carstens0ad775d2005-11-07 00:59:12 -080023 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 */
25
Tim Abbott2133bb82009-04-25 22:11:06 -040026#include <linux/init.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/setup.h>
28#include <asm/lowcore.h>
Sam Ravnborg0013a852005-09-09 20:57:26 +020029#include <asm/asm-offsets.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <asm/thread_info.h>
31#include <asm/page.h>
32
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -080033#ifdef CONFIG_64BIT
Heiko Carstens0ad775d2005-11-07 00:59:12 -080034#define ARCH_OFFSET 4
35#else
36#define ARCH_OFFSET 0
37#endif
38
Tim Abbott2133bb82009-04-25 22:11:06 -040039__HEAD
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#ifndef CONFIG_IPL
Heiko Carstens25d83cb2006-09-28 16:56:37 +020041 .org 0
42 .long 0x00080000,0x80000000+startup # Just a restart PSW
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#else
44#ifdef CONFIG_IPL_TAPE
45#define IPL_BS 1024
Heiko Carstens25d83cb2006-09-28 16:56:37 +020046 .org 0
47 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
48 .long 0x27000000,0x60000001 # by ipl to addresses 0-23.
49 .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs).
50 .long 0x00000000,0x00000000 # external old psw
51 .long 0x00000000,0x00000000 # svc old psw
52 .long 0x00000000,0x00000000 # program check old psw
53 .long 0x00000000,0x00000000 # machine check old psw
54 .long 0x00000000,0x00000000 # io old psw
55 .long 0x00000000,0x00000000
56 .long 0x00000000,0x00000000
57 .long 0x00000000,0x00000000
58 .long 0x000a0000,0x00000058 # external new psw
59 .long 0x000a0000,0x00000060 # svc new psw
60 .long 0x000a0000,0x00000068 # program check new psw
61 .long 0x000a0000,0x00000070 # machine check new psw
62 .long 0x00080000,0x80000000+.Lioint # io new psw
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Heiko Carstens25d83cb2006-09-28 16:56:37 +020064 .org 0x100
Linus Torvalds1da177e2005-04-16 15:20:36 -070065#
66# subroutine for loading from tape
Heiko Carstens25d83cb2006-09-28 16:56:37 +020067# Paramters:
Linus Torvalds1da177e2005-04-16 15:20:36 -070068# R1 = device number
69# R2 = load address
Heiko Carstens25d83cb2006-09-28 16:56:37 +020070.Lloader:
71 st %r14,.Lldret
72 la %r3,.Lorbread # r3 = address of orb
73 la %r5,.Lirb # r5 = address of irb
74 st %r2,.Lccwread+4 # initialize CCW data addresses
75 lctl %c6,%c6,.Lcr6
76 slr %r2,%r2
Linus Torvalds1da177e2005-04-16 15:20:36 -070077.Lldlp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020078 la %r6,3 # 3 retries
Linus Torvalds1da177e2005-04-16 15:20:36 -070079.Lssch:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020080 ssch 0(%r3) # load chunk of IPL_BS bytes
81 bnz .Llderr
Linus Torvalds1da177e2005-04-16 15:20:36 -070082.Lw4end:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020083 bas %r14,.Lwait4io
84 tm 8(%r5),0x82 # do we have a problem ?
85 bnz .Lrecov
86 slr %r7,%r7
87 icm %r7,3,10(%r5) # get residual count
88 lcr %r7,%r7
89 la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read
90 ar %r2,%r7 # add to total size
91 tm 8(%r5),0x01 # found a tape mark ?
92 bnz .Ldone
93 l %r0,.Lccwread+4 # update CCW data addresses
94 ar %r0,%r7
95 st %r0,.Lccwread+4
96 b .Lldlp
Linus Torvalds1da177e2005-04-16 15:20:36 -070097.Ldone:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020098 l %r14,.Lldret
99 br %r14 # r2 contains the total size
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100.Lrecov:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200101 bas %r14,.Lsense # do the sensing
102 bct %r6,.Lssch # dec. retry count & branch
103 b .Llderr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104#
105# Sense subroutine
106#
107.Lsense:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200108 st %r14,.Lsnsret
109 la %r7,.Lorbsense
110 ssch 0(%r7) # start sense command
111 bnz .Llderr
112 bas %r14,.Lwait4io
113 l %r14,.Lsnsret
114 tm 8(%r5),0x82 # do we have a problem ?
115 bnz .Llderr
116 br %r14
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117#
118# Wait for interrupt subroutine
119#
120.Lwait4io:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200121 lpsw .Lwaitpsw
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122.Lioint:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200123 c %r1,0xb8 # compare subchannel number
124 bne .Lwait4io
125 tsch 0(%r5)
126 slr %r0,%r0
127 tm 8(%r5),0x82 # do we have a problem ?
128 bnz .Lwtexit
129 tm 8(%r5),0x04 # got device end ?
130 bz .Lwait4io
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131.Lwtexit:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200132 br %r14
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133.Llderr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200134 lpsw .Lcrash
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200136 .align 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137.Lorbread:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200138 .long 0x00000000,0x0080ff00,.Lccwread
139 .align 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140.Lorbsense:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200141 .long 0x00000000,0x0080ff00,.Lccwsense
142 .align 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143.Lccwread:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200144 .long 0x02200000+IPL_BS,0x00000000
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145.Lccwsense:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200146 .long 0x04200001,0x00000000
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147.Lwaitpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200148 .long 0x020a0000,0x80000000+.Lioint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200150.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
151.Lcr6: .long 0xff000000
152 .align 8
153.Lcrash:.long 0x000a0000,0x00000000
154.Lldret:.long 0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155.Lsnsret: .long 0
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200156#endif /* CONFIG_IPL_TAPE */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157
158#ifdef CONFIG_IPL_VM
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200159#define IPL_BS 0x730
160 .org 0
161 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
162 .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
163 .long 0x02000068,0x60000050 # (a PSW and two CCWs).
164 .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
165 .long 0x020000f0,0x60000050 # The next 160 byte are loaded
166 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
167 .long 0x02000190,0x60000050 # They form the continuation
168 .long 0x020001e0,0x60000050 # of the CCW program started
169 .long 0x02000230,0x60000050 # by ipl and load the range
170 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
171 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
172 .long 0x02000320,0x60000050 # in memory. At the end of
173 .long 0x02000370,0x60000050 # the channel program the PSW
174 .long 0x020003c0,0x60000050 # at location 0 is loaded.
175 .long 0x02000410,0x60000050 # Initial processing starts
176 .long 0x02000460,0x60000050 # at 0xf0 = iplstart.
177 .long 0x020004b0,0x60000050
178 .long 0x02000500,0x60000050
179 .long 0x02000550,0x60000050
180 .long 0x020005a0,0x60000050
181 .long 0x020005f0,0x60000050
182 .long 0x02000640,0x60000050
183 .long 0x02000690,0x60000050
184 .long 0x020006e0,0x20000050
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200186 .org 0xf0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187#
188# subroutine for loading cards from the reader
189#
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200190.Lloader:
191 la %r3,.Lorb # r2 = address of orb into r2
192 la %r5,.Lirb # r4 = address of irb
193 la %r6,.Lccws
194 la %r7,20
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195.Linit:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200196 st %r2,4(%r6) # initialize CCW data addresses
197 la %r2,0x50(%r2)
198 la %r6,8(%r6)
199 bct 7,.Linit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200201 lctl %c6,%c6,.Lcr6 # set IO subclass mask
202 slr %r2,%r2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203.Lldlp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200204 ssch 0(%r3) # load chunk of 1600 bytes
205 bnz .Llderr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206.Lwait4irq:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200207 mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
208 lpsw .Lwaitpsw
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209.Lioint:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200210 c %r1,0xb8 # compare subchannel number
211 bne .Lwait4irq
212 tsch 0(%r5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200214 slr %r0,%r0
215 ic %r0,8(%r5) # get device status
216 chi %r0,8 # channel end ?
217 be .Lcont
218 chi %r0,12 # channel end + device end ?
219 be .Lcont
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200221 l %r0,4(%r5)
222 s %r0,8(%r3) # r0/8 = number of ccws executed
223 mhi %r0,10 # *10 = number of bytes in ccws
224 lh %r3,10(%r5) # get residual count
225 sr %r0,%r3 # #ccws*80-residual=#bytes read
226 ar %r2,%r0
227
228 br %r14 # r2 contains the total size
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230.Lcont:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200231 ahi %r2,0x640 # add 0x640 to total size
232 la %r6,.Lccws
233 la %r7,20
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234.Lincr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200235 l %r0,4(%r6) # update CCW data addresses
236 ahi %r0,0x640
237 st %r0,4(%r6)
238 ahi %r6,8
239 bct 7,.Lincr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200241 b .Lldlp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242.Llderr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200243 lpsw .Lcrash
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200245 .align 8
246.Lorb: .long 0x00000000,0x0080ff00,.Lccws
247.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
248.Lcr6: .long 0xff000000
249.Lloadp:.long 0,0
250 .align 8
251.Lcrash:.long 0x000a0000,0x00000000
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252.Lnewpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200253 .long 0x00080000,0x80000000+.Lioint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254.Lwaitpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200255 .long 0x020a0000,0x80000000+.Lioint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200257 .align 8
258.Lccws: .rept 19
259 .long 0x02600050,0x00000000
260 .endr
261 .long 0x02200050,0x00000000
262#endif /* CONFIG_IPL_VM */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263
264iplstart:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200265 lh %r1,0xb8 # test if subchannel number
266 bct %r1,.Lnoload # is valid
267 l %r1,0xb8 # load ipl subchannel number
268 la %r2,IPL_BS # load start address
269 bas %r14,.Lloader # load rest of ipl image
270 l %r12,.Lparm # pointer to parameter area
271 st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
273#
274# load parameter file from ipl device
275#
276.Lagain1:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200277 l %r2,.Linitrd # ramdisk loc. is temp
278 bas %r14,.Lloader # load parameter file
279 ltr %r2,%r2 # got anything ?
280 bz .Lnopf
281 chi %r2,895
282 bnh .Lnotrunc
283 la %r2,895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284.Lnotrunc:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200285 l %r4,.Linitrd
286 clc 0(3,%r4),.L_hdr # if it is HDRx
287 bz .Lagain1 # skip dataset header
288 clc 0(3,%r4),.L_eof # if it is EOFx
289 bz .Lagain1 # skip dateset trailer
290 la %r5,0(%r4,%r2)
291 lr %r3,%r2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292.Lidebc:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200293 tm 0(%r5),0x80 # high order bit set ?
294 bo .Ldocv # yes -> convert from EBCDIC
295 ahi %r5,-1
296 bct %r3,.Lidebc
297 b .Lnocv
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298.Ldocv:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200299 l %r3,.Lcvtab
300 tr 0(256,%r4),0(%r3) # convert parameters to ascii
301 tr 256(256,%r4),0(%r3)
302 tr 512(256,%r4),0(%r3)
303 tr 768(122,%r4),0(%r3)
304.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
305 mvc 0(256,%r3),0(%r4)
306 mvc 256(256,%r3),256(%r4)
307 mvc 512(256,%r3),512(%r4)
308 mvc 768(122,%r3),768(%r4)
309 slr %r0,%r0
310 b .Lcntlp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311.Ldelspc:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200312 ic %r0,0(%r2,%r3)
313 chi %r0,0x20 # is it a space ?
314 be .Lcntlp
315 ahi %r2,1
316 b .Leolp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317.Lcntlp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200318 brct %r2,.Ldelspc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319.Leolp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200320 slr %r0,%r0
321 stc %r0,0(%r2,%r3) # terminate buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322.Lnopf:
323
324#
325# load ramdisk from ipl device
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200326#
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327.Lagain2:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200328 l %r2,.Linitrd # addr of ramdisk
329 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
330 bas %r14,.Lloader # load ramdisk
331 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
332 ltr %r2,%r2
333 bnz .Lrdcont
334 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335.Lrdcont:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200336 l %r2,.Linitrd
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200338 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
339 bz .Lagain2
340 clc 0(3,%r2),.L_eof
341 bz .Lagain2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
343#ifdef CONFIG_IPL_VM
344#
345# reset files in VM reader
346#
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200347 stidp __LC_CPUID # store cpuid
348 tm __LC_CPUID,0xff # running VM ?
349 bno .Lnoreset
350 la %r2,.Lreset
351 lhi %r3,26
352 diag %r2,%r3,8
353 la %r5,.Lirb
354 stsch 0(%r5) # check if irq is pending
355 tm 30(%r5),0x0f # by verifying if any of the
356 bnz .Lwaitforirq # activity or status control
357 tm 31(%r5),0xff # bits is set in the schib
358 bz .Lnoreset
Heiko Carstens350e3ad2005-07-29 14:03:36 -0700359.Lwaitforirq:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200360 mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
Heiko Carstens2b071882005-06-21 17:16:31 -0700361.Lwaitrdrirq:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200362 lpsw .Lrdrwaitpsw
Heiko Carstens2b071882005-06-21 17:16:31 -0700363.Lrdrint:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200364 c %r1,0xb8 # compare subchannel number
365 bne .Lwaitrdrirq
366 la %r5,.Lirb
367 tsch 0(%r5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368.Lnoreset:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200369 b .Lnoload
Heiko Carstens2b071882005-06-21 17:16:31 -0700370
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200371 .align 8
Heiko Carstens2b071882005-06-21 17:16:31 -0700372.Lrdrnewpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200373 .long 0x00080000,0x80000000+.Lrdrint
Heiko Carstens2b071882005-06-21 17:16:31 -0700374.Lrdrwaitpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200375 .long 0x020a0000,0x80000000+.Lrdrint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376#endif
Heiko Carstens2b071882005-06-21 17:16:31 -0700377
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378#
379# everything loaded, go for it
380#
381.Lnoload:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200382 l %r1,.Lstartup
383 br %r1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200385.Linitrd:.long _end + 0x400000 # default address of initrd
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386.Lparm: .long PARMAREA
387.Lstartup: .long startup
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200388.Lcvtab:.long _ebcasc # ebcdic to ascii table
389.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
390 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
391 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
392.L_eof: .long 0xc5d6c600 /* C'EOF' */
393.L_hdr: .long 0xc8c4d900 /* C'HDR' */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200395#endif /* CONFIG_IPL */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
397#
398# SALIPL loader support. Based on a patch by Rob van der Heij.
399# This entry point is called directly from the SALIPL loader and
400# doesn't need a builtin ipl record.
401#
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200402 .org 0x800
403 .globl start
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404start:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200405 stm %r0,%r15,0x07b0 # store registers
406 basr %r12,%r0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407.base:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200408 l %r11,.parm
409 l %r8,.cmd # pointer to command buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200411 ltr %r9,%r9 # do we have SALIPL parameters?
412 bp .sk8x8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200414 mvc 0(64,%r8),0x00b0 # copy saved registers
415 xc 64(240-64,%r8),0(%r8) # remainder of buffer
416 tr 0(64,%r8),.lowcase
417 b .gotr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418.sk8x8:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200419 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420.gotr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200421 l %r10,.tbl # EBCDIC to ASCII table
422 tr 0(240,%r8),0(%r10)
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200423 slr %r0,%r0
424 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
425 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
426 j startup # continue with startup
427.tbl: .long _ebcasc # translate table
428.cmd: .long COMMAND_LINE # address of command line buffer
429.parm: .long PARMAREA
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430.lowcase:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200431 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200433 .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200435 .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200437 .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200439 .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200441 .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200443 .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200445 .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
447
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200448 .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200450 .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200452 .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200454 .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200456 .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200458 .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr
460 .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx
461 .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200462 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
464
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100465#
466# startup-code at 0x10000, running in absolute addressing mode
467# this is called either by the ipl loader or directly by PSW restart
468# or linload or SALIPL
469#
470 .org 0x10000
471startup:basr %r13,0 # get base
472.LPG0:
Martin Schwidefsky866ba282009-03-26 15:24:44 +0100473 xc 0x200(256),0x200 # partially clear lowcore
474 xc 0x300(256),0x300
Martin Schwidefskyb6112cc2009-04-14 15:36:28 +0200475 l %r1,5f-.LPG0(%r13)
476 stck 0(%r1)
Martin Schwidefskyab96e792009-04-14 15:36:29 +0200477 spt 6f-.LPG0(%r13)
478 mvc __LC_LAST_UPDATE_CLOCK(8),0(%r1)
479 mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
480 mvc __LC_EXIT_TIMER(8),5f-.LPG0(%r13)
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100481#ifndef CONFIG_MARCH_G5
482 # check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
483 stidp __LC_CPUID # store cpuid
484 lhi %r0,(3f-2f) / 2
485 la %r1,2f-.LPG0(%r13)
4860: clc __LC_CPUID+4(2),0(%r1)
487 jne 3f
488 lpsw 1f-.LPG0(13) # machine type not good enough, crash
489 .align 16
4901: .long 0x000a0000,0x00000000
4912:
492#if defined(CONFIG_MARCH_Z10)
493 .short 0x9672, 0x2064, 0x2066, 0x2084, 0x2086, 0x2094, 0x2096
494#elif defined(CONFIG_MARCH_Z9_109)
495 .short 0x9672, 0x2064, 0x2066, 0x2084, 0x2086
496#elif defined(CONFIG_MARCH_Z990)
497 .short 0x9672, 0x2064, 0x2066
498#elif defined(CONFIG_MARCH_Z900)
499 .short 0x9672
500#endif
5013: la %r1,2(%r1)
502 brct %r0,0b
503#endif
504
Martin Schwidefskyb6112cc2009-04-14 15:36:28 +0200505 l %r13,4f-.LPG0(%r13)
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100506 b 0(%r13)
Martin Schwidefskyab96e792009-04-14 15:36:29 +0200507 .align 4
Martin Schwidefskyb6112cc2009-04-14 15:36:28 +02005084: .long startup_continue
5095: .long sched_clock_base_cc
Martin Schwidefskyab96e792009-04-14 15:36:29 +0200510 .align 8
5116: .long 0x7fffffff,0xffffffff
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100512
513#
514# params at 10400 (setup.h)
515#
516 .org PARMAREA
517 .long 0,0 # IPL_DEVICE
518 .long 0,0 # INITRD_START
519 .long 0,0 # INITRD_SIZE
520
521 .org COMMAND_LINE
522 .byte "root=/dev/ram0 ro"
523 .byte 0
524
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800525#ifdef CONFIG_64BIT
Heiko Carstens0ad775d2005-11-07 00:59:12 -0800526#include "head64.S"
527#else
528#include "head31.S"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529#endif