Import version 1.8.3
[s390-tools.git] / zipl / boot / fba2dump.S
blobe14d04705a65751f3e71d84c99398adc294975f2
1 /*
2  *  Dump boot loader for FBA DASDs
3  *    Copyright IBM Corp. 2004, 2006.
4  *    Author(s): Michael Holzheu  <holzheu@de.ibm.com>
5  *               
6  * Uses extern functions:            
7  *  - _panik
8  *  - _enable_device
9  *  - _take_dump
10  *
11  * Functions:
12  *  - _dump_mem
13  */
15 #include "dumpcommon.S"
16 #if defined(__s390x__)
17 #define USE_64BIT_SCLP
18 #endif
19 #include "sclp.S"
21 /* General defines */
23 #define IPL_BS 0x1000
24 #define BLOCKS_PER_WRITE 64 
25 #define FBA_BLK_SIZE 0x200
26 #define STAGE2_DESC 0x218
28 ################################################################################
29 # Function entry point at 0x2000 (not used for dump) is called with C linkage
30 #   %r2-%r3: load descriptor
31 #   %r3    : device subchannel id
32 #   %r4    : load address
33 ################################################################################
35 #if defined(__s390x__)
36 dump_magic:  .long 0x5a444642, 0x41363401 # ZDFBA64, version 1
37 #else
38 dump_magic:  .long 0x5a444642, 0x41333101 # ZDFBA31, version 1
39 #endif
41 #if defined(__s390x__)
44 /******************************** 64 BIT **************************************/
47 ################################################################################
48 # Program execution of the second stage boot loader starts at 0x2008
49 ################################################################################
51         .globl _start
52 _start: 
53         basr  %r13,0
54 .Linit_base:
55         la    %r9,0
56         st    %r9,.Ldh_arch-.Linit_base(%r13) # init arch 
57         l     %r15,1f-.Linit_base(%r13)       # load end of stack address
58         la    %r7,0
59         tm    __LC_ARCH_MODE_ID(%r9),0x01     # check arch mode
60         bnz   .Larch_64-.Linit_base(%r13)
62         /* 32 bit store status */
64         l     %r14,.Lstore_status_32-.Linit_base(%r13)
65         basr  %r14,%r14
66         la    %r10,ARCH_S390_ID
67         st    %r10,.Ldh_arch-.Linit_base(%r13)
69 .Larch_64:
70         la    %r7,2                             # first try code 2:
71         la    %r6,0                             # 64 bit psws are restored
72         sigp  %r7,%r6,0x12                      # switch to 64 bit
73         bc    8,.Lswitched_64-.Linit_base(%r13) # order accepted ?
74         la    %r7,1                             # code 2 failed - try code 1
75         sigp  %r7,%r6,0x12                      # switch to 64 bit
76 .Lswitched_64:
77         sam64                                   # switch to 64 bit addr mode
78         basr   %r13,0
79 0:      llgf   %r15,1f-0b(%r13)                 # load end of stack address
80         
81         llgf   %r10,.Ldh_arch-0b(%r13)
82         cghi   %r10,ARCH_S390_ID
83         be     .Larch_32-0b(%r13)
85         /* 64 bit store status */
87         llgf   %r14,.Lstore_status_64-0b(%r13)
88         basr   %r14,%r14
89         lghi   %r10,ARCH_S390X_ID
90         st     %r10,.Ldh_arch-0b(%r13)
92 .Larch_32:
93         llgf   %r2,IPL_SC                   # load ipl device subchannel id
94         llgf   %r14,.Lenable_device_64-0b(%r13)
95         basr   %r14,%r14
96         llgf   %r14,.Ltake_dump_64-0b(%r13)
97         basr   %r14,%r14
98 1:      .long  0x10000-128                  # end of stack
100 ################################################################################
101 # Dump memory
102 #  -no parameters
103 ################################################################################
105 _dump_mem_64:    
106         stmg   %r6,%r15,48(%r15)
107         basr   %r13,0                         # base register
108 0:      aghi   %r15,-200                      # create stack frame
110         # init progress bar
112         bras %r14,_init_print_progress_64
114         # get start and end block
116         mvc    .Ldev_start_blk-0b(4,%r13),STAGE2_DESC+4
117         mvc    .Ldev_end_blk-0b(4,%r13),STAGE2_DESC+8+4
119         # setup define extend
121         l         %r7,.Ldev_end_blk-0b(%r13)
122         st        %r7,12+.Ldedata-0b(%r13)
124         # calculate bytes per write (blksize * blwr)
126         llgf    %r11,.Ldev_blk_size-0b(%r13)
127         mh      %r11,.Lblocks_per_write-0b(%r13)
128         st      %r11,.Lbytes_per_write-0b(%r13)
130 # write header
132         stck    .Ldh_time-0b(%r13)            # store time
133         stidp   .Ldh_cpuid-0b(%r13)           # store cpu id
135         llgf    %r11,.Ldev_start_blk-0b(%r13) # start block
137         lgr     %r2,%r11
138         lghi    %r3, TMP_PAGE_START
139         mvc     0(256,%r3),.Ldh_dumpheader-0b(%r13) # move to 4k boundary
140         llgf    %r4,.Lheader_size-0b(%r13)
141         srda    %r4,32                        # shift ==> 64 bit number        
142         llgf    %r6,.Ldev_blk_size-0b(%r13)   # get blocksize
143         
144         dr      %r4,%r6                       # nr of blocks for header = 
145                                               # HEADER_SIZE / BLOCKSIZE = r5
146         lgr     %r4,%r5
147         lgr     %r12,%r5                      # save nr of blocks        
148         bas     %r14,_writeblock_64-0b(%r13)  # write block to disk
149         ar      %r11,%r12                     # update block counter
151 # write memory
153         lghi    %r10,0                        # start at address 0
155 .Lmloop:        
156         lghi    %r4,BLOCKS_PER_WRITE          # write so many blocks at a time
157         lgr     %r2,%r11                      # restore r2
158         lgr     %r3,%r10                      # restore r3
159         bas     %r14,_writeblock_64-0b(%r13)  # write block to disk
160         llgf    %r2,.Lbytes_per_write-0b(%r13)
161         agr     %r10,%r2                      # update data address
162         aghi    %r11,BLOCKS_PER_WRITE         # skip to next block
164         lgr     %r2,%r10                      # print progress to console
165         bras    %r14,_print_progress_64
167         lg      %r3,.Ldh_mem_size-0b(%r13)    # get memsize
168         clgr    %r10,%r3                      # enough ?
169         bl      .Lmloop-0b(%r13)              # branch if r10 < r3
171 # write end marker
173 .lendmarker:                                  # terminate dump file
174         stck    .Ld_end_time-0b(%r13)         # store end time
175         lgr     %r2,%r11                      # restore r2
176         lghi     %r3, TMP_PAGE_START
177         mvc     0(256,%r3),.Ld_endmarker-0b(%r13) # move to 4k boundary
178         lghi    %r4,1                         # write one block
179         bas     %r14,_writeblock_64-0b(%r13)  # write block to disk
181         lmg     %r6,%r15,248(%r15)
182         br      %r14                          # return to caller
183 .Lbytes_per_write:  .long 0x00000000
184 .Lheader_size:      .long HEADER_SIZE
185 .Lblocks_per_write: .word BLOCKS_PER_WRITE
187 ################################################################################
188 # This function writes a block number given in r2 to disk
189 #  -r2:  number of first block to write ( input by caller )
190 #        We start counting with Block Nr 0 !!!
191 #  -r3:  address to write data from ( input by caller )
192 #  -r4:  number of blocks to write ( input by caller )
193 ################################################################################
195 _writeblock_64:
196         stmg    %r6,%r15,48(%r15)
197         basr    %r13,0                        # base register
198 0:      aghi    %r15,-200                     # create stack frame
200         # check if blocks are within range:
202         lgr     %r11,%r2
203         agr     %r11,%r4                      # End block
204         llgf    %r12,.Ldev_end_blk-0b(%r13)
205         clr     %r11,%r12                     # End block < dev_end_blk ?
206         bl      1f-0b(%r13)                   # no
207         la      %r2,EMEM                      # if yes panik
208         llgf    %r14,.Lpanik_64-0b(%r13)
209         basr    %r14,%r14 
210         
211 1:      la      %r12,.Ldeccw-0b(%r13)
212         st      %r12,8+.Lorb-0b(%r13)         # store cpaddr to orb
213         la      %r12,.Lwrccw-0b(%r13)
214         oi      1(%r12),0x04                  # enable indirect data addressing
216         #setup locate ccw
217         sth     %r4,2+.Llodata-0b(%r13)       # store number of blocks
218         st      %r2,4+.Llodata-0b(%r13)       # store first block
220         # setup write ccw
221         la      %r12,.Lwrccw-0b(%r13)
222         la      %r10,.Lida_list-0b(%r13)      # pointer to ida list
223         st      %r10,4+.Lwrccw-0b(%r13)       # store idal data address
224         lgr     %r7,%r4
225         mh      %r7,2+.Ldev_blk_size-0b(%r13)
226         sth     %r7,2+.Lwrccw-0b(%r13)        # store byte count
228         # setup idas
230         lgr     %r2,%r3                       # start address
231         lgr     %r3,%r7                       # byte count
232         lgr     %r4,%r10                      # address of ida list
233         bas     %r14,_create_ida_list_64-0b(%r13) # create ida list
234         
235         # CCWs are setup now, arent they?
237         llgf    %r2,IPL_SC                    # subchannel id
238         la      %r3,.Lorb-0b(%r13)
239         la      %r4,.Lirb-0b(%r13)
240         la      %r5,10                        # initialize retries
242         bas     %r14,_ssch_64-0b(%r13)        # start I/O
244         lmg     %r6,%r15,248(%r15)
245         br      %r14                          # return to caller
246 .align 8
247 .Lorb:
248         .long 0x0049504c,0x0082ff00
249         .long 0x00000000,0x00000000
250 .Lirb:
251         .long 0x00000000,0x00000000
252         .long 0x00000000,0x00000000
253         .long 0x00000000,0x00000000
254         .long 0x00000000,0x00000000
255         .long 0x00000000,0x00000000
256         .long 0x00000000,0x00000000
257         .long 0x00000000,0x00000000
258         .long 0x00000000,0x00000000
259 .Ldedata:
260         .long 0xc0000200,0x00000000
261         .long 0x00000000,0x00001000
262 .Llodata:
263         .long 0x01000000,0x00000000
264 .align 8
265 .Lida_list: # enough for 128 blocks a 512 byte
266         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
267         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
268         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
269         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
271 ################################################################################
272 # expand Macros
273 ################################################################################
275         hex_to_ebcdic
276         print_progress_64
277         dump_common_store_status_32
278         dump_common_fn_64
279         dump_io_subroutines_64
280         dump_idal_64
281         dump_messages
282         dump_header
283         tmp_data
284         sclp_base
285         sclp_print
286         sclp_read_info
288 # extern functions
290 .Lpanik_64:
291         .long      _panik_64
292 .Lenable_device_64:
293         .long      _enable_device_64
294 .Ltake_dump_64:
295         .long      _take_dump_64
296 .Lstore_status_32:
297         .long      _store_status_32
298 .Lstore_status_64:
299         .long      _store_status_64
305 #else /* __s390x__ */
309 /******************************** 32 BIT **************************************/
312 ################################################################################
313 # Program execution of the second stage boot loader starts at 0x2008
314 ################################################################################
316         .globl _start
317 _start: basr   %r13,0
318 0:      l      %r15,1f-0b(%r13)             # load end of stack address
320         tm    __LC_ARCH_MODE_ID,0x01        # check arch mode
321         bz   .Larch_31-0b(%r13)
322         la    %r10,ARCH_S390X_ID
323         st    %r10,.Ldh_arch-0b(%r13)
325 .Larch_31:
326         l      %r11,IPL_SC                  # load ipl device subchannel id
327         lr     %r2,%r11
328         l      %r14,.Lenable_device_32-0b(%r13)
329         basr   %r14,%r14
330         l      %r14,.Ltake_dump_32-0b(%r13)
331         basr   %r14,%r14
332 1:      .long  0x10000-96                   # end of stack
335 ################################################################################
336 # Dump memory
337 #  - no parameters
338 ################################################################################
340 _dump_mem_32:    
341         stm    %r6,%r15,24(%r15)
342         basr   %r13,0                         # base register
343 0:      s      %r15,.Lc96-0b(%r13)            # create stack frame
345         # init progress bar
347         bras %r14,_init_print_progress_32
349         # get start and end block
351         mvc    .Ldev_start_blk-0b(4,%r13),STAGE2_DESC+4
352         mvc    .Ldev_end_blk-0b(4,%r13),STAGE2_DESC+8+4
354         # setup define extend
356         l         %r7,.Ldev_end_blk-0b(%r13)
357         st        %r7,12+.Ldedata-0b(%r13)
359         # calculate bytes per write (blksize * blwr)
361         l       %r11,.Ldev_blk_size-0b(%r13)
362         mh      %r11,.Lblocks_per_write-0b(%r13)
363         st      %r11,.Lbytes_per_write-0b(%r13)
365 # write header
367         stck    .Ldh_time-0b(%r13)            # store time
368         stidp   .Ldh_cpuid-0b(%r13)           # store cpu id
370         l       %r11,.Ldev_start_blk-0b(%r13) # start block
372         lr      %r2,%r11
373         lhi     %r3, TMP_PAGE_START
374         mvc     0(256,%r3),.Ldh_dumpheader-0b(%r13) # move to 4k boundary
375         
376         l       %r4,.Lheader_size-0b(%r13)
377         srda    %r4,32                        # shift ==> 64 bit number        
378         l       %r6,.Ldev_blk_size-0b(%r13)   # get blocksize
379         
380         dr      %r4,%r6                       # nr of blocks for header = 
381                                               # HEADER_SIZE / BLOCKSIZE = r5
382         lr      %r4,%r5
383         lr      %r12,%r5                      # save nr of blocks        
384         bas     %r14,_writeblock_32-0b(%r13)  # write block to disk
385         ar      %r11,%r12                     # update block counter
387 # write memory
389         la      %r10,0                        # start at address 0
391 .Lmloop:        
392         la      %r4,BLOCKS_PER_WRITE          # write so many blocks at a time
393         lr      %r2,%r11                      # restore r2
394         lr      %r3,%r10                      # restore r3
395         bas     %r14,_writeblock_32-0b(%r13)  # write block to disk
396         l       %r2,.Lbytes_per_write-0b(%r13)
397         ar      %r10,%r2                      # update data address
398         ah      %r11,.Lblocks_per_write-0b(%r13) # skip to next block
400         lr      %r2,%r10                      # print progress to console
401         bras    %r14,_print_progress_32
403         l       %r3,.Ldh_mem_size+4-0b(%r13)  # get memsize
404         clr     %r10,%r3                      # enough ?
405         bl      .Lmloop-0b(%r13)              # branch if r10 < r3
407 # write end marker
409 .lendmarker:                                  # terminate dump file
410         la      %r4,1                         # write endmaker with one block
411         stck    .Ld_end_time-0b(%r13)         # store end time
412         lr      %r2,%r11                      # restore r2
413         lhi     %r3, TMP_PAGE_START
414         mvc     0(256,%r3),.Ld_endmarker-0b(%r13) # move to 4k boundary
415         la      %r4,1                         # write 4k at a time
416         bas     %r14,_writeblock_32-0b(%r13)  # write block to disk
418         lm      %r6,%r15,120(%r15)
419         br      %r14                          # return to caller
420 .Lbytes_per_write:  .long 0x00000000
421 .Lheader_size:      .long HEADER_SIZE
422 .Lblocks_per_write: .word BLOCKS_PER_WRITE
424 ################################################################################
425 # This function writes a block number given in r2 to disk
426 #  -r2:   number of first block to write ( input by caller )
427 #         We start counting with Block Nr 0 !!!
428 #  -r3:   address to write data from ( input by caller )
429 #  -r4:   number of blocks to write ( input by caller )
430 ################################################################################
432 _writeblock_32:
433         stm     %r6,%r15,24(%r15)
434         basr    %r13,0                        # base register
435 0:      s       %r15,.Lc96-0b(%r13)           # create stack frame
437         # check if blocks are within range:
438         
439         lr      %r11,%r2
440         ar      %r11,%r4                      # End block
441         l       %r12,.Ldev_end_blk-0b(%r13)
442         clr     %r11,%r12                     # End block < dev_end_blk ?
443         bl      1f-0b(%r13)                   # no
444         la      %r2,EMEM                      # if yes panik
445         l       %r14,.Lpanik_32-0b(%r13)
446         basr    %r14,%r14 
447         
448 1:      la      %r12,.Ldeccw-0b(%r13)
449         st      %r12,8+.Lorb-0b(%r13)         # store cpaddr to orb
451         #setup locate ccw
452         sth     %r4,2+.Llodata-0b(%r13)       # store number of blocks
453         st      %r2,4+.Llodata-0b(%r13)       # store first block
455         # setup write ccw
456         la      %r12,.Lwrccw-0b(%r13) 
457         oi      1(%r12),0x04                  # enable ida
458         la      %r10,.Lida_list-0b(%r13)      # pointer to ida list
459         st      %r10,4+.Lwrccw-0b(%r13)       # store data address
460         lr      %r7,%r4
461         mh      %r7,2+.Ldev_blk_size-0b(%r13)
462         sth     %r7,2+.Lwrccw-0b(%r13)        # store byte count 
464         # setup idas
465         lr      %r2,%r3                       # start address
466         lr      %r3,%r7                       # byte count
467         lr      %r4,%r10                      # address of ida list
468         bas     %r14,_create_ida_list_32-0b(%r13)  # create the list
469         
470         # CCWs are setup now, arent they?
472         l       %r2,IPL_SC                    # subchannel id
473         la      %r3,.Lorb-0b(%r13)
474         la      %r4,.Lirb-0b(%r13)
475         la      %r5,10                        # initialize retries
477         bas     %r14,_ssch_32-0b(%r13)        # start I/O
479         lm      %r6,%r15,120(%r15)
480         br      %r14                          # return to caller
481 .Lccw_size:
482         .word 0x8
483 .align 8
484 .Lorb:
485         .long 0x0049504c,0x0080ff00           # intparm is " IPL"
486         .long 0x00000000,0x00000000
487 .Lirb:
488         .long 0x00000000,0x00000000
489         .long 0x00000000,0x00000000
490         .long 0x00000000,0x00000000
491         .long 0x00000000,0x00000000
492         .long 0x00000000,0x00000000
493         .long 0x00000000,0x00000000
494         .long 0x00000000,0x00000000
495         .long 0x00000000,0x00000000
496 .Ldedata:
497         .long 0xc0000200,0x00000000
498         .long 0x00000000,0x00001000
499 .Llodata:
500         .long 0x01000000,0x00000000
501 .align 8
502 .Lida_list: # enough for 128 blocks a 512 byte
503         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
504         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
505         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
506         .long 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
508 ################################################################################
509 # expand Macros
510 ################################################################################
512         hex_to_ebcdic
513         print_progress_32
514         dump_common_fn_32
515         dump_io_subroutines_32
516         dump_idal_32
517         dump_messages
518         dump_header
519         tmp_data
520         sclp_base
521         sclp_print
522         sclp_read_info
524 # extern functions
526 .Lpanik_32:
527         .long      _panik_32
528 .Lenable_device_32:
529         .long      _enable_device_32
530 .Ltake_dump_32:
531         .long      _take_dump_32
533 #endif /* __s390x__ */
536 ################################################################################
537 # DATA
538 ################################################################################
540 .Lc96:  .long  96 # for creating stackframes
542 # device characteristics
543 .align 8
544 .Ldev_start_blk:
545         .long  0x00000000
546 .Ldev_end_blk:
547         .long  0x00000000
548 .Ldev_blk_size:
549         .long  FBA_BLK_SIZE 
552 # CCWs
555 .align 8
557 # channel program for one write
559 .Ldeccw:
560         .long 0x63400010,0x00000000+.Ldedata     # define extent
561 .Lloccw:
562         .long 0x43400008,0x00000000+.Llodata     # locate
563 .Lwrccw:
564         .long 0x41200000,0x00000000              # write blocks
566 .org (IPL_BS - 8)
567 .Lmem_upper_limit:
568         .long 0xffffffff,0xffffffff              # can be used for memsize=xxx