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
|