~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/s390/boot/head.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  *
  9  * There are 5 different IPL methods
 10  *  1) load the image directly into ram at address 0 and do an PSW restart
 11  *  2) linload will load the image from address 0x10000 to memory 0x10000
 12  *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
 13  *  3) generate the tape ipl header, store the generated image on a tape
 14  *     and ipl from it
 15  *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
 16  *  4) generate the vm reader ipl header, move the generated image to the
 17  *     VM reader (use option NOH!) and do a ipl from reader (VM only)
 18  *  5) direct call of start by the SALIPL loader
 19  *  We use the cpuid to distinguish between VM and native ipl
 20  *  params for kernel are pushed to 0x10400 (see setup.h)
 21  *
 22  */
 23 
 24 #include <linux/init.h>
 25 #include <linux/linkage.h>
 26 #include <asm/asm-offsets.h>
 27 #include <asm/page.h>
 28 #include <asm/ptrace.h>
 29 #include <asm/sclp.h>
 30 #include "boot.h"
 31 
 32 #define EP_OFFSET       0x10008
 33 #define EP_STRING       "S390EP"
 34 #define IPL_BS          0x730
 35 
 36 __HEAD
 37 ipl_start:
 38         mvi     __LC_AR_MODE_ID,1       # set esame flag
 39         slr     %r0,%r0                 # set cpuid to zero
 40         lhi     %r1,2                   # mode 2 = esame (dump)
 41         sigp    %r1,%r0,0x12            # switch to esame mode
 42         sam64                           # switch to 64 bit addressing mode
 43         lgh     %r1,__LC_SUBCHANNEL_ID  # test if subchannel number
 44         brctg   %r1,.Lnoload            #  is valid
 45         llgf    %r1,__LC_SUBCHANNEL_ID  # load ipl subchannel number
 46         lghi    %r2,IPL_BS              # load start address
 47         bras    %r14,.Lloader           # load rest of ipl image
 48         larl    %r12,parmarea           # pointer to parameter area
 49         stg     %r1,IPL_DEVICE-PARMAREA(%r12) # save ipl device number
 50 #
 51 # load parameter file from ipl device
 52 #
 53 .Lagain1:
 54         larl    %r2,_end                # ramdisk loc. is temp
 55         bras    %r14,.Lloader           # load parameter file
 56         ltgr    %r2,%r2                 # got anything ?
 57         jz      .Lnopf
 58         lg      %r3,MAX_COMMAND_LINE_SIZE-PARMAREA(%r12)
 59         aghi    %r3,-1
 60         clgr    %r2,%r3
 61         jl      .Lnotrunc
 62         lgr     %r2,%r3
 63 .Lnotrunc:
 64         larl    %r4,_end
 65         larl    %r13,.L_hdr
 66         clc     0(3,%r4),0(%r13)        # if it is HDRx
 67         jz      .Lagain1                # skip dataset header
 68         larl    %r13,.L_eof
 69         clc     0(3,%r4),0(%r13)        # if it is EOFx
 70         jz      .Lagain1                # skip data set trailer
 71         lgr     %r5,%r2
 72         la      %r6,COMMAND_LINE-PARMAREA(%r12)
 73         lgr     %r7,%r2
 74         aghi    %r7,1
 75         mvcl    %r6,%r4
 76 .Lnopf:
 77 #
 78 # load ramdisk from ipl device
 79 #
 80 .Lagain2:
 81         larl    %r2,_end                # addr of ramdisk
 82         stg     %r2,INITRD_START-PARMAREA(%r12)
 83         bras    %r14,.Lloader           # load ramdisk
 84         stg     %r2,INITRD_SIZE-PARMAREA(%r12) # store size of rd
 85         ltgr    %r2,%r2
 86         jnz     .Lrdcont
 87         stg     %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found
 88 .Lrdcont:
 89         larl    %r2,_end
 90         larl    %r13,.L_hdr             # skip HDRx and EOFx
 91         clc     0(3,%r2),0(%r13)
 92         jz      .Lagain2
 93         larl    %r13,.L_eof
 94         clc     0(3,%r2),0(%r13)
 95         jz      .Lagain2
 96 #
 97 # reset files in VM reader
 98 #
 99         larl    %r13,.Lcpuid
100         stidp   0(%r13)                 # store cpuid
101         tm      0(%r13),0xff            # running VM ?
102         jno     .Lnoreset
103         larl    %r2,.Lreset
104         lghi    %r3,26
105         diag    %r2,%r3,8
106         larl    %r5,.Lirb
107         stsch   0(%r5)                  # check if irq is pending
108         tm      30(%r5),0x0f            # by verifying if any of the
109         jnz     .Lwaitforirq            # activity or status control
110         tm      31(%r5),0xff            # bits is set in the schib
111         jz      .Lnoreset
112 .Lwaitforirq:
113         bras    %r14,.Lirqwait          # wait for IO interrupt
114         c       %r1,__LC_SUBCHANNEL_ID  # compare subchannel number
115         jne     .Lwaitforirq
116         larl    %r5,.Lirb
117         tsch    0(%r5)
118 .Lnoreset:
119         j       .Lnoload
120 #
121 # everything loaded, go for it
122 #
123 .Lnoload:
124         jg      startup
125 #
126 # subroutine to wait for end I/O
127 #
128 .Lirqwait:
129         larl    %r13,.Lnewpswmask       # set up IO interrupt psw
130         mvc     __LC_IO_NEW_PSW(8),0(%r13)
131         stg     %r14,__LC_IO_NEW_PSW+8
132         larl    %r13,.Lwaitpsw
133         lpswe   0(%r13)
134 .Lioint:
135 #
136 # subroutine for loading cards from the reader
137 #
138 .Lloader:
139         lgr     %r4,%r14
140         larl    %r3,.Lorb               # r2 = address of orb into r2
141         larl    %r5,.Lirb               # r4 = address of irb
142         larl    %r6,.Lccws
143         lghi    %r7,20
144 .Linit:
145         st      %r2,4(%r6)              # initialize CCW data addresses
146         la      %r2,0x50(%r2)
147         la      %r6,8(%r6)
148         brctg   %r7,.Linit
149         larl    %r13,.Lcr6
150         lctlg   %c6,%c6,0(%r13)
151         xgr     %r2,%r2
152 .Lldlp:
153         ssch    0(%r3)                  # load chunk of 1600 bytes
154         jnz     .Llderr
155 .Lwait4irq:
156         bras    %r14,.Lirqwait
157         c       %r1,__LC_SUBCHANNEL_ID  # compare subchannel number
158         jne     .Lwait4irq
159         tsch    0(%r5)
160         xgr     %r0,%r0
161         ic      %r0,8(%r5)              # get device status
162         cghi    %r0,8                   # channel end ?
163         je      .Lcont
164         cghi    %r0,12                  # channel end + device end ?
165         je      .Lcont
166         llgf    %r0,4(%r5)
167         sgf     %r0,8(%r3)              # r0/8 = number of ccws executed
168         mghi    %r0,10                  # *10 = number of bytes in ccws
169         llgh    %r3,10(%r5)             # get residual count
170         sgr     %r0,%r3                 # #ccws*80-residual=#bytes read
171         agr     %r2,%r0
172         br      %r4                     # r2 contains the total size
173 .Lcont:
174         aghi    %r2,0x640               # add 0x640 to total size
175         larl    %r6,.Lccws
176         lghi    %r7,20
177 .Lincr:
178         l       %r0,4(%r6)              # update CCW data addresses
179         aghi    %r0,0x640
180         st      %r0,4(%r6)
181         aghi    %r6,8
182         brctg   %r7,.Lincr
183         j       .Lldlp
184 .Llderr:
185         larl    %r13,.Lcrash
186         lpsw    0(%r13)
187 
188         .balign 8
189 .Lwaitpsw:
190         .quad   0x0202000180000000,.Lioint
191 .Lnewpswmask:
192         .quad   0x0000000180000000
193         .balign 8
194 .Lorb:  .long   0x00000000,0x0080ff00,.Lccws
195 .Lirb:  .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
196         .balign 8
197 .Lcr6:  .quad   0x00000000ff000000
198         .balign 8
199 .Lcrash:.long   0x000a0000,0x00000000
200         .balign 8
201 .Lccws: .rept   19
202         .long   0x02600050,0x00000000
203         .endr
204         .long   0x02200050,0x00000000
205 .Lreset:.byte   0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
206         .byte   0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
207         .byte   0xc8,0xd6,0xd3,0xc4     # "change rdr all keep nohold"
208 .L_eof: .long   0xc5d6c600       /* C'EOF' */
209 .L_hdr: .long   0xc8c4d900       /* C'HDR' */
210         .balign 8
211 .Lcpuid:.fill   8,1,0
212 
213 #
214 # normal startup-code, running in absolute addressing mode
215 # this is called either by the ipl loader or directly by PSW restart
216 # or linload or SALIPL
217 #
218         .org    STARTUP_NORMAL_OFFSET - IPL_START
219 SYM_CODE_START(startup)
220         j       startup_normal
221         .org    EP_OFFSET - IPL_START
222 #
223 # This is a list of s390 kernel entry points. At address 0x1000f the number of
224 # valid entry points is stored.
225 #
226 # IMPORTANT: Do not change this table, it is s390 kernel ABI!
227 #
228         .ascii  EP_STRING
229         .byte   0x00,0x01
230 #
231 # kdump startup-code, running in 64 bit absolute addressing mode
232 #
233         .org    STARTUP_KDUMP_OFFSET - IPL_START
234         j       startup_kdump
235 SYM_CODE_END(startup)
236 SYM_CODE_START_LOCAL(startup_normal)
237         mvi     __LC_AR_MODE_ID,1       # set esame flag
238         slr     %r0,%r0                 # set cpuid to zero
239         lhi     %r1,2                   # mode 2 = esame (dump)
240         sigp    %r1,%r0,0x12            # switch to esame mode
241         bras    %r13,0f
242         .fill   16,4,0x0
243 0:      lmh     %r0,%r15,0(%r13)        # clear high-order half of gprs
244         sam64                           # switch to 64 bit addressing mode
245         larl    %r13,.Lext_new_psw
246         mvc     __LC_EXT_NEW_PSW(16),0(%r13)
247         larl    %r13,.Lpgm_new_psw
248         mvc     __LC_PGM_NEW_PSW(16),0(%r13)
249         larl    %r13,.Lio_new_psw
250         mvc     __LC_IO_NEW_PSW(16),0(%r13)
251         xc      0x200(256),0x200        # partially clear lowcore
252         xc      0x300(256),0x300
253         xc      0xe00(256),0xe00
254         xc      0xf00(256),0xf00
255         larl    %r13,.Lctl
256         lctlg   %c0,%c15,0(%r13)        # load control registers
257         stcke   __LC_BOOT_CLOCK
258         mvc     __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
259         larl    %r13,6f
260         spt     0(%r13)
261         mvc     __LC_LAST_UPDATE_TIMER(8),0(%r13)
262         larl    %r15,_stack_end-STACK_FRAME_OVERHEAD
263         brasl   %r14,sclp_early_setup_buffer
264         brasl   %r14,verify_facilities
265         brasl   %r14,startup_kernel
266 SYM_CODE_END(startup_normal)
267 
268         .balign 8
269 6:      .long   0x7fffffff,0xffffffff
270 .Lext_new_psw:
271         .quad   0x0002000180000000,0x1b0        # disabled wait
272 .Lpgm_new_psw:
273         .quad   0x0000000180000000,startup_pgm_check_handler
274 .Lio_new_psw:
275         .quad   0x0002000180000000,0x1f0        # disabled wait
276 .Lctl:  .quad   0x04040000              # cr0: AFP registers & secondary space
277         .quad   0                       # cr1: primary space segment table
278         .quad   0                       # cr2: dispatchable unit control table
279         .quad   0                       # cr3: instruction authorization
280         .quad   0xffff                  # cr4: instruction authorization
281         .quad   0                       # cr5: primary-aste origin
282         .quad   0                       # cr6:  I/O interrupts
283         .quad   0                       # cr7:  secondary space segment table
284         .quad   0x0000000000008000      # cr8:  access registers translation
285         .quad   0                       # cr9:  tracing off
286         .quad   0                       # cr10: tracing off
287         .quad   0                       # cr11: tracing off
288         .quad   0                       # cr12: tracing off
289         .quad   0                       # cr13: home space segment table
290         .quad   0xc0000000              # cr14: machine check handling off
291         .quad   0                       # cr15: linkage stack operations
292 
293 #include "head_kdump.S"
294 
295 #
296 # This program check is active immediately after kernel start
297 # and until early_pgm_check_handler is set in kernel/early.c
298 # It simply saves general/control registers and psw in
299 # the save area and does disabled wait with a faulty address.
300 #
301 SYM_CODE_START_LOCAL(startup_pgm_check_handler)
302         stmg    %r8,%r15,__LC_SAVE_AREA
303         la      %r8,4095
304         stctg   %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8)
305         stmg    %r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8)
306         mvc     __LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA
307         mvc     __LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW
308         mvc     __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW
309         ni      __LC_RETURN_PSW,0xfc    # remove IO and EX bits
310         ni      __LC_RETURN_PSW+1,0xfb  # remove MCHK bit
311         oi      __LC_RETURN_PSW+1,0x2   # set wait state bit
312         larl    %r9,.Lold_psw_disabled_wait
313         stg     %r9,__LC_PGM_NEW_PSW+8
314         larl    %r15,_dump_info_stack_end-STACK_FRAME_OVERHEAD
315         brasl   %r14,print_pgm_check_info
316 .Lold_psw_disabled_wait:
317         la      %r8,4095
318         lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8)
319         lpswe   __LC_RETURN_PSW         # disabled wait
320 SYM_CODE_END(startup_pgm_check_handler)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php