bootConfig.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:147k
源码类别:

VxWorks

开发平台:

C/C++

  1. #ifdef  INCLUDE_TFFS
  2.     if (strncmp (sysBootParams.bootDev, "tffs", 4) == 0)
  3.         {
  4.         int drive = 0;
  5.         int removable = 0;
  6.         if (sysBootParams.bootDev[4] == EOS)
  7.             return (ERROR);
  8.         sscanf (sysBootParams.bootDev, "%*4s%*c%d%*c%d", &drive, &removable);
  9.         /* tffsLoad () should be after pcmciaInit () */
  10.         if (tffsLoad (drive, removable, sysBootParams.bootFile, pEntry) != OK)
  11.             {
  12.             printErr ("nError loading file: errno = 0x%x.n", errno);
  13.             return (ERROR);
  14.             }
  15.         return (OK);
  16.         }
  17. #endif  /* INCLUDE_TFFS */
  18. #ifdef  INCLUDE_TSFS_BOOT
  19.     if (strncmp (sysBootParams.bootDev, "tsfs", 4) == 0)
  20.         {
  21.         if (tsfsLoad (sysBootParams.bootFile, pEntry) != OK)
  22.             {
  23.             printErr ("nError loading file: errno = 0x%x.n", errno);
  24.             return (ERROR);
  25.             }
  26.         return (OK);
  27.         }
  28. #endif  /* INCLUDE_TSFS_BOOT */
  29. #ifndef  INCLUDE_NETWORK
  30.     printf ("nError loading file: networking code not present.n");
  31.     return (ERROR);
  32.     }
  33. #else  /* INCLUDE_NETWORK */
  34.     /* verify unsupported booting devices */
  35.     if (strncmp (sysBootParams.bootDev, "sl", 2) == 0)
  36.         {
  37.     printf ("booting via slip is unsupported.n");
  38.         return (ERROR);
  39.         }
  40.     strncpy (bootDev, sysBootParams.bootDev, sizeof (bootDev));
  41.     /* attach and configure boot interface */
  42.     pBootAddr = sysBootParams.ead;
  43. #ifdef INCLUDE_SM_NET
  44.     if ((strncmp (sysBootParams.bootDev, "bp", 2) == 0) ||
  45.     (strncmp (sysBootParams.bootDev, "sm", 2) == 0))
  46.         {
  47.         backplaneBoot = TRUE;
  48.         pBootAddr = sysBootParams.bad;
  49.     }
  50. #endif /* INCLUDE_SM_NET */
  51.     /* Save requested lease length, if any. Ignore lease origin value. */
  52.     result = bootLeaseExtract (pBootAddr, &leaseLen, NULL);
  53.     if (result < 0)
  54.         {
  55.         printf ("Error reading target address information.n");
  56.         return (ERROR);
  57.         }
  58.     /* Handle any lease information attached to the address entry. */
  59.     if (result == 2)
  60.         {
  61.     /*
  62.          * The current address contains both a duration value and a start
  63.      * time, indicating that it was assigned by a DHCP server.
  64.      */
  65.     /* Handle finite and infinite address assignment. */
  66.     if (sysFlags & SYSFLG_AUTOCONFIG)
  67.         *pBootAddr = EOS;    /* Remove for later replacement. */
  68.         else
  69.         {
  70.             /*
  71.              * Technically, this address is invalid since it contains
  72.              * a finite interval that requires DHCP for verification
  73.              * and the automatic configuration flag is not set.
  74.              * However, this situation can only occur if caused
  75.              * deliberately by the user. So, just ignore the timing
  76.              * information and assign the address permanently.
  77.              */
  78.             result = 0;    /* Prevents restoration of time values. */
  79.             }
  80.     }
  81. #ifdef INCLUDE_DHCPC
  82.     /* Set the DHCP lease information, if needed. */
  83.     if (sysFlags & SYSFLG_AUTOCONFIG)
  84.         {
  85.         /* Save the requested lease length if entered by the user. */
  86.         if (result == 1)
  87.             dhcpLease.lease_duration = leaseLen;
  88.         else
  89. #ifdef INCLUDE_PCCARD
  90.         if (!attached)
  91.             {
  92.             csClientLoad (CS_END_ENABLER);
  93.             pCookie = muxTkCookieGet (bootDev, params.unitNum);
  94.             if (pCookie != NULL)
  95.                 {
  96.                 /* The enabler has started the device - no muxDevStart
  97.                  * necessary.
  98.                  */
  99.                 /* Add our default address resolution functions. */
  100.                 muxAddrResFuncAdd (M2_ifType_ethernet_csmacd, 0x800,
  101.                                    ipEtherResolvRtn);
  102.                 if (ipAttach (params.unitNum, bootDev) != OK)
  103.                     {
  104.                     printf ("Failed to attach TCP/IP to device %s",
  105.                             muxDevName);
  106.                     return (ERROR);
  107.                     }
  108.                 printf ("Attached TCP/IP interface to %s%d.n", bootDev,
  109.                         params.unitNum);
  110.                 attached = TRUE;
  111.                 }
  112.             }
  113. #endif /* INCLUDE_PCCARD */
  114.             {
  115.             /*
  116.              * The lease length is either not present or left over from
  117.              * an earlier lease. Use the default value.
  118.              */
  119.             dhcpLease.lease_duration = DHCPC_DEFAULT_LEASE;
  120.             }
  121.         dhcpLease.lease_origin = 0;
  122.         }
  123. #endif /* INCLUDE_DHCPC */
  124.     /*
  125.      * Initialize network stack. Once usrNetworkInit is completed,
  126.      * the bootrom can start loading the vxWorks image via network.
  127.      * Note that MUX is already initialized in usrRoot().
  128.      */
  129.     if (usrNetworkInit() == ERROR)
  130.     return (ERROR);
  131.     if (netmask != 0)               /* reconstruct address with mask */
  132.     {
  133.     sprintf (buf, ":%x", netmask);
  134.     strcat  (pBootAddr, buf);
  135.     }
  136.     /*
  137.      * If a value was specified for the requested lease length and the
  138.      * address information was not replaced by automatic configuration,
  139.      * restore that value for use by later reboots.
  140.      */
  141.     if (!(sysFlags & SYSFLG_AUTOCONFIG) && result == 1)
  142.         {
  143.         /*
  144.          * The value is ignored if <result> is 2, since that is only
  145.          * possible at this point for permanent DHCP assignments,
  146.          * which need no special processing by later reboots.
  147.          */
  148.         if (netmask == 0)   /* Create empty netmask field. */
  149.             sprintf (buf, "::%lx", leaseLen);
  150.         else                /* Append requested lease length to netmask. */
  151.             sprintf(buf, ":%lx", leaseLen);
  152.         strcat (pBootAddr, buf);
  153.         }
  154. #ifdef INCLUDE_DHCPC
  155.     /*
  156.      * If the target IP address was assigned by a DHCP server, append
  157.      * the lease times. The presence of those fields in the address string
  158.      * will cause the runtime image to renew the corresponding lease.
  159.      */
  160.     if (sysFlags & SYSFLG_AUTOCONFIG)
  161.         {
  162.         /* Add lease origin and lease duration if needed. */
  163.         if (dhcpcBindType == DHCP_NATIVE)
  164.             {
  165.             if (netmask == 0)       /* Create empty netmask field. */
  166.                 sprintf (buf, "::%lx:%lx", dhcpLease.lease_duration,
  167.                          dhcpLease.lease_origin);
  168.             else            /* Append lease timestamps to netmask. */
  169.                 sprintf (buf, ":%lx:%lx", dhcpLease.lease_duration,
  170.                          dhcpLease.lease_origin);
  171.             strcat (pBootAddr, buf);
  172.             }
  173.         }
  174. #endif    /* INCLUDE_DHCPC */
  175.     bootStructToString (BOOT_LINE_ADRS, &sysBootParams);
  176.     /* load specified file */
  177.     taskPriorityGet (0, &oldTaskPriority);
  178.     taskPrioritySet (0, netTaskPriority + 1);
  179.     if (netLoad (sysBootParams.had, sysBootParams.bootFile, sysBootParams.usr,
  180.          sysBootParams.passwd, pEntry) != OK)
  181.     {
  182.     printf ("nError loading file: errno = 0x%x.n", errno);
  183.     status = ERROR;
  184.     }
  185.     else
  186.     status = OK;
  187.     taskPrioritySet (0, oldTaskPriority);
  188. #ifdef INCLUDE_VXWORKS_5_X_EQUIV_PPP
  189.     if ((strncmp (sysBootParams.bootDev, "ppp", 3) == 0) &&
  190.         ((pppBootHandle->status & PPP_LCP_OPENED) != 0))
  191.         {
  192.         if (ppp5xDisconnect (pppBootHandle) == ERROR ||
  193.             pppBootHandle->syncSem == NULL)
  194.             return (ERROR);
  195.         if (semTake (pppBootHandle->syncSem,
  196.             PPP_DISCONNECT_DELAY * sysClkRateGet()) == ERROR)
  197.             {
  198.             printf ("PPP: timeout: could not disconnect the link.n");
  199.             return (ERROR);
  200.             }
  201.         printf ("PPP: link disconnected OKn");
  202.         }
  203. #endif /* INCLUDE_VXWORKS_5_X_EQUIV_PPP */
  204.     return (status);
  205.     }
  206. /*******************************************************************************
  207. *
  208. * netLoad - downLoad a file from a remote machine via the network.
  209. *
  210. * The remote shell daemon on the machine 'host' is used to download
  211. * the given file to the specified previously opened network file descriptor.
  212. * The remote userId should have been set previously by a call to iam().
  213. * If the file does not exist, the error message from the Unix 'host'
  214. * is printed to the VxWorks standard error fd and ERROR is returned.
  215. *
  216. * RETURNS: OK or ERROR
  217. */
  218. LOCAL STATUS netLoad
  219.     (
  220.     char *hostName,
  221.     char *fileName,
  222.     char *usr,
  223.     char *passwd,
  224.     FUNCPTR *pEntry
  225.     )
  226.     {
  227.     int fd;
  228.     int errFd;      /* for receiving standard error messages from Unix */
  229.     BOOL bootFtp = (passwd[0] != EOS);
  230.     BOOL bootRsh = FALSE;
  231. #ifdef INCLUDE_REMLIB
  232.     char command [BOOT_FILE_LEN + BOOT_HOST_LEN];
  233. #endif
  234.     printf ("Loading... ");
  235. #ifdef INCLUDE_TFTP_CLIENT
  236.     if (sysFlags & SYSFLG_TFTP)     /* use tftp to get image */
  237.         {
  238.     if (tftpXfer (hostName, 0, fileName, "get", "binary", &fd,
  239.               &errFd) == ERROR)
  240.         return (ERROR);
  241.     }
  242.    else
  243. #endif
  244.        {
  245.     if (bootFtp)
  246.         {
  247. #ifdef INCLUDE_FTP
  248.         if (ftpXfer (hostName, usr, passwd, "", "RETR %s", "", fileName,
  249.                  &errFd, &fd) == ERROR)
  250. #endif
  251.         return (ERROR);
  252.         }
  253.     else
  254.         {
  255.         bootRsh = TRUE;
  256. #ifdef INCLUDE_REMLIB
  257.         sprintf (command, "cat %s", fileName);
  258.         fd = rcmd (hostName, RSHD, usr, usr, command, &errFd);
  259.         if (fd == ERROR)
  260. #endif
  261.         return (ERROR);
  262.         }
  263.     }
  264.     if (bootLoadModule (fd, pEntry) != OK)
  265.     goto readErr;
  266. #ifdef INCLUDE_TFTP_CLIENT
  267.     /*
  268.      * Successful TFTP transfers don't need any cleanup. The tftpXfer()
  269.      * routine closes all file descriptors once the data has been
  270.      * retrieved from the remote host.
  271.      */
  272.     if (sysFlags & SYSFLG_TFTP) /* used tftp to get image - just exit */
  273.     {
  274.     DEV_HDR *dhp = iosFdDevFind(fd);
  275.     /*
  276.      * Empty the data socket so that the entire file is received from
  277.      * TFTP server - allows for graceful close on server side
  278.      */
  279.         while (dhp && ((iosFdDrvValue(fd, dhp->drvNum) != ERROR))
  280.            && (read (fd, command, sizeof (command)) > 0));
  281.         return (OK);
  282.     }
  283. #endif
  284.     if (bootRsh == FALSE)
  285.     {
  286. #ifdef INCLUDE_FTP
  287.     /* Empty the Data Socket before close. PC FTP server hangs otherwise */
  288.     while ((read (fd, command, sizeof (command))) > 0);
  289.         /* close the data socket before checking for a ftp reply (SPR #77169) */
  290.         close (fd);
  291.     if (bootFtp)
  292.         (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
  293. #endif
  294.     }
  295.     else
  296.         close (fd);
  297.     close (errFd);
  298.     return (OK);
  299. readErr:
  300.     /* check standard error on Unix */
  301.     if (bootRsh == FALSE)
  302.     {
  303. #ifdef INCLUDE_FTP
  304.     /* Empty the Data Socket before close. PC FTP server hangs otherwise */
  305.     while ((read (fd, command, sizeof (command))) > 0);
  306.         /* close the data socket before checking for a ftp reply (SPR #77169) */
  307.         close (fd);
  308.     if (bootFtp)
  309.         {
  310.         (void) ftpReplyGet (errFd, FALSE); /* error message on std. err */
  311.         (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
  312.         }
  313. #endif /* INCLUDE_FTP */
  314.     }
  315.     else
  316.     {
  317.     char buf [BOOT_FILE_LEN + BOOT_HOST_LEN];
  318.     int errBytesRecv = fioRead (errFd, buf, sizeof (buf));
  319.     if (errBytesRecv > 0)
  320.         {
  321.         /* print error message on standard error fd */
  322.         buf [errBytesRecv] = EOS;
  323.         printf ("n%s:%s: %sn", hostName, fileName, buf);
  324.         }
  325.         close (fd);
  326.     }
  327.     close (errFd);
  328.     return (ERROR);
  329.     }
  330. #endif  /* INCLUDE_NETWORK */
  331. #ifdef INCLUDE_FLASH_BOOT
  332. LOCAL STATUS flashLoad(char *fileName, FUNCPTR *pEntry)
  333. {
  334.     int                 fd;
  335.     int                 rv;
  336.     int                 err;
  337.     usrDosfsInit (DOSFS_DEFAULT_MAX_FILES, DOSFS_DEFAULT_CREATE_OPTIONS);
  338.     flashFsLibInit();                   /* Mounts flsh: */
  339.     do {
  340.         /*
  341.          * Load the boot file.
  342.          * Support loading deflated files.
  343.          */
  344.         if ((fd = open(fileName, O_RDONLY, 0)) == ERROR) {
  345.             printErr("Cannot open "%s".n", fileName);
  346.             return ERROR;
  347.         }
  348.         printf("Loading %s ... ", fileName);
  349.         rv = bootLoadModule(fd, pEntry);
  350.         if (rv != OK) {
  351.             err = errnoGet();
  352.             err = err & 0x7fff; /* mask module code. */
  353.         }
  354.         close(fd);
  355.     } while (rv != OK && err == EINTR); /* If interrupted, try again */
  356.     printf("n");
  357.     return rv;
  358. }
  359. #endif  /* INCLUDE_FLASH_BOOT */
  360. #if     (defined (INCLUDE_SCSI_BOOT) || defined (INCLUDE_FD) || 
  361.      defined (INCLUDE_IDE) || defined (INCLUDE_ATA) || 
  362.      defined (INCLUDE_TFFS))
  363. #define SPIN_UP_TIMEOUT 45  /* max # of seconds to wait for spinup */
  364. /******************************************************************************
  365. *
  366. * devSplit - split the device name from a full path name
  367. *
  368. * This routine returns the device name from a valid UNIX-style path name
  369. * by copying until two slashes ("/") are detected.  The device name is
  370. * copied into <devName>.
  371. *
  372. * RETURNS: N/A
  373. *
  374. * NOMANUAL
  375. */
  376. void devSplit
  377.     (
  378.     FAST char *fullFileName,    /* full file name being parsed */
  379.     FAST char *devName      /* result device name */
  380.     )
  381.     {
  382.     FAST int nChars = 0;
  383.     if (fullFileName != NULL)
  384.     {
  385.     char *p0 = fullFileName;
  386.     char *p1 = devName;
  387.     while ((nChars < 2) && (*p0 != EOS))
  388.         {
  389.         if (*p0 == '/')
  390.         nChars++;
  391.         *p1++ = *p0++;
  392.         }
  393.     *p1 = EOS;
  394.     }
  395.     else
  396.     {
  397.     (void) strcpy (devName, "");
  398.     }
  399.     }
  400. #endif  /* (defined (INCLUDE_SCSI_BOOT) || (INCLUDE_FD) || (INCLUDE_IDE)) */
  401. #ifdef  INCLUDE_SCSI_BOOT
  402. /******************************************************************************
  403. *
  404. * scsiLoad - load a vxWorks image from a local SCSI disk
  405. *
  406. * RETURNS: OK, or ERROR if file can not be loaded.
  407. */
  408. LOCAL STATUS scsiLoad
  409.     (
  410.     int     bootDevId,
  411.     int     bootDevLUN,
  412.     char    *fileName,
  413.     FUNCPTR *pEntry
  414.     )
  415.     {
  416.     int fd;
  417.     SCSI_PHYS_DEV *pScsiPhysBootDev;
  418.     BLK_DEV       *pScsiBlkBootDev;
  419.     char bootDir  [BOOT_FILE_LEN];
  420.     int           ix;
  421. #ifdef INCLUDE_SCSI2
  422.     SCSI_OPTIONS  options;
  423.     UINT          which;
  424. #endif /* INCLUDE_SCSI2 */
  425.     char          fsmName[16];
  426. #if 0
  427.     CBIO_DEV_ID pCbio;
  428. #endif
  429.     if (!scsiInitialized)       /* skip if this is a retry */
  430.         {
  431.         if (sysScsiInit () == ERROR)
  432.             {
  433.             printErr ("Could not initialize SCSI.n");
  434.             return (ERROR);
  435.             }
  436.         scsiInitialized = TRUE;
  437.         }
  438.     taskDelay (sysClkRateGet ());   /* delay 1 second after reset */
  439.     if ((bootDevId  < SCSI_MIN_BUS_ID) ||
  440.         (bootDevId  > SCSI_MAX_BUS_ID) ||
  441.         (bootDevLUN < SCSI_MIN_LUN)    ||
  442.         (bootDevLUN > SCSI_MAX_LUN))
  443.         {
  444.         printErr ("SCSI device parameters < busId = %d, lun = %d > ",
  445.                   bootDevId, bootDevLUN);
  446.         printErr ("are out of range (0-7).n");
  447.         printErr ("Check boot device format:n");
  448.         printErr ("    scsi=<busId>,<lun>  e.g.  scsi=2,0n");
  449.         return (ERROR);
  450.         }
  451. #ifdef INCLUDE_SCSI2
  452.     /* Set all devices to asynchronous data transfer */
  453.     which = SCSI_SET_OPT_XFER_PARAMS;
  454.     options.maxOffset = 0;
  455.     options.minPeriod = SCSI_SYNC_XFER_MIN_PERIOD;
  456.     scsiTargetOptionsSet (pSysScsiCtrl, bootDevId, &options, which);
  457. #endif /* INCLUDE_SCSI2 */
  458.     /* create device handle for TEST UNIT READY commands */
  459.     if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
  460.                                                bootDevLUN, 128, 0, 0,
  461.                                                0xffff, 512)) == NULL)
  462.         {
  463.         printErr ("scsiPhysDevCreate failed.n");
  464.         return (ERROR);
  465.         }
  466.     /* issue two TEST UNIT READY commands to clear reset exception */
  467.     scsiTestUnitRdy (pScsiPhysBootDev);
  468.     scsiTestUnitRdy (pScsiPhysBootDev);
  469.     /*
  470.      * issue a TEST UNIT READY every second for SPIN_UP_TIMEOUT seconds,
  471.      * or until device returns OK status.
  472.      */
  473.     if (scsiTestUnitRdy (pScsiPhysBootDev) != OK)
  474.         {
  475.         printf ("Waiting for disk to spin up...");
  476.         for (ix = 0; ix < SPIN_UP_TIMEOUT; ix++)
  477.             {
  478.             if (scsiTestUnitRdy (pScsiPhysBootDev) == OK)
  479.                 {
  480.                 printf (" done.n");
  481.                 break;
  482.                 }
  483.             if (ix != (SPIN_UP_TIMEOUT - 1))
  484.                 printf (".");
  485.             else
  486.                 {
  487.                 printf (" timed out.n");
  488.                 return (ERROR);
  489.                 }
  490.             taskDelay (sysClkRateGet ());
  491.             }
  492.         }
  493.     /* delete temporary device handle */
  494.     scsiPhysDevDelete (pScsiPhysBootDev);
  495.     printf ("Attaching to scsi device... ");
  496.     /* recreate a device handle, with polling for actual device parameters */
  497.     taskDelay (sysClkRateGet ());
  498.     if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
  499.                                                bootDevLUN, 0, -1, 0, 0, 0))
  500.          == NULL)
  501.         {
  502.         printErr ("scsiPhysDevCreate failed.n");
  503.         return (ERROR);
  504.         }
  505.     /*-------------------------------------------------------------------------
  506.      *
  507.      * Configuration of an OMTI3500
  508.      *
  509.      *-----------------------------------------------------------------------*/
  510.     if ((strncmp (pScsiPhysBootDev->devVendorID, "SMS", 3) == 0) &&
  511.         (strncmp (pScsiPhysBootDev->devProductID, "OMTI3500", 8) == 0))
  512.         {
  513.         char modeData [4];  /* array for floppy MODE SELECT data */
  514.         /*
  515.          * zero modeData array, then set byte 1 to "medium code" (0x1b).
  516.          * NOTE: MODE SELECT data is highly device-specific.  If your device
  517.          * requires configuration via MODE SELECT, please consult the device's
  518.          * Programmer's Reference for the relevant data format.
  519.          */
  520.         bzero (modeData, sizeof (modeData));
  521.         modeData [1] = 0x1b;
  522.         /* issue a MODE SELECT cmd to correctly configure floppy controller */
  523.         scsiModeSelect (pScsiPhysBootDev, 1, 0, modeData, sizeof (modeData));
  524.         /*
  525.          * delete and re-create the SCSI_PHYS_DEV so that INQUIRY will return
  526.          * the new device parameters, i.e., correct number of blocks
  527.          */
  528.         scsiPhysDevDelete (pScsiPhysBootDev);
  529.         /* recreate a device handle, polling for actual device parameters */
  530.         if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
  531.                                                    bootDevLUN, 0, -1, 0, 0, 0))
  532.             == NULL)
  533.             {
  534.             printErr ("scsiPhysDevCreate failed.n");
  535.             return (ERROR);
  536.             }
  537.         }
  538.     /*
  539.      * -----------------------------------------------------------------------
  540.      *
  541.      *  END of OMTI3500 configuration
  542.      *
  543.      * -----------------------------------------------------------------------
  544.      */
  545.     /* create a block device spanning entire disk (non-destructive!) */
  546.     if ((pScsiBlkBootDev = scsiBlkDevCreate (pScsiPhysBootDev, 0, 0)) == NULL)
  547.         {
  548.         printErr ("scsiLoad: scsiBlkDevCreate failed.n");
  549.         return (ERROR);
  550.         }
  551.     sprintf (fsmName, "/scsi%d:0", bootDevLUN);
  552.     fsmNameInstall (fsmName, bootDir);
  553.     /* split off boot device from boot file */
  554.     devSplit (fileName, bootDir);
  555.     xbdBlkDevCreate (pScsiBlkBootDev, bootDir);
  556.     /* now support booting from partitions on SCSI devices */
  557. #if 0
  558.     pCbio = dpartDevCreate ((CBIO_DEV_ID) pScsiBlkBootDev,
  559.                             NUM_PARTITIONS_DISK_BOOT,
  560.                             usrFdiskPartRead);
  561.     if (NULL == pCbio)
  562.         {
  563.         printErr ("scsiLoad: dpartDevCreate returned NULL.n");
  564.         return (ERROR);
  565.         }
  566.     /* initialize the boot block device as a dosFs device named <bootDir> */
  567.     if (ERROR == dosFsDevCreate (bootDir,
  568.                                  dpartPartGet(pCbio,PARTITION_DISK_BOOT),
  569.                                  20, NONE))
  570.         {
  571.         printErr ("scsiLoad: dosFsDevCreate returned ERROR.n");
  572.         return (ERROR);
  573.         }
  574. #endif
  575.     printErr ("done.n");
  576.     /* load the boot file */
  577.     printErr ("Loading %s...", fileName);
  578.     fd = open (fileName, O_RDONLY, 0);
  579.     if (fd == ERROR)
  580.         {
  581.         printErr ("nCannot open "%s".n", fileName);
  582.         return (ERROR);
  583.         }
  584.     if (bootLoadModule (fd, pEntry) != OK)
  585.         goto readErr;
  586.     close (fd);
  587.     return (OK);
  588. readErr:
  589.     close (fd);
  590.     return (ERROR);
  591.     }
  592. #endif  /* INCLUDE_SCSI_BOOT */
  593. #ifdef  INCLUDE_FD
  594. #include <usrFd.c>
  595. /******************************************************************************
  596. *
  597. * fdLoad - load a vxWorks image from a local floppy disk
  598. *
  599. * RETURNS: OK, or ERROR if file can not be loaded.
  600. */
  601. LOCAL STATUS fdLoad
  602.     (
  603.     int     drive,
  604.     int     type,
  605.     char    *fileName,
  606.     FUNCPTR *pEntry
  607.     )
  608.     {
  609.     int fd;
  610.     if (fdDrv (FD_INT_VEC, FD_INT_LVL) != OK)
  611.         {
  612.         printErr ("Could not initialize.n");
  613.         return (ERROR);
  614.         }
  615.     printf ("Attaching to floppy disk device... ");
  616.     /*
  617.      * Initialize DosFs.  When booting from a floppy, it is assumed that it is
  618.      * formatted with DosFs.  Hence the unconditional initialization of the
  619.      * DosFs file system libraries.
  620.      */
  621.     if (usrFdConfig (drive, type, fileName) == ERROR)
  622.         {
  623.         printErr ("usrFdConfig failed.n");
  624.         return (ERROR);
  625.         }
  626.     printErr ("done.n");
  627.     /* load the boot file */
  628.     printErr ("Loading %s...", fileName);
  629.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  630.         {
  631.         printErr ("nCannot open "%s".n", fileName);
  632.         return (ERROR);
  633.         }
  634.     if (bootLoadModule (fd, pEntry) != OK)
  635.         goto fdLoadErr;
  636.     close (fd);
  637.     return (OK);
  638. fdLoadErr:
  639.     close (fd);
  640.     return (ERROR);
  641.     }
  642. #endif  /* INCLUDE_FD */
  643. #ifdef  INCLUDE_IDE
  644. #define IDE_MEM_DOSFS   0x200000
  645. #include <usrIde.c>
  646. /******************************************************************************
  647. *
  648. * ideLoad - load a vxWorks image from a local IDE disk
  649. *
  650. * RETURNS: OK, or ERROR if file can not be loaded.
  651. */
  652. LOCAL STATUS ideLoad
  653.     (
  654.     int     drive,
  655.     int     type,
  656.     char    *fileName,
  657.     FUNCPTR *pEntry
  658.     )
  659.     {
  660.     int fd;
  661.     if (ideDrv (IDE_INT_VEC, IDE_INT_LVL, type) == ERROR)
  662.         {
  663.         printErr ("Could not initialize.n");
  664.         return (ERROR);
  665.         }
  666.     printf ("Attaching to IDE disk device... ");
  667.     if (usrIdeConfig (drive, fileName) == ERROR)
  668.         {
  669.         printErr ("usrIdeConfig failed.n");
  670.         return (ERROR);
  671.         }
  672.     printErr ("done.n");
  673.     /* load the boot file */
  674.     printErr ("Loading %s...", fileName);
  675.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  676.         {
  677.         printErr ("nCannot open "%s".n", fileName);
  678.         return (ERROR);
  679.         }
  680.     if (bootLoadModule (fd, pEntry) != OK)
  681.         goto ideLoadErr;
  682.     close (fd);
  683.     return (OK);
  684. ideLoadErr:
  685.     close (fd);
  686.     return (ERROR);
  687.     }
  688. #endif  /* INCLUDE_IDE */
  689. #ifdef  INCLUDE_ATA
  690. #define ATA_MEM_DOSFS   0x200000
  691. #include <usrAta.c>
  692. /******************************************************************************
  693. *
  694. * ataLoad - load a vxWorks image from a local ATA disk
  695. *
  696. * RETURNS: OK, or ERROR if file can not be loaded.
  697. */
  698. LOCAL STATUS ataLoad
  699.     (
  700.     int     ctrl,
  701.     int     drive,
  702.     char    *fileName,
  703.     FUNCPTR *pEntry
  704.     )
  705.     {
  706.     IMPORT ATA_RESOURCE   ataResources[];
  707.     ATA_RESOURCE *        pAtaResource  = &ataResources[ctrl];
  708.     int                   fd;
  709.     char                  tmp[BOOT_FILE_LEN];
  710. #ifdef INCLUDE_PCCARD
  711.     if (pAtaResource->ctrlType == IDE_LOCAL)
  712.         {
  713. #endif /* INCLUDE_PCCARD */
  714.     if (ataDrv (ctrl, pAtaResource->drives, pAtaResource->intVector,
  715.         pAtaResource->intLevel, pAtaResource->configType,
  716.         pAtaResource->semTimeout, pAtaResource->wdgTimeout) == ERROR)
  717.         {
  718.         printErr ("Could not initialize.n");
  719.         return (ERROR);
  720.         }
  721. #ifdef INCLUDE_PCCARD
  722.         }
  723.     else
  724.         csClientLoad (CS_ATA_ENABLER);
  725. #endif /* INCLUDE_PCCARD */
  726.     printf ("Attaching to ATA disk device... ");
  727.     /*
  728.      * Initialize DosFs.  When booting from an ATA device, it is assumed that
  729.      * it is formatted with DosFs.  Hence the unconditional initialization of
  730.      * the DosFs file system libraries.
  731.      */
  732.     devSplit (fileName, tmp);
  733.     if (usrAtaConfig (ctrl, drive, tmp) == ERROR)
  734.         {
  735.         printErr ("usrAtaConfig failed.n");
  736.         return (ERROR);
  737.         }
  738.     printErr ("done.n");
  739.     /* load the boot file */
  740.     printErr ("Loading %s...", fileName);
  741.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  742.         {
  743.         printErr ("nCannot open "%s".n", fileName);
  744.         return (ERROR);
  745.         }
  746.     if (bootLoadModule (fd, pEntry) != OK)
  747.         goto ataLoadErr;
  748.     close (fd);
  749.     return (OK);
  750. ataLoadErr:
  751.     close (fd);
  752.     return (ERROR);
  753.     }
  754. #endif  /* INCLUDE_ATA */
  755. #ifdef  INCLUDE_PCMCIA
  756. #define PCMCIA_MEM_DOSFS    0x200000
  757. #include <usrPcmcia.c>
  758. /******************************************************************************
  759. *
  760. * pcmciaLoad - load a vxWorks image from a PCMCIA disk device
  761. *
  762. * RETURNS: OK, or ERROR if file can not be loaded.
  763. */
  764. LOCAL STATUS pcmciaLoad
  765.     (
  766.     int     sock,
  767.     char    *fileName,
  768.     FUNCPTR *pEntry
  769.     )
  770.     {
  771.     int fd;
  772.     printf ("Attaching to PCMCIA block device... ");
  773.     /*
  774.      * Initialize DosFs.  When booting from a PCMCIA device, it is assumed that
  775.      * it is formatted with DosFs.  Hence the unconditional initialization of
  776.      * the DosFs file system libraries.
  777.      */
  778.     if (usrPcmciaConfig (sock, fileName) != OK)
  779.         return (ERROR);
  780.     printErr ("done.n");
  781.     /* load the boot file */
  782.     printErr ("Loading %s...", fileName);
  783.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  784.         {
  785.         printErr ("nCannot open "%s".n", fileName);
  786.         return (ERROR);
  787.         }
  788.     if (bootLoadModule (fd, pEntry) != OK)
  789.         goto pcmciaLoadErr;
  790.     close (fd);
  791.     return (OK);
  792. pcmciaLoadErr:
  793.     close (fd);
  794.     return (ERROR);
  795.     }
  796. #endif  /* INCLUDE_PCMCIA */
  797. #ifdef  INCLUDE_TFFS
  798. #define TFFS_MEM_DOSFS  0x200000
  799. #include <usrTffs.c>
  800. #include "sysTffs.c"      /* the BSP stub file, in the BSP directory */
  801. /******************************************************************************
  802. *
  803. * tffsLoad - load a vxWorks image from a TFFS Flash disk
  804. *
  805. * RETURNS: OK, or ERROR if file can not be loaded.
  806. *
  807. * NOMANUAL
  808. */
  809. LOCAL STATUS tffsLoad
  810.     (
  811.     int     drive,      /* TFFS drive number (0 - (noOfDrives-1)) */
  812.     int     removable,      /* 0 - nonremovable flash media */
  813.     char    * fileName,     /* file name to download */
  814.     FUNCPTR * pEntry
  815.     )
  816.     {
  817.     int fd;
  818.     if (tffsDrv () != OK)
  819.         {
  820.         printErr ("Could not initialize.n");
  821.         return (ERROR);
  822.         }
  823.     printf ("Attaching to TFFS... ");
  824.     if (usrTffsConfig (drive, removable, fileName) == ERROR)
  825.         {
  826.         printErr ("usrTffsConfig failed.n");
  827.         return (ERROR);
  828.         }
  829.     printErr ("done.n");
  830.     /* load the boot file */
  831.     printErr ("Loading %s...", fileName);
  832.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  833.         {
  834.         printErr ("nCannot open "%s".n", fileName);
  835.         return (ERROR);
  836.         }
  837.     if (bootLoadModule (fd, pEntry) != OK)
  838.         goto tffsLoadErr;
  839.     close (fd);
  840.     return (OK);
  841. tffsLoadErr:
  842.     close (fd);
  843.     return (ERROR);
  844.     }
  845. #endif  /* INCLUDE_TFFS */
  846. #ifdef INCLUDE_TSFS_BOOT
  847. /******************************************************************************
  848. *
  849. * tsfsLoad - load a vxWorks image from a Target Server File System (TSFS).
  850. *
  851. * RETURNS: OK, or ERROR if file can not be loaded.
  852. *
  853. * NOMANUAL
  854. */
  855. LOCAL STATUS tsfsLoad
  856.     (
  857.     char    * fileName,     /* file name to download */
  858.     FUNCPTR * pEntry
  859.     )
  860.     {
  861.     int fd;
  862.     WDB_EVT_NODE rebootEventNode;
  863.     char corefile [PATH_MAX + 1];
  864.     /* add a leading slash if the filename is a relative path */
  865.     if (fileName[0] != '/' && fileName[0] != '\')
  866.         sprintf (corefile, "/tgtsvr/%s", fileName);
  867.     else
  868.         sprintf (corefile, "/tgtsvr%s", fileName);
  869.     printf ("Booting using TSFS...nMake sure that your");
  870.     printf (" Target Server is started with -R[oot] option.n");
  871. #ifndef INCLUDE_TSFS_BOOT_VIO_CONSOLE
  872.     printf ("Waiting for Target Server connection...");
  873.     /* wait for Target Server connection */
  874.     while (!wdbTargetIsConnected())
  875.         taskDelay (sysClkRateGet());
  876.     printf (" Done.n");
  877. #endif  /* INCLUDE_TSFS_BOOT_VIO_CONSOLE */
  878.     /* open the core file via tsfs */
  879.     printErr ("nLoading %s...n", corefile);
  880.     if ((fd = open (corefile, O_RDONLY, 0)) == ERROR)
  881.         {
  882.         printErr ("nCannot open "%s".n", corefile);
  883.         return (ERROR);
  884.         }
  885.     /* load the core file */
  886.     if (bootLoadModule (fd, pEntry) != OK)
  887.         goto tsfsLoadErr;
  888.     close (fd);
  889. #if (WDB_COMM_TYPE != WDB_COMM_SERIAL)
  890.     /* Notify the host of the target reboot */
  891.     wdbEventNodeInit (&rebootEventNode, wdbRebootEventGet, NULL, NULL);
  892.     wdbEventPost (&rebootEventNode);
  893.     /* let some time to WDB to post the event */
  894.     taskDelay (sysClkRateGet() / 10);
  895. #endif  /* WDB_COMM_TYPE != WDB_COMM_SERIAL */
  896.     return (OK);
  897. tsfsLoadErr:
  898.     close (fd);
  899.     return (ERROR);
  900.     }
  901. /******************************************************************************
  902. *
  903. * wdbRebootEventGet - dummy eventGet routine to force the Target Server restart
  904. *
  905. * suspend the WDB task, so the Target Server will get a RPC_SYSTEMERROR
  906. * will trying to get an event, so it will restart and try to re-attach to
  907. * the target.
  908. */
  909. LOCAL void wdbRebootEventGet
  910.     (
  911.     void *      pNode,
  912.     WDB_EVT_DATA *  pEvtData
  913.     )
  914.     {
  915.     taskSuspend (0);
  916.     }
  917. #endif  /* INCLUDE_TSFS_BOOT */
  918. #ifdef  INCLUDE_NETWORK
  919. /******************************************************************************
  920. *
  921. * netifAdrsPrint - print MAC address of a network interface
  922. */
  923. LOCAL void netifAdrsPrint
  924.     (
  925.     char *ifname        /* interface name */
  926.     )
  927.     {
  928.     IMPORT struct ifnet *ifunit ();
  929.     char *buf;
  930.     char  devName [10];
  931.     int i, value;
  932.     if (ifname == NULL || *ifname == EOS)
  933.     {
  934.     printf ("Interface not specifiedn");
  935.     return;
  936.     }
  937.     while (*ifname == ' ')
  938.     ifname++;       /* skip leading blanks */
  939.     if (*ifname == EOS)
  940.     {
  941.     printf ("Interface not specifiedn");
  942.     return;
  943.     }
  944.     /* Search for unit number of network device. */
  945.     i = 0;
  946.     while (!isdigit((int)ifname[i]) && !isspace((int)ifname[i]) && ifname[i] != EOS)
  947.        i++;
  948.     if (ifname[i] == EOS)          /* No unit number given - use 0. */
  949.        value = 0;
  950.     buf = &ifname[i];
  951.     if (bootScanNum (&buf, &value, FALSE) != OK)  /* No unit number - use 0. */
  952.        value = 0;
  953.     ifname[i] = EOS;
  954.     sprintf (devName, "%s%d", ifname, value);
  955.     if (strncmp (devName, "bp", 2) == 0)
  956.     {
  957.     /* address for backplane is just processor number */
  958.     printf ("Address for device "%s" == 00:00:00:00:00:%02xn",
  959.         devName,  sysProcNumGet ());
  960.     return;
  961.     }
  962.     }
  963. #endif  /* INCLUDE_NETWORK */
  964. /*******************************************************************************
  965. *
  966. * go - start at specified address
  967. */
  968. LOCAL void go
  969.     (
  970.     FUNCPTR entry
  971.     )
  972.     {
  973.     printf ("Starting at 0x%x...nn", (int) entry);
  974.     taskDelay (sysClkRateGet ());   /* give the network a moment to close */
  975. #ifdef INCLUDE_END
  976.     /* Stop all ENDs to restore to known state for interrupts and DMA */
  977.     (void) muxDevStopAll (0);
  978. #endif  /* INCLUDE_END */
  979. #if (CPU_FAMILY == PPC)
  980.     cacheTextUpdate ((void *) (LOCAL_MEM_LOCAL_ADRS),   /* cache coherency */
  981.              (size_t) (sysMemTop() - LOCAL_MEM_LOCAL_ADRS));
  982. #else
  983. #ifdef  INCLUDE_CACHE_SUPPORT
  984.     cacheClear (DATA_CACHE, NULL, ENTIRE_CACHE);    /* push cache to mem */
  985. #endif  /* INCLUDE_CACHE_SUPPORT */
  986. #endif  /* (CPU_FAMILY == PPC) */
  987. #if (CPU_FAMILY == I80X86)
  988.     sysClkDisable ();           /* disable the system clock interrupt */
  989.     sysIntLock ();          /* lock the used/owned interrupts */
  990. #   if defined (SYMMETRIC_IO_MODE) || defined (VIRTUAL_WIRE_MODE)
  991.     {
  992.     extern void loApicEnable ();
  993.     loApicEnable (FALSE);       /* disable the LOAPIC */
  994.     }
  995. #       if defined (SYMMETRIC_IO_MODE)
  996.     {
  997.     extern BOOL sysBp;          /* TRUE for BP, FALSE for AP */
  998.     extern void ioApicEnable ();
  999.     if (sysBp)
  1000.         ioApicEnable (FALSE);       /* disable the IO APIC */
  1001.     }
  1002. #       endif /* (SYMMETRIC_IO_MODE) */
  1003. #   endif /* (SYMMETRIC_IO_MODE) || (VIRTUAL_WIRE_MODE) */
  1004. #endif  /* (CPU_FAMILY == I80X86) */
  1005.     /* Lock interrupts before jumping out of boot image. The interrupts
  1006.      * enabled during system initialization in sysHwInit()
  1007.      */
  1008.     intLock();
  1009.     (entry) (sysStartType);     /* go to entry point - never to return */
  1010.     }
  1011. /*******************************************************************************
  1012. *
  1013. * m - modify memory
  1014. *
  1015. * This routine prompts the user for modifications to memory, starting at the
  1016. * specified address.  It prints each address, and the current contents of
  1017. * that address, in turn.  The user can respond in one of several ways:
  1018. *
  1019. *   RETURN   - No change to that address, but continue
  1020. *          prompting at next address.
  1021. *   <number> - Set the contents to <number>.
  1022. *   . (dot)  - No change to that address, and quit.
  1023. *   <EOF>    - No change to that address, and quit.
  1024. *
  1025. * All numbers entered and displayed are in hexadecimal.
  1026. * Memory is treated as 16-bit words.
  1027. */
  1028. LOCAL void m
  1029.     (
  1030.     char *adrs      /* address to change */
  1031.     )
  1032.     {
  1033.     char line [MAX_LINE + 1];   /* leave room for EOS */
  1034.     char *pLine;        /* ptr to current position in line */
  1035.     int value;          /* value found in line */
  1036.     char excess;
  1037.     /* round down to word boundary */
  1038.     for (adrs = (char *) ((int) adrs & 0xfffffffe); /* start on even addr */
  1039.          ;                      /* FOREVER */
  1040.      adrs = (char *) (((short *) adrs) + 1))    /* bump as short ptr */
  1041.     {
  1042.     /* prompt for substitution */
  1043.     printf ("%06x:  %04x-", (int) adrs, (*(short *)adrs) & 0x0000ffff);
  1044.     /* get substitution value:
  1045.      *   skip empty lines (CR only);
  1046.      *   quit on end of file or invalid input;
  1047.      *   otherwise put specified value at address */
  1048.     if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
  1049.         break;
  1050.     line [MAX_LINE] = EOS;  /* make sure input line has EOS */
  1051.     /* skip leading spaces*/
  1052.     for (pLine = line; isspace ((UINT) * pLine); ++pLine)
  1053.         ;
  1054.     if (*pLine == EOS)          /* skip field if just CR */
  1055.         continue;
  1056.     if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
  1057.         break;              /* quit if not number */
  1058.     * (short *) adrs = value;       /* assign new value */
  1059.     }
  1060.     printf ("n");
  1061.     }
  1062. /*******************************************************************************
  1063. *
  1064. * d - display memory
  1065. *
  1066. * Display contents of memory, starting at adrs.  Memory is displayed in
  1067. * words.  The number of words displayed defaults to 64.  If
  1068. * nwords is non-zero, that number of words is printed, rounded up to
  1069. * the nearest number of full lines.  That number then becomes the default.
  1070. */
  1071. LOCAL void d
  1072.     (
  1073.     FAST char *adrs,    /* address to display */
  1074.     int        nwords   /* number of words to print. */
  1075.     )           /* If 0, print 64 or last specified. */
  1076.     {
  1077.     static char *last_adrs;
  1078.     static int dNbytes = 128;
  1079.     char ascii [17];
  1080.     FAST int nbytes;
  1081.     FAST int byte;
  1082.     ascii [16] = EOS;           /* put an EOS on the string */
  1083.     nbytes = 2 * nwords;
  1084.     if (nbytes == 0)
  1085.     nbytes = dNbytes;   /* no count specified: use current byte count */
  1086.     else
  1087.     dNbytes = nbytes;   /* change current byte count */
  1088.     if (adrs == 0)
  1089.     adrs = last_adrs;   /* no address specified: use last address */
  1090.     adrs = (char *) ((int) adrs & ~1);  /* round adrs down to word boundary */
  1091.     /* print leading spaces on first line */
  1092.     bfill ((char *) ascii, 16, '.');
  1093.     printf ("%06x:  ", (int) adrs & ~0xf);
  1094.     for (byte = 0; byte < ((int) adrs & 0xf); byte++)
  1095.     {
  1096.     printf ("  ");
  1097.     if (byte & 1)
  1098.         printf (" ");   /* space between words */
  1099.     if (byte == 7)
  1100.         printf (" ");   /* extra space between words 3 and 4 */
  1101.     ascii [byte] = ' ';
  1102.     }
  1103.     /* print out all the words */
  1104.     while (nbytes-- > 0)
  1105.     {
  1106.     if (byte == 16)
  1107.         {
  1108.         /* end of line:
  1109.          *   print out ascii format values and address of next line */
  1110.         printf ("  *%16s*n%06x:  ", ascii, (int) adrs);
  1111.         bfill ((char *) ascii, 16, '.');    /* clear out ascii buffer */
  1112.         byte = 0;               /* reset word count */
  1113.         }
  1114. #if  _BYTE_ORDER == _BIG_ENDIAN
  1115.     printf ("%02x", *adrs & 0x000000ff);
  1116. #else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */
  1117.     /* swap odd and even bytes */
  1118.     if ( (long)adrs & 1)
  1119.         {
  1120.         printf ("%02x", *((char *)((long)adrs & 0xfffffffe)) & 0x000000ff);
  1121.         }
  1122.     else
  1123.         {
  1124.         printf ("%02x", *((char *)((long)adrs + 1)) & 0x000000ff);
  1125.         }
  1126. #endif /* _BYTE_ORDER == _BIG_ENDIAN  */
  1127.     if (byte & 1)
  1128.         printf (" ");   /* space between words */
  1129.     if (byte == 7)
  1130.         printf (" ");   /* extra space between words 3 and 4 */
  1131.     if (* adrs == ' ' ||
  1132.             (isascii ((UINT) * adrs) && isprint ((UINT) * adrs)))
  1133.         ascii [byte] = (UINT) * adrs;
  1134.     adrs++;
  1135.     byte++;
  1136.     }
  1137.     /* print remainder of last line */
  1138.     for (; byte < 16; byte++)
  1139.     {
  1140.     printf ("  ");
  1141.     if (byte & 1)
  1142.         printf (" ");   /* space between words */
  1143.     if (byte == 7)
  1144.         printf (" ");   /* extra space between words 3 and 4 */
  1145.     ascii [byte] = ' ';
  1146.     }
  1147.     printf ("  *%16s*n", ascii);   /* print out ascii format values */
  1148.     last_adrs = adrs;
  1149.     }
  1150. /*******************************************************************************
  1151. *
  1152. * bootExcHandler - bootrom exception handling routine
  1153. */
  1154. LOCAL void bootExcHandler
  1155.     (
  1156.     int tid     /* task ID */
  1157.     )
  1158.     {
  1159.     REG_SET regSet;       /* task's registers */
  1160.     /* get registers of task to be traced */
  1161.     if (taskRegsGet (tid, &regSet) != ERROR)
  1162.         {
  1163.         trcStack (&regSet, (FUNCPTR) NULL, tid);
  1164.         taskRegsShow (tid);
  1165.         }
  1166.     else
  1167.         printf ("bootExcHandler: exception caught but no valid task.n");
  1168.     taskDelay (sysClkRateGet ());       /* pause a second */
  1169.     reboot (BOOT_NO_AUTOBOOT);
  1170.     }
  1171. /*******************************************************************************
  1172. *
  1173. * skipSpace - advance pointer past white space
  1174. *
  1175. * Increments the string pointer passed as a parameter to the next
  1176. * non-white-space character in the string.
  1177. */
  1178. LOCAL void skipSpace
  1179.     (
  1180.     FAST char **strptr  /* pointer to pointer to string */
  1181.     )
  1182.     {
  1183.     while (isspace ((UINT) ** strptr))
  1184.     ++ * strptr;
  1185.     }
  1186. /*******************************************************************************
  1187. *
  1188. * printExcMsg - print exception message
  1189. *
  1190. * Avoid printing possible control characters in exception message area.
  1191. */
  1192. LOCAL void printExcMsg
  1193.     (
  1194.     char *string
  1195.     )
  1196.     {
  1197.     printf ("n");
  1198.     while (isascii ((UINT) * string) && (isprint ((UINT) * string) ||
  1199.                         isspace ((UINT) * string)))
  1200.     printf ("%c", * string++);
  1201.     printf ("n");
  1202.     }
  1203. /******************************************************************************
  1204. *
  1205. * getArg - get argument from command line
  1206. *
  1207. * This routine gets the next numerical argument from the command line.
  1208. * If the argument is not optional, then an error is reported if no argument
  1209. * is found.  <ppString> will be updated to point to the new position in the
  1210. * command line.
  1211. *
  1212. * RETURNS: OK or ERROR
  1213. */
  1214. LOCAL STATUS getArg
  1215.     (
  1216.     FAST char **ppString,   /* ptr to ptr to current position in line */
  1217.     int *   pValue,     /* ptr where to return value */
  1218.     BOOL    defaultHex, /* TRUE = arg is hex (even w/o 0x) */
  1219.     BOOL    optional    /* TRUE = ok if end of line */
  1220.     )
  1221.     {
  1222.     skipSpace (ppString);
  1223.     /* if nothing left, complain if arg is not optional */
  1224.     if (**ppString == EOS)
  1225.     {
  1226.     if (!optional)
  1227.         {
  1228.         printf ("missing parametern");
  1229.         return (ERROR);
  1230.         }
  1231.     else
  1232.         return (OK);
  1233.     }
  1234.     /* scan arg */
  1235.     if (bootScanNum (ppString, pValue, defaultHex) != OK)
  1236.     {
  1237.     printf ("invalid parametern");
  1238.     return (ERROR);
  1239.     }
  1240.     skipSpace (ppString);
  1241.     /* if we encountered ',' delimiter, step over it */
  1242.     if (**ppString == ',')
  1243.     {
  1244.     ++*ppString;
  1245.     return (OK);
  1246.     }
  1247.     /* if end of line, scan is ok */
  1248.     if (**ppString == EOS)
  1249.     return (OK);
  1250.     /* we got stopped by something else */
  1251.     printf ("invalid parametern");
  1252.     return (ERROR);
  1253.     }
  1254. /* The following routines are common to bootConfig and usrConfig and will
  1255.  * eventually be merged
  1256.  */
  1257. /******************************************************************************
  1258. *
  1259. * usrBootLineInit - initialize system boot line
  1260. *
  1261. * Initializes system boot line as per specified start type.
  1262. * If this is a COLD boot, i.e., with CLEAR option to clear memory,
  1263. * then the boot line is initialized from non-volatile RAM, if any,
  1264. * otherwise from the compiled in default boot line.
  1265. */
  1266. LOCAL void usrBootLineInit
  1267.     (
  1268.     int startType
  1269.     )
  1270.     {
  1271.     if (startType & BOOT_CLEAR)
  1272.     {
  1273.     /* this is a cold boot so get the default boot line */
  1274.     if ((sysNvRamGet (BOOT_LINE_ADRS, BOOT_LINE_SIZE, 0) == ERROR) ||
  1275.         (*BOOT_LINE_ADRS == EOS) || (*BOOT_LINE_ADRS == (char) -1))
  1276.         {
  1277.         /* either no non-volatile RAM or empty boot line */
  1278.         strcpy (BOOT_LINE_ADRS, DEFAULT_BOOT_LINE);
  1279.         }
  1280.     }
  1281.     }
  1282. /******************************************************************************
  1283. *
  1284. * usrBootLineCrack - interpret and verify boot line
  1285. *
  1286. * This routine interprets the specified boot line and checks the validity
  1287. * of certain parameters.  If there are errors, a diagnostic message is
  1288. * printed.
  1289. *
  1290. * RETURNS: OK or ERROR
  1291. */
  1292. LOCAL STATUS usrBootLineCrack
  1293.     (
  1294.     char *   bootString,
  1295.     BOOT_PARAMS *pParams
  1296.     )
  1297.     {
  1298.     FAST char * pS;
  1299.     pS = bootStringToStruct (bootString, pParams);
  1300.     if (*pS != EOS)
  1301.     {
  1302.     bootParamsErrorPrint (bootString, pS);
  1303.     return (ERROR);
  1304.     }
  1305. #ifdef  INCLUDE_NETWORK
  1306.     /* check inet addresses */
  1307.     if ((checkInetAddrField (pParams->ead, TRUE) != OK) ||
  1308.     (checkInetAddrField (pParams->bad, TRUE) != OK) ||
  1309.     (checkInetAddrField (pParams->had, FALSE) != OK) ||
  1310.     (checkInetAddrField (pParams->gad, FALSE) != OK))
  1311.     {
  1312.     return (ERROR);
  1313.     }
  1314. #endif  /* INCLUDE_NETWORK */
  1315.     return (OK);
  1316.     }
  1317. #ifdef  INCLUDE_NETWORK
  1318. /******************************************************************************
  1319. *
  1320. * checkInetAddrField - check for valid inet address in boot field
  1321. */
  1322. LOCAL STATUS checkInetAddrField
  1323.     (
  1324.     char *pInetAddr,
  1325.     BOOL subnetMaskOK
  1326.     )
  1327.     {
  1328.     char inetAddr [30];
  1329.     /*
  1330.      * The bzero() call corrects SPR 6326. The calls to bootNetmaskExtract()
  1331.      * and inet_addr() did not delimit the input string with a ''. When
  1332.      * inet_addr attempted to print the invalid address, the system would
  1333.      * crash or hang.
  1334.      */
  1335.     bzero (inetAddr, sizeof(inetAddr));
  1336.     if (*pInetAddr == EOS)
  1337.     return (OK);
  1338.     strncpy (inetAddr, pInetAddr, sizeof (inetAddr) - 1);
  1339.     if (subnetMaskOK)
  1340.     {
  1341.     if (bootNetmaskExtract (inetAddr, &netmask) < 0)
  1342.         {
  1343.         printf ("Error: invalid netmask in boot field "%s".n", inetAddr);
  1344.         return (ERROR);
  1345.         }
  1346.     }
  1347.     if (inet_addr (inetAddr) == (ULONG) ERROR)
  1348.     {
  1349.     printf ("Error: invalid inet address in boot field "%s".n",inetAddr);
  1350.     return (ERROR);
  1351.     }
  1352.     return (OK);
  1353.     }
  1354. #ifdef ETHERNET_MAC_HANDLER
  1355. /***********************************************************
  1356. *
  1357. * macAddressShow - Displays the device and MAC address in
  1358. *                     string form.
  1359. *
  1360. *  This routine returns a pointer to a string of the form:
  1361. *
  1362. *   id device unit address
  1363. *
  1364. *   where:
  1365. *    id is an integer 1..MAX_MAC_ADRS
  1366. *    device is a string (e.g. motfcc)
  1367. *    unit is unit number
  1368. *    address is a six byte hex mac address
  1369. *   example:
  1370. *    "01  motfcc0 00:A0:1E:00:10:0A
  1371. *
  1372. *  The function takes index as an argument  where index is
  1373. *  range 00..MAX_MAC_ADRS-1
  1374. *
  1375. *  If the passed index is out of range, the return value
  1376. *  points to an error message.
  1377. *
  1378. * RETURNS: pointer to string
  1379. */
  1380. LOCAL char *macAddressShow
  1381.     (
  1382.     int index
  1383.     )
  1384.     {
  1385.     int devNameIndex;
  1386.     int unit;
  1387.     UINT8 macAddr[6] = { 0xff,0xff,0xff,0xff,0xff,0xff };
  1388.     /* range check passed index */
  1389.     if ((index < 0) || (index >= MAX_MAC_ADRS))
  1390.         {
  1391.         return ((char *) macErrStr);  /* if error, return error string */
  1392. }
  1393.     /* convert MAC index to device index and unit number */
  1394.     devNameIndex = sysMacIndex2Dev (index);
  1395.     unit = sysMacIndex2Unit(index);
  1396.     /* get a copy of the current device address */
  1397.     /* macAddr initialized so returns all f's if ERROR */
  1398.     sysNetMacNVRamAddrGet ((char *)sysNetDevName[devNameIndex], unit,
  1399.                            macAddr, MAC_ADRS_LEN);
  1400.     /* convert to string */
  1401.     
  1402.     sprintf (macShowStr[index],
  1403.               "%2d  %6s%d  %02x:%02x:%02x:%02x:%02x:%02xn",
  1404.               index+1, sysNetDevName[devNameIndex],
  1405.       unit,
  1406.       macAddr[0],
  1407.       macAddr[1],
  1408.       macAddr[2],
  1409.       macAddr[3],
  1410.       macAddr[4],
  1411.       macAddr[5]
  1412.     );
  1413.     return (macShowStr[index]);
  1414.     }
  1415. /***********************************************************
  1416. *
  1417. *  ifGet - Get network interface name
  1418. *
  1419. *  This routine parses the remaining command line (after the command
  1420. *  character has been removed) and attempts to
  1421. *  identify the requested device and unit using that string.  If the
  1422. *  command line does not provide the device name, a dialog is
  1423. *  initiated to identify the device.
  1424. *
  1425. *
  1426. * RETURNS: IFG_MAC_SUPPLIED - if remaining boot line identifies new MAC address.
  1427. *          IFG_OPR_QUIT     - if the operator elects to quit the dialog
  1428. *          IFG_DEV_SUPPLIED - if a device is selected, but no MAC address
  1429. *
  1430. */
  1431. LOCAL int ifGet
  1432.     (
  1433.     char **   ifName,  /* interface name */
  1434.     int *     unit,     /* interface unit */
  1435.     char *    pNum,     /* Command line */
  1436.     uchar_t * curArr    /* current MAC address */
  1437.     )
  1438.     {
  1439.     char line [MAX_LINE + 1];
  1440.     uchar_t passedMac [MAX_ADR_SIZE];
  1441.     int numMacDigiRead = 0;
  1442.     char *pLine; /* ptr to current position in line */
  1443.     char excess;
  1444.     int nameLen = 0;
  1445.     int index;
  1446.     int macAddressPassed = 0;
  1447.     int macDevPassed = 0;
  1448.     pLine = pNum;
  1449.     SKIPSPACE(pLine);  /* advance past any leading whitespaces */
  1450.     *ifName = pLine;
  1451.     /* determine if the bootline passed includes ifName, unit, and MAC */
  1452.      while (NOTEOS(pLine) &&  isalpha((int)*pLine))
  1453.         {
  1454.         nameLen++;   /* count device length */
  1455. pLine++;
  1456. }
  1457.     /* if device name found */
  1458.     if (nameLen != 0)
  1459.         {
  1460.         for (index = 0; index < MAX_MAC_DEVS; index++)
  1461.     {
  1462.     /* if indexed device matches passed device name */
  1463.     if (strncmp (sysNetDevName[sysMacIndex2Dev(index)], *ifName,
  1464.         strlen((char *)sysNetDevName[sysMacIndex2Dev(index)])) == 0)
  1465.         {
  1466. /* save return dev name */
  1467.                 *ifName = (char *)sysNetDevName[sysMacIndex2Dev(index)];
  1468. macDevPassed = 1;               /* set flag */
  1469. /* was unit number supplied? */
  1470.                 if (isdigit((int)*pLine))
  1471.     {
  1472.     *unit = strtol(pLine, &pLine, 0); /* extract unit number */
  1473.     }
  1474.                 else
  1475.     {
  1476.     *unit = 0; /* if not supplied, assume unit 0 */
  1477.     }
  1478. /* look for MAC address */
  1479.                 while (NOTEOS(pLine))
  1480.     {
  1481.                     SKIPSPACE(pLine);  /* advance to next field */
  1482.             if (!NOTEOS(pLine))
  1483. {
  1484. break; /* end of string */
  1485. }
  1486.     if (isxdigit((int)*pLine))
  1487. {
  1488. passedMac[numMacDigiRead++] =
  1489.     (uchar_t) strtol(pLine, &pLine, 16);
  1490. }
  1491.             else /* some illegal character read */
  1492. {
  1493. break;
  1494. }
  1495.     if (*pLine == ':')
  1496.     pLine++;
  1497.     }
  1498. /* if we were able to read the MAC address */
  1499. #if _BYTE_ORDER == _BIG_ENDIAN
  1500.                 if (numMacDigiRead == 6)  /* if full MAC address */
  1501.                     {
  1502.     macAddressPassed = 1;
  1503.                     for (index = 0; index < 6; index++)
  1504.                 {
  1505.                 curArr[index] = passedMac[5-index];
  1506.                 }
  1507.             }
  1508.                 else if (numMacDigiRead == 3) /* if half MAC address */
  1509.                     {
  1510.     macAddressPassed = 1;
  1511.             for (index = 0; index < 3; index++)  /* 3 bytes only */
  1512.                 {
  1513.                 curArr[index] = passedMac[2-index];
  1514.                 }
  1515.             curArr[0] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  1516.             curArr[1] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  1517.             curArr[2] = ((ENET_DEFAULT & 0xff000000) >> 24);
  1518.             }
  1519. #else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */
  1520.                 if (numMacDigiRead == 6) /* if full MAC address */
  1521.                     {
  1522.     macAddressPassed = 1;
  1523.             for (index = 0; index < 6; index++)
  1524.                 {
  1525.                 curArr[index] = passedMac[index];
  1526.                 }
  1527.             }
  1528.                 else if (numMacDigiRead == 3) /* if half MAC address */
  1529.                     {
  1530.     macAddressPassed = 1;
  1531.             for (index = 3; index < 6; index++) /* 3 bytes only */
  1532.                 {
  1533.                 curArr[index] = passedMac[index];
  1534.                 }
  1535.             curArr[0] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  1536.             curArr[1] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  1537.             curArr[2] = (ENET_DEFAULT & 0x000000ff);
  1538.             }
  1539. #endif
  1540. break; /* matching device found.  Look no further */
  1541. } /* end if indexed device matches passed device name */
  1542.     }
  1543. } /* end if no device name found */
  1544.     if (macDevPassed == 0)  /* if the command line lacks a device name */
  1545.         {
  1546. /* print known devices */
  1547.         printf ("Set device MAC addressnn");
  1548.         printf ("  0  quitn");
  1549.         for (index = 0; index < MAX_MAC_ADRS; index++)
  1550.             {
  1551.             printf (" %s",macAddressShow(index));
  1552.             }
  1553.         index = -1; /* initialize to invalid index */
  1554. /* query for new network device (1..n) */
  1555. while ((index < 0) || ( index >= MAX_MAC_ADRS))
  1556.             {
  1557.             printf ("  Selection : ");
  1558.     if (fioRdString (STD_IN, line, MAX_LINE) == EOF) /* end of line */
  1559. {
  1560. continue;
  1561. }
  1562.     line [MAX_LINE] = EOS; /* make sure input line has EOS */
  1563.             /* skip leading spaces*/
  1564.     for (pLine = line; isspace ((int) *pLine); ++pLine)
  1565. ;
  1566.     if (*pLine == EOS) /* if field is just CR */
  1567. {
  1568. continue;
  1569. }
  1570.             /* if not number */
  1571.     if (sscanf (pLine, "%d%1s", &index, &excess) != 1)
  1572. {
  1573.          printf("ninvalid selectionn");
  1574. index  = -1;
  1575.                 return (IFG_OPR_QUIT); /* quit */
  1576. }
  1577.             if (index == 0)
  1578.         {
  1579. index  = -1;
  1580.                 return (IFG_OPR_QUIT); /* quit */
  1581.                 }
  1582.            index--;   /* set to zero based index */
  1583.            }  /* end query for new network device (1..n) */
  1584.         /* return device string and unit number */
  1585.         *ifName = (char *)sysNetDevName[sysMacIndex2Dev(index)];
  1586. *unit = sysMacIndex2Unit(index);
  1587. }
  1588.     if (macAddressPassed)
  1589.         return (IFG_MAC_SUPPLIED);
  1590.     return (IFG_DEV_SUPPLIED);
  1591.     }
  1592. /***********************************************************
  1593. *
  1594. * dynamicMacAddrGen - Generate a dynamic MAC address
  1595. *
  1596. *  This routine generates a 3-byte network interface MAC address.
  1597. *  This should be used as the last three bytes of the device address.
  1598. *  It attempts to make the address unique, but is not
  1599. *  guaranteed to do so.
  1600. *
  1601. *  This routine should only be called if both sysNetMacAddrGet()
  1602. *  and sysNVRamNetMacAddrGet() return ERROR, indicating that
  1603. *  there is no other suitable mechanism for generating a
  1604. *  MAC address.
  1605. *
  1606. * RETURNS: 1 for an address which will be reproducible across
  1607. * multiple runs, or 0 if the address is likely to change between
  1608. * vxWorks and bootrom or between two invocations within either vxWorks
  1609. * or bootrom.
  1610. */
  1611. LOCAL int dynamicMacAddrGen
  1612.     (
  1613.     UINT8 * ifName,
  1614.     int ifUnit,
  1615.     UINT8 * ifMacAddr
  1616.     )
  1617.     {
  1618.     BOOT_PARAMS         params;
  1619.     int i = 0;
  1620.     UINT32 sum = 0;
  1621.     char  adrs [BOOT_TARGET_ADDR_LEN];
  1622.     /* hash sum of specified interface name */
  1623.     while ( EOS != ifName[i] )
  1624.         sum += ifName[i++];
  1625.     /* check boot command */
  1626.     if (usrBootLineCrack (BOOT_LINE_ADRS, &params) == OK)
  1627.         {
  1628. if ( ( params.ead[0] != EOS ) && ( params.ead[1] != EOS ) &&
  1629.      ( params.ead[2] != EOS ) && ( params.ead[3] != EOS ) &&
  1630.      ( params.ead[4] != EOS ) && ( params.ead[5] != EOS ) )
  1631.     {
  1632.     /* OK, use target address */
  1633.     *ifMacAddr++ = params.ead[3] + sum + ifUnit;
  1634.     *ifMacAddr++ = params.ead[4];
  1635.     *ifMacAddr++ = params.ead[5];
  1636.     return(1);
  1637.     }
  1638. adrs[0] = params.bad[0] + params.had[0] + params.gad[0];
  1639. adrs[1] = params.bad[1] + params.had[1] + params.gad[1];
  1640. adrs[2] = params.bad[2] + params.had[2] + params.gad[2];
  1641. adrs[3] = params.bad[3] + params.had[3] + params.gad[3];
  1642. adrs[4] = params.bad[4] + params.had[4] + params.gad[4];
  1643. adrs[5] = params.bad[5] + params.had[5] + params.gad[5];
  1644. if ( ( adrs[0] != EOS ) && ( adrs[1] != EOS ) &&
  1645.      ( adrs[2] != EOS ) && ( adrs[3] != EOS ) &&
  1646.      ( adrs[4] != EOS ) && ( adrs[5] != EOS ) )
  1647.     {
  1648.     /* use host + gateway + backplane */
  1649.     *ifMacAddr++ = adrs[0] + adrs[3] + sum + ifUnit;
  1650.     *ifMacAddr++ = adrs[1] + adrs[4];
  1651.     *ifMacAddr++ = adrs[2] + adrs[5];
  1652.     return(1);
  1653.     }
  1654. /* hash some strings together */
  1655. for ( i = 0 ; i < BOOT_DEV_LEN ; i++ )
  1656.     sum += params.bootDev[i];
  1657. for ( i = 0 ; i < BOOT_HOST_LEN ; i++ )
  1658.     sum += params.hostName[i];
  1659. for ( i = 0 ; i < BOOT_HOST_LEN ; i++ )
  1660.     sum += params.targetName[i];
  1661. for ( i = 0 ; i < BOOT_FILE_LEN ; i++ )
  1662.     sum += params.bootFile[i];
  1663. for ( i = 0 ; i < BOOT_FILE_LEN ; i++ )
  1664.     sum += params.startupScript[i];
  1665. for ( i = 0 ; i < BOOT_USR_LEN ; i++ )
  1666.     sum += params.usr[i];
  1667. for ( i = 0 ; i < BOOT_PASSWORD_LEN ; i++ )
  1668.     sum += params.passwd[i];
  1669. for ( i = 0 ; i < BOOT_OTHER_LEN ; i++ )
  1670.     sum += params.other[i];
  1671. adrs[0] = 0;
  1672. adrs[1] = 4;
  1673. adrs[2] = ( sum >> 24 ) & 0x00ff;
  1674. adrs[3] = ( sum >> 16 ) & 0x00ff;
  1675. adrs[4] = ( sum >>  8 ) & 0x00ff;
  1676. adrs[5] = ( sum >>  0 ) & 0x00ff;
  1677. *ifMacAddr++ = adrs[0] + adrs[3] + sum + ifUnit;
  1678. *ifMacAddr++ = adrs[1] + adrs[4];
  1679. *ifMacAddr++ = adrs[2] + adrs[5];
  1680. return(1);
  1681. }
  1682.     /*
  1683.      * boot command not available, generate address
  1684.      * which is as close to random as we can make it.
  1685.      * If we get here, there isn't any reasonable way to
  1686.      * make a highly unique number, but we'll do the
  1687.      * best we reasonably can.
  1688.      *
  1689.      * NOTE: This is guaranteed to cause problems when
  1690.      * booting, unless rommable vxWorks image is used.
  1691.      * If we get here, the vxWorks and bootrom images
  1692.      * will use different MAC addresses.  When the interface
  1693.      * changes, vxWorks will correctly send a gratuitous
  1694.      * ARP packet.  However, some switches will ignore
  1695.      * the gratuitous ARP packet which came so quickly
  1696.      * after the vxWorks image download.  In this case,
  1697.      * the target will be able to send traffic out, but
  1698.      * until it has done so, no other computer will be able
  1699.      * to contact it.  To resolve this problem, the target
  1700.      * should initiate outbound IP traffic after a suitable
  1701.      * delay.  This can be a simple ping, or it can be
  1702.      * a symbol table download, or whatever.
  1703.      */
  1704.     sum += tickGet(); /* time component */
  1705.     sum += (int)&params; /* stack addr: runtime mem use component */
  1706.     sum += (int)ifMacAddr; /* data addr: compile-time component */
  1707.     adrs[0] = 0;
  1708.     adrs[1] = 4;
  1709.     adrs[2] = ( sum >> 24 ) & 0x00ff;
  1710.     adrs[3] = ( sum >> 16 ) & 0x00ff;
  1711.     adrs[4] = ( sum >>  8 ) & 0x00ff;
  1712.     adrs[5] = ( sum >>  0 ) & 0x00ff;
  1713.     *ifMacAddr++ = adrs[0] + adrs[3] + ifUnit;
  1714.     *ifMacAddr++ = adrs[1] + adrs[4];
  1715.     *ifMacAddr++ = adrs[2] + adrs[5];
  1716.     return(0);
  1717.     }
  1718. /*******************************************************************************
  1719. *
  1720. * sEnet - set the device ethernet address
  1721. *  This routine checks the passed boot line to see if it can set the
  1722. *  MAC address of the requested device.  The command line is parsed to
  1723. *  extract device name, unit name, and MAC address.  All three items
  1724. *  are optional.  Example command lines follow:
  1725. *
  1726. *    M
  1727. *    M motfcc
  1728. *    M motfcc1
  1729. *    M motfcc1 00:01:00
  1730. *    M motfcc0 00:A0:1E:00:01:00
  1731. *
  1732. *    The first example will invoke a dialog with the user to display
  1733. *    current devices and prompt for which device address to change as below.
  1734. *      0  quit
  1735. *      1  motfcc0 00:A0:1E:00:01:1A
  1736. *      2  motscc0 00:A0:1E:00:01:1B
  1737. *    Selection :
  1738. *
  1739. *    Once a selection is made, the dialog will contine by quiting the dialog
  1740. *    if option zero is slected, or prompting for the MAC address for the
  1741. *    selected device as show below.
  1742. *
  1743. *    00- 00
  1744. *    A0- A0
  1745. *    1E- 1E
  1746. *    00-
  1747. *
  1748. *    The first three bytes of the MAC address are fixed and can't be changed
  1749. *    using this method.  The remaining three subsequent values will be
  1750. *    displayed for modification.  If no entry is made, the previous value
  1751. *    remains unchanged.
  1752. *
  1753. *    If the MAC address read from configuration memory does not include the
  1754. *    three byte vendor code, it is assumed that the address read is invalid.
  1755. *    In this case, a pseudo-random address is generated before the dialog
  1756. *    commences.  The address generation algorithm uses a hashing method
  1757. *    to generate the address based on the sum of various fixed parameters
  1758. *    such as the contents of the boot configuration.  This method generates
  1759. *    an address that is reproducible, given the same build and boot
  1760. *    parameters.  If the boot record is not valid, a random address is
  1761. *    generated that is not reproducible.
  1762. *
  1763. *    The second example shows a method used to avoid the first part of
  1764. *    the user dialog.  In this case, the device is specified on the
  1765. *    command line.  Since the unit number is not included, unit zero is
  1766. *    assumed.  The third example shows the command format that should be
  1767. *    used to select other than unit zero.
  1768. *
  1769. *    The fourth example shows a method used that avoids the user dialog.  In
  1770. *    this example, the first three bytes of the MAC address will be the WR
  1771. *    vendor code.  The remaining three bytes will be as specified on the
  1772. *    line.  This method requires that exactly three bytes of address be
  1773. *    supplied.
  1774. *
  1775. *    The last example shows a method that can be used to set all six bytes
  1776. *    of the MAC address, including the vendor code.  If other than the
  1777. *    default WR vendor code, care must be taken when using the command
  1778. *    shown in the previous examples.  These other forms assume that
  1779. *    other vendor codes are not valid and will overwrite.
  1780. *
  1781. *
  1782. * RETURNS: void
  1783. *
  1784. * NOMANUAL
  1785. */
  1786. void sEnet
  1787.     (
  1788.     char *  pNum   /* Boot line, including unit number. */
  1789.     )
  1790.     {
  1791.     uchar_t curArr [MAX_ADR_SIZE]; /* array to hold current Enet addr */
  1792.     int unitNum;
  1793.     char *ifName ="n";
  1794.     int ifGetStatus;
  1795.     /* identify the network device */
  1796.     ifGetStatus = ifGet (&ifName, &unitNum, pNum, curArr);
  1797.     if (ifGetStatus == IFG_OPR_QUIT)
  1798.         return; /* operator abort */
  1799.     if (ifGetStatus == IFG_MAC_SUPPLIED)
  1800.         {
  1801.         if (sysNetMacAddrSet (ifName, unitNum, curArr, MAC_ADRS_LEN) != OK)
  1802.             {
  1803.     printf ("** error setting address for %s%dn", ifName, unitNum);
  1804.     return;
  1805.     }
  1806.         }
  1807.     else
  1808. {
  1809. mEnet (pNum, unitNum, ifName);
  1810. }
  1811.     }
  1812. /*******************************************************************************
  1813. *
  1814. * mEnet - modify the last three bytes of the device ethernet address.
  1815. *
  1816. *  This routine is called if the command line lacks a network address
  1817. *  for the selected device.  It initiates a dialog with the user to
  1818. *  obtain the address.
  1819. *
  1820. * RETURNS: void
  1821. *
  1822. * NOMANUAL
  1823. */
  1824. void mEnet
  1825.     (
  1826.     char *  pNum,    /* Boot line, including unit number. */
  1827.     int         unitNum, /* array to hold current Enet addr */
  1828.     char       *ifName
  1829.     )
  1830.     {
  1831.     uchar_t byte [MAX_ADR_SIZE]; /* array to hold new Enet addr */
  1832.     uchar_t curArr [MAX_ADR_SIZE]; /* array to hold current Enet addr */
  1833.     char line [MAX_LINE + 1];
  1834.     char *pEnet;                /* dummy variable */
  1835.     int *pOffset = NULL;        /* dummy variable */
  1836.     char *pLine; /* ptr to current position in line */
  1837.     int value; /* value found in line */
  1838.     STATUS status;
  1839.     char excess;
  1840.     int ix;
  1841.     /* make sure device is valid */
  1842.     if (sysMacOffsetGet (ifName, unitNum, &pEnet, pOffset) != OK)
  1843.         {
  1844. printf ("** invalid devicen");
  1845. return;
  1846. }
  1847.     /* read current value */
  1848.     status = sysNetMacNVRamAddrGet (ifName, unitNum, curArr, MAC_ADRS_LEN);
  1849.     /* if at first we don't succeed, try second method */
  1850.     if (status !=OK)
  1851.         sysNetMacAddrGet (ifName, unitNum, curArr, MAC_ADRS_LEN);
  1852.     /* if current MAC address is invalid */
  1853. #if _BYTE_ORDER == _BIG_ENDIAN
  1854.     if ((status != OK) ||
  1855.         (curArr[0] != ((ENET_DEFAULT & 0x0000ff00) >> 8)) ||
  1856.         (curArr[1] != ((ENET_DEFAULT & 0x00ff0000) >> 16)) ||
  1857.         (curArr[2] != ((ENET_DEFAULT & 0xff000000) >> 24)))
  1858. {
  1859. curArr[0] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  1860. curArr[1] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  1861. curArr[2] = ((ENET_DEFAULT & 0xff000000) >> 24);
  1862. #else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */
  1863.     if ((status != OK) ||
  1864.         (curArr[0] != ((ENET_DEFAULT & 0x00ff0000) >> 16)) ||
  1865.         (curArr[1] != ((ENET_DEFAULT & 0x0000ff00) >> 8)) ||
  1866.         (curArr[2] != ((ENET_DEFAULT & 0x000000ff) )))
  1867. {
  1868. curArr[0] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  1869. curArr[1] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  1870. curArr[2] = (ENET_DEFAULT & 0x000000ff);
  1871. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  1872.         
  1873. ix = dynamicMacAddrGen(ifName, unitNum, &curArr[3]);
  1874. printf ("Mac address for %s%d invalid. ", ifName, unitNum);
  1875. if  (ix == 1)
  1876.     printf ("Using a reproducible random address.n");
  1877. else
  1878.     printf ("Using a non-reproducible random address.n");
  1879. }
  1880.     printf ("%s%d current Ethernet Address is: ", ifName, unitNum);
  1881.     printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[0],
  1882.     curArr[1], curArr[2], curArr[3],
  1883.     curArr[4], curArr[5]);
  1884.     byte[5] = curArr[5];
  1885.     byte[4] = curArr[4];
  1886.     byte[3] = curArr[3];
  1887.     byte[2] = curArr[2];
  1888.     byte[1] = curArr[1];
  1889.     byte[0] = curArr[0];
  1890.     printf ("Modify only the last 3 bytes (board unique portion) of Ethernet Address.n"
  1891.             "The first 3 bytes are fixed at manufacturer's default address block.n");
  1892.     for (ix = 0; ix < 3; ix++)
  1893.         printf ("%02x- %02xn", byte[ix], byte[ix]);
  1894.     /* start on fourth byte of enet addr */
  1895.     for (ix = 3; ix < 6; ix++)
  1896. {
  1897. /* prompt for substitution */
  1898. printf ("%02x- ", byte[ix]);
  1899. /* get substitution value:
  1900.  *   skip empty lines (CR only);
  1901.  *   quit on end of file or invalid input;
  1902.  *   otherwise put specified value at address */
  1903. if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
  1904.     break;
  1905. line [MAX_ADR_SIZE] = EOS; /* make sure input line has EOS */
  1906. for (pLine = line; isspace ((int) *pLine); ++pLine) /* skip leading spaces*/
  1907.     ;
  1908. if (*pLine == EOS) /* skip field if just CR */
  1909.     continue;
  1910. if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
  1911.     break; /* quit if not number */
  1912. byte[ix]  = (uchar_t)value; /* assign new value */
  1913. }
  1914.     printf ("n");
  1915.     if (sysNetMacAddrSet (ifName, unitNum, byte, MAC_ADRS_LEN) != OK)
  1916.         {
  1917. printf ("** error setting address for %s%dn", ifName, unitNum);
  1918. return;
  1919. }
  1920.     sysNetMacNVRamAddrGet (ifName, unitNum, byte, MAC_ADRS_LEN);
  1921.     printf ("New Ethernet Address is: ");
  1922.     for (ix = 0; ix < 5; ix++)
  1923.         printf ("%02x:", byte[ix]);
  1924.     printf ("%02xn", byte[5]);
  1925.     }
  1926. #endif  /* ETHERNET_MAC_HANDLER */
  1927. #ifdef ETHERNET_ADR_SET
  1928. /*******************************************************************************
  1929. *
  1930. * mEnet - modify the last three bytes of the ethernet address
  1931. *
  1932. * RETURNS: void
  1933. *
  1934. * NOMANUAL
  1935. */
  1936. void mEnet
  1937.     (
  1938.     char *  pNum   /* Boot line, including unit number. */
  1939.     )
  1940.     {
  1941.     uchar_t byte [MAX_ADR_SIZE];    /* array to hold new Enet addr */
  1942.     uchar_t curArr [MAX_ADR_SIZE];  /* array to hold current Enet addr */
  1943.     char line [MAX_LINE + 1];
  1944.     char *pLine;        /* ptr to current position in line */
  1945.     int value;          /* value found in line */
  1946.     char excess;
  1947.     char *buf;
  1948.     int unitNum;
  1949.     int ix;
  1950.     /* Search for unit number of network device. */
  1951.     buf = pNum;
  1952.     if (bootScanNum (&buf, &unitNum, FALSE) != OK)  /* Use 0 if no unit #. */
  1953.        unitNum = 0;
  1954.     sysEnetAddrGet (unitNum, curArr);
  1955.     printf ("Current Ethernet Address is: ");
  1956. #if _BYTE_ORDER == _BIG_ENDIAN
  1957.     printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[5],
  1958.         curArr[4], curArr[3], curArr[2],
  1959.         curArr[1], curArr[0]);
  1960.     byte[0] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  1961.     byte[1] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  1962.     byte[2] = ((ENET_DEFAULT & 0xff000000) >> 24);
  1963.     byte[3] = curArr[2];
  1964.     byte[4] = curArr[1];
  1965.     byte[5] = curArr[0];
  1966. #else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */
  1967.     printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[0],
  1968.         curArr[1], curArr[2], curArr[3],
  1969.         curArr[4], curArr[5]);
  1970.     byte[0] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  1971.     byte[1] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  1972.     byte[2] = (ENET_DEFAULT & 0x000000ff);
  1973.     byte[3] = curArr[3];
  1974.     byte[4] = curArr[4];
  1975.     byte[5] = curArr[5];
  1976. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  1977.     printf ("Modify only the last 3 bytes (board unique portion) of Ethernet Address.n");
  1978.     printf ("The first 3 bytes are fixed at manufacturer's default address block.n");
  1979.     for (ix = 0; ix < 3; ix++)
  1980.         printf ("%02x- %02xn", byte[ix], byte[ix]);
  1981.     /* start on fourth byte of enet addr */
  1982.     for (ix = 3; ix < 6; ix++)
  1983.     {
  1984.     /* prompt for substitution */
  1985.     printf ("%02x- ", byte[ix]);
  1986.     /* get substitution value:
  1987.      *   skip empty lines (CR only);
  1988.      *   quit on end of file or invalid input;
  1989.      *   otherwise put specified value at address */
  1990.     if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
  1991.         break;
  1992.     line [MAX_ADR_SIZE] = EOS;  /* make sure input line has EOS */
  1993.     for (pLine = line; isspace ((int) *pLine); ++pLine) /* skip leading spaces*/
  1994.         ;
  1995.     if (*pLine == EOS)          /* skip field if just CR */
  1996.         continue;
  1997.     if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
  1998.         break;              /* quit if not number */
  1999.     byte[ix]  = (uchar_t)value;     /* assign new value */
  2000.     }
  2001.     printf ("n");
  2002.     sysEnetAddrSet (byte[0], byte[1], byte[2], byte[3], byte[4], byte[5]);
  2003.     printf ("New Ethernet Address is: ");
  2004.     for (ix = 0; ix < 5; ix++)
  2005.         printf ("%02x:", byte[ix]);
  2006.     printf ("%02xn", byte[5]);
  2007.     }
  2008. #endif  /* ETHERNET_ADR_SET */
  2009. #ifdef INCLUDE_VXBUS
  2010. LOCAL void vxbFindHend
  2011. (
  2012. VXB_DEVICE_ID pDev,
  2013. void * pArg
  2014. )
  2015. {
  2016. char devStr[END_NAME_MAX];
  2017. int strSize;
  2018. /* Is there an HEnd in the device name */
  2019. if (strstr (pDev->pName, "HEnd") == NULL)
  2020. return;
  2021. strSize = strlen(pDev->pName)-4; /* truncate HEnd */
  2022. if (vxbDevMethodGet(pDev, (UINT32)&muxDevConnect_desc) != NULL)
  2023. {
  2024. strncpy(devStr,pDev->pName,strSize);
  2025. devStr[strSize]=EOS;
  2026. printf(" %s%d",devStr,pDev->unitNumber);
  2027. }
  2028. }
  2029. #endif /* INCLUDE_VXBUS */
  2030. #endif  /* INCLUDE_NETWORK */
  2031. /******************************************************************************
  2032. *
  2033. * usrPccardDevShow - Show PC Card clients
  2034. *
  2035. * This routine shows all PC Card clients of the specified type.
  2036. *
  2037. * RETURNS: OK or ERROR.
  2038. *
  2039. */
  2040. #ifdef INCLUDE_PCCARD
  2041. LOCAL void usrPccardDevShow
  2042.     (
  2043.     UINT16 type
  2044.     )
  2045.     {
  2046.     CS_CHANDLE client;
  2047.     STATUS status;
  2048.     CS_CLIENT_INFO info;
  2049.     char nameString[80];
  2050.     char vendorString[80];
  2051.     UINT16 attr = type | CS_CLIENT_TYPE;
  2052.     info.nameStringMax = 80;
  2053.     info.nameString = nameString;
  2054.     info.vendorStringMax = 80;
  2055.     info.vendorString = vendorString;
  2056.     status = csGetFirstClient (&client, 0, 0, attr);
  2057.     while (status != ERROR)
  2058.         {
  2059.         if (csGetClientInfo (client, &info) == OK)
  2060.            printf (" %s", info.nameString);
  2061.         status = csGetNextClient (&client, 0, 0, attr);
  2062.         }
  2063.     }
  2064. #endif /* INCLUDE_PCCARD */
  2065. #if (CPU_FAMILY == MIPS)
  2066. UINT32 mmuMipsTlbVecSize = 0x10;
  2067. UINT32 mmuMipsXtlbVecSize = 0x10;
  2068. /****************************************************************************
  2069. *
  2070. * mmuMipsInitialMemoryMap - dummy function
  2071. *
  2072. * This function is a dummy to prevent the linker from calling in the
  2073. * MIPS mmu library for bootroms.
  2074. *
  2075. * RETURNS: OK always.
  2076. *
  2077. */
  2078. STATUS mmuMipsInitialMemoryMapSet
  2079.     (
  2080.     UINT nTlbEntries,
  2081.     ULONG       excTlbPageBaseAddress,
  2082.     UINT32 localMemLocalAdrs, /* LOCAL_MEM_LOCAL_ADRS */
  2083.     UINT32 memTop /* top of memory */
  2084.     )
  2085.     {
  2086.     return OK;
  2087.     }
  2088. /****************************************************************************
  2089. *
  2090. * mmuMipsTlbVec - dummy function
  2091. *
  2092. * This function is a dummy to prevent the linker from calling in the
  2093. * MIPS mmu library for bootroms.
  2094. *
  2095. * RETURNS: OK always.
  2096. *
  2097. */
  2098. VOID mmuMipsTlbVec(void)
  2099.     {
  2100.     WRS_ASM (".set noat");
  2101.     WRS_ASM ("la $26, excStub");
  2102.     WRS_ASM ("jr $26");
  2103.     WRS_ASM (".set at");
  2104.     }
  2105. /****************************************************************************
  2106. *
  2107. * mmuMipsXTlbVec - dummy function
  2108. *
  2109. * This function is a dummy to prevent the linker from calling in the
  2110. * MIPS mmu library for bootroms.
  2111. *
  2112. * RETURNS: OK always.
  2113. *
  2114. */
  2115. VOID mmuMipsXtlbVec(void)
  2116.     {
  2117.     WRS_ASM (".set noat");
  2118.     WRS_ASM ("la $26, excStub");
  2119.     WRS_ASM ("jr $26");
  2120.     WRS_ASM (".set at");
  2121.     }
  2122. #endif /* CPU_FAMILY == MIPS */