2 * Copyright (c) 2011-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 static char *deck_head
=
30 "# NOTE: This file was automatically generated by " __FILE__
"\n"
32 "# During the system IPL, 24 bytes are read from the device.\n"
34 "# NOTE: zArch IPLs in ESA/390 mode.\n"
40 " .type START, @function\n"
43 static char *card_head
=
45 "#######################################################################\n"
47 "#######################################################################\n";
49 static char *psw_head
=
51 "# Bytes 0-7 contain PSW to be loaded after IO operation completes\n"
56 " # bits value name desc\n"
58 " # 1 0 PER Mask (R) disabled\n"
60 " # 5 0 DAT Mode (T) disabled\n"
61 " # 6 0 I/O Mask (IO) disabled\n"
62 " # 7 0 External Mask (EX) disabled\n"
65 " # bits value name desc\n"
68 " # 13 0 Machine-Check Mask (M) disabled\n"
69 " # 14 0 Wait State (W) executing\n"
70 " # 15 0 Problem State (P) supervisor state\n"
73 " # bits value name desc\n"
74 " # 16-17 0 Address-Space Control (AS) disabled\n"
75 " # 18-19 0 Condition Code (CC)\n"
76 " # 20-23 0 Program Mask exceptions disabled\n"
79 " # bits value name desc\n"
81 " # 31 0 Extended Addressing (EA) ! 64 mode\n"
83 " .byte 0x%c%c # bits 32-39\n"
84 " .byte 0x%c%c # bits 40-47\n"
85 " .byte 0x%c%c # bits 48-55\n"
86 " .byte 0x%c%c # bits 56-63\n"
87 " # bits value name desc\n"
88 " # 32 1 Basic Addressing (BA) BA = 31, !BA = 24\n"
89 " # 33-63 addr Instruction Address Address to exec\n";
91 static char *psw_tail
=
94 "# The remaining 16 bytes should contain CCW to read data from device\n"
100 "# 8-31 Data Address\n"
101 "# 32 Chain-Data (CD)\n"
102 "# 33 Chain-Command (CC)\n"
103 "# 34 Sup.-Len.-Inditcation (SLI)\n"
105 "# 36 Prog.-Contr.-Inter. (PCI)\n"
106 "# 37 Indir.-Data-Addr. (IDA)\n"
108 "# 39 Modified I.D.A. (MIDA)\n"
109 "# 40-47 <ignored>\n"
110 "# 48-63 number of bytes to read\n"
113 " # READ 80 bytes of CCWs to 0x%06X\n"
114 " .byte 0x02, 0x%02X, 0x%02X, 0x%02X\n"
115 " .byte 0x%02X, 0x00, 0x00, 0x50\n"
119 " .byte 0x08, 0x%02X, 0x%02X, 0x%02X\n"
120 " .byte 0x00, 0x00, 0x00, 0x00\n";
125 "# Pad to 80 bytes\n"
127 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
128 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
129 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
130 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
131 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
132 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
133 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n";
135 static char *cp_ccw
=
138 " .byte 0x02, 0x%02X, 0x%02X, 0x%02X\n"
139 " .byte 0x40, 0x00, 0x00, 0x50\n";
143 static char *data_ccw
=
146 " .byte 0x02, 0x%02X, 0x%02X, 0x%02X\n"
147 " .byte 0x%02X, 0x00, 0x00, 0x50\n";
149 static char *nop_ccw
=
152 " .byte 0x03, 0x00, 0x00, 0x08\n"
153 " .byte 0x60, 0x00, 0x00, 0x01\n";
155 #define ADDR(x) (((x)[0]<<16) | \
159 #define ADDRS(x) (x)[0], (x)[1], (x)[2]
161 static void die(char *pgm
, char *s
)
163 fprintf(stderr
, "Error: %s\n", s
);
164 fprintf(stderr
, "Usage: %s <psw word 1> <psw word 2> <loaded file> "
165 "<address> <channel pgm addr>\n", pgm
);
169 static unsigned int get_file_size(const char *fname
)
174 ret
= stat(fname
, &buf
);
176 return ret
? 0 : buf
.st_size
;
179 static unsigned int unhex(char *pgm
, char c
)
181 if ((c
>= '0') && (c
<= '9'))
183 if ((c
>= 'A') && (c
<= 'F'))
185 if ((c
>= 'a') && (c
<= 'f'))
187 die(pgm
, "Argument not hexadecimal");
191 static void __add(unsigned int *addr
, int a
)
196 for(i
=2; i
>=0; i
--) {
198 addr
[i
-1] += addr
[i
] / 256;
204 int main(int argc
, char **argv
)
208 unsigned int ccw_addr
[3];
209 unsigned int addr
[3];
211 unsigned int data_cards
;
214 die(argv
[0], "Invalid number of args");
216 if ((strlen(argv
[1]) != 8) ||
217 (strlen(argv
[2]) != 8))
218 die(argv
[0], "Invalid PSW argument length");
220 size
= get_file_size(argv
[3]);
222 die(argv
[0], "cannot get file size");
224 if ((strlen(argv
[4]) != 6) ||
225 (strlen(argv
[5]) != 6))
226 die(argv
[0], "Invalid addr argument length");
228 addr
[0] = (unhex(argv
[0], argv
[4][0]) << 4) |
229 unhex(argv
[0], argv
[4][1]);
230 addr
[1] = (unhex(argv
[0], argv
[4][2]) << 4) |
231 unhex(argv
[0], argv
[4][3]);
232 addr
[2] = (unhex(argv
[0], argv
[4][4]) << 4) |
233 unhex(argv
[0], argv
[4][5]);
235 ccw_addr
[0] = (unhex(argv
[0], argv
[5][0]) << 4) |
236 unhex(argv
[0], argv
[5][1]);
237 ccw_addr
[1] = (unhex(argv
[0], argv
[5][2]) << 4) |
238 unhex(argv
[0], argv
[5][3]);
239 ccw_addr
[2] = (unhex(argv
[0], argv
[5][4]) << 4) |
240 unhex(argv
[0], argv
[5][5]);
244 size
= size
- (size
% 80) + 80;
246 data_cards
= size
/ 80;
250 printf(card_head
, i
);
253 argv
[1][0], argv
[1][1], argv
[1][2], argv
[1][3],
254 argv
[1][4], argv
[1][5], argv
[1][6], argv
[1][7],
255 argv
[2][0], argv
[2][1], argv
[2][2], argv
[2][3],
256 argv
[2][4], argv
[2][5], argv
[2][6], argv
[2][7]);
259 die(argv
[0], "Cannot handle the case where size <= 80");
265 printf(psw_tail
, ADDR(ccw_addr
), ADDRS(ccw_addr
), CHAIN
,
266 ADDR(ccw_addr
), ADDRS(ccw_addr
));
270 for(i
=0; i
<=((data_cards
+9)/10) + (((data_cards
+9)/10)+9)/10 - 2; i
++) {
271 printf(cp_ccw
, i
+3, ADDRS(ccw_addr
));
280 for(i
=1; i
<=data_cards
; i
++) {
281 printf(data_ccw
, i
, ADDRS(addr
),
282 (i
== data_cards
) ? 0 : CHAIN
);
289 printf(card_head
, card
++);