Back to home page

LXR

 
 

    


0001 /*
0002  * Copyright IBM Corp. 1999, 2010
0003  *
0004  *    Author(s): Hartmut Penner <hp@de.ibm.com>
0005  *       Martin Schwidefsky <schwidefsky@de.ibm.com>
0006  *       Rob van der Heij <rvdhei@iae.nl>
0007  *       Heiko Carstens <heiko.carstens@de.ibm.com>
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/thread_info.h>
0028 #include <asm/facility.h>
0029 #include <asm/page.h>
0030 #include <asm/ptrace.h>
0031 
0032 #define ARCH_OFFSET 4
0033 
0034 __HEAD
0035 
0036 #define IPL_BS  0x730
0037     .org    0
0038     .long   0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
0039     .long   0x02000018,0x60000050       # by ipl to addresses 0-23.
0040     .long   0x02000068,0x60000050       # (a PSW and two CCWs).
0041     .fill   80-24,1,0x40            # bytes 24-79 are discarded !!
0042     .long   0x020000f0,0x60000050       # The next 160 byte are loaded
0043     .long   0x02000140,0x60000050       # to addresses 0x18-0xb7
0044     .long   0x02000190,0x60000050       # They form the continuation
0045     .long   0x020001e0,0x60000050       # of the CCW program started
0046     .long   0x02000230,0x60000050       # by ipl and load the range
0047     .long   0x02000280,0x60000050       # 0x0f0-0x730 from the image
0048     .long   0x020002d0,0x60000050       # to the range 0x0f0-0x730
0049     .long   0x02000320,0x60000050       # in memory. At the end of
0050     .long   0x02000370,0x60000050       # the channel program the PSW
0051     .long   0x020003c0,0x60000050       # at location 0 is loaded.
0052     .long   0x02000410,0x60000050       # Initial processing starts
0053     .long   0x02000460,0x60000050       # at 0x200 = iplstart.
0054     .long   0x020004b0,0x60000050
0055     .long   0x02000500,0x60000050
0056     .long   0x02000550,0x60000050
0057     .long   0x020005a0,0x60000050
0058     .long   0x020005f0,0x60000050
0059     .long   0x02000640,0x60000050
0060     .long   0x02000690,0x60000050
0061     .long   0x020006e0,0x20000050
0062 
0063     .org    0x200
0064 
0065 #
0066 # subroutine to wait for end I/O
0067 #
0068 .Lirqwait:
0069     mvc 0x1f0(16),.Lnewpsw  # set up IO interrupt psw
0070     lpsw    .Lwaitpsw
0071 .Lioint:
0072     br  %r14
0073     .align  8
0074 .Lnewpsw:
0075     .quad   0x0000000080000000,.Lioint
0076 .Lwaitpsw:
0077     .long   0x020a0000,0x80000000+.Lioint
0078 
0079 #
0080 # subroutine for loading cards from the reader
0081 #
0082 .Lloader:
0083     la  %r4,0(%r14)
0084     la  %r3,.Lorb       # r2 = address of orb into r2
0085     la  %r5,.Lirb       # r4 = address of irb
0086     la  %r6,.Lccws
0087     la  %r7,20
0088 .Linit:
0089     st  %r2,4(%r6)      # initialize CCW data addresses
0090     la  %r2,0x50(%r2)
0091     la  %r6,8(%r6)
0092     bct 7,.Linit
0093 
0094     lctl    %c6,%c6,.Lcr6       # set IO subclass mask
0095     slr %r2,%r2
0096 .Lldlp:
0097     ssch    0(%r3)          # load chunk of 1600 bytes
0098     bnz .Llderr
0099 .Lwait4irq:
0100     bas %r14,.Lirqwait
0101     c   %r1,0xb8        # compare subchannel number
0102     bne .Lwait4irq
0103     tsch    0(%r5)
0104 
0105     slr %r0,%r0
0106     ic  %r0,8(%r5)      # get device status
0107     chi %r0,8           # channel end ?
0108     be  .Lcont
0109     chi %r0,12          # channel end + device end ?
0110     be  .Lcont
0111 
0112     l   %r0,4(%r5)
0113     s   %r0,8(%r3)      # r0/8 = number of ccws executed
0114     mhi %r0,10          # *10 = number of bytes in ccws
0115     lh  %r3,10(%r5)     # get residual count
0116     sr  %r0,%r3         # #ccws*80-residual=#bytes read
0117     ar  %r2,%r0
0118 
0119     br  %r4         # r2 contains the total size
0120 
0121 .Lcont:
0122     ahi %r2,0x640       # add 0x640 to total size
0123     la  %r6,.Lccws
0124     la  %r7,20
0125 .Lincr:
0126     l   %r0,4(%r6)      # update CCW data addresses
0127     ahi %r0,0x640
0128     st  %r0,4(%r6)
0129     ahi %r6,8
0130     bct 7,.Lincr
0131 
0132     b   .Lldlp
0133 .Llderr:
0134     lpsw    .Lcrash
0135 
0136     .align  8
0137 .Lorb:  .long   0x00000000,0x0080ff00,.Lccws
0138 .Lirb:  .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0139 .Lcr6:  .long   0xff000000
0140 .Lloadp:.long   0,0
0141     .align  8
0142 .Lcrash:.long   0x000a0000,0x00000000
0143 
0144     .align  8
0145 .Lccws: .rept   19
0146     .long   0x02600050,0x00000000
0147     .endr
0148     .long   0x02200050,0x00000000
0149 
0150 iplstart:
0151     mvi __LC_AR_MODE_ID,1   # set esame flag
0152     slr %r0,%r0         # set cpuid to zero
0153     lhi %r1,2           # mode 2 = esame (dump)
0154     sigp    %r1,%r0,0x12        # switch to esame mode
0155     bras    %r13,0f
0156     .fill   16,4,0x0
0157 0:  lmh %r0,%r15,0(%r13)    # clear high-order half of gprs
0158     sam31               # switch to 31 bit addressing mode
0159     lh  %r1,0xb8        # test if subchannel number
0160     bct %r1,.Lnoload        #  is valid
0161     l   %r1,0xb8        # load ipl subchannel number
0162     la  %r2,IPL_BS      # load start address
0163     bas %r14,.Lloader       # load rest of ipl image
0164     l   %r12,.Lparm     # pointer to parameter area
0165     st  %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
0166 
0167 #
0168 # load parameter file from ipl device
0169 #
0170 .Lagain1:
0171     l   %r2,.Linitrd        # ramdisk loc. is temp
0172     bas %r14,.Lloader       # load parameter file
0173     ltr %r2,%r2         # got anything ?
0174     bz  .Lnopf
0175     chi %r2,895
0176     bnh .Lnotrunc
0177     la  %r2,895
0178 .Lnotrunc:
0179     l   %r4,.Linitrd
0180     clc 0(3,%r4),.L_hdr     # if it is HDRx
0181     bz  .Lagain1        # skip dataset header
0182     clc 0(3,%r4),.L_eof     # if it is EOFx
0183     bz  .Lagain1        # skip dateset trailer
0184     la  %r5,0(%r4,%r2)
0185     lr  %r3,%r2
0186     la  %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
0187     mvc 0(256,%r3),0(%r4)
0188     mvc 256(256,%r3),256(%r4)
0189     mvc 512(256,%r3),512(%r4)
0190     mvc 768(122,%r3),768(%r4)
0191     slr %r0,%r0
0192     b   .Lcntlp
0193 .Ldelspc:
0194     ic  %r0,0(%r2,%r3)
0195     chi %r0,0x20        # is it a space ?
0196     be  .Lcntlp
0197     ahi %r2,1
0198     b   .Leolp
0199 .Lcntlp:
0200     brct    %r2,.Ldelspc
0201 .Leolp:
0202     slr %r0,%r0
0203     stc %r0,0(%r2,%r3)      # terminate buffer
0204 .Lnopf:
0205 
0206 #
0207 # load ramdisk from ipl device
0208 #
0209 .Lagain2:
0210     l   %r2,.Linitrd        # addr of ramdisk
0211     st  %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
0212     bas %r14,.Lloader       # load ramdisk
0213     st  %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
0214     ltr %r2,%r2
0215     bnz .Lrdcont
0216     st  %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
0217 .Lrdcont:
0218     l   %r2,.Linitrd
0219 
0220     clc 0(3,%r2),.L_hdr     # skip HDRx and EOFx
0221     bz  .Lagain2
0222     clc 0(3,%r2),.L_eof
0223     bz  .Lagain2
0224 
0225 #
0226 # reset files in VM reader
0227 #
0228     stidp   .Lcpuid         # store cpuid
0229     tm  .Lcpuid,0xff        # running VM ?
0230     bno .Lnoreset
0231     la  %r2,.Lreset
0232     lhi %r3,26
0233     diag    %r2,%r3,8
0234     la  %r5,.Lirb
0235     stsch   0(%r5)          # check if irq is pending
0236     tm  30(%r5),0x0f        # by verifying if any of the
0237     bnz .Lwaitforirq        # activity or status control
0238     tm  31(%r5),0xff        # bits is set in the schib
0239     bz  .Lnoreset
0240 .Lwaitforirq:
0241     bas %r14,.Lirqwait      # wait for IO interrupt
0242     c   %r1,0xb8        # compare subchannel number
0243     bne .Lwaitforirq
0244     la  %r5,.Lirb
0245     tsch    0(%r5)
0246 .Lnoreset:
0247     b   .Lnoload
0248 
0249 #
0250 # everything loaded, go for it
0251 #
0252 .Lnoload:
0253     l   %r1,.Lstartup
0254     br  %r1
0255 
0256 .Linitrd:.long _end         # default address of initrd
0257 .Lparm: .long  PARMAREA
0258 .Lstartup: .long startup
0259 .Lreset:.byte   0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
0260     .byte   0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
0261     .byte   0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
0262 .L_eof: .long   0xc5d6c600   /* C'EOF' */
0263 .L_hdr: .long   0xc8c4d900   /* C'HDR' */
0264     .align  8
0265 .Lcpuid:.fill   8,1,0
0266 
0267 #
0268 # startup-code at 0x10000, running in absolute addressing mode
0269 # this is called either by the ipl loader or directly by PSW restart
0270 # or linload or SALIPL
0271 #
0272     .org    0x10000
0273 ENTRY(startup)
0274     j   .Lep_startup_normal
0275     .org    0x10008
0276 #
0277 # This is a list of s390 kernel entry points. At address 0x1000f the number of
0278 # valid entry points is stored.
0279 #
0280 # IMPORTANT: Do not change this table, it is s390 kernel ABI!
0281 #
0282     .ascii  "S390EP"
0283     .byte   0x00,0x01
0284 #
0285 # kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
0286 #
0287     .org    0x10010
0288 ENTRY(startup_kdump)
0289     j   .Lep_startup_kdump
0290 .Lep_startup_normal:
0291     mvi __LC_AR_MODE_ID,1   # set esame flag
0292     slr %r0,%r0         # set cpuid to zero
0293     lhi %r1,2           # mode 2 = esame (dump)
0294     sigp    %r1,%r0,0x12        # switch to esame mode
0295     bras    %r13,0f
0296     .fill   16,4,0x0
0297 0:  lmh %r0,%r15,0(%r13)    # clear high-order half of gprs
0298     sam64               # switch to 64 bit addressing mode
0299     basr    %r13,0          # get base
0300 .LPG0:
0301     xc  0x200(256),0x200    # partially clear lowcore
0302     xc  0x300(256),0x300
0303     xc  0xe00(256),0xe00
0304     xc  0xf00(256),0xf00
0305     lctlg   %c0,%c15,0x200(%r0) # initialize control registers
0306     stck    __LC_LAST_UPDATE_CLOCK
0307     spt 6f-.LPG0(%r13)
0308     mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
0309     l   %r15,.Lstack-.LPG0(%r13)
0310     ahi %r15,-STACK_FRAME_OVERHEAD
0311     brasl   %r14,verify_facilities
0312 # For uncompressed images, continue in
0313 # arch/s390/kernel/head64.S. For compressed images, continue in
0314 # arch/s390/boot/compressed/head.S.
0315     jg  startup_continue
0316 
0317 .Lstack:
0318     .long   0x8000 + (1<<(PAGE_SHIFT+THREAD_SIZE_ORDER))
0319     .align  8
0320 6:  .long   0x7fffffff,0xffffffff
0321 
0322 #include "head_kdump.S"
0323 
0324 #
0325 # params at 10400 (setup.h)
0326 #
0327     .org    PARMAREA
0328     .long   0,0         # IPL_DEVICE
0329     .long   0,0         # INITRD_START
0330     .long   0,0         # INITRD_SIZE
0331     .long   0,0         # OLDMEM_BASE
0332     .long   0,0         # OLDMEM_SIZE
0333 
0334     .org    COMMAND_LINE
0335     .byte   "root=/dev/ram0 ro"
0336     .byte   0
0337 
0338     .org    0x11000