1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright IBM Corp. 1999, 2010 4 * 5 * Author(s): Hartmut Penner <hp@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Rob van der Heij <rvdhei@iae.nl> 8 * Heiko Carstens <heiko.carstens@de.ibm.com> 9 * 10 * There are 5 different IPL methods 11 * 1) load the image directly into ram at address 0 and do an PSW restart 12 * 2) linload will load the image from address 0x10000 to memory 0x10000 13 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated) 14 * 3) generate the tape ipl header, store the generated image on a tape 15 * and ipl from it 16 * In case of SL tape you need to IPL 5 times to get past VOL1 etc 17 * 4) generate the vm reader ipl header, move the generated image to the 18 * VM reader (use option NOH!) and do a ipl from reader (VM only) 19 * 5) direct call of start by the SALIPL loader 20 * We use the cpuid to distinguish between VM and native ipl 21 * params for kernel are pushed to 0x10400 (see setup.h) 22 * 23 */ 24 25#include <linux/init.h> 26#include <linux/linkage.h> 27#include <asm/asm-offsets.h> 28#include <asm/thread_info.h> 29#include <asm/page.h> 30#include <asm/ptrace.h> 31 32#define ARCH_OFFSET 4 33 34__HEAD 35 36#define IPL_BS 0x730 37 .org 0 38 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded 39 .long 0x02000018,0x60000050 # by ipl to addresses 0-23. 40 .long 0x02000068,0x60000050 # (a PSW and two CCWs). 41 .fill 80-24,1,0x40 # bytes 24-79 are discarded !! 42 .long 0x020000f0,0x60000050 # The next 160 byte are loaded 43 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 44 .long 0x02000190,0x60000050 # They form the continuation 45 .long 0x020001e0,0x60000050 # of the CCW program started 46 .long 0x02000230,0x60000050 # by ipl and load the range 47 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image 48 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 49 .long 0x02000320,0x60000050 # in memory. At the end of 50 .long 0x02000370,0x60000050 # the channel program the PSW 51 .long 0x020003c0,0x60000050 # at location 0 is loaded. 52 .long 0x02000410,0x60000050 # Initial processing starts 53 .long 0x02000460,0x60000050 # at 0x200 = iplstart. 54 .long 0x020004b0,0x60000050 55 .long 0x02000500,0x60000050 56 .long 0x02000550,0x60000050 57 .long 0x020005a0,0x60000050 58 .long 0x020005f0,0x60000050 59 .long 0x02000640,0x60000050 60 .long 0x02000690,0x60000050 61 .long 0x020006e0,0x20000050 62 63 .org 0x1a0 64 .quad 0,iplstart 65 66 .org 0x200 67 68# 69# subroutine to wait for end I/O 70# 71.Lirqwait: 72 mvc __LC_IO_NEW_PSW(16),.Lnewpsw # set up IO interrupt psw 73 lpsw .Lwaitpsw 74.Lioint: 75 br %r14 76 .align 8 77.Lnewpsw: 78 .quad 0x0000000080000000,.Lioint 79.Lwaitpsw: 80 .long 0x020a0000,0x80000000+.Lioint 81 82# 83# subroutine for loading cards from the reader 84# 85.Lloader: 86 la %r4,0(%r14) 87 la %r3,.Lorb # r2 = address of orb into r2 88 la %r5,.Lirb # r4 = address of irb 89 la %r6,.Lccws 90 la %r7,20 91.Linit: 92 st %r2,4(%r6) # initialize CCW data addresses 93 la %r2,0x50(%r2) 94 la %r6,8(%r6) 95 bct 7,.Linit 96 97 lctl %c6,%c6,.Lcr6 # set IO subclass mask 98 slr %r2,%r2 99.Lldlp: 100 ssch 0(%r3) # load chunk of 1600 bytes 101 bnz .Llderr 102.Lwait4irq: 103 bas %r14,.Lirqwait 104 c %r1,__LC_SUBCHANNEL_ID # compare subchannel number 105 bne .Lwait4irq 106 tsch 0(%r5) 107 108 slr %r0,%r0 109 ic %r0,8(%r5) # get device status 110 chi %r0,8 # channel end ? 111 be .Lcont 112 chi %r0,12 # channel end + device end ? 113 be .Lcont 114 115 l %r0,4(%r5) 116 s %r0,8(%r3) # r0/8 = number of ccws executed 117 mhi %r0,10 # *10 = number of bytes in ccws 118 lh %r3,10(%r5) # get residual count 119 sr %r0,%r3 # #ccws*80-residual=#bytes read 120 ar %r2,%r0 121 122 br %r4 # r2 contains the total size 123 124.Lcont: 125 ahi %r2,0x640 # add 0x640 to total size 126 la %r6,.Lccws 127 la %r7,20 128.Lincr: 129 l %r0,4(%r6) # update CCW data addresses 130 ahi %r0,0x640 131 st %r0,4(%r6) 132 ahi %r6,8 133 bct 7,.Lincr 134 135 b .Lldlp 136.Llderr: 137 lpsw .Lcrash 138 139 .align 8 140.Lorb: .long 0x00000000,0x0080ff00,.Lccws 141.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 142.Lcr6: .long 0xff000000 143.Lloadp:.long 0,0 144 .align 8 145.Lcrash:.long 0x000a0000,0x00000000 146 147 .align 8 148.Lccws: .rept 19 149 .long 0x02600050,0x00000000 150 .endr 151 .long 0x02200050,0x00000000 152 153iplstart: 154 mvi __LC_AR_MODE_ID,1 # set esame flag 155 slr %r0,%r0 # set cpuid to zero 156 lhi %r1,2 # mode 2 = esame (dump) 157 sigp %r1,%r0,0x12 # switch to esame mode 158 bras %r13,0f 159 .fill 16,4,0x0 1600: lmh %r0,%r15,0(%r13) # clear high-order half of gprs 161 sam31 # switch to 31 bit addressing mode 162 lh %r1,__LC_SUBCHANNEL_ID # test if subchannel number 163 bct %r1,.Lnoload # is valid 164 l %r1,__LC_SUBCHANNEL_ID # load ipl subchannel number 165 la %r2,IPL_BS # load start address 166 bas %r14,.Lloader # load rest of ipl image 167 l %r12,.Lparm # pointer to parameter area 168 st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number 169 170# 171# load parameter file from ipl device 172# 173.Lagain1: 174 l %r2,.Linitrd # ramdisk loc. is temp 175 bas %r14,.Lloader # load parameter file 176 ltr %r2,%r2 # got anything ? 177 bz .Lnopf 178 chi %r2,895 179 bnh .Lnotrunc 180 la %r2,895 181.Lnotrunc: 182 l %r4,.Linitrd 183 clc 0(3,%r4),.L_hdr # if it is HDRx 184 bz .Lagain1 # skip dataset header 185 clc 0(3,%r4),.L_eof # if it is EOFx 186 bz .Lagain1 # skip dateset trailer 187 la %r5,0(%r4,%r2) 188 lr %r3,%r2 189 la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line 190 mvc 0(256,%r3),0(%r4) 191 mvc 256(256,%r3),256(%r4) 192 mvc 512(256,%r3),512(%r4) 193 mvc 768(122,%r3),768(%r4) 194 slr %r0,%r0 195 b .Lcntlp 196.Ldelspc: 197 ic %r0,0(%r2,%r3) 198 chi %r0,0x20 # is it a space ? 199 be .Lcntlp 200 ahi %r2,1 201 b .Leolp 202.Lcntlp: 203 brct %r2,.Ldelspc 204.Leolp: 205 slr %r0,%r0 206 stc %r0,0(%r2,%r3) # terminate buffer 207.Lnopf: 208 209# 210# load ramdisk from ipl device 211# 212.Lagain2: 213 l %r2,.Linitrd # addr of ramdisk 214 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) 215 bas %r14,.Lloader # load ramdisk 216 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd 217 ltr %r2,%r2 218 bnz .Lrdcont 219 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found 220.Lrdcont: 221 l %r2,.Linitrd 222 223 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx 224 bz .Lagain2 225 clc 0(3,%r2),.L_eof 226 bz .Lagain2 227 228# 229# reset files in VM reader 230# 231 stidp .Lcpuid # store cpuid 232 tm .Lcpuid,0xff # running VM ? 233 bno .Lnoreset 234 la %r2,.Lreset 235 lhi %r3,26 236 diag %r2,%r3,8 237 la %r5,.Lirb 238 stsch 0(%r5) # check if irq is pending 239 tm 30(%r5),0x0f # by verifying if any of the 240 bnz .Lwaitforirq # activity or status control 241 tm 31(%r5),0xff # bits is set in the schib 242 bz .Lnoreset 243.Lwaitforirq: 244 bas %r14,.Lirqwait # wait for IO interrupt 245 c %r1,__LC_SUBCHANNEL_ID # compare subchannel number 246 bne .Lwaitforirq 247 la %r5,.Lirb 248 tsch 0(%r5) 249.Lnoreset: 250 b .Lnoload 251 252# 253# everything loaded, go for it 254# 255.Lnoload: 256 l %r1,.Lstartup 257 br %r1 258 259.Linitrd:.long _end # default address of initrd 260.Lparm: .long PARMAREA 261.Lstartup: .long startup 262.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 263 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 264 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" 265.L_eof: .long 0xc5d6c600 /* C'EOF' */ 266.L_hdr: .long 0xc8c4d900 /* C'HDR' */ 267 .align 8 268.Lcpuid:.fill 8,1,0 269 270# 271# startup-code at 0x10000, running in absolute addressing mode 272# this is called either by the ipl loader or directly by PSW restart 273# or linload or SALIPL 274# 275 .org 0x10000 276ENTRY(startup) 277 j .Lep_startup_normal 278 .org EP_OFFSET 279# 280# This is a list of s390 kernel entry points. At address 0x1000f the number of 281# valid entry points is stored. 282# 283# IMPORTANT: Do not change this table, it is s390 kernel ABI! 284# 285 .ascii EP_STRING 286 .byte 0x00,0x01 287# 288# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode 289# 290 .org 0x10010 291ENTRY(startup_kdump) 292 j .Lep_startup_kdump 293.Lep_startup_normal: 294 mvi __LC_AR_MODE_ID,1 # set esame flag 295 slr %r0,%r0 # set cpuid to zero 296 lhi %r1,2 # mode 2 = esame (dump) 297 sigp %r1,%r0,0x12 # switch to esame mode 298 bras %r13,0f 299 .fill 16,4,0x0 3000: lmh %r0,%r15,0(%r13) # clear high-order half of gprs 301 sam64 # switch to 64 bit addressing mode 302 basr %r13,0 # get base 303.LPG0: 304 xc 0x200(256),0x200 # partially clear lowcore 305 xc 0x300(256),0x300 306 xc 0xe00(256),0xe00 307 xc 0xf00(256),0xf00 308 lctlg %c0,%c15,.Lctl-.LPG0(%r13) # load control registers 309 stcke __LC_BOOT_CLOCK 310 mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1 311 spt 6f-.LPG0(%r13) 312 mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) 313 l %r15,.Lstack-.LPG0(%r13) 314 brasl %r14,verify_facilities 315 brasl %r14,startup_kernel 316 317.Lstack: 318 .long 0x8000 + (1<<(PAGE_SHIFT+BOOT_STACK_ORDER)) - STACK_FRAME_OVERHEAD 319 .align 8 3206: .long 0x7fffffff,0xffffffff 321 322.Lctl: .quad 0x04040000 # cr0: AFP registers & secondary space 323 .quad 0 # cr1: primary space segment table 324 .quad .Lduct # cr2: dispatchable unit control table 325 .quad 0 # cr3: instruction authorization 326 .quad 0xffff # cr4: instruction authorization 327 .quad .Lduct # cr5: primary-aste origin 328 .quad 0 # cr6: I/O interrupts 329 .quad 0 # cr7: secondary space segment table 330 .quad 0 # cr8: access registers translation 331 .quad 0 # cr9: tracing off 332 .quad 0 # cr10: tracing off 333 .quad 0 # cr11: tracing off 334 .quad 0 # cr12: tracing off 335 .quad 0 # cr13: home space segment table 336 .quad 0xc0000000 # cr14: machine check handling off 337 .quad .Llinkage_stack # cr15: linkage stack operations 338 339 .section .dma.data,"aw",@progbits 340.Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0 341 .long 0,0,0,0,0,0,0,0 342.Llinkage_stack: 343 .long 0,0,0x89000000,0,0,0,0x8a000000,0 344 .align 64 345.Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0 346 .align 128 347.Lduald:.rept 8 348 .long 0x80000000,0,0,0 # invalid access-list entries 349 .endr 350 .previous 351 352#include "head_kdump.S" 353 354# 355# params at 10400 (setup.h) 356# Must be keept in sync with struct parmarea in setup.h 357# 358 .org PARMAREA 359 .quad 0 # IPL_DEVICE 360 .quad 0 # INITRD_START 361 .quad 0 # INITRD_SIZE 362 .quad 0 # OLDMEM_BASE 363 .quad 0 # OLDMEM_SIZE 364 .quad kernel_version # points to kernel version string 365 366 .org COMMAND_LINE 367 .byte "root=/dev/ram0 ro" 368 .byte 0 369 370 .org EARLY_SCCB_OFFSET 371 .fill 4096 372 373 .org HEAD_END 374