xref: /openbsd/sys/dev/microcode/bnx/build.c (revision ee4ffdb6)
1 /*	$OpenBSD: build.c,v 1.9 2017/08/27 08:15:48 otto Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 Theo de Raadt <deraadt@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #include <sys/types.h>
19 #include <dev/pci/if_bnxreg.h>
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include <err.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <stdio.h>
26 
27 #include "bnxfw.h"
28 
29 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
30 
31 int	bnx_rv2p_proc1len;
32 int	bnx_rv2p_proc2len;
33 
34 struct chunks {
35 	void *start;
36 	int *len;
37 };
38 
39 #define FILENAME_B06 "bnx-b06"
40 struct chunks chunks_b06[] = {
41 	{ bnx_COM_b06FwText, &bnx_COM_b06FwTextLen },
42 	{ bnx_COM_b06FwData, &bnx_COM_b06FwDataLen },
43 	{ bnx_COM_b06FwRodata, &bnx_COM_b06FwRodataLen },
44 	{ bnx_COM_b06FwBss, &bnx_COM_b06FwBssLen },
45 	{ bnx_COM_b06FwSbss, &bnx_COM_b06FwSbssLen },
46 
47 	{ bnx_RXP_b06FwText, &bnx_RXP_b06FwTextLen },
48 	{ bnx_RXP_b06FwData, &bnx_RXP_b06FwDataLen },
49 	{ bnx_RXP_b06FwRodata, &bnx_RXP_b06FwRodataLen },
50 	{ bnx_RXP_b06FwBss, &bnx_RXP_b06FwBssLen },
51 	{ bnx_RXP_b06FwSbss, &bnx_RXP_b06FwSbssLen },
52 
53 	{ bnx_TPAT_b06FwText, &bnx_TPAT_b06FwTextLen },
54 	{ bnx_TPAT_b06FwData, &bnx_TPAT_b06FwDataLen },
55 	{ bnx_TPAT_b06FwRodata, &bnx_TPAT_b06FwRodataLen },
56 	{ bnx_TPAT_b06FwBss, &bnx_TPAT_b06FwBssLen },
57 	{ bnx_TPAT_b06FwSbss, &bnx_TPAT_b06FwSbssLen },
58 
59 	{ bnx_TXP_b06FwText, &bnx_TXP_b06FwTextLen },
60 	{ bnx_TXP_b06FwData, &bnx_TXP_b06FwDataLen },
61 	{ bnx_TXP_b06FwRodata, &bnx_TXP_b06FwRodataLen },
62 	{ bnx_TXP_b06FwBss, &bnx_TXP_b06FwBssLen },
63 	{ bnx_TXP_b06FwSbss, &bnx_TXP_b06FwSbssLen }
64 };
65 
66 #define FILENAME_B09 "bnx-b09"
67 struct chunks chunks_b09[] = {
68 	{ bnx_COM_b09FwText, &bnx_COM_b09FwTextLen },
69 	{ bnx_COM_b09FwData, &bnx_COM_b09FwDataLen },
70 	{ bnx_COM_b09FwRodata, &bnx_COM_b09FwRodataLen },
71 	{ bnx_COM_b09FwBss, &bnx_COM_b09FwBssLen },
72 	{ bnx_COM_b09FwSbss, &bnx_COM_b09FwSbssLen },
73 
74 	{ bnx_RXP_b09FwText, &bnx_RXP_b09FwTextLen },
75 	{ bnx_RXP_b09FwData, &bnx_RXP_b09FwDataLen },
76 	{ bnx_RXP_b09FwRodata, &bnx_RXP_b09FwRodataLen },
77 	{ bnx_RXP_b09FwBss, &bnx_RXP_b09FwBssLen },
78 	{ bnx_RXP_b09FwSbss, &bnx_RXP_b09FwSbssLen },
79 
80 	{ bnx_TPAT_b09FwText, &bnx_TPAT_b09FwTextLen },
81 	{ bnx_TPAT_b09FwData, &bnx_TPAT_b09FwDataLen },
82 	{ bnx_TPAT_b09FwRodata, &bnx_TPAT_b09FwRodataLen },
83 	{ bnx_TPAT_b09FwBss, &bnx_TPAT_b09FwBssLen },
84 	{ bnx_TPAT_b09FwSbss, &bnx_TPAT_b09FwSbssLen },
85 
86 	{ bnx_TXP_b09FwText, &bnx_TXP_b09FwTextLen },
87 	{ bnx_TXP_b09FwData, &bnx_TXP_b09FwDataLen },
88 	{ bnx_TXP_b09FwRodata, &bnx_TXP_b09FwRodataLen },
89 	{ bnx_TXP_b09FwBss, &bnx_TXP_b09FwBssLen },
90 	{ bnx_TXP_b09FwSbss, &bnx_TXP_b09FwSbssLen }
91 };
92 
93 #define FILENAME_RV2P "bnx-rv2p"
94 struct chunks chunks_rv2p[] = {
95 	{ bnx_rv2p_proc1, &bnx_rv2p_proc1len },
96 	{ bnx_rv2p_proc2, &bnx_rv2p_proc2len }
97 };
98 
99 #define FILENAME_XI_RV2P "bnx-xi-rv2p"
100 struct chunks chunks_xi_rv2p[] = {
101 	{ bnx_xi_rv2p_proc1, &bnx_rv2p_proc1len },
102 	{ bnx_xi_rv2p_proc2, &bnx_rv2p_proc2len }
103 };
104 
105 #define FILENAME_XI90_RV2P "bnx-xi90-rv2p"
106 struct chunks chunks_xi90_rv2p[] = {
107 	{ bnx_xi90_rv2p_proc1, &bnx_rv2p_proc1len },
108 	{ bnx_xi90_rv2p_proc2, &bnx_rv2p_proc2len }
109 };
110 
111 void
112 hswapn(u_int32_t *p, int wcount)
113 {
114 	for (; wcount; wcount -=4) {
115 		*p = htonl(*p);
116 		p++;
117 	}
118 }
119 
120 void
121 write_firmware(char *filename, void *header, size_t hlen,
122     struct chunks *chunks, u_int nchunks)
123 {
124 	int fd, i, total;
125 	ssize_t rlen;
126 
127 	printf("creating %s", filename);
128 	fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
129 	if (fd == -1)
130 		err(1, "%s", filename);
131 
132 	rlen = write(fd, header, hlen);
133 	if (rlen == -1)
134 		err(1, "%s", filename);
135 	if (rlen != hlen)
136 		errx(1, "%s: short write", filename);
137 	total = rlen;
138 	printf(" [%d", total);
139 	fflush(stdout);
140 
141 	for (i = 0; i < nchunks; i++) {
142 		hswapn(chunks[i].start, *chunks[i].len);
143 		rlen = write(fd, chunks[i].start, *chunks[i].len);
144 		if (rlen == -1) {
145 			printf("\n");
146 			err(1, "%s", filename);
147 		}
148 		if (rlen != *chunks[i].len) {
149 			printf("\n");
150 			errx(1, "%s: short write", filename);
151 		}
152 		printf("+%zd", rlen);
153 		fflush(stdout);
154 		total += rlen;
155 	}
156 
157 	printf("] total %d\n", total);
158 
159 	close(fd);
160 }
161 
162 int
163 main(int argc, char *argv[])
164 {
165 	struct	bnx_firmware_header *bf;
166 	struct	bnx_rv2p_header	*rh;
167 
168 	bf = (struct bnx_firmware_header *)malloc(sizeof *bf);
169 	bzero(bf, sizeof *bf);
170 
171 	/* initialize the file header */
172 	bf->bnx_COM_FwReleaseMajor = htonl(bnx_COM_b06FwReleaseMajor);
173 	bf->bnx_COM_FwReleaseMinor = htonl(bnx_COM_b06FwReleaseMinor);
174 	bf->bnx_COM_FwReleaseFix = htonl(bnx_COM_b06FwReleaseFix);
175 	bf->bnx_COM_FwStartAddr = htonl(bnx_COM_b06FwStartAddr);
176 	bf->bnx_COM_FwTextAddr = htonl(bnx_COM_b06FwTextAddr);
177 	bf->bnx_COM_FwTextLen = htonl(bnx_COM_b06FwTextLen);
178 	bf->bnx_COM_FwDataAddr = htonl(bnx_COM_b06FwDataAddr);
179 	bf->bnx_COM_FwDataLen = htonl(bnx_COM_b06FwDataLen);
180 	bf->bnx_COM_FwRodataAddr = htonl(bnx_COM_b06FwRodataAddr);
181 	bf->bnx_COM_FwRodataLen = htonl(bnx_COM_b06FwRodataLen);
182 	bf->bnx_COM_FwBssAddr = htonl(bnx_COM_b06FwBssAddr);
183 	bf->bnx_COM_FwBssLen = htonl(bnx_COM_b06FwBssLen);
184 	bf->bnx_COM_FwSbssAddr = htonl(bnx_COM_b06FwSbssAddr);
185 	bf->bnx_COM_FwSbssLen = htonl(bnx_COM_b06FwSbssLen);
186 
187 	bf->bnx_RXP_FwReleaseMajor = htonl(bnx_RXP_b06FwReleaseMajor);
188 	bf->bnx_RXP_FwReleaseMinor = htonl(bnx_RXP_b06FwReleaseMinor);
189 	bf->bnx_RXP_FwReleaseFix = htonl(bnx_RXP_b06FwReleaseFix);
190 	bf->bnx_RXP_FwStartAddr = htonl(bnx_RXP_b06FwStartAddr);
191 	bf->bnx_RXP_FwTextAddr = htonl(bnx_RXP_b06FwTextAddr);
192 	bf->bnx_RXP_FwTextLen = htonl(bnx_RXP_b06FwTextLen);
193 	bf->bnx_RXP_FwDataAddr = htonl(bnx_RXP_b06FwDataAddr);
194 	bf->bnx_RXP_FwDataLen = htonl(bnx_RXP_b06FwDataLen);
195 	bf->bnx_RXP_FwRodataAddr = htonl(bnx_RXP_b06FwRodataAddr);
196 	bf->bnx_RXP_FwRodataLen = htonl(bnx_RXP_b06FwRodataLen);
197 	bf->bnx_RXP_FwBssAddr = htonl(bnx_RXP_b06FwBssAddr);
198 	bf->bnx_RXP_FwBssLen = htonl(bnx_RXP_b06FwBssLen);
199 	bf->bnx_RXP_FwSbssAddr = htonl(bnx_RXP_b06FwSbssAddr);
200 	bf->bnx_RXP_FwSbssLen = htonl(bnx_RXP_b06FwSbssLen);
201 
202 	bf->bnx_TPAT_FwReleaseMajor = htonl(bnx_TPAT_b06FwReleaseMajor);
203 	bf->bnx_TPAT_FwReleaseMinor = htonl(bnx_TPAT_b06FwReleaseMinor);
204 	bf->bnx_TPAT_FwReleaseFix = htonl(bnx_TPAT_b06FwReleaseFix);
205 	bf->bnx_TPAT_FwStartAddr = htonl(bnx_TPAT_b06FwStartAddr);
206 	bf->bnx_TPAT_FwTextAddr = htonl(bnx_TPAT_b06FwTextAddr);
207 	bf->bnx_TPAT_FwTextLen = htonl(bnx_TPAT_b06FwTextLen);
208 	bf->bnx_TPAT_FwDataAddr = htonl(bnx_TPAT_b06FwDataAddr);
209 	bf->bnx_TPAT_FwDataLen = htonl(bnx_TPAT_b06FwDataLen);
210 	bf->bnx_TPAT_FwRodataAddr = htonl(bnx_TPAT_b06FwRodataAddr);
211 	bf->bnx_TPAT_FwRodataLen = htonl(bnx_TPAT_b06FwRodataLen);
212 	bf->bnx_TPAT_FwBssAddr = htonl(bnx_TPAT_b06FwBssAddr);
213 	bf->bnx_TPAT_FwBssLen = htonl(bnx_TPAT_b06FwBssLen);
214 	bf->bnx_TPAT_FwSbssAddr = htonl(bnx_TPAT_b06FwSbssAddr);
215 	bf->bnx_TPAT_FwSbssLen = htonl(bnx_TPAT_b06FwSbssLen);
216 
217 	bf->bnx_TXP_FwReleaseMajor = htonl(bnx_TXP_b06FwReleaseMajor);
218 	bf->bnx_TXP_FwReleaseMinor = htonl(bnx_TXP_b06FwReleaseMinor);
219 	bf->bnx_TXP_FwReleaseFix = htonl(bnx_TXP_b06FwReleaseFix);
220 	bf->bnx_TXP_FwStartAddr = htonl(bnx_TXP_b06FwStartAddr);
221 	bf->bnx_TXP_FwTextAddr = htonl(bnx_TXP_b06FwTextAddr);
222 	bf->bnx_TXP_FwTextLen = htonl(bnx_TXP_b06FwTextLen);
223 	bf->bnx_TXP_FwDataAddr = htonl(bnx_TXP_b06FwDataAddr);
224 	bf->bnx_TXP_FwDataLen = htonl(bnx_TXP_b06FwDataLen);
225 	bf->bnx_TXP_FwRodataAddr = htonl(bnx_TXP_b06FwRodataAddr);
226 	bf->bnx_TXP_FwRodataLen = htonl(bnx_TXP_b06FwRodataLen);
227 	bf->bnx_TXP_FwBssAddr = htonl(bnx_TXP_b06FwBssAddr);
228 	bf->bnx_TXP_FwBssLen = htonl(bnx_TXP_b06FwBssLen);
229 	bf->bnx_TXP_FwSbssAddr = htonl(bnx_TXP_b06FwSbssAddr);
230 	bf->bnx_TXP_FwSbssLen = htonl(bnx_TXP_b06FwSbssLen);
231 
232 	write_firmware(FILENAME_B06, bf, sizeof(*bf), chunks_b06,
233 	    nitems(chunks_b06));
234 
235 	bzero(bf, sizeof *bf);
236 
237 	bf->bnx_COM_FwReleaseMajor = htonl(bnx_COM_b09FwReleaseMajor);
238 	bf->bnx_COM_FwReleaseMinor = htonl(bnx_COM_b09FwReleaseMinor);
239 	bf->bnx_COM_FwReleaseFix = htonl(bnx_COM_b09FwReleaseFix);
240 	bf->bnx_COM_FwStartAddr = htonl(bnx_COM_b09FwStartAddr);
241 	bf->bnx_COM_FwTextAddr = htonl(bnx_COM_b09FwTextAddr);
242 	bf->bnx_COM_FwTextLen = htonl(bnx_COM_b09FwTextLen);
243 	bf->bnx_COM_FwDataAddr = htonl(bnx_COM_b09FwDataAddr);
244 	bf->bnx_COM_FwDataLen = htonl(bnx_COM_b09FwDataLen);
245 	bf->bnx_COM_FwRodataAddr = htonl(bnx_COM_b09FwRodataAddr);
246 	bf->bnx_COM_FwRodataLen = htonl(bnx_COM_b09FwRodataLen);
247 	bf->bnx_COM_FwBssAddr = htonl(bnx_COM_b09FwBssAddr);
248 	bf->bnx_COM_FwBssLen = htonl(bnx_COM_b09FwBssLen);
249 	bf->bnx_COM_FwSbssAddr = htonl(bnx_COM_b09FwSbssAddr);
250 	bf->bnx_COM_FwSbssLen = htonl(bnx_COM_b09FwSbssLen);
251 
252 	bf->bnx_RXP_FwReleaseMajor = htonl(bnx_RXP_b09FwReleaseMajor);
253 	bf->bnx_RXP_FwReleaseMinor = htonl(bnx_RXP_b09FwReleaseMinor);
254 	bf->bnx_RXP_FwReleaseFix = htonl(bnx_RXP_b09FwReleaseFix);
255 	bf->bnx_RXP_FwStartAddr = htonl(bnx_RXP_b09FwStartAddr);
256 	bf->bnx_RXP_FwTextAddr = htonl(bnx_RXP_b09FwTextAddr);
257 	bf->bnx_RXP_FwTextLen = htonl(bnx_RXP_b09FwTextLen);
258 	bf->bnx_RXP_FwDataAddr = htonl(bnx_RXP_b09FwDataAddr);
259 	bf->bnx_RXP_FwDataLen = htonl(bnx_RXP_b09FwDataLen);
260 	bf->bnx_RXP_FwRodataAddr = htonl(bnx_RXP_b09FwRodataAddr);
261 	bf->bnx_RXP_FwRodataLen = htonl(bnx_RXP_b09FwRodataLen);
262 	bf->bnx_RXP_FwBssAddr = htonl(bnx_RXP_b09FwBssAddr);
263 	bf->bnx_RXP_FwBssLen = htonl(bnx_RXP_b09FwBssLen);
264 	bf->bnx_RXP_FwSbssAddr = htonl(bnx_RXP_b09FwSbssAddr);
265 	bf->bnx_RXP_FwSbssLen = htonl(bnx_RXP_b09FwSbssLen);
266 
267 	bf->bnx_TPAT_FwReleaseMajor = htonl(bnx_TPAT_b09FwReleaseMajor);
268 	bf->bnx_TPAT_FwReleaseMinor = htonl(bnx_TPAT_b09FwReleaseMinor);
269 	bf->bnx_TPAT_FwReleaseFix = htonl(bnx_TPAT_b09FwReleaseFix);
270 	bf->bnx_TPAT_FwStartAddr = htonl(bnx_TPAT_b09FwStartAddr);
271 	bf->bnx_TPAT_FwTextAddr = htonl(bnx_TPAT_b09FwTextAddr);
272 	bf->bnx_TPAT_FwTextLen = htonl(bnx_TPAT_b09FwTextLen);
273 	bf->bnx_TPAT_FwDataAddr = htonl(bnx_TPAT_b09FwDataAddr);
274 	bf->bnx_TPAT_FwDataLen = htonl(bnx_TPAT_b09FwDataLen);
275 	bf->bnx_TPAT_FwRodataAddr = htonl(bnx_TPAT_b09FwRodataAddr);
276 	bf->bnx_TPAT_FwRodataLen = htonl(bnx_TPAT_b09FwRodataLen);
277 	bf->bnx_TPAT_FwBssAddr = htonl(bnx_TPAT_b09FwBssAddr);
278 	bf->bnx_TPAT_FwBssLen = htonl(bnx_TPAT_b09FwBssLen);
279 	bf->bnx_TPAT_FwSbssAddr = htonl(bnx_TPAT_b09FwSbssAddr);
280 	bf->bnx_TPAT_FwSbssLen = htonl(bnx_TPAT_b09FwSbssLen);
281 
282 	bf->bnx_TXP_FwReleaseMajor = htonl(bnx_TXP_b09FwReleaseMajor);
283 	bf->bnx_TXP_FwReleaseMinor = htonl(bnx_TXP_b09FwReleaseMinor);
284 	bf->bnx_TXP_FwReleaseFix = htonl(bnx_TXP_b09FwReleaseFix);
285 	bf->bnx_TXP_FwStartAddr = htonl(bnx_TXP_b09FwStartAddr);
286 	bf->bnx_TXP_FwTextAddr = htonl(bnx_TXP_b09FwTextAddr);
287 	bf->bnx_TXP_FwTextLen = htonl(bnx_TXP_b09FwTextLen);
288 	bf->bnx_TXP_FwDataAddr = htonl(bnx_TXP_b09FwDataAddr);
289 	bf->bnx_TXP_FwDataLen = htonl(bnx_TXP_b09FwDataLen);
290 	bf->bnx_TXP_FwRodataAddr = htonl(bnx_TXP_b09FwRodataAddr);
291 	bf->bnx_TXP_FwRodataLen = htonl(bnx_TXP_b09FwRodataLen);
292 	bf->bnx_TXP_FwBssAddr = htonl(bnx_TXP_b09FwBssAddr);
293 	bf->bnx_TXP_FwBssLen = htonl(bnx_TXP_b09FwBssLen);
294 	bf->bnx_TXP_FwSbssAddr = htonl(bnx_TXP_b09FwSbssAddr);
295 	bf->bnx_TXP_FwSbssLen = htonl(bnx_TXP_b09FwSbssLen);
296 
297 	write_firmware(FILENAME_B09, bf, sizeof(*bf), chunks_b09,
298 	    nitems(chunks_b09));
299 
300 	free(bf);
301 
302 	rh = (struct bnx_rv2p_header *)malloc(sizeof *rh);
303 
304 	bzero(rh, sizeof *rh);
305 	bnx_rv2p_proc1len = sizeof bnx_rv2p_proc1;
306 	bnx_rv2p_proc2len = sizeof bnx_rv2p_proc2;
307 	rh->bnx_rv2p_proc1len = htonl(bnx_rv2p_proc1len);
308 	rh->bnx_rv2p_proc2len = htonl(bnx_rv2p_proc2len);
309 
310 	write_firmware(FILENAME_RV2P, rh, sizeof(*rh), chunks_rv2p,
311 	    nitems(chunks_rv2p));
312 
313 	bzero(rh, sizeof *rh);
314 	bnx_rv2p_proc1len = sizeof bnx_xi_rv2p_proc1;
315 	bnx_rv2p_proc2len = sizeof bnx_xi_rv2p_proc2;
316 	rh->bnx_rv2p_proc1len = htonl(bnx_rv2p_proc1len);
317 	rh->bnx_rv2p_proc2len = htonl(bnx_rv2p_proc2len);
318 
319 	write_firmware(FILENAME_XI_RV2P, rh, sizeof(*rh), chunks_xi_rv2p,
320 	    nitems(chunks_xi_rv2p));
321 
322 	bzero(rh, sizeof *rh);
323 	bnx_rv2p_proc1len = sizeof bnx_xi90_rv2p_proc1;
324 	bnx_rv2p_proc2len = sizeof bnx_xi90_rv2p_proc2;
325 	rh->bnx_rv2p_proc1len = htonl(bnx_rv2p_proc1len);
326 	rh->bnx_rv2p_proc2len = htonl(bnx_rv2p_proc2len);
327 
328 	write_firmware(FILENAME_XI90_RV2P, rh, sizeof(*rh), chunks_xi90_rv2p,
329 	    nitems(chunks_xi90_rv2p));
330 
331 	free(rh);
332 
333 	return 0;
334 }
335