Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright IBM Corp. 1999, 2010
0004  *
0005  *    Author(s): Hartmut Penner <hp@de.ibm.com>
0006  *       Martin Schwidefsky <schwidefsky@de.ibm.com>
0007  *       Rob van der Heij <rvdhei@iae.nl>
0008  *
0009  * There are 5 different IPL methods
0010  *  1) load the image directly into ram at address 0 and do an PSW restart
0011  *  2) linload will load the image from address 0x10000 to memory 0x10000
0012  *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
0013  *  3) generate the tape ipl header, store the generated image on a tape
0014  *     and ipl from it
0015  *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
0016  *  4) generate the vm reader ipl header, move the generated image to the
0017  *     VM reader (use option NOH!) and do a ipl from reader (VM only)
0018  *  5) direct call of start by the SALIPL loader
0019  *  We use the cpuid to distinguish between VM and native ipl
0020  *  params for kernel are pushed to 0x10400 (see setup.h)
0021  *
0022  */
0023 
0024 #include <linux/init.h>
0025 #include <linux/linkage.h>
0026 #include <asm/asm-offsets.h>
0027 #include <asm/page.h>
0028 #include <asm/ptrace.h>
0029 #include <asm/sclp.h>
0030 #include "boot.h"
0031 
0032 #define EP_OFFSET   0x10008
0033 #define EP_STRING   "S390EP"
0034 #define IPL_BS      0x730
0035 
0036 __HEAD
0037 ipl_start:
0038     mvi __LC_AR_MODE_ID,1   # set esame flag
0039     slr %r0,%r0         # set cpuid to zero
0040     lhi %r1,2           # mode 2 = esame (dump)
0041     sigp    %r1,%r0,0x12        # switch to esame mode
0042     sam64               # switch to 64 bit addressing mode
0043     lgh %r1,__LC_SUBCHANNEL_ID  # test if subchannel number
0044     brctg   %r1,.Lnoload        #  is valid
0045     llgf    %r1,__LC_SUBCHANNEL_ID  # load ipl subchannel number
0046     lghi    %r2,IPL_BS      # load start address
0047     bras    %r14,.Lloader       # load rest of ipl image
0048     larl    %r12,parmarea       # pointer to parameter area
0049     stg %r1,IPL_DEVICE-PARMAREA(%r12) # save ipl device number
0050 #
0051 # load parameter file from ipl device
0052 #
0053 .Lagain1:
0054     larl    %r2,_end        # ramdisk loc. is temp
0055     bras    %r14,.Lloader       # load parameter file
0056     ltgr    %r2,%r2         # got anything ?
0057     jz  .Lnopf
0058     lg  %r3,MAX_COMMAND_LINE_SIZE-PARMAREA(%r12)
0059     aghi    %r3,-1
0060     clgr    %r2,%r3
0061     jl  .Lnotrunc
0062     lgr %r2,%r3
0063 .Lnotrunc:
0064     larl    %r4,_end
0065     larl    %r13,.L_hdr
0066     clc 0(3,%r4),0(%r13)    # if it is HDRx
0067     jz  .Lagain1        # skip dataset header
0068     larl    %r13,.L_eof
0069     clc 0(3,%r4),0(%r13)    # if it is EOFx
0070     jz  .Lagain1        # skip dateset trailer
0071     lgr %r5,%r2
0072     la  %r6,COMMAND_LINE-PARMAREA(%r12)
0073     lgr %r7,%r2
0074     aghi    %r7,1
0075     mvcl    %r6,%r4
0076 .Lnopf:
0077 #
0078 # load ramdisk from ipl device
0079 #
0080 .Lagain2:
0081     larl    %r2,_end        # addr of ramdisk
0082     stg %r2,INITRD_START-PARMAREA(%r12)
0083     bras    %r14,.Lloader       # load ramdisk
0084     stg %r2,INITRD_SIZE-PARMAREA(%r12) # store size of rd
0085     ltgr    %r2,%r2
0086     jnz .Lrdcont
0087     stg %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found
0088 .Lrdcont:
0089     larl    %r2,_end
0090     larl    %r13,.L_hdr     # skip HDRx and EOFx
0091     clc 0(3,%r2),0(%r13)
0092     jz  .Lagain2
0093     larl    %r13,.L_eof
0094     clc 0(3,%r2),0(%r13)
0095     jz  .Lagain2
0096 #
0097 # reset files in VM reader
0098 #
0099     larl    %r13,.Lcpuid
0100     stidp   0(%r13)         # store cpuid
0101     tm  0(%r13),0xff        # running VM ?
0102     jno .Lnoreset
0103     larl    %r2,.Lreset
0104     lghi    %r3,26
0105     diag    %r2,%r3,8
0106     larl    %r5,.Lirb
0107     stsch   0(%r5)          # check if irq is pending
0108     tm  30(%r5),0x0f        # by verifying if any of the
0109     jnz .Lwaitforirq        # activity or status control
0110     tm  31(%r5),0xff        # bits is set in the schib
0111     jz  .Lnoreset
0112 .Lwaitforirq:
0113     bras    %r14,.Lirqwait      # wait for IO interrupt
0114     c   %r1,__LC_SUBCHANNEL_ID  # compare subchannel number
0115     jne .Lwaitforirq
0116     larl    %r5,.Lirb
0117     tsch    0(%r5)
0118 .Lnoreset:
0119     j   .Lnoload
0120 #
0121 # everything loaded, go for it
0122 #
0123 .Lnoload:
0124     jg  startup
0125 #
0126 # subroutine to wait for end I/O
0127 #
0128 .Lirqwait:
0129     larl    %r13,.Lnewpswmask   # set up IO interrupt psw
0130     mvc __LC_IO_NEW_PSW(8),0(%r13)
0131     stg %r14,__LC_IO_NEW_PSW+8
0132     larl    %r13,.Lwaitpsw
0133     lpswe   0(%r13)
0134 .Lioint:
0135 #
0136 # subroutine for loading cards from the reader
0137 #
0138 .Lloader:
0139     lgr %r4,%r14
0140     larl    %r3,.Lorb       # r2 = address of orb into r2
0141     larl    %r5,.Lirb       # r4 = address of irb
0142     larl    %r6,.Lccws
0143     lghi    %r7,20
0144 .Linit:
0145     st  %r2,4(%r6)      # initialize CCW data addresses
0146     la  %r2,0x50(%r2)
0147     la  %r6,8(%r6)
0148     brctg   %r7,.Linit
0149     larl    %r13,.Lcr6
0150     lctlg   %c6,%c6,0(%r13)
0151     xgr %r2,%r2
0152 .Lldlp:
0153     ssch    0(%r3)          # load chunk of 1600 bytes
0154     jnz .Llderr
0155 .Lwait4irq:
0156     bras    %r14,.Lirqwait
0157     c   %r1,__LC_SUBCHANNEL_ID  # compare subchannel number
0158     jne .Lwait4irq
0159     tsch    0(%r5)
0160     xgr %r0,%r0
0161     ic  %r0,8(%r5)      # get device status
0162     cghi    %r0,8           # channel end ?
0163     je  .Lcont
0164     cghi    %r0,12          # channel end + device end ?
0165     je  .Lcont
0166     llgf    %r0,4(%r5)
0167     sgf %r0,8(%r3)      # r0/8 = number of ccws executed
0168     mghi    %r0,10          # *10 = number of bytes in ccws
0169     llgh    %r3,10(%r5)     # get residual count
0170     sgr %r0,%r3         # #ccws*80-residual=#bytes read
0171     agr %r2,%r0
0172     br  %r4         # r2 contains the total size
0173 .Lcont:
0174     aghi    %r2,0x640       # add 0x640 to total size
0175     larl    %r6,.Lccws
0176     lghi    %r7,20
0177 .Lincr:
0178     l   %r0,4(%r6)      # update CCW data addresses
0179     aghi    %r0,0x640
0180     st  %r0,4(%r6)
0181     aghi    %r6,8
0182     brctg   %r7,.Lincr
0183     j   .Lldlp
0184 .Llderr:
0185     larl    %r13,.Lcrash
0186     lpsw    0(%r13)
0187 
0188     .align  8
0189 .Lwaitpsw:
0190     .quad   0x0202000180000000,.Lioint
0191 .Lnewpswmask:
0192     .quad   0x0000000180000000
0193     .align  8
0194 .Lorb:  .long   0x00000000,0x0080ff00,.Lccws
0195 .Lirb:  .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0196     .align  8
0197 .Lcr6:  .quad   0x00000000ff000000
0198     .align  8
0199 .Lcrash:.long   0x000a0000,0x00000000
0200     .align  8
0201 .Lccws: .rept   19
0202     .long   0x02600050,0x00000000
0203     .endr
0204     .long   0x02200050,0x00000000
0205 .Lreset:.byte   0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
0206     .byte   0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
0207     .byte   0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
0208 .L_eof: .long   0xc5d6c600   /* C'EOF' */
0209 .L_hdr: .long   0xc8c4d900   /* C'HDR' */
0210     .align  8
0211 .Lcpuid:.fill   8,1,0
0212 
0213 #
0214 # normal startup-code, running in absolute addressing mode
0215 # this is called either by the ipl loader or directly by PSW restart
0216 # or linload or SALIPL
0217 #
0218     .org    STARTUP_NORMAL_OFFSET - IPL_START
0219 SYM_CODE_START(startup)
0220     j   startup_normal
0221     .org    EP_OFFSET - IPL_START
0222 #
0223 # This is a list of s390 kernel entry points. At address 0x1000f the number of
0224 # valid entry points is stored.
0225 #
0226 # IMPORTANT: Do not change this table, it is s390 kernel ABI!
0227 #
0228     .ascii  EP_STRING
0229     .byte   0x00,0x01
0230 #
0231 # kdump startup-code, running in 64 bit absolute addressing mode
0232 #
0233     .org    STARTUP_KDUMP_OFFSET - IPL_START
0234     j   startup_kdump
0235 SYM_CODE_END(startup)
0236 SYM_CODE_START_LOCAL(startup_normal)
0237     mvi __LC_AR_MODE_ID,1   # set esame flag
0238     slr %r0,%r0         # set cpuid to zero
0239     lhi %r1,2           # mode 2 = esame (dump)
0240     sigp    %r1,%r0,0x12        # switch to esame mode
0241     bras    %r13,0f
0242     .fill   16,4,0x0
0243 0:  lmh %r0,%r15,0(%r13)    # clear high-order half of gprs
0244     sam64               # switch to 64 bit addressing mode
0245     larl    %r13,.Lext_new_psw
0246     mvc __LC_EXT_NEW_PSW(16),0(%r13)
0247     larl    %r13,.Lpgm_new_psw
0248     mvc __LC_PGM_NEW_PSW(16),0(%r13)
0249     larl    %r13,.Lio_new_psw
0250     mvc __LC_IO_NEW_PSW(16),0(%r13)
0251     xc  0x200(256),0x200    # partially clear lowcore
0252     xc  0x300(256),0x300
0253     xc  0xe00(256),0xe00
0254     xc  0xf00(256),0xf00
0255     larl    %r13,.Lctl
0256     lctlg   %c0,%c15,0(%r13)    # load control registers
0257     stcke   __LC_BOOT_CLOCK
0258     mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
0259     larl    %r13,6f
0260     spt 0(%r13)
0261     mvc __LC_LAST_UPDATE_TIMER(8),0(%r13)
0262     larl    %r15,_stack_end-STACK_FRAME_OVERHEAD
0263     brasl   %r14,sclp_early_setup_buffer
0264     brasl   %r14,verify_facilities
0265     brasl   %r14,startup_kernel
0266 SYM_CODE_END(startup_normal)
0267 
0268     .align  8
0269 6:  .long   0x7fffffff,0xffffffff
0270 .Lext_new_psw:
0271     .quad   0x0002000180000000,0x1b0    # disabled wait
0272 .Lpgm_new_psw:
0273     .quad   0x0000000180000000,startup_pgm_check_handler
0274 .Lio_new_psw:
0275     .quad   0x0002000180000000,0x1f0    # disabled wait
0276 .Lctl:  .quad   0x04040000      # cr0: AFP registers & secondary space
0277     .quad   0           # cr1: primary space segment table
0278     .quad   0           # cr2: dispatchable unit control table
0279     .quad   0           # cr3: instruction authorization
0280     .quad   0xffff          # cr4: instruction authorization
0281     .quad   0           # cr5: primary-aste origin
0282     .quad   0           # cr6:  I/O interrupts
0283     .quad   0           # cr7:  secondary space segment table
0284     .quad   0x0000000000008000  # cr8:  access registers translation
0285     .quad   0           # cr9:  tracing off
0286     .quad   0           # cr10: tracing off
0287     .quad   0           # cr11: tracing off
0288     .quad   0           # cr12: tracing off
0289     .quad   0           # cr13: home space segment table
0290     .quad   0xc0000000      # cr14: machine check handling off
0291     .quad   0           # cr15: linkage stack operations
0292 
0293 #include "head_kdump.S"
0294 
0295 #
0296 # This program check is active immediately after kernel start
0297 # and until early_pgm_check_handler is set in kernel/early.c
0298 # It simply saves general/control registers and psw in
0299 # the save area and does disabled wait with a faulty address.
0300 #
0301 SYM_CODE_START_LOCAL(startup_pgm_check_handler)
0302     stmg    %r8,%r15,__LC_SAVE_AREA_SYNC
0303     la  %r8,4095
0304     stctg   %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8)
0305     stmg    %r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8)
0306     mvc __LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA_SYNC
0307     mvc __LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW
0308     mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW
0309     ni  __LC_RETURN_PSW,0xfc    # remove IO and EX bits
0310     ni  __LC_RETURN_PSW+1,0xfb  # remove MCHK bit
0311     oi  __LC_RETURN_PSW+1,0x2   # set wait state bit
0312     larl    %r9,.Lold_psw_disabled_wait
0313     stg %r9,__LC_PGM_NEW_PSW+8
0314     larl    %r15,_dump_info_stack_end-STACK_FRAME_OVERHEAD
0315     brasl   %r14,print_pgm_check_info
0316 .Lold_psw_disabled_wait:
0317     la  %r8,4095
0318     lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8)
0319     lpswe   __LC_RETURN_PSW     # disabled wait
0320 SYM_CODE_END(startup_pgm_check_handler)