dccp: do not assume DCCP code is non preemptible
[linux/fpc-iii.git] / arch / s390 / kernel / head.S
blobfcaefb041364c13f15ddd0c976846b683c626c5a
1 /*
2  * Copyright IBM Corp. 1999, 2010
3  *
4  *    Author(s): Hartmut Penner <hp@de.ibm.com>
5  *               Martin Schwidefsky <schwidefsky@de.ibm.com>
6  *               Rob van der Heij <rvdhei@iae.nl>
7  *               Heiko Carstens <heiko.carstens@de.ibm.com>
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  */
24 #include <linux/init.h>
25 #include <linux/linkage.h>
26 #include <asm/asm-offsets.h>
27 #include <asm/thread_info.h>
28 #include <asm/facility.h>
29 #include <asm/page.h>
30 #include <asm/ptrace.h>
32 #define ARCH_OFFSET     4
34 __HEAD
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
63         .org    0x200
66 # subroutine to wait for end I/O
68 .Lirqwait:
69         mvc     0x1f0(16),.Lnewpsw      # set up IO interrupt psw
70         lpsw    .Lwaitpsw
71 .Lioint:
72         br      %r14
73         .align  8
74 .Lnewpsw:
75         .quad   0x0000000080000000,.Lioint
76 .Lwaitpsw:
77         .long   0x020a0000,0x80000000+.Lioint
80 # subroutine for loading cards from the reader
82 .Lloader:
83         la      %r4,0(%r14)
84         la      %r3,.Lorb               # r2 = address of orb into r2
85         la      %r5,.Lirb               # r4 = address of irb
86         la      %r6,.Lccws
87         la      %r7,20
88 .Linit:
89         st      %r2,4(%r6)              # initialize CCW data addresses
90         la      %r2,0x50(%r2)
91         la      %r6,8(%r6)
92         bct     7,.Linit
94         lctl    %c6,%c6,.Lcr6           # set IO subclass mask
95         slr     %r2,%r2
96 .Lldlp:
97         ssch    0(%r3)                  # load chunk of 1600 bytes
98         bnz     .Llderr
99 .Lwait4irq:
100         bas     %r14,.Lirqwait
101         c       %r1,0xb8                # compare subchannel number
102         bne     .Lwait4irq
103         tsch    0(%r5)
105         slr     %r0,%r0
106         ic      %r0,8(%r5)              # get device status
107         chi     %r0,8                   # channel end ?
108         be      .Lcont
109         chi     %r0,12                  # channel end + device end ?
110         be      .Lcont
112         l       %r0,4(%r5)
113         s       %r0,8(%r3)              # r0/8 = number of ccws executed
114         mhi     %r0,10                  # *10 = number of bytes in ccws
115         lh      %r3,10(%r5)             # get residual count
116         sr      %r0,%r3                 # #ccws*80-residual=#bytes read
117         ar      %r2,%r0
119         br      %r4                     # r2 contains the total size
121 .Lcont:
122         ahi     %r2,0x640               # add 0x640 to total size
123         la      %r6,.Lccws
124         la      %r7,20
125 .Lincr:
126         l       %r0,4(%r6)              # update CCW data addresses
127         ahi     %r0,0x640
128         st      %r0,4(%r6)
129         ahi     %r6,8
130         bct     7,.Lincr
132         b       .Lldlp
133 .Llderr:
134         lpsw    .Lcrash
136         .align  8
137 .Lorb:  .long   0x00000000,0x0080ff00,.Lccws
138 .Lirb:  .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
139 .Lcr6:  .long   0xff000000
140 .Lloadp:.long   0,0
141         .align  8
142 .Lcrash:.long   0x000a0000,0x00000000
144         .align  8
145 .Lccws: .rept   19
146         .long   0x02600050,0x00000000
147         .endr
148         .long   0x02200050,0x00000000
150 iplstart:
151         mvi     __LC_AR_MODE_ID,1       # set esame flag
152         slr     %r0,%r0                 # set cpuid to zero
153         lhi     %r1,2                   # mode 2 = esame (dump)
154         sigp    %r1,%r0,0x12            # switch to esame mode
155         bras    %r13,0f
156         .fill   16,4,0x0
157 0:      lmh     %r0,%r15,0(%r13)        # clear high-order half of gprs
158         sam31                           # switch to 31 bit addressing mode
159         lh      %r1,0xb8                # test if subchannel number
160         bct     %r1,.Lnoload            #  is valid
161         l       %r1,0xb8                # load ipl subchannel number
162         la      %r2,IPL_BS              # load start address
163         bas     %r14,.Lloader           # load rest of ipl image
164         l       %r12,.Lparm             # pointer to parameter area
165         st      %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
168 # load parameter file from ipl device
170 .Lagain1:
171         l       %r2,.Linitrd            # ramdisk loc. is temp
172         bas     %r14,.Lloader           # load parameter file
173         ltr     %r2,%r2                 # got anything ?
174         bz      .Lnopf
175         chi     %r2,895
176         bnh     .Lnotrunc
177         la      %r2,895
178 .Lnotrunc:
179         l       %r4,.Linitrd
180         clc     0(3,%r4),.L_hdr         # if it is HDRx
181         bz      .Lagain1                # skip dataset header
182         clc     0(3,%r4),.L_eof         # if it is EOFx
183         bz      .Lagain1                # skip dateset trailer
184         la      %r5,0(%r4,%r2)
185         lr      %r3,%r2
186         la      %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
187         mvc     0(256,%r3),0(%r4)
188         mvc     256(256,%r3),256(%r4)
189         mvc     512(256,%r3),512(%r4)
190         mvc     768(122,%r3),768(%r4)
191         slr     %r0,%r0
192         b       .Lcntlp
193 .Ldelspc:
194         ic      %r0,0(%r2,%r3)
195         chi     %r0,0x20                # is it a space ?
196         be      .Lcntlp
197         ahi     %r2,1
198         b       .Leolp
199 .Lcntlp:
200         brct    %r2,.Ldelspc
201 .Leolp:
202         slr     %r0,%r0
203         stc     %r0,0(%r2,%r3)          # terminate buffer
204 .Lnopf:
207 # load ramdisk from ipl device
209 .Lagain2:
210         l       %r2,.Linitrd            # addr of ramdisk
211         st      %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
212         bas     %r14,.Lloader           # load ramdisk
213         st      %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
214         ltr     %r2,%r2
215         bnz     .Lrdcont
216         st      %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
217 .Lrdcont:
218         l       %r2,.Linitrd
220         clc     0(3,%r2),.L_hdr         # skip HDRx and EOFx
221         bz      .Lagain2
222         clc     0(3,%r2),.L_eof
223         bz      .Lagain2
226 # reset files in VM reader
228         stidp   .Lcpuid                 # store cpuid
229         tm      .Lcpuid,0xff            # running VM ?
230         bno     .Lnoreset
231         la      %r2,.Lreset
232         lhi     %r3,26
233         diag    %r2,%r3,8
234         la      %r5,.Lirb
235         stsch   0(%r5)                  # check if irq is pending
236         tm      30(%r5),0x0f            # by verifying if any of the
237         bnz     .Lwaitforirq            # activity or status control
238         tm      31(%r5),0xff            # bits is set in the schib
239         bz      .Lnoreset
240 .Lwaitforirq:
241         bas     %r14,.Lirqwait          # wait for IO interrupt
242         c       %r1,0xb8                # compare subchannel number
243         bne     .Lwaitforirq
244         la      %r5,.Lirb
245         tsch    0(%r5)
246 .Lnoreset:
247         b       .Lnoload
250 # everything loaded, go for it
252 .Lnoload:
253         l       %r1,.Lstartup
254         br      %r1
256 .Linitrd:.long _end                     # default address of initrd
257 .Lparm: .long  PARMAREA
258 .Lstartup: .long startup
259 .Lreset:.byte   0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
260         .byte   0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
261         .byte   0xc8,0xd6,0xd3,0xc4     # "change rdr all keep nohold"
262 .L_eof: .long   0xc5d6c600       /* C'EOF' */
263 .L_hdr: .long   0xc8c4d900       /* C'HDR' */
264         .align  8
265 .Lcpuid:.fill   8,1,0
268 # startup-code at 0x10000, running in absolute addressing mode
269 # this is called either by the ipl loader or directly by PSW restart
270 # or linload or SALIPL
272         .org    0x10000
273 ENTRY(startup)
274         j       .Lep_startup_normal
275         .org    0x10008
277 # This is a list of s390 kernel entry points. At address 0x1000f the number of
278 # valid entry points is stored.
280 # IMPORTANT: Do not change this table, it is s390 kernel ABI!
282         .ascii  "S390EP"
283         .byte   0x00,0x01
285 # kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
287         .org    0x10010
288 ENTRY(startup_kdump)
289         j       .Lep_startup_kdump
290 .Lep_startup_normal:
291         mvi     __LC_AR_MODE_ID,1       # set esame flag
292         slr     %r0,%r0                 # set cpuid to zero
293         lhi     %r1,2                   # mode 2 = esame (dump)
294         sigp    %r1,%r0,0x12            # switch to esame mode
295         bras    %r13,0f
296         .fill   16,4,0x0
297 0:      lmh     %r0,%r15,0(%r13)        # clear high-order half of gprs
298         sam64                           # switch to 64 bit addressing mode
299         basr    %r13,0                  # get base
300 .LPG0:
301         xc      0x200(256),0x200        # partially clear lowcore
302         xc      0x300(256),0x300
303         xc      0xe00(256),0xe00
304         xc      0xf00(256),0xf00
305         lctlg   %c0,%c15,0x200(%r0)     # initialize control registers
306         stck    __LC_LAST_UPDATE_CLOCK
307         spt     6f-.LPG0(%r13)
308         mvc     __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
309         stfl    0(%r0)                  # store facilities @ __LC_STFL_FAC_LIST
310         mvc     __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
311         tm      __LC_STFLE_FAC_LIST,0x01        # stfle available ?
312         jz      0f
313         lghi    %r0,FACILITIES_ALS_DWORDS-1
314         .insn   s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
315         # verify if all required facilities are supported by the machine
316 0:      la      %r1,__LC_STFLE_FAC_LIST
317         la      %r2,3f+8-.LPG0(%r13)
318         lhi     %r3,FACILITIES_ALS_DWORDS
319 1:      lg      %r0,0(%r1)
320         ng      %r0,0(%r2)
321         clg     %r0,0(%r2)
322         jne     2f
323         la      %r1,8(%r1)
324         la      %r2,8(%r2)
325         ahi     %r3,-1
326         jnz     1b
327         j       4f
328 2:      l       %r15,.Lstack-.LPG0(%r13)
329         ahi     %r15,-STACK_FRAME_OVERHEAD
330         la      %r2,.Lals_string-.LPG0(%r13)
331         l       %r3,.Lsclp_print-.LPG0(%r13)
332         basr    %r14,%r3
333         lpsw    3f-.LPG0(%r13)          # machine type not good enough, crash
334 .Lals_string:
335         .asciz  "The Linux kernel requires more recent processor hardware"
336 .Lsclp_print:
337         .long   _sclp_print_early
338 .Lstack:
339         .long   0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
340         .align 16
341 3:      .long   0x000a0000,0x8badcccc
343 # List of facilities that are required. If not all facilities are present
344 # the kernel will crash.
346         .quad FACILITIES_ALS
349         /* Continue with startup code in head64.S */
350         jg      startup_continue
352         .align  8
353 6:      .long   0x7fffffff,0xffffffff
355 #include "head_kdump.S"
358 # params at 10400 (setup.h)
360         .org    PARMAREA
361         .long   0,0                     # IPL_DEVICE
362         .long   0,0                     # INITRD_START
363         .long   0,0                     # INITRD_SIZE
364         .long   0,0                     # OLDMEM_BASE
365         .long   0,0                     # OLDMEM_SIZE
367         .org    COMMAND_LINE
368         .byte   "root=/dev/ram0 ro"
369         .byte   0
371         .org    0x11000