1/*
2 *  arch/s390/boot/ipldump.S
3 *
4 *  S390 version
5 *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7 *
8 *  Tape dump ipl record. Put it on a tape and ipl from it and it will
9 *  write a dump of the real storage after the ipl record on that tape.
10 */
11
12#include <asm/setup.h>
13#include <asm/lowcore.h>
14
15#define IPL_BS 1024
16        .org   0
17        .long  0x00080000,0x80000000+_start    # The first 24 bytes are loaded
18        .long  0x07000000,0x60000001           # by ipl to addresses 0-23.
19        .long  0x02000000,0x20000000+IPL_BS    # (a PSW and two CCWs).
20        .long  0x00000000,0x00000000
21        .long  0x00000000,0x00000000           # svc old psw
22        .long  0x00000000,0x00000000           # program check old psw
23        .long  0x00000000,0x00000000           # machine check old psw
24        .long  0x00000000,0x00000000           # io old psw
25        .long  0x00000000,0x00000000
26        .long  0x00000000,0x00000000
27        .long  0x00000000,0x00000000
28        .long  0x000a0000,0x00000058           # external new psw
29        .long  0x000a0000,0x00000060           # svc new psw
30        .long  0x000a0000,0x00000068           # program check new psw
31        .long  0x000a0000,0x00000070           # machine check new psw
32        .long  0x00080000,0x80000000+.Lioint   # io new psw
33
34        .org   0x100
35        .globl _start
36_start:
37	l     %r1,0xb8                         # load ipl subchannel number
38#
39# find out memory size
40#
41        mvc   104(8),.Lpcmem0          # setup program check handler
42        slr   %r3,%r3
43        lhi   %r2,1
44        sll   %r2,20
45.Lloop0:
46        l     %r0,0(%r3)                 # test page
47        ar    %r3,%r2                    # add 1M
48        jnm   .Lloop0                    # r1 < 0x80000000 -> loop
49.Lchkmem0:
50        n     %r3,.L4malign0             # align to multiples of 4M
51        st    %r3,.Lmemsize              # store memory size
52.Lmemok:
53
54#
55# first write a tape mark
56#
57        bras  %r14,.Ltapemark
58#
59# write real storage to tape
60#
61 	slr   %r2,%r2                          # start at address 0
62        bras  %r14,.Lwriter                    # load ramdisk
63#
64# write another tape mark
65#
66        bras  %r14,.Ltapemark
67#
68# everything written, stop processor
69#
70        lpsw  .Lstopped
71#
72# subroutine for writing to tape
73# Paramters:
74#  R1 = device number
75#  R2 = start address
76#  R3 = length
77.Lwriter:
78        st    %r14,.Lldret
79        la    %r12,.Lorbread                   # r12 = address of orb
80	la    %r5,.Lirb                        # r5 = address of irb
81        st    %r2,.Lccwwrite+4                 # initialize CCW data addresses
82        lctl  %c6,%c6,.Lcr6
83        slr   %r2,%r2
84.Lldlp:
85        lhi   %r6,3                            # 3 retries
86.Lssch:
87        ssch  0(%r12)                          # write chunk of IPL_BS bytes
88        jnz   .Llderr
89.Lw4end:
90        bras  %r14,.Lwait4io
91        tm    8(%r5),0x82                      # do we have a problem ?
92        jnz   .Lrecov
93        l     %r0,.Lccwwrite+4                 # update CCW data addresses
94        ahi   %r0,IPL_BS
95        st    %r0,.Lccwwrite+4
96        clr   %r0,%r3                          # enough ?
97        jl    .Lldlp
98.Ldone:
99        l     %r14,.Lldret
100        br    %r14                             # r2 contains the total size
101.Lrecov:
102        bras  %r14,.Lsense                     # do the sensing
103        brct  %r6,.Lssch                       # dec. retry count & branch
104        j     .Llderr
105.Ltapemark:
106        st    %r14,.Lldret
107        la    %r12,.Lorbmark                   # r12 = address of orb
108        la    %r5,.Lirb                        # r5 = address of irb
109        lctl  %c6,%c6,.Lcr6
110        ssch  0(%r12)                          # write a tape mark
111        jnz   .Llderr
112        bras  %r14,.Lwait4io
113        l     %r14,.Lldret
114        br    %r14
115#
116# Sense subroutine
117#
118.Lsense:
119        st    %r14,.Lsnsret
120        la    %r7,.Lorbsense
121        ssch  0(%r7)                           # start sense command
122        jnz   .Llderr
123        bras  %r14,.Lwait4io
124        l     %r14,.Lsnsret
125        tm    8(%r5),0x82                      # do we have a problem ?
126        jnz   .Llderr
127        br    %r14
128#
129# Wait for interrupt subroutine
130#
131.Lwait4io:
132        lpsw  .Lwaitpsw
133.Lioint:
134        c     %r1,0xb8                         # compare subchannel number
135        jne   .Lwait4io
136        tsch  0(%r5)
137        slr   %r0,%r0
138        tm    8(%r5),0x82                      # do we have a problem ?
139        jnz   .Lwtexit
140        tm    8(%r5),0x04                      # got device end ?
141        jz    .Lwait4io
142.Lwtexit:
143        br    %r14
144.Llderr:
145        lpsw  .Lcrash
146
147        .align 8
148.Lorbread:
149	.long  0x00000000,0x0080ff00,.Lccwwrite
150        .align 8
151.Lorbsense:
152        .long  0x00000000,0x0080ff00,.Lccwsense
153        .align 8
154.Lorbmark:
155        .long  0x00000000,0x0080ff00,.Lccwmark
156        .align 8
157.Lccwwrite:
158        .long  0x01200000+IPL_BS,0x00000000
159.Lccwsense:
160        .long  0x04200001,0x00000000
161.Lccwmark:
162        .long  0x1f200001,0x00000000
163.Lwaitpsw:
164	.long  0x020a0000,0x80000000+.Lioint
165
166.Lirb:	.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
167.Lcr6:  .long  0xff000000
168        .align 8
169.Lcrash:.long  0x000a0000,0x00000000
170.Lstopped: .long 0x000a0000,0x00001234
171.Lpcmem0:.long  0x00080000,0x80000000 + .Lchkmem0
172.L4malign0:.long 0xffc00000
173.Lmemsize:.long 0
174.Lldret:.long  0
175.Lsnsret: .long 0
176
177         .org IPL_BS
178
179