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.2 2003/06/17 04:30:03 dillon 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 /*****************************************************************************/
104 fprintf(stderr, "%s\n%s\n",
105 "usage: stlload [-vhVR] [-i image-file] [-c control-device] [-r rx-buf-size]",
106 " [-t tx-buf-size] [-B boot-banner] [-b unit-number]");
110 /*****************************************************************************/
113 * Given a boards signature determine how many ports it has. We need to
114 * know this to setup the slave feature arguments. This function is for
118 int ecpfindports(cdkecpsig_t *sigp)
124 for (bank = 0; (bank < 8); bank++) {
125 id = (unsigned int) sigp->panelid[bank];
128 if ((id & 0x07) != bank)
141 /*****************************************************************************/
144 * Given a boards signature determine how many ports it has. We need to
145 * know this to setup the slave feature arguments. This function is for
146 * ONboards and Brumbys.
149 int onbfindports(cdkonbsig_t *sigp)
156 for (i = 0; (i < 16); i++) {
157 if (((sigp->amask0 << i) & 0x8000) == 0)
166 /*****************************************************************************/
169 * Download an image to the slave board. There is a long sequence of
170 * things to do to get the slave running, but it is basically a simple
171 * process. Main things to do are: copy slave image into shared memory,
172 * start slave running and then read shared memory map.
177 unsigned char alivemarker;
180 int nrdevs, sigok, n;
183 printf("Opening shared memory device %s\n", memdevice);
184 if ((memfd = open(memdevice, O_RDWR)) < 0) {
185 warn("failed to open memory device %s", memdevice);
190 * Before starting the download must tell driver that we are about to
191 * stop its slave. This is only important if it is already running.
192 * Once we have told the driver its stopped then do a hardware reset
193 * on it, to get it into a known state.
196 printf("Stoping any current slave\n");
197 if (ioctl(memfd, STL_BSTOP, 0) < 0) {
198 warn("ioctl(STL_BSTOP)");
199 printf(" (Perhaps you're trying to download firmare to a PCI card that\n doesn't require this?)\n");
204 printf("Reseting the board\n");
205 if (ioctl(memfd, STL_BRESET, 0) < 0) {
206 warn("ioctl(STL_BRESET)");
213 * After reseting the board we need to send an interrupt to the older
214 * board types to get them to become active. Do that now.
217 printf("Interrupting board to activate shared memory\n");
218 if (ioctl(memfd, STL_BINTR, 0) < 0) {
219 warn("ioctl(STL_BINTR)");
225 printf("Opening slave image file %s\n", image);
226 if ((ifd = open(image, O_RDONLY)) < 0) {
227 warn("failed to open image file %s", image);
232 * At this point get the signature of the board from the shared memory.
233 * Do a double check that it is a board we know about. We will also need
234 * to calculate the number of ports on this board (to use later).
238 printf("Reading ROM signature from board\n");
240 if (lseek(memfd, CDK_SIGADDR, SEEK_SET) != CDK_SIGADDR) {
241 warn("lseek(%x) failed on memory file", CDK_FEATADDR);
244 if (read(memfd, &ecpsig, sizeof(cdkecpsig_t)) < 0) {
245 warn("read of ROM signature failed");
248 if (ecpsig.magic == ECP_MAGIC) {
249 nrdevs = ecpfindports(&ecpsig);
255 if (lseek(memfd, CDK_SIGADDR, SEEK_SET) != CDK_SIGADDR) {
256 warn("lseek(%x) failed on memory file", CDK_FEATADDR);
259 if (read(memfd, &onbsig, sizeof(cdkonbsig_t)) < 0) {
260 warn("read of ROM signature failed");
263 if ((onbsig.magic0 == ONB_MAGIC0) && (onbsig.magic1 == ONB_MAGIC1) &&
264 (onbsig.magic2 == ONB_MAGIC2) &&
265 (onbsig.magic3 == ONB_MAGIC3)) {
266 nrdevs = onbfindports(&onbsig);
273 warnx("unknown signature from board");
278 printf("Board signature reports %d ports\n", nrdevs);
281 * Start to copy the image file into shared memory. The first thing to
282 * do is copy the vector region in from shared memory address 0. We will
283 * then skip over the signature and feature area and start copying the
284 * actual image data and code from 4k upwards.
287 printf("Copying vector table into shared memory\n");
288 if ((n = read(ifd, buf, CDK_SIGADDR)) < 0) {
289 warn("read of image file failed");
292 if (lseek(memfd, 0, SEEK_SET) != 0) {
293 warn("lseek(%x) failed on memory file", CDK_FEATADDR);
296 if (write(memfd, buf, n) < 0) {
297 warn("write to memory device failed");
301 if (lseek(ifd, 0x1000, SEEK_SET) != 0x1000) {
302 warn("lseek(%x) failed on image file", CDK_FEATADDR);
305 if (lseek(memfd, 0x1000, SEEK_SET) != 0x1000) {
306 warn("lseek(%x) failed on memory device", CDK_FEATADDR);
311 * Copy buffer size chunks of data from the image file into shared memory.
314 if ((n = read(ifd, buf, BUFSIZE)) < 0) {
315 warn("read of image file failed");
318 if (write(memfd, buf, n) < 0) {
319 warn("write to memory device failed");
322 } while (n == BUFSIZE);
327 * We need to down load the start up parameters for the slave. This is
328 * done via the feature area of shared memory. Think of the feature area
329 * as a way of passing "command line" arguments to the slave.
330 * FIX: should do something here to load "brdspec" as well...
332 feature.nrdevs = nrdevs;
334 printf("Loading features into shared memory\n");
335 if (lseek(memfd, CDK_FEATADDR, SEEK_SET) != CDK_FEATADDR) {
336 warn("lseek(%x) failed on memory device", CDK_FEATADDR);
339 if (write(memfd, &feature, sizeof(cdkfeature_t)) < 0) {
340 warn("write to memory device failed");
345 * Wait for board alive marker to be set. The slave image will set the
346 * byte at address CDK_RDYADDR to 0x13 after it has successfully started.
347 * If this doesn't happen we timeout and fail.
350 printf("Setting alive marker to 0\n");
351 if (lseek(memfd, CDK_RDYADDR, SEEK_SET) != CDK_RDYADDR) {
352 warn("lseek(%x) failed on memory device", CDK_RDYADDR);
356 if (write(memfd, &alivemarker, 1) < 0) {
357 warn("write to memory device failed");
362 * At this point the entire image is loaded into shared memory. To start
363 * it executiong we poke the board with an interrupt.
366 printf("Interrupting board to start slave image\n");
367 if (ioctl(memfd, STL_BINTR, 0) < 0) {
368 warn("ioctl(STL_BINTR) failed");
372 strttime = time((time_t *) NULL);
374 printf("Waiting for slave alive marker, time=%x timeout=%d\n",
376 while (time((time_t *) NULL) < (strttime + TIMEOUT)) {
377 if (lseek(memfd, CDK_RDYADDR, SEEK_SET) != CDK_RDYADDR) {
378 warn("lseek(%x) failed on memory device", CDK_RDYADDR);
381 if (read(memfd, &alivemarker, 1) < 0){
382 warn("read of image file failed");
385 if (alivemarker == CDK_ALIVEMARKER)
389 if (alivemarker != CDK_ALIVEMARKER) {
390 warnx("slave image failed to start");
394 if (lseek(memfd, CDK_RDYADDR, SEEK_SET) != CDK_RDYADDR) {
395 warn("lseek(%x) failed on memory device", CDK_RDYADDR);
399 if (write(memfd, &alivemarker, 1) < 0) {
400 warn("write to memory device failed");
405 printf("Slave image started successfully\n");
408 * The last thing to do now is to get the driver started. Now that the
409 * slave is operational it must read in the memory map and gets its
410 * internal tables initialized.
413 printf("Driver initializing host shared memory interface\n");
414 if (ioctl(memfd, STL_BSTART, 0) < 0) {
415 warn("ioctl(STL_BSTART) failed");
423 /*****************************************************************************/
425 int main(int argc, char *argv[])
427 struct stat statinfo;
430 while ((c = getopt(argc, argv, "hvVRB:i:b:c:t:r:")) != -1) {
433 printf("stlload version %s\n", version);
437 feature.banner = atol(optarg);
452 brdnr = atoi(optarg);
458 feature.txrqsize = atol(optarg);
461 feature.rxrqsize = atol(optarg);
470 if (memdevice == (char *) NULL) {
471 if ((brdnr < 0) || (brdnr >= 8))
472 errx(1, "invalid board number %d specified", brdnr);
473 sprintf(devstr, defdevice, brdnr);
474 memdevice = &devstr[0];
476 printf("Using shared memory device %s\n", memdevice);
480 printf("Downloading image %s to board %d\n", image, brdnr);
483 * Check that the shared memory device exits and is a character device.
485 if (stat(memdevice, &statinfo) < 0)
486 errx(1, "memory device %s does not exist", memdevice);
487 if ((statinfo.st_mode & S_IFMT) != S_IFCHR)
488 errx(1, "memory device %s is not a char device", memdevice);
490 if (stat(image, &statinfo) < 0)
491 errx(1, "image file %s does not exist", image);
494 * All argument checking is now done. So lets get this show on the road.
501 /*****************************************************************************/