root/arch/s390/boot/head.S

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

/* [<][>][^][v][top][bottom][index][help] */