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