blob: db1696e210af496d0cd9a807b53dfdd7bebcf5d9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +01002 * Copyright IBM Corp. 1999,2010
Heiko Carstens0ad775d2005-11-07 00:59:12 -08003 *
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>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 *
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)
Heiko Carstens0ad775d2005-11-07 00:59:12 -080021 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 */
23
Tim Abbott2133bb82009-04-25 22:11:06 -040024#include <linux/init.h>
Sam Ravnborg0013a852005-09-09 20:57:26 +020025#include <asm/asm-offsets.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <asm/thread_info.h>
27#include <asm/page.h>
28
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -080029#ifdef CONFIG_64BIT
Heiko Carstens0ad775d2005-11-07 00:59:12 -080030#define ARCH_OFFSET 4
31#else
32#define ARCH_OFFSET 0
33#endif
34
Tim Abbott2133bb82009-04-25 22:11:06 -040035__HEAD
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#ifndef CONFIG_IPL
Heiko Carstens25d83cb2006-09-28 16:56:37 +020037 .org 0
38 .long 0x00080000,0x80000000+startup # Just a restart PSW
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#else
40#ifdef CONFIG_IPL_TAPE
41#define IPL_BS 1024
Heiko Carstens25d83cb2006-09-28 16:56:37 +020042 .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
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Heiko Carstens25d83cb2006-09-28 16:56:37 +020060 .org 0x100
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#
62# subroutine for loading from tape
Martin Olsson98a17082009-04-22 18:21:29 +020063# Parameters:
Linus Torvalds1da177e2005-04-16 15:20:36 -070064# R1 = device number
65# R2 = load address
Heiko Carstens25d83cb2006-09-28 16:56:37 +020066.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
Linus Torvalds1da177e2005-04-16 15:20:36 -070073.Lldlp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020074 la %r6,3 # 3 retries
Linus Torvalds1da177e2005-04-16 15:20:36 -070075.Lssch:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020076 ssch 0(%r3) # load chunk of IPL_BS bytes
77 bnz .Llderr
Linus Torvalds1da177e2005-04-16 15:20:36 -070078.Lw4end:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020079 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070093.Ldone:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020094 l %r14,.Lldret
95 br %r14 # r2 contains the total size
Linus Torvalds1da177e2005-04-16 15:20:36 -070096.Lrecov:
Heiko Carstens25d83cb2006-09-28 16:56:37 +020097 bas %r14,.Lsense # do the sensing
98 bct %r6,.Lssch # dec. retry count & branch
99 b .Llderr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100#
101# Sense subroutine
102#
103.Lsense:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200104 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113#
114# Wait for interrupt subroutine
115#
116.Lwait4io:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200117 lpsw .Lwaitpsw
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118.Lioint:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200119 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127.Lwtexit:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200128 br %r14
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129.Llderr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200130 lpsw .Lcrash
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200132 .align 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133.Lorbread:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200134 .long 0x00000000,0x0080ff00,.Lccwread
135 .align 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136.Lorbsense:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200137 .long 0x00000000,0x0080ff00,.Lccwsense
138 .align 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139.Lccwread:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200140 .long 0x02200000+IPL_BS,0x00000000
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141.Lccwsense:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200142 .long 0x04200001,0x00000000
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143.Lwaitpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200144 .long 0x020a0000,0x80000000+.Lioint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200146.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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151.Lsnsret: .long 0
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200152#endif /* CONFIG_IPL_TAPE */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
154#ifdef CONFIG_IPL_VM
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200155#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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200182 .org 0xf0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183#
184# subroutine for loading cards from the reader
185#
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200186.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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191.Linit:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200192 st %r2,4(%r6) # initialize CCW data addresses
193 la %r2,0x50(%r2)
194 la %r6,8(%r6)
195 bct 7,.Linit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200197 lctl %c6,%c6,.Lcr6 # set IO subclass mask
198 slr %r2,%r2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199.Lldlp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200200 ssch 0(%r3) # load chunk of 1600 bytes
201 bnz .Llderr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202.Lwait4irq:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200203 mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
204 lpsw .Lwaitpsw
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205.Lioint:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200206 c %r1,0xb8 # compare subchannel number
207 bne .Lwait4irq
208 tsch 0(%r5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200210 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200217 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
226.Lcont:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200227 ahi %r2,0x640 # add 0x640 to total size
228 la %r6,.Lccws
229 la %r7,20
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230.Lincr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200231 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200237 b .Lldlp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238.Llderr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200239 lpsw .Lcrash
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200241 .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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248.Lnewpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200249 .long 0x00080000,0x80000000+.Lioint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250.Lwaitpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200251 .long 0x020a0000,0x80000000+.Lioint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200253 .align 8
254.Lccws: .rept 19
255 .long 0x02600050,0x00000000
256 .endr
257 .long 0x02200050,0x00000000
258#endif /* CONFIG_IPL_VM */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260iplstart:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200261 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
269#
270# load parameter file from ipl device
271#
272.Lagain1:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200273 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280.Lnotrunc:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200281 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
Martin Schwidefsky61fd3302010-02-26 22:37:51 +0100288 la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200289 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295.Ldelspc:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200296 ic %r0,0(%r2,%r3)
297 chi %r0,0x20 # is it a space ?
298 be .Lcntlp
299 ahi %r2,1
300 b .Leolp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301.Lcntlp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200302 brct %r2,.Ldelspc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303.Leolp:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200304 slr %r0,%r0
305 stc %r0,0(%r2,%r3) # terminate buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306.Lnopf:
307
308#
309# load ramdisk from ipl device
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200310#
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311.Lagain2:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200312 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319.Lrdcont:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200320 l %r2,.Linitrd
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200322 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
323 bz .Lagain2
324 clc 0(3,%r2),.L_eof
325 bz .Lagain2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
327#ifdef CONFIG_IPL_VM
328#
329# reset files in VM reader
330#
Martin Schwidefsky94038a92010-05-17 10:00:00 +0200331 stidp __LC_SAVE_AREA # store cpuid
332 tm __LC_SAVE_AREA,0xff # running VM ?
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200333 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
Heiko Carstens350e3ad2005-07-29 14:03:36 -0700343.Lwaitforirq:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200344 mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
Heiko Carstens2b071882005-06-21 17:16:31 -0700345.Lwaitrdrirq:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200346 lpsw .Lrdrwaitpsw
Heiko Carstens2b071882005-06-21 17:16:31 -0700347.Lrdrint:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200348 c %r1,0xb8 # compare subchannel number
349 bne .Lwaitrdrirq
350 la %r5,.Lirb
351 tsch 0(%r5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352.Lnoreset:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200353 b .Lnoload
Heiko Carstens2b071882005-06-21 17:16:31 -0700354
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200355 .align 8
Heiko Carstens2b071882005-06-21 17:16:31 -0700356.Lrdrnewpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200357 .long 0x00080000,0x80000000+.Lrdrint
Heiko Carstens2b071882005-06-21 17:16:31 -0700358.Lrdrwaitpsw:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200359 .long 0x020a0000,0x80000000+.Lrdrint
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360#endif
Heiko Carstens2b071882005-06-21 17:16:31 -0700361
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362#
363# everything loaded, go for it
364#
365.Lnoload:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200366 l %r1,.Lstartup
367 br %r1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Heiko Carstense033b9a2010-08-09 18:12:57 +0200369.Linitrd:.long _end # default address of initrd
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370.Lparm: .long PARMAREA
371.Lstartup: .long startup
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200372.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' */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200378#endif /* CONFIG_IPL */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
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#
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200385 .org 0x800
386 .globl start
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387start:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200388 stm %r0,%r15,0x07b0 # store registers
389 basr %r12,%r0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390.base:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200391 l %r11,.parm
392 l %r8,.cmd # pointer to command buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200394 ltr %r9,%r9 # do we have SALIPL parameters?
395 bp .sk8x8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200397 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401.sk8x8:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200402 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403.gotr:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200404 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
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200408.cmd: .long COMMAND_LINE # address of command line buffer
409.parm: .long PARMAREA
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410.lowcase:
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200411 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200413 .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200415 .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200417 .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200419 .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200421 .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200423 .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200425 .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
427
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200428 .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200430 .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200432 .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200434 .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200436 .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200438 .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 .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
Heiko Carstens25d83cb2006-09-28 16:56:37 +0200442 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
444
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100445#
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
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100451 .globl startup
452startup:
453 basr %r13,0 # get base
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100454.LPG0:
Martin Schwidefsky866ba282009-03-26 15:24:44 +0100455 xc 0x200(256),0x200 # partially clear lowcore
456 xc 0x300(256),0x300
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100457 stck __LC_LAST_UPDATE_CLOCK
458 spt 5f-.LPG0(%r13)
459 mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100460#ifndef CONFIG_MARCH_G5
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +0200461 # 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
Heiko Carstensd90cbd42009-06-12 10:26:24 +02004761: l %r15,.Lstack-.LPG0(%r13)
Heiko Carstensd90cbd42009-06-12 10:26:24 +0200477 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:
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100487 .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100488 .align 16
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +02004892: .long 0x000a0000,0x8badcccc
490#if defined(CONFIG_64BIT)
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100491#if defined(CONFIG_MARCH_Z10)
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +0200492 .long 0xc100efe3, 0xf0680000
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100493#elif defined(CONFIG_MARCH_Z9_109)
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +0200494 .long 0xc100efc3, 0x00000000
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100495#elif defined(CONFIG_MARCH_Z990)
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +0200496 .long 0xc0002000, 0x00000000
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100497#elif defined(CONFIG_MARCH_Z900)
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +0200498 .long 0xc0000000, 0x00000000
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100499#endif
Martin Schwidefsky8c4caa42009-06-12 10:26:23 +0200500#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:
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100512#endif
513
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100514#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
Martin Schwidefsky06c0dd72010-03-24 11:49:57 +0100520 larl %r13,4f
521 lmh %r0,%r15,0(%r13) # clear high-order half
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100522 jg startup_continue
Martin Schwidefsky06c0dd72010-03-24 11:49:57 +01005234: .fill 16,4,0x0
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100524#else
525 mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
Martin Schwidefskyb6112cc2009-04-14 15:36:28 +0200526 l %r13,4f-.LPG0(%r13)
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100527 b 0(%r13)
Martin Schwidefskyab96e792009-04-14 15:36:29 +0200528 .align 8
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +01005294: .long startup_continue
530#endif
531 .align 8
5325: .long 0x7fffffff,0xffffffff
Martin Schwidefskye37f50e2008-12-25 13:39:19 +0100533
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
Martin Schwidefsky1844c9b2010-02-26 22:37:53 +0100546 .org 0x11000