1 /*****************************************************************************/
4 * stlload.c -- stallion intelligent multiport down loader.
6 * Copyright (c) 1994-1998 Greg Ungerer (gerg@stallion.oz.au).
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Greg Ungerer.
20 * 4. Neither the name of the author nor the names of any co-contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $FreeBSD: src/usr.sbin/stallion/stlload/stlload.c,v 1.10.2.2 2002/02/13 22:55:45 dbaker Exp $
37 * $DragonFly: src/usr.sbin/stallion/stlload/stlload.c,v 1.4 2007/02/03 23:13:19 swildner Exp $
40 /*****************************************************************************/
49 #include <sys/ioctl.h>
51 #include <machine/cdk.h>
53 /*****************************************************************************/
55 char *version
= "2.0.0";
56 char *defdevice
= "/dev/staliomem%d";
57 char *image
= BOOTDIR
"/cdk.sys";
58 char *oldimage
= BOOTDIR
"/2681.sys";
67 * Define a local buffer for copying the image into the shared memory.
74 * Define the timeout length when waiting for slave to start up.
75 * The quantity is measured in seconds.
80 * Set up a default feature area structure.
82 cdkfeature_t feature
= { 0, 0, ETYP_CDK
, 0, 0, 0, 0, 0 };
85 * Have local copies of the board signatures ready.
90 /*****************************************************************************/
93 * Declare internal function prototypes here.
95 static void usage(void);
96 int ecpfindports(cdkecpsig_t
*sigp
);
97 int onbfindports(cdkonbsig_t
*sigp
);
100 /*****************************************************************************/
105 fprintf(stderr
, "%s\n%s\n",
106 "usage: stlload [-vhVR] [-i image-file] [-c control-device] [-r rx-buf-size]",
107 " [-t tx-buf-size] [-B boot-banner] [-b unit-number]");
111 /*****************************************************************************/
114 * Given a boards signature determine how many ports it has. We need to
115 * know this to setup the slave feature arguments. This function is for
120 ecpfindports(cdkecpsig_t
*sigp
)
126 for (bank
= 0; (bank
< 8); bank
++) {
127 id
= (unsigned int) sigp
->panelid
[bank
];
130 if ((id
& 0x07) != bank
)
143 /*****************************************************************************/
146 * Given a boards signature determine how many ports it has. We need to
147 * know this to setup the slave feature arguments. This function is for
148 * ONboards and Brumbys.
152 onbfindports(cdkonbsig_t
*sigp
)
159 for (i
= 0; (i
< 16); i
++) {
160 if (((sigp
->amask0
<< i
) & 0x8000) == 0)
169 /*****************************************************************************/
172 * Download an image to the slave board. There is a long sequence of
173 * things to do to get the slave running, but it is basically a simple
174 * process. Main things to do are: copy slave image into shared memory,
175 * start slave running and then read shared memory map.
181 unsigned char alivemarker
;
184 int nrdevs
, sigok
, n
;
187 printf("Opening shared memory device %s\n", memdevice
);
188 if ((memfd
= open(memdevice
, O_RDWR
)) < 0) {
189 warn("failed to open memory device %s", memdevice
);
194 * Before starting the download must tell driver that we are about to
195 * stop its slave. This is only important if it is already running.
196 * Once we have told the driver its stopped then do a hardware reset
197 * on it, to get it into a known state.
200 printf("Stoping any current slave\n");
201 if (ioctl(memfd
, STL_BSTOP
, 0) < 0) {
202 warn("ioctl(STL_BSTOP)");
203 printf(" (Perhaps you're trying to download firmware to a PCI card that\n doesn't require this?)\n");
208 printf("Reseting the board\n");
209 if (ioctl(memfd
, STL_BRESET
, 0) < 0) {
210 warn("ioctl(STL_BRESET)");
217 * After reseting the board we need to send an interrupt to the older
218 * board types to get them to become active. Do that now.
221 printf("Interrupting board to activate shared memory\n");
222 if (ioctl(memfd
, STL_BINTR
, 0) < 0) {
223 warn("ioctl(STL_BINTR)");
229 printf("Opening slave image file %s\n", image
);
230 if ((ifd
= open(image
, O_RDONLY
)) < 0) {
231 warn("failed to open image file %s", image
);
236 * At this point get the signature of the board from the shared memory.
237 * Do a double check that it is a board we know about. We will also need
238 * to calculate the number of ports on this board (to use later).
242 printf("Reading ROM signature from board\n");
244 if (lseek(memfd
, CDK_SIGADDR
, SEEK_SET
) != CDK_SIGADDR
) {
245 warn("lseek(%x) failed on memory file", CDK_FEATADDR
);
248 if (read(memfd
, &ecpsig
, sizeof(cdkecpsig_t
)) < 0) {
249 warn("read of ROM signature failed");
252 if (ecpsig
.magic
== ECP_MAGIC
) {
253 nrdevs
= ecpfindports(&ecpsig
);
259 if (lseek(memfd
, CDK_SIGADDR
, SEEK_SET
) != CDK_SIGADDR
) {
260 warn("lseek(%x) failed on memory file", CDK_FEATADDR
);
263 if (read(memfd
, &onbsig
, sizeof(cdkonbsig_t
)) < 0) {
264 warn("read of ROM signature failed");
267 if ((onbsig
.magic0
== ONB_MAGIC0
) && (onbsig
.magic1
== ONB_MAGIC1
) &&
268 (onbsig
.magic2
== ONB_MAGIC2
) &&
269 (onbsig
.magic3
== ONB_MAGIC3
)) {
270 nrdevs
= onbfindports(&onbsig
);
277 warnx("unknown signature from board");
282 printf("Board signature reports %d ports\n", nrdevs
);
285 * Start to copy the image file into shared memory. The first thing to
286 * do is copy the vector region in from shared memory address 0. We will
287 * then skip over the signature and feature area and start copying the
288 * actual image data and code from 4k upwards.
291 printf("Copying vector table into shared memory\n");
292 if ((n
= read(ifd
, buf
, CDK_SIGADDR
)) < 0) {
293 warn("read of image file failed");
296 if (lseek(memfd
, 0, SEEK_SET
) != 0) {
297 warn("lseek(%x) failed on memory file", CDK_FEATADDR
);
300 if (write(memfd
, buf
, n
) < 0) {
301 warn("write to memory device failed");
305 if (lseek(ifd
, 0x1000, SEEK_SET
) != 0x1000) {
306 warn("lseek(%x) failed on image file", CDK_FEATADDR
);
309 if (lseek(memfd
, 0x1000, SEEK_SET
) != 0x1000) {
310 warn("lseek(%x) failed on memory device", CDK_FEATADDR
);
315 * Copy buffer size chunks of data from the image file into shared memory.
318 if ((n
= read(ifd
, buf
, BUFSIZE
)) < 0) {
319 warn("read of image file failed");
322 if (write(memfd
, buf
, n
) < 0) {
323 warn("write to memory device failed");
326 } while (n
== BUFSIZE
);
331 * We need to down load the start up parameters for the slave. This is
332 * done via the feature area of shared memory. Think of the feature area
333 * as a way of passing "command line" arguments to the slave.
334 * FIX: should do something here to load "brdspec" as well...
336 feature
.nrdevs
= nrdevs
;
338 printf("Loading features into shared memory\n");
339 if (lseek(memfd
, CDK_FEATADDR
, SEEK_SET
) != CDK_FEATADDR
) {
340 warn("lseek(%x) failed on memory device", CDK_FEATADDR
);
343 if (write(memfd
, &feature
, sizeof(cdkfeature_t
)) < 0) {
344 warn("write to memory device failed");
349 * Wait for board alive marker to be set. The slave image will set the
350 * byte at address CDK_RDYADDR to 0x13 after it has successfully started.
351 * If this doesn't happen we timeout and fail.
354 printf("Setting alive marker to 0\n");
355 if (lseek(memfd
, CDK_RDYADDR
, SEEK_SET
) != CDK_RDYADDR
) {
356 warn("lseek(%x) failed on memory device", CDK_RDYADDR
);
360 if (write(memfd
, &alivemarker
, 1) < 0) {
361 warn("write to memory device failed");
366 * At this point the entire image is loaded into shared memory. To start
367 * it executiong we poke the board with an interrupt.
370 printf("Interrupting board to start slave image\n");
371 if (ioctl(memfd
, STL_BINTR
, 0) < 0) {
372 warn("ioctl(STL_BINTR) failed");
376 strttime
= time(NULL
);
378 printf("Waiting for slave alive marker, time=%lx timeout=%d\n",
380 while (time(NULL
) < (strttime
+ TIMEOUT
)) {
381 if (lseek(memfd
, CDK_RDYADDR
, SEEK_SET
) != CDK_RDYADDR
) {
382 warn("lseek(%x) failed on memory device", CDK_RDYADDR
);
385 if (read(memfd
, &alivemarker
, 1) < 0){
386 warn("read of image file failed");
389 if (alivemarker
== CDK_ALIVEMARKER
)
393 if (alivemarker
!= CDK_ALIVEMARKER
) {
394 warnx("slave image failed to start");
398 if (lseek(memfd
, CDK_RDYADDR
, SEEK_SET
) != CDK_RDYADDR
) {
399 warn("lseek(%x) failed on memory device", CDK_RDYADDR
);
403 if (write(memfd
, &alivemarker
, 1) < 0) {
404 warn("write to memory device failed");
409 printf("Slave image started successfully\n");
412 * The last thing to do now is to get the driver started. Now that the
413 * slave is operational it must read in the memory map and gets its
414 * internal tables initialized.
417 printf("Driver initializing host shared memory interface\n");
418 if (ioctl(memfd
, STL_BSTART
, 0) < 0) {
419 warn("ioctl(STL_BSTART) failed");
427 /*****************************************************************************/
430 main(int argc
, char *argv
[])
432 struct stat statinfo
;
435 while ((c
= getopt(argc
, argv
, "hvVRB:i:b:c:t:r:")) != -1) {
438 printf("stlload version %s\n", version
);
442 feature
.banner
= atol(optarg
);
457 brdnr
= atoi(optarg
);
463 feature
.txrqsize
= atol(optarg
);
466 feature
.rxrqsize
= atol(optarg
);
475 if (memdevice
== NULL
) {
476 if ((brdnr
< 0) || (brdnr
>= 8))
477 errx(1, "invalid board number %d specified", brdnr
);
478 sprintf(devstr
, defdevice
, brdnr
);
479 memdevice
= &devstr
[0];
481 printf("Using shared memory device %s\n", memdevice
);
485 printf("Downloading image %s to board %d\n", image
, brdnr
);
488 * Check that the shared memory device exits and is a character device.
490 if (stat(memdevice
, &statinfo
) < 0)
491 errx(1, "memory device %s does not exist", memdevice
);
492 if ((statinfo
.st_mode
& S_IFMT
) != S_IFCHR
)
493 errx(1, "memory device %s is not a char device", memdevice
);
495 if (stat(image
, &statinfo
) < 0)
496 errx(1, "image file %s does not exist", image
);
499 * All argument checking is now done. So lets get this show on the road.
506 /*****************************************************************************/