summaryrefslogtreecommitdiffstats
path: root/arch/s390x/boot/ipldump.S
blob: 84150b5af02c077bdbd9b0dabf492a9d713dce8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 *  arch/s390/boot/ipldump.S
 *
 *  S390 version
 *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
 *
 *  Tape dump ipl record. Put it on a tape and ipl from it and it will
 *  write a dump of the real storage after the ipl record on that tape.
 */

#include <asm/setup.h>
#include <asm/lowcore.h>

#define IPL_BS 1024
        .org   0
        .long  0x00080000,0x80000000+_start    # The first 24 bytes are loaded
        .long  0x07000000,0x60000001           # by ipl to addresses 0-23.
        .long  0x02000000,0x20000000+IPL_BS    # (a PSW and two CCWs).
        .long  0x00000000,0x00000000
        .long  0x00000000,0x00000000           # svc old psw
        .long  0x00000000,0x00000000           # program check old psw
        .long  0x00000000,0x00000000           # machine check old psw
        .long  0x00000000,0x00000000           # io old psw
        .long  0x00000000,0x00000000
        .long  0x00000000,0x00000000
        .long  0x00000000,0x00000000
        .long  0x000a0000,0x00000058           # external new psw
        .long  0x000a0000,0x00000060           # svc new psw
        .long  0x000a0000,0x00000068           # program check new psw
        .long  0x000a0000,0x00000070           # machine check new psw
        .long  0x00080000,0x80000000+.Lioint   # io new psw

        .org   0x100
        .globl _start
_start:
	l     %r1,0xb8                         # load ipl subchannel number
#
# find out memory size
#
        mvc   104(8),.Lpcmem0            # setup program check handler
        slr   %r3,%r3
        lhi   %r2,1
        sll   %r2,20
.Lloop0:
        l     %r0,0(%r3)                 # test page
        ar    %r3,%r2                    # add 1M
        jnm   .Lloop0                    # r1 < 0x80000000 -> loop
.Lchkmem0:
        n     %r3,.L4malign0             # align to multiples of 4M
        st    %r3,.Lmemsize              # store memory size
.Lmemok:

#
# first write a tape mark
#
        bras  %r14,.Ltapemark
#
# write real storage to tape
#	
 	slr   %r2,%r2                          # start at address 0
        bras  %r14,.Lwriter                    # load ramdisk
#
# write another tape mark
#
        bras  %r14,.Ltapemark
#
# everything written, stop processor
#
        lpsw  .Lstopped
#
# subroutine for writing to tape
# Paramters:	
#  R1 = device number
#  R2 = start address
#  R3 = length
.Lwriter:	
        st    %r14,.Lldret
        la    %r12,.Lorbread                   # r12 = address of orb 
	la    %r5,.Lirb                        # r5 = address of irb
        st    %r2,.Lccwwrite+4                 # initialize CCW data addresses
        lctl  %c6,%c6,.Lcr6               
        slr   %r2,%r2
.Lldlp:
        lhi   %r6,3                            # 3 retries
.Lssch:
        ssch  0(%r12)                          # write chunk of IPL_BS bytes
        jnz   .Llderr
.Lw4end:
        bras  %r14,.Lwait4io
        tm    8(%r5),0x82                      # do we have a problem ?
        jnz   .Lrecov
        l     %r0,.Lccwwrite+4                 # update CCW data addresses
        ahi   %r0,IPL_BS
        st    %r0,.Lccwwrite+4
        clr   %r0,%r3                          # enough ?
        jl    .Lldlp
.Ldone:
        l     %r14,.Lldret
        br    %r14                             # r2 contains the total size
.Lrecov:
        bras  %r14,.Lsense                     # do the sensing
        brct  %r6,.Lssch                       # dec. retry count & branch
        j     .Llderr
.Ltapemark:
        st    %r14,.Lldret
        la    %r12,.Lorbmark                   # r12 = address of orb
        la    %r5,.Lirb                        # r5 = address of irb
        lctl  %c6,%c6,.Lcr6
        ssch  0(%r12)                          # write a tape mark
        jnz   .Llderr
        bras  %r14,.Lwait4io
        l     %r14,.Lldret
        br    %r14
#
# Sense subroutine
#
.Lsense:
        st    %r14,.Lsnsret
        la    %r7,.Lorbsense              
        ssch  0(%r7)                           # start sense command
        jnz   .Llderr
        bras  %r14,.Lwait4io
        l     %r14,.Lsnsret
        tm    8(%r5),0x82                      # do we have a problem ?
        jnz   .Llderr
        br    %r14
#
# Wait for interrupt subroutine
#
.Lwait4io:
        lpsw  .Lwaitpsw                 
.Lioint:
        c     %r1,0xb8                         # compare subchannel number
        jne   .Lwait4io
        tsch  0(%r5)
        slr   %r0,%r0
        tm    8(%r5),0x82                      # do we have a problem ?
        jnz   .Lwtexit
        tm    8(%r5),0x04                      # got device end ?
        jz    .Lwait4io
.Lwtexit:
        br    %r14
.Llderr:
        lpsw  .Lcrash              

        .align 8
.Lorbread:
	.long  0x00000000,0x0080ff00,.Lccwwrite
        .align 8
.Lorbsense:
        .long  0x00000000,0x0080ff00,.Lccwsense
        .align 8
.Lorbmark:
        .long  0x00000000,0x0080ff00,.Lccwmark
        .align 8
.Lccwwrite:
        .long  0x01200000+IPL_BS,0x00000000
.Lccwsense:
        .long  0x04200001,0x00000000
.Lccwmark:
        .long  0x1f200001,0x00000000
.Lwaitpsw:
	.long  0x020a0000,0x80000000+.Lioint

.Lirb:	.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.Lcr6:  .long  0xff000000
        .align 8
.Lcrash:.long  0x000a0000,0x00000000
.Lstopped: .long 0x000a0000,0x00001234
.Lpcmem0:.long  0x00080000,0x80000000 + .Lchkmem0
.L4malign0:.long 0xffc00000
.Lmemsize:.long 0
.Lldret:.long  0
.Lsnsret: .long 0

         .org IPL_BS