bootConfig.c
资源名称:mpc8548.rar [点击查看]
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:147k
源码类别:
VxWorks
开发平台:
C/C++
- #ifdef INCLUDE_TFFS
- if (strncmp (sysBootParams.bootDev, "tffs", 4) == 0)
- {
- int drive = 0;
- int removable = 0;
- if (sysBootParams.bootDev[4] == EOS)
- return (ERROR);
- sscanf (sysBootParams.bootDev, "%*4s%*c%d%*c%d", &drive, &removable);
- /* tffsLoad () should be after pcmciaInit () */
- if (tffsLoad (drive, removable, sysBootParams.bootFile, pEntry) != OK)
- {
- printErr ("nError loading file: errno = 0x%x.n", errno);
- return (ERROR);
- }
- return (OK);
- }
- #endif /* INCLUDE_TFFS */
- #ifdef INCLUDE_TSFS_BOOT
- if (strncmp (sysBootParams.bootDev, "tsfs", 4) == 0)
- {
- if (tsfsLoad (sysBootParams.bootFile, pEntry) != OK)
- {
- printErr ("nError loading file: errno = 0x%x.n", errno);
- return (ERROR);
- }
- return (OK);
- }
- #endif /* INCLUDE_TSFS_BOOT */
- #ifndef INCLUDE_NETWORK
- printf ("nError loading file: networking code not present.n");
- return (ERROR);
- }
- #else /* INCLUDE_NETWORK */
- /* verify unsupported booting devices */
- if (strncmp (sysBootParams.bootDev, "sl", 2) == 0)
- {
- printf ("booting via slip is unsupported.n");
- return (ERROR);
- }
- strncpy (bootDev, sysBootParams.bootDev, sizeof (bootDev));
- /* attach and configure boot interface */
- pBootAddr = sysBootParams.ead;
- #ifdef INCLUDE_SM_NET
- if ((strncmp (sysBootParams.bootDev, "bp", 2) == 0) ||
- (strncmp (sysBootParams.bootDev, "sm", 2) == 0))
- {
- backplaneBoot = TRUE;
- pBootAddr = sysBootParams.bad;
- }
- #endif /* INCLUDE_SM_NET */
- /* Save requested lease length, if any. Ignore lease origin value. */
- result = bootLeaseExtract (pBootAddr, &leaseLen, NULL);
- if (result < 0)
- {
- printf ("Error reading target address information.n");
- return (ERROR);
- }
- /* Handle any lease information attached to the address entry. */
- if (result == 2)
- {
- /*
- * The current address contains both a duration value and a start
- * time, indicating that it was assigned by a DHCP server.
- */
- /* Handle finite and infinite address assignment. */
- if (sysFlags & SYSFLG_AUTOCONFIG)
- *pBootAddr = EOS; /* Remove for later replacement. */
- else
- {
- /*
- * Technically, this address is invalid since it contains
- * a finite interval that requires DHCP for verification
- * and the automatic configuration flag is not set.
- * However, this situation can only occur if caused
- * deliberately by the user. So, just ignore the timing
- * information and assign the address permanently.
- */
- result = 0; /* Prevents restoration of time values. */
- }
- }
- #ifdef INCLUDE_DHCPC
- /* Set the DHCP lease information, if needed. */
- if (sysFlags & SYSFLG_AUTOCONFIG)
- {
- /* Save the requested lease length if entered by the user. */
- if (result == 1)
- dhcpLease.lease_duration = leaseLen;
- else
- #ifdef INCLUDE_PCCARD
- if (!attached)
- {
- csClientLoad (CS_END_ENABLER);
- pCookie = muxTkCookieGet (bootDev, params.unitNum);
- if (pCookie != NULL)
- {
- /* The enabler has started the device - no muxDevStart
- * necessary.
- */
- /* Add our default address resolution functions. */
- muxAddrResFuncAdd (M2_ifType_ethernet_csmacd, 0x800,
- ipEtherResolvRtn);
- if (ipAttach (params.unitNum, bootDev) != OK)
- {
- printf ("Failed to attach TCP/IP to device %s",
- muxDevName);
- return (ERROR);
- }
- printf ("Attached TCP/IP interface to %s%d.n", bootDev,
- params.unitNum);
- attached = TRUE;
- }
- }
- #endif /* INCLUDE_PCCARD */
- {
- /*
- * The lease length is either not present or left over from
- * an earlier lease. Use the default value.
- */
- dhcpLease.lease_duration = DHCPC_DEFAULT_LEASE;
- }
- dhcpLease.lease_origin = 0;
- }
- #endif /* INCLUDE_DHCPC */
- /*
- * Initialize network stack. Once usrNetworkInit is completed,
- * the bootrom can start loading the vxWorks image via network.
- * Note that MUX is already initialized in usrRoot().
- */
- if (usrNetworkInit() == ERROR)
- return (ERROR);
- if (netmask != 0) /* reconstruct address with mask */
- {
- sprintf (buf, ":%x", netmask);
- strcat (pBootAddr, buf);
- }
- /*
- * If a value was specified for the requested lease length and the
- * address information was not replaced by automatic configuration,
- * restore that value for use by later reboots.
- */
- if (!(sysFlags & SYSFLG_AUTOCONFIG) && result == 1)
- {
- /*
- * The value is ignored if <result> is 2, since that is only
- * possible at this point for permanent DHCP assignments,
- * which need no special processing by later reboots.
- */
- if (netmask == 0) /* Create empty netmask field. */
- sprintf (buf, "::%lx", leaseLen);
- else /* Append requested lease length to netmask. */
- sprintf(buf, ":%lx", leaseLen);
- strcat (pBootAddr, buf);
- }
- #ifdef INCLUDE_DHCPC
- /*
- * If the target IP address was assigned by a DHCP server, append
- * the lease times. The presence of those fields in the address string
- * will cause the runtime image to renew the corresponding lease.
- */
- if (sysFlags & SYSFLG_AUTOCONFIG)
- {
- /* Add lease origin and lease duration if needed. */
- if (dhcpcBindType == DHCP_NATIVE)
- {
- if (netmask == 0) /* Create empty netmask field. */
- sprintf (buf, "::%lx:%lx", dhcpLease.lease_duration,
- dhcpLease.lease_origin);
- else /* Append lease timestamps to netmask. */
- sprintf (buf, ":%lx:%lx", dhcpLease.lease_duration,
- dhcpLease.lease_origin);
- strcat (pBootAddr, buf);
- }
- }
- #endif /* INCLUDE_DHCPC */
- bootStructToString (BOOT_LINE_ADRS, &sysBootParams);
- /* load specified file */
- taskPriorityGet (0, &oldTaskPriority);
- taskPrioritySet (0, netTaskPriority + 1);
- if (netLoad (sysBootParams.had, sysBootParams.bootFile, sysBootParams.usr,
- sysBootParams.passwd, pEntry) != OK)
- {
- printf ("nError loading file: errno = 0x%x.n", errno);
- status = ERROR;
- }
- else
- status = OK;
- taskPrioritySet (0, oldTaskPriority);
- #ifdef INCLUDE_VXWORKS_5_X_EQUIV_PPP
- if ((strncmp (sysBootParams.bootDev, "ppp", 3) == 0) &&
- ((pppBootHandle->status & PPP_LCP_OPENED) != 0))
- {
- if (ppp5xDisconnect (pppBootHandle) == ERROR ||
- pppBootHandle->syncSem == NULL)
- return (ERROR);
- if (semTake (pppBootHandle->syncSem,
- PPP_DISCONNECT_DELAY * sysClkRateGet()) == ERROR)
- {
- printf ("PPP: timeout: could not disconnect the link.n");
- return (ERROR);
- }
- printf ("PPP: link disconnected OKn");
- }
- #endif /* INCLUDE_VXWORKS_5_X_EQUIV_PPP */
- return (status);
- }
- /*******************************************************************************
- *
- * netLoad - downLoad a file from a remote machine via the network.
- *
- * The remote shell daemon on the machine 'host' is used to download
- * the given file to the specified previously opened network file descriptor.
- * The remote userId should have been set previously by a call to iam().
- * If the file does not exist, the error message from the Unix 'host'
- * is printed to the VxWorks standard error fd and ERROR is returned.
- *
- * RETURNS: OK or ERROR
- */
- LOCAL STATUS netLoad
- (
- char *hostName,
- char *fileName,
- char *usr,
- char *passwd,
- FUNCPTR *pEntry
- )
- {
- int fd;
- int errFd; /* for receiving standard error messages from Unix */
- BOOL bootFtp = (passwd[0] != EOS);
- BOOL bootRsh = FALSE;
- #ifdef INCLUDE_REMLIB
- char command [BOOT_FILE_LEN + BOOT_HOST_LEN];
- #endif
- printf ("Loading... ");
- #ifdef INCLUDE_TFTP_CLIENT
- if (sysFlags & SYSFLG_TFTP) /* use tftp to get image */
- {
- if (tftpXfer (hostName, 0, fileName, "get", "binary", &fd,
- &errFd) == ERROR)
- return (ERROR);
- }
- else
- #endif
- {
- if (bootFtp)
- {
- #ifdef INCLUDE_FTP
- if (ftpXfer (hostName, usr, passwd, "", "RETR %s", "", fileName,
- &errFd, &fd) == ERROR)
- #endif
- return (ERROR);
- }
- else
- {
- bootRsh = TRUE;
- #ifdef INCLUDE_REMLIB
- sprintf (command, "cat %s", fileName);
- fd = rcmd (hostName, RSHD, usr, usr, command, &errFd);
- if (fd == ERROR)
- #endif
- return (ERROR);
- }
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto readErr;
- #ifdef INCLUDE_TFTP_CLIENT
- /*
- * Successful TFTP transfers don't need any cleanup. The tftpXfer()
- * routine closes all file descriptors once the data has been
- * retrieved from the remote host.
- */
- if (sysFlags & SYSFLG_TFTP) /* used tftp to get image - just exit */
- {
- DEV_HDR *dhp = iosFdDevFind(fd);
- /*
- * Empty the data socket so that the entire file is received from
- * TFTP server - allows for graceful close on server side
- */
- while (dhp && ((iosFdDrvValue(fd, dhp->drvNum) != ERROR))
- && (read (fd, command, sizeof (command)) > 0));
- return (OK);
- }
- #endif
- if (bootRsh == FALSE)
- {
- #ifdef INCLUDE_FTP
- /* Empty the Data Socket before close. PC FTP server hangs otherwise */
- while ((read (fd, command, sizeof (command))) > 0);
- /* close the data socket before checking for a ftp reply (SPR #77169) */
- close (fd);
- if (bootFtp)
- (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
- #endif
- }
- else
- close (fd);
- close (errFd);
- return (OK);
- readErr:
- /* check standard error on Unix */
- if (bootRsh == FALSE)
- {
- #ifdef INCLUDE_FTP
- /* Empty the Data Socket before close. PC FTP server hangs otherwise */
- while ((read (fd, command, sizeof (command))) > 0);
- /* close the data socket before checking for a ftp reply (SPR #77169) */
- close (fd);
- if (bootFtp)
- {
- (void) ftpReplyGet (errFd, FALSE); /* error message on std. err */
- (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
- }
- #endif /* INCLUDE_FTP */
- }
- else
- {
- char buf [BOOT_FILE_LEN + BOOT_HOST_LEN];
- int errBytesRecv = fioRead (errFd, buf, sizeof (buf));
- if (errBytesRecv > 0)
- {
- /* print error message on standard error fd */
- buf [errBytesRecv] = EOS;
- printf ("n%s:%s: %sn", hostName, fileName, buf);
- }
- close (fd);
- }
- close (errFd);
- return (ERROR);
- }
- #endif /* INCLUDE_NETWORK */
- #ifdef INCLUDE_FLASH_BOOT
- LOCAL STATUS flashLoad(char *fileName, FUNCPTR *pEntry)
- {
- int fd;
- int rv;
- int err;
- usrDosfsInit (DOSFS_DEFAULT_MAX_FILES, DOSFS_DEFAULT_CREATE_OPTIONS);
- flashFsLibInit(); /* Mounts flsh: */
- do {
- /*
- * Load the boot file.
- * Support loading deflated files.
- */
- if ((fd = open(fileName, O_RDONLY, 0)) == ERROR) {
- printErr("Cannot open "%s".n", fileName);
- return ERROR;
- }
- printf("Loading %s ... ", fileName);
- rv = bootLoadModule(fd, pEntry);
- if (rv != OK) {
- err = errnoGet();
- err = err & 0x7fff; /* mask module code. */
- }
- close(fd);
- } while (rv != OK && err == EINTR); /* If interrupted, try again */
- printf("n");
- return rv;
- }
- #endif /* INCLUDE_FLASH_BOOT */
- #if (defined (INCLUDE_SCSI_BOOT) || defined (INCLUDE_FD) ||
- defined (INCLUDE_IDE) || defined (INCLUDE_ATA) ||
- defined (INCLUDE_TFFS))
- #define SPIN_UP_TIMEOUT 45 /* max # of seconds to wait for spinup */
- /******************************************************************************
- *
- * devSplit - split the device name from a full path name
- *
- * This routine returns the device name from a valid UNIX-style path name
- * by copying until two slashes ("/") are detected. The device name is
- * copied into <devName>.
- *
- * RETURNS: N/A
- *
- * NOMANUAL
- */
- void devSplit
- (
- FAST char *fullFileName, /* full file name being parsed */
- FAST char *devName /* result device name */
- )
- {
- FAST int nChars = 0;
- if (fullFileName != NULL)
- {
- char *p0 = fullFileName;
- char *p1 = devName;
- while ((nChars < 2) && (*p0 != EOS))
- {
- if (*p0 == '/')
- nChars++;
- *p1++ = *p0++;
- }
- *p1 = EOS;
- }
- else
- {
- (void) strcpy (devName, "");
- }
- }
- #endif /* (defined (INCLUDE_SCSI_BOOT) || (INCLUDE_FD) || (INCLUDE_IDE)) */
- #ifdef INCLUDE_SCSI_BOOT
- /******************************************************************************
- *
- * scsiLoad - load a vxWorks image from a local SCSI disk
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- */
- LOCAL STATUS scsiLoad
- (
- int bootDevId,
- int bootDevLUN,
- char *fileName,
- FUNCPTR *pEntry
- )
- {
- int fd;
- SCSI_PHYS_DEV *pScsiPhysBootDev;
- BLK_DEV *pScsiBlkBootDev;
- char bootDir [BOOT_FILE_LEN];
- int ix;
- #ifdef INCLUDE_SCSI2
- SCSI_OPTIONS options;
- UINT which;
- #endif /* INCLUDE_SCSI2 */
- char fsmName[16];
- #if 0
- CBIO_DEV_ID pCbio;
- #endif
- if (!scsiInitialized) /* skip if this is a retry */
- {
- if (sysScsiInit () == ERROR)
- {
- printErr ("Could not initialize SCSI.n");
- return (ERROR);
- }
- scsiInitialized = TRUE;
- }
- taskDelay (sysClkRateGet ()); /* delay 1 second after reset */
- if ((bootDevId < SCSI_MIN_BUS_ID) ||
- (bootDevId > SCSI_MAX_BUS_ID) ||
- (bootDevLUN < SCSI_MIN_LUN) ||
- (bootDevLUN > SCSI_MAX_LUN))
- {
- printErr ("SCSI device parameters < busId = %d, lun = %d > ",
- bootDevId, bootDevLUN);
- printErr ("are out of range (0-7).n");
- printErr ("Check boot device format:n");
- printErr (" scsi=<busId>,<lun> e.g. scsi=2,0n");
- return (ERROR);
- }
- #ifdef INCLUDE_SCSI2
- /* Set all devices to asynchronous data transfer */
- which = SCSI_SET_OPT_XFER_PARAMS;
- options.maxOffset = 0;
- options.minPeriod = SCSI_SYNC_XFER_MIN_PERIOD;
- scsiTargetOptionsSet (pSysScsiCtrl, bootDevId, &options, which);
- #endif /* INCLUDE_SCSI2 */
- /* create device handle for TEST UNIT READY commands */
- if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
- bootDevLUN, 128, 0, 0,
- 0xffff, 512)) == NULL)
- {
- printErr ("scsiPhysDevCreate failed.n");
- return (ERROR);
- }
- /* issue two TEST UNIT READY commands to clear reset exception */
- scsiTestUnitRdy (pScsiPhysBootDev);
- scsiTestUnitRdy (pScsiPhysBootDev);
- /*
- * issue a TEST UNIT READY every second for SPIN_UP_TIMEOUT seconds,
- * or until device returns OK status.
- */
- if (scsiTestUnitRdy (pScsiPhysBootDev) != OK)
- {
- printf ("Waiting for disk to spin up...");
- for (ix = 0; ix < SPIN_UP_TIMEOUT; ix++)
- {
- if (scsiTestUnitRdy (pScsiPhysBootDev) == OK)
- {
- printf (" done.n");
- break;
- }
- if (ix != (SPIN_UP_TIMEOUT - 1))
- printf (".");
- else
- {
- printf (" timed out.n");
- return (ERROR);
- }
- taskDelay (sysClkRateGet ());
- }
- }
- /* delete temporary device handle */
- scsiPhysDevDelete (pScsiPhysBootDev);
- printf ("Attaching to scsi device... ");
- /* recreate a device handle, with polling for actual device parameters */
- taskDelay (sysClkRateGet ());
- if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
- bootDevLUN, 0, -1, 0, 0, 0))
- == NULL)
- {
- printErr ("scsiPhysDevCreate failed.n");
- return (ERROR);
- }
- /*-------------------------------------------------------------------------
- *
- * Configuration of an OMTI3500
- *
- *-----------------------------------------------------------------------*/
- if ((strncmp (pScsiPhysBootDev->devVendorID, "SMS", 3) == 0) &&
- (strncmp (pScsiPhysBootDev->devProductID, "OMTI3500", 8) == 0))
- {
- char modeData [4]; /* array for floppy MODE SELECT data */
- /*
- * zero modeData array, then set byte 1 to "medium code" (0x1b).
- * NOTE: MODE SELECT data is highly device-specific. If your device
- * requires configuration via MODE SELECT, please consult the device's
- * Programmer's Reference for the relevant data format.
- */
- bzero (modeData, sizeof (modeData));
- modeData [1] = 0x1b;
- /* issue a MODE SELECT cmd to correctly configure floppy controller */
- scsiModeSelect (pScsiPhysBootDev, 1, 0, modeData, sizeof (modeData));
- /*
- * delete and re-create the SCSI_PHYS_DEV so that INQUIRY will return
- * the new device parameters, i.e., correct number of blocks
- */
- scsiPhysDevDelete (pScsiPhysBootDev);
- /* recreate a device handle, polling for actual device parameters */
- if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
- bootDevLUN, 0, -1, 0, 0, 0))
- == NULL)
- {
- printErr ("scsiPhysDevCreate failed.n");
- return (ERROR);
- }
- }
- /*
- * -----------------------------------------------------------------------
- *
- * END of OMTI3500 configuration
- *
- * -----------------------------------------------------------------------
- */
- /* create a block device spanning entire disk (non-destructive!) */
- if ((pScsiBlkBootDev = scsiBlkDevCreate (pScsiPhysBootDev, 0, 0)) == NULL)
- {
- printErr ("scsiLoad: scsiBlkDevCreate failed.n");
- return (ERROR);
- }
- sprintf (fsmName, "/scsi%d:0", bootDevLUN);
- fsmNameInstall (fsmName, bootDir);
- /* split off boot device from boot file */
- devSplit (fileName, bootDir);
- xbdBlkDevCreate (pScsiBlkBootDev, bootDir);
- /* now support booting from partitions on SCSI devices */
- #if 0
- pCbio = dpartDevCreate ((CBIO_DEV_ID) pScsiBlkBootDev,
- NUM_PARTITIONS_DISK_BOOT,
- usrFdiskPartRead);
- if (NULL == pCbio)
- {
- printErr ("scsiLoad: dpartDevCreate returned NULL.n");
- return (ERROR);
- }
- /* initialize the boot block device as a dosFs device named <bootDir> */
- if (ERROR == dosFsDevCreate (bootDir,
- dpartPartGet(pCbio,PARTITION_DISK_BOOT),
- 20, NONE))
- {
- printErr ("scsiLoad: dosFsDevCreate returned ERROR.n");
- return (ERROR);
- }
- #endif
- printErr ("done.n");
- /* load the boot file */
- printErr ("Loading %s...", fileName);
- fd = open (fileName, O_RDONLY, 0);
- if (fd == ERROR)
- {
- printErr ("nCannot open "%s".n", fileName);
- return (ERROR);
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto readErr;
- close (fd);
- return (OK);
- readErr:
- close (fd);
- return (ERROR);
- }
- #endif /* INCLUDE_SCSI_BOOT */
- #ifdef INCLUDE_FD
- #include <usrFd.c>
- /******************************************************************************
- *
- * fdLoad - load a vxWorks image from a local floppy disk
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- */
- LOCAL STATUS fdLoad
- (
- int drive,
- int type,
- char *fileName,
- FUNCPTR *pEntry
- )
- {
- int fd;
- if (fdDrv (FD_INT_VEC, FD_INT_LVL) != OK)
- {
- printErr ("Could not initialize.n");
- return (ERROR);
- }
- printf ("Attaching to floppy disk device... ");
- /*
- * Initialize DosFs. When booting from a floppy, it is assumed that it is
- * formatted with DosFs. Hence the unconditional initialization of the
- * DosFs file system libraries.
- */
- if (usrFdConfig (drive, type, fileName) == ERROR)
- {
- printErr ("usrFdConfig failed.n");
- return (ERROR);
- }
- printErr ("done.n");
- /* load the boot file */
- printErr ("Loading %s...", fileName);
- if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
- {
- printErr ("nCannot open "%s".n", fileName);
- return (ERROR);
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto fdLoadErr;
- close (fd);
- return (OK);
- fdLoadErr:
- close (fd);
- return (ERROR);
- }
- #endif /* INCLUDE_FD */
- #ifdef INCLUDE_IDE
- #define IDE_MEM_DOSFS 0x200000
- #include <usrIde.c>
- /******************************************************************************
- *
- * ideLoad - load a vxWorks image from a local IDE disk
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- */
- LOCAL STATUS ideLoad
- (
- int drive,
- int type,
- char *fileName,
- FUNCPTR *pEntry
- )
- {
- int fd;
- if (ideDrv (IDE_INT_VEC, IDE_INT_LVL, type) == ERROR)
- {
- printErr ("Could not initialize.n");
- return (ERROR);
- }
- printf ("Attaching to IDE disk device... ");
- if (usrIdeConfig (drive, fileName) == ERROR)
- {
- printErr ("usrIdeConfig failed.n");
- return (ERROR);
- }
- printErr ("done.n");
- /* load the boot file */
- printErr ("Loading %s...", fileName);
- if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
- {
- printErr ("nCannot open "%s".n", fileName);
- return (ERROR);
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto ideLoadErr;
- close (fd);
- return (OK);
- ideLoadErr:
- close (fd);
- return (ERROR);
- }
- #endif /* INCLUDE_IDE */
- #ifdef INCLUDE_ATA
- #define ATA_MEM_DOSFS 0x200000
- #include <usrAta.c>
- /******************************************************************************
- *
- * ataLoad - load a vxWorks image from a local ATA disk
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- */
- LOCAL STATUS ataLoad
- (
- int ctrl,
- int drive,
- char *fileName,
- FUNCPTR *pEntry
- )
- {
- IMPORT ATA_RESOURCE ataResources[];
- ATA_RESOURCE * pAtaResource = &ataResources[ctrl];
- int fd;
- char tmp[BOOT_FILE_LEN];
- #ifdef INCLUDE_PCCARD
- if (pAtaResource->ctrlType == IDE_LOCAL)
- {
- #endif /* INCLUDE_PCCARD */
- if (ataDrv (ctrl, pAtaResource->drives, pAtaResource->intVector,
- pAtaResource->intLevel, pAtaResource->configType,
- pAtaResource->semTimeout, pAtaResource->wdgTimeout) == ERROR)
- {
- printErr ("Could not initialize.n");
- return (ERROR);
- }
- #ifdef INCLUDE_PCCARD
- }
- else
- csClientLoad (CS_ATA_ENABLER);
- #endif /* INCLUDE_PCCARD */
- printf ("Attaching to ATA disk device... ");
- /*
- * Initialize DosFs. When booting from an ATA device, it is assumed that
- * it is formatted with DosFs. Hence the unconditional initialization of
- * the DosFs file system libraries.
- */
- devSplit (fileName, tmp);
- if (usrAtaConfig (ctrl, drive, tmp) == ERROR)
- {
- printErr ("usrAtaConfig failed.n");
- return (ERROR);
- }
- printErr ("done.n");
- /* load the boot file */
- printErr ("Loading %s...", fileName);
- if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
- {
- printErr ("nCannot open "%s".n", fileName);
- return (ERROR);
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto ataLoadErr;
- close (fd);
- return (OK);
- ataLoadErr:
- close (fd);
- return (ERROR);
- }
- #endif /* INCLUDE_ATA */
- #ifdef INCLUDE_PCMCIA
- #define PCMCIA_MEM_DOSFS 0x200000
- #include <usrPcmcia.c>
- /******************************************************************************
- *
- * pcmciaLoad - load a vxWorks image from a PCMCIA disk device
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- */
- LOCAL STATUS pcmciaLoad
- (
- int sock,
- char *fileName,
- FUNCPTR *pEntry
- )
- {
- int fd;
- printf ("Attaching to PCMCIA block device... ");
- /*
- * Initialize DosFs. When booting from a PCMCIA device, it is assumed that
- * it is formatted with DosFs. Hence the unconditional initialization of
- * the DosFs file system libraries.
- */
- if (usrPcmciaConfig (sock, fileName) != OK)
- return (ERROR);
- printErr ("done.n");
- /* load the boot file */
- printErr ("Loading %s...", fileName);
- if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
- {
- printErr ("nCannot open "%s".n", fileName);
- return (ERROR);
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto pcmciaLoadErr;
- close (fd);
- return (OK);
- pcmciaLoadErr:
- close (fd);
- return (ERROR);
- }
- #endif /* INCLUDE_PCMCIA */
- #ifdef INCLUDE_TFFS
- #define TFFS_MEM_DOSFS 0x200000
- #include <usrTffs.c>
- #include "sysTffs.c" /* the BSP stub file, in the BSP directory */
- /******************************************************************************
- *
- * tffsLoad - load a vxWorks image from a TFFS Flash disk
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- *
- * NOMANUAL
- */
- LOCAL STATUS tffsLoad
- (
- int drive, /* TFFS drive number (0 - (noOfDrives-1)) */
- int removable, /* 0 - nonremovable flash media */
- char * fileName, /* file name to download */
- FUNCPTR * pEntry
- )
- {
- int fd;
- if (tffsDrv () != OK)
- {
- printErr ("Could not initialize.n");
- return (ERROR);
- }
- printf ("Attaching to TFFS... ");
- if (usrTffsConfig (drive, removable, fileName) == ERROR)
- {
- printErr ("usrTffsConfig failed.n");
- return (ERROR);
- }
- printErr ("done.n");
- /* load the boot file */
- printErr ("Loading %s...", fileName);
- if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
- {
- printErr ("nCannot open "%s".n", fileName);
- return (ERROR);
- }
- if (bootLoadModule (fd, pEntry) != OK)
- goto tffsLoadErr;
- close (fd);
- return (OK);
- tffsLoadErr:
- close (fd);
- return (ERROR);
- }
- #endif /* INCLUDE_TFFS */
- #ifdef INCLUDE_TSFS_BOOT
- /******************************************************************************
- *
- * tsfsLoad - load a vxWorks image from a Target Server File System (TSFS).
- *
- * RETURNS: OK, or ERROR if file can not be loaded.
- *
- * NOMANUAL
- */
- LOCAL STATUS tsfsLoad
- (
- char * fileName, /* file name to download */
- FUNCPTR * pEntry
- )
- {
- int fd;
- WDB_EVT_NODE rebootEventNode;
- char corefile [PATH_MAX + 1];
- /* add a leading slash if the filename is a relative path */
- if (fileName[0] != '/' && fileName[0] != '\')
- sprintf (corefile, "/tgtsvr/%s", fileName);
- else
- sprintf (corefile, "/tgtsvr%s", fileName);
- printf ("Booting using TSFS...nMake sure that your");
- printf (" Target Server is started with -R[oot] option.n");
- #ifndef INCLUDE_TSFS_BOOT_VIO_CONSOLE
- printf ("Waiting for Target Server connection...");
- /* wait for Target Server connection */
- while (!wdbTargetIsConnected())
- taskDelay (sysClkRateGet());
- printf (" Done.n");
- #endif /* INCLUDE_TSFS_BOOT_VIO_CONSOLE */
- /* open the core file via tsfs */
- printErr ("nLoading %s...n", corefile);
- if ((fd = open (corefile, O_RDONLY, 0)) == ERROR)
- {
- printErr ("nCannot open "%s".n", corefile);
- return (ERROR);
- }
- /* load the core file */
- if (bootLoadModule (fd, pEntry) != OK)
- goto tsfsLoadErr;
- close (fd);
- #if (WDB_COMM_TYPE != WDB_COMM_SERIAL)
- /* Notify the host of the target reboot */
- wdbEventNodeInit (&rebootEventNode, wdbRebootEventGet, NULL, NULL);
- wdbEventPost (&rebootEventNode);
- /* let some time to WDB to post the event */
- taskDelay (sysClkRateGet() / 10);
- #endif /* WDB_COMM_TYPE != WDB_COMM_SERIAL */
- return (OK);
- tsfsLoadErr:
- close (fd);
- return (ERROR);
- }
- /******************************************************************************
- *
- * wdbRebootEventGet - dummy eventGet routine to force the Target Server restart
- *
- * suspend the WDB task, so the Target Server will get a RPC_SYSTEMERROR
- * will trying to get an event, so it will restart and try to re-attach to
- * the target.
- */
- LOCAL void wdbRebootEventGet
- (
- void * pNode,
- WDB_EVT_DATA * pEvtData
- )
- {
- taskSuspend (0);
- }
- #endif /* INCLUDE_TSFS_BOOT */
- #ifdef INCLUDE_NETWORK
- /******************************************************************************
- *
- * netifAdrsPrint - print MAC address of a network interface
- */
- LOCAL void netifAdrsPrint
- (
- char *ifname /* interface name */
- )
- {
- IMPORT struct ifnet *ifunit ();
- char *buf;
- char devName [10];
- int i, value;
- if (ifname == NULL || *ifname == EOS)
- {
- printf ("Interface not specifiedn");
- return;
- }
- while (*ifname == ' ')
- ifname++; /* skip leading blanks */
- if (*ifname == EOS)
- {
- printf ("Interface not specifiedn");
- return;
- }
- /* Search for unit number of network device. */
- i = 0;
- while (!isdigit((int)ifname[i]) && !isspace((int)ifname[i]) && ifname[i] != EOS)
- i++;
- if (ifname[i] == EOS) /* No unit number given - use 0. */
- value = 0;
- buf = &ifname[i];
- if (bootScanNum (&buf, &value, FALSE) != OK) /* No unit number - use 0. */
- value = 0;
- ifname[i] = EOS;
- sprintf (devName, "%s%d", ifname, value);
- if (strncmp (devName, "bp", 2) == 0)
- {
- /* address for backplane is just processor number */
- printf ("Address for device "%s" == 00:00:00:00:00:%02xn",
- devName, sysProcNumGet ());
- return;
- }
- }
- #endif /* INCLUDE_NETWORK */
- /*******************************************************************************
- *
- * go - start at specified address
- */
- LOCAL void go
- (
- FUNCPTR entry
- )
- {
- printf ("Starting at 0x%x...nn", (int) entry);
- taskDelay (sysClkRateGet ()); /* give the network a moment to close */
- #ifdef INCLUDE_END
- /* Stop all ENDs to restore to known state for interrupts and DMA */
- (void) muxDevStopAll (0);
- #endif /* INCLUDE_END */
- #if (CPU_FAMILY == PPC)
- cacheTextUpdate ((void *) (LOCAL_MEM_LOCAL_ADRS), /* cache coherency */
- (size_t) (sysMemTop() - LOCAL_MEM_LOCAL_ADRS));
- #else
- #ifdef INCLUDE_CACHE_SUPPORT
- cacheClear (DATA_CACHE, NULL, ENTIRE_CACHE); /* push cache to mem */
- #endif /* INCLUDE_CACHE_SUPPORT */
- #endif /* (CPU_FAMILY == PPC) */
- #if (CPU_FAMILY == I80X86)
- sysClkDisable (); /* disable the system clock interrupt */
- sysIntLock (); /* lock the used/owned interrupts */
- # if defined (SYMMETRIC_IO_MODE) || defined (VIRTUAL_WIRE_MODE)
- {
- extern void loApicEnable ();
- loApicEnable (FALSE); /* disable the LOAPIC */
- }
- # if defined (SYMMETRIC_IO_MODE)
- {
- extern BOOL sysBp; /* TRUE for BP, FALSE for AP */
- extern void ioApicEnable ();
- if (sysBp)
- ioApicEnable (FALSE); /* disable the IO APIC */
- }
- # endif /* (SYMMETRIC_IO_MODE) */
- # endif /* (SYMMETRIC_IO_MODE) || (VIRTUAL_WIRE_MODE) */
- #endif /* (CPU_FAMILY == I80X86) */
- /* Lock interrupts before jumping out of boot image. The interrupts
- * enabled during system initialization in sysHwInit()
- */
- intLock();
- (entry) (sysStartType); /* go to entry point - never to return */
- }
- /*******************************************************************************
- *
- * m - modify memory
- *
- * This routine prompts the user for modifications to memory, starting at the
- * specified address. It prints each address, and the current contents of
- * that address, in turn. The user can respond in one of several ways:
- *
- * RETURN - No change to that address, but continue
- * prompting at next address.
- * <number> - Set the contents to <number>.
- * . (dot) - No change to that address, and quit.
- * <EOF> - No change to that address, and quit.
- *
- * All numbers entered and displayed are in hexadecimal.
- * Memory is treated as 16-bit words.
- */
- LOCAL void m
- (
- char *adrs /* address to change */
- )
- {
- char line [MAX_LINE + 1]; /* leave room for EOS */
- char *pLine; /* ptr to current position in line */
- int value; /* value found in line */
- char excess;
- /* round down to word boundary */
- for (adrs = (char *) ((int) adrs & 0xfffffffe); /* start on even addr */
- ; /* FOREVER */
- adrs = (char *) (((short *) adrs) + 1)) /* bump as short ptr */
- {
- /* prompt for substitution */
- printf ("%06x: %04x-", (int) adrs, (*(short *)adrs) & 0x0000ffff);
- /* get substitution value:
- * skip empty lines (CR only);
- * quit on end of file or invalid input;
- * otherwise put specified value at address */
- if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
- break;
- line [MAX_LINE] = EOS; /* make sure input line has EOS */
- /* skip leading spaces*/
- for (pLine = line; isspace ((UINT) * pLine); ++pLine)
- ;
- if (*pLine == EOS) /* skip field if just CR */
- continue;
- if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
- break; /* quit if not number */
- * (short *) adrs = value; /* assign new value */
- }
- printf ("n");
- }
- /*******************************************************************************
- *
- * d - display memory
- *
- * Display contents of memory, starting at adrs. Memory is displayed in
- * words. The number of words displayed defaults to 64. If
- * nwords is non-zero, that number of words is printed, rounded up to
- * the nearest number of full lines. That number then becomes the default.
- */
- LOCAL void d
- (
- FAST char *adrs, /* address to display */
- int nwords /* number of words to print. */
- ) /* If 0, print 64 or last specified. */
- {
- static char *last_adrs;
- static int dNbytes = 128;
- char ascii [17];
- FAST int nbytes;
- FAST int byte;
- ascii [16] = EOS; /* put an EOS on the string */
- nbytes = 2 * nwords;
- if (nbytes == 0)
- nbytes = dNbytes; /* no count specified: use current byte count */
- else
- dNbytes = nbytes; /* change current byte count */
- if (adrs == 0)
- adrs = last_adrs; /* no address specified: use last address */
- adrs = (char *) ((int) adrs & ~1); /* round adrs down to word boundary */
- /* print leading spaces on first line */
- bfill ((char *) ascii, 16, '.');
- printf ("%06x: ", (int) adrs & ~0xf);
- for (byte = 0; byte < ((int) adrs & 0xf); byte++)
- {
- printf (" ");
- if (byte & 1)
- printf (" "); /* space between words */
- if (byte == 7)
- printf (" "); /* extra space between words 3 and 4 */
- ascii [byte] = ' ';
- }
- /* print out all the words */
- while (nbytes-- > 0)
- {
- if (byte == 16)
- {
- /* end of line:
- * print out ascii format values and address of next line */
- printf (" *%16s*n%06x: ", ascii, (int) adrs);
- bfill ((char *) ascii, 16, '.'); /* clear out ascii buffer */
- byte = 0; /* reset word count */
- }
- #if _BYTE_ORDER == _BIG_ENDIAN
- printf ("%02x", *adrs & 0x000000ff);
- #else /* _BYTE_ORDER == _LITTLE_ENDIAN */
- /* swap odd and even bytes */
- if ( (long)adrs & 1)
- {
- printf ("%02x", *((char *)((long)adrs & 0xfffffffe)) & 0x000000ff);
- }
- else
- {
- printf ("%02x", *((char *)((long)adrs + 1)) & 0x000000ff);
- }
- #endif /* _BYTE_ORDER == _BIG_ENDIAN */
- if (byte & 1)
- printf (" "); /* space between words */
- if (byte == 7)
- printf (" "); /* extra space between words 3 and 4 */
- if (* adrs == ' ' ||
- (isascii ((UINT) * adrs) && isprint ((UINT) * adrs)))
- ascii [byte] = (UINT) * adrs;
- adrs++;
- byte++;
- }
- /* print remainder of last line */
- for (; byte < 16; byte++)
- {
- printf (" ");
- if (byte & 1)
- printf (" "); /* space between words */
- if (byte == 7)
- printf (" "); /* extra space between words 3 and 4 */
- ascii [byte] = ' ';
- }
- printf (" *%16s*n", ascii); /* print out ascii format values */
- last_adrs = adrs;
- }
- /*******************************************************************************
- *
- * bootExcHandler - bootrom exception handling routine
- */
- LOCAL void bootExcHandler
- (
- int tid /* task ID */
- )
- {
- REG_SET regSet; /* task's registers */
- /* get registers of task to be traced */
- if (taskRegsGet (tid, ®Set) != ERROR)
- {
- trcStack (®Set, (FUNCPTR) NULL, tid);
- taskRegsShow (tid);
- }
- else
- printf ("bootExcHandler: exception caught but no valid task.n");
- taskDelay (sysClkRateGet ()); /* pause a second */
- reboot (BOOT_NO_AUTOBOOT);
- }
- /*******************************************************************************
- *
- * skipSpace - advance pointer past white space
- *
- * Increments the string pointer passed as a parameter to the next
- * non-white-space character in the string.
- */
- LOCAL void skipSpace
- (
- FAST char **strptr /* pointer to pointer to string */
- )
- {
- while (isspace ((UINT) ** strptr))
- ++ * strptr;
- }
- /*******************************************************************************
- *
- * printExcMsg - print exception message
- *
- * Avoid printing possible control characters in exception message area.
- */
- LOCAL void printExcMsg
- (
- char *string
- )
- {
- printf ("n");
- while (isascii ((UINT) * string) && (isprint ((UINT) * string) ||
- isspace ((UINT) * string)))
- printf ("%c", * string++);
- printf ("n");
- }
- /******************************************************************************
- *
- * getArg - get argument from command line
- *
- * This routine gets the next numerical argument from the command line.
- * If the argument is not optional, then an error is reported if no argument
- * is found. <ppString> will be updated to point to the new position in the
- * command line.
- *
- * RETURNS: OK or ERROR
- */
- LOCAL STATUS getArg
- (
- FAST char **ppString, /* ptr to ptr to current position in line */
- int * pValue, /* ptr where to return value */
- BOOL defaultHex, /* TRUE = arg is hex (even w/o 0x) */
- BOOL optional /* TRUE = ok if end of line */
- )
- {
- skipSpace (ppString);
- /* if nothing left, complain if arg is not optional */
- if (**ppString == EOS)
- {
- if (!optional)
- {
- printf ("missing parametern");
- return (ERROR);
- }
- else
- return (OK);
- }
- /* scan arg */
- if (bootScanNum (ppString, pValue, defaultHex) != OK)
- {
- printf ("invalid parametern");
- return (ERROR);
- }
- skipSpace (ppString);
- /* if we encountered ',' delimiter, step over it */
- if (**ppString == ',')
- {
- ++*ppString;
- return (OK);
- }
- /* if end of line, scan is ok */
- if (**ppString == EOS)
- return (OK);
- /* we got stopped by something else */
- printf ("invalid parametern");
- return (ERROR);
- }
- /* The following routines are common to bootConfig and usrConfig and will
- * eventually be merged
- */
- /******************************************************************************
- *
- * usrBootLineInit - initialize system boot line
- *
- * Initializes system boot line as per specified start type.
- * If this is a COLD boot, i.e., with CLEAR option to clear memory,
- * then the boot line is initialized from non-volatile RAM, if any,
- * otherwise from the compiled in default boot line.
- */
- LOCAL void usrBootLineInit
- (
- int startType
- )
- {
- if (startType & BOOT_CLEAR)
- {
- /* this is a cold boot so get the default boot line */
- if ((sysNvRamGet (BOOT_LINE_ADRS, BOOT_LINE_SIZE, 0) == ERROR) ||
- (*BOOT_LINE_ADRS == EOS) || (*BOOT_LINE_ADRS == (char) -1))
- {
- /* either no non-volatile RAM or empty boot line */
- strcpy (BOOT_LINE_ADRS, DEFAULT_BOOT_LINE);
- }
- }
- }
- /******************************************************************************
- *
- * usrBootLineCrack - interpret and verify boot line
- *
- * This routine interprets the specified boot line and checks the validity
- * of certain parameters. If there are errors, a diagnostic message is
- * printed.
- *
- * RETURNS: OK or ERROR
- */
- LOCAL STATUS usrBootLineCrack
- (
- char * bootString,
- BOOT_PARAMS *pParams
- )
- {
- FAST char * pS;
- pS = bootStringToStruct (bootString, pParams);
- if (*pS != EOS)
- {
- bootParamsErrorPrint (bootString, pS);
- return (ERROR);
- }
- #ifdef INCLUDE_NETWORK
- /* check inet addresses */
- if ((checkInetAddrField (pParams->ead, TRUE) != OK) ||
- (checkInetAddrField (pParams->bad, TRUE) != OK) ||
- (checkInetAddrField (pParams->had, FALSE) != OK) ||
- (checkInetAddrField (pParams->gad, FALSE) != OK))
- {
- return (ERROR);
- }
- #endif /* INCLUDE_NETWORK */
- return (OK);
- }
- #ifdef INCLUDE_NETWORK
- /******************************************************************************
- *
- * checkInetAddrField - check for valid inet address in boot field
- */
- LOCAL STATUS checkInetAddrField
- (
- char *pInetAddr,
- BOOL subnetMaskOK
- )
- {
- char inetAddr [30];
- /*
- * The bzero() call corrects SPR 6326. The calls to bootNetmaskExtract()
- * and inet_addr() did not delimit the input string with a ' '. When
- * inet_addr attempted to print the invalid address, the system would
- * crash or hang.
- */
- bzero (inetAddr, sizeof(inetAddr));
- if (*pInetAddr == EOS)
- return (OK);
- strncpy (inetAddr, pInetAddr, sizeof (inetAddr) - 1);
- if (subnetMaskOK)
- {
- if (bootNetmaskExtract (inetAddr, &netmask) < 0)
- {
- printf ("Error: invalid netmask in boot field "%s".n", inetAddr);
- return (ERROR);
- }
- }
- if (inet_addr (inetAddr) == (ULONG) ERROR)
- {
- printf ("Error: invalid inet address in boot field "%s".n",inetAddr);
- return (ERROR);
- }
- return (OK);
- }
- #ifdef ETHERNET_MAC_HANDLER
- /***********************************************************
- *
- * macAddressShow - Displays the device and MAC address in
- * string form.
- *
- * This routine returns a pointer to a string of the form:
- *
- * id device unit address
- *
- * where:
- * id is an integer 1..MAX_MAC_ADRS
- * device is a string (e.g. motfcc)
- * unit is unit number
- * address is a six byte hex mac address
- * example:
- * "01 motfcc0 00:A0:1E:00:10:0A
- *
- * The function takes index as an argument where index is
- * range 00..MAX_MAC_ADRS-1
- *
- * If the passed index is out of range, the return value
- * points to an error message.
- *
- * RETURNS: pointer to string
- */
- LOCAL char *macAddressShow
- (
- int index
- )
- {
- int devNameIndex;
- int unit;
- UINT8 macAddr[6] = { 0xff,0xff,0xff,0xff,0xff,0xff };
- /* range check passed index */
- if ((index < 0) || (index >= MAX_MAC_ADRS))
- {
- return ((char *) macErrStr); /* if error, return error string */
- }
- /* convert MAC index to device index and unit number */
- devNameIndex = sysMacIndex2Dev (index);
- unit = sysMacIndex2Unit(index);
- /* get a copy of the current device address */
- /* macAddr initialized so returns all f's if ERROR */
- sysNetMacNVRamAddrGet ((char *)sysNetDevName[devNameIndex], unit,
- macAddr, MAC_ADRS_LEN);
- /* convert to string */
- sprintf (macShowStr[index],
- "%2d %6s%d %02x:%02x:%02x:%02x:%02x:%02xn",
- index+1, sysNetDevName[devNameIndex],
- unit,
- macAddr[0],
- macAddr[1],
- macAddr[2],
- macAddr[3],
- macAddr[4],
- macAddr[5]
- );
- return (macShowStr[index]);
- }
- /***********************************************************
- *
- * ifGet - Get network interface name
- *
- * This routine parses the remaining command line (after the command
- * character has been removed) and attempts to
- * identify the requested device and unit using that string. If the
- * command line does not provide the device name, a dialog is
- * initiated to identify the device.
- *
- *
- * RETURNS: IFG_MAC_SUPPLIED - if remaining boot line identifies new MAC address.
- * IFG_OPR_QUIT - if the operator elects to quit the dialog
- * IFG_DEV_SUPPLIED - if a device is selected, but no MAC address
- *
- */
- LOCAL int ifGet
- (
- char ** ifName, /* interface name */
- int * unit, /* interface unit */
- char * pNum, /* Command line */
- uchar_t * curArr /* current MAC address */
- )
- {
- char line [MAX_LINE + 1];
- uchar_t passedMac [MAX_ADR_SIZE];
- int numMacDigiRead = 0;
- char *pLine; /* ptr to current position in line */
- char excess;
- int nameLen = 0;
- int index;
- int macAddressPassed = 0;
- int macDevPassed = 0;
- pLine = pNum;
- SKIPSPACE(pLine); /* advance past any leading whitespaces */
- *ifName = pLine;
- /* determine if the bootline passed includes ifName, unit, and MAC */
- while (NOTEOS(pLine) && isalpha((int)*pLine))
- {
- nameLen++; /* count device length */
- pLine++;
- }
- /* if device name found */
- if (nameLen != 0)
- {
- for (index = 0; index < MAX_MAC_DEVS; index++)
- {
- /* if indexed device matches passed device name */
- if (strncmp (sysNetDevName[sysMacIndex2Dev(index)], *ifName,
- strlen((char *)sysNetDevName[sysMacIndex2Dev(index)])) == 0)
- {
- /* save return dev name */
- *ifName = (char *)sysNetDevName[sysMacIndex2Dev(index)];
- macDevPassed = 1; /* set flag */
- /* was unit number supplied? */
- if (isdigit((int)*pLine))
- {
- *unit = strtol(pLine, &pLine, 0); /* extract unit number */
- }
- else
- {
- *unit = 0; /* if not supplied, assume unit 0 */
- }
- /* look for MAC address */
- while (NOTEOS(pLine))
- {
- SKIPSPACE(pLine); /* advance to next field */
- if (!NOTEOS(pLine))
- {
- break; /* end of string */
- }
- if (isxdigit((int)*pLine))
- {
- passedMac[numMacDigiRead++] =
- (uchar_t) strtol(pLine, &pLine, 16);
- }
- else /* some illegal character read */
- {
- break;
- }
- if (*pLine == ':')
- pLine++;
- }
- /* if we were able to read the MAC address */
- #if _BYTE_ORDER == _BIG_ENDIAN
- if (numMacDigiRead == 6) /* if full MAC address */
- {
- macAddressPassed = 1;
- for (index = 0; index < 6; index++)
- {
- curArr[index] = passedMac[5-index];
- }
- }
- else if (numMacDigiRead == 3) /* if half MAC address */
- {
- macAddressPassed = 1;
- for (index = 0; index < 3; index++) /* 3 bytes only */
- {
- curArr[index] = passedMac[2-index];
- }
- curArr[0] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
- curArr[1] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
- curArr[2] = ((ENET_DEFAULT & 0xff000000) >> 24);
- }
- #else /* _BYTE_ORDER == _LITTLE_ENDIAN */
- if (numMacDigiRead == 6) /* if full MAC address */
- {
- macAddressPassed = 1;
- for (index = 0; index < 6; index++)
- {
- curArr[index] = passedMac[index];
- }
- }
- else if (numMacDigiRead == 3) /* if half MAC address */
- {
- macAddressPassed = 1;
- for (index = 3; index < 6; index++) /* 3 bytes only */
- {
- curArr[index] = passedMac[index];
- }
- curArr[0] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
- curArr[1] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
- curArr[2] = (ENET_DEFAULT & 0x000000ff);
- }
- #endif
- break; /* matching device found. Look no further */
- } /* end if indexed device matches passed device name */
- }
- } /* end if no device name found */
- if (macDevPassed == 0) /* if the command line lacks a device name */
- {
- /* print known devices */
- printf ("Set device MAC addressnn");
- printf (" 0 quitn");
- for (index = 0; index < MAX_MAC_ADRS; index++)
- {
- printf (" %s",macAddressShow(index));
- }
- index = -1; /* initialize to invalid index */
- /* query for new network device (1..n) */
- while ((index < 0) || ( index >= MAX_MAC_ADRS))
- {
- printf (" Selection : ");
- if (fioRdString (STD_IN, line, MAX_LINE) == EOF) /* end of line */
- {
- continue;
- }
- line [MAX_LINE] = EOS; /* make sure input line has EOS */
- /* skip leading spaces*/
- for (pLine = line; isspace ((int) *pLine); ++pLine)
- ;
- if (*pLine == EOS) /* if field is just CR */
- {
- continue;
- }
- /* if not number */
- if (sscanf (pLine, "%d%1s", &index, &excess) != 1)
- {
- printf("ninvalid selectionn");
- index = -1;
- return (IFG_OPR_QUIT); /* quit */
- }
- if (index == 0)
- {
- index = -1;
- return (IFG_OPR_QUIT); /* quit */
- }
- index--; /* set to zero based index */
- } /* end query for new network device (1..n) */
- /* return device string and unit number */
- *ifName = (char *)sysNetDevName[sysMacIndex2Dev(index)];
- *unit = sysMacIndex2Unit(index);
- }
- if (macAddressPassed)
- return (IFG_MAC_SUPPLIED);
- return (IFG_DEV_SUPPLIED);
- }
- /***********************************************************
- *
- * dynamicMacAddrGen - Generate a dynamic MAC address
- *
- * This routine generates a 3-byte network interface MAC address.
- * This should be used as the last three bytes of the device address.
- * It attempts to make the address unique, but is not
- * guaranteed to do so.
- *
- * This routine should only be called if both sysNetMacAddrGet()
- * and sysNVRamNetMacAddrGet() return ERROR, indicating that
- * there is no other suitable mechanism for generating a
- * MAC address.
- *
- * RETURNS: 1 for an address which will be reproducible across
- * multiple runs, or 0 if the address is likely to change between
- * vxWorks and bootrom or between two invocations within either vxWorks
- * or bootrom.
- */
- LOCAL int dynamicMacAddrGen
- (
- UINT8 * ifName,
- int ifUnit,
- UINT8 * ifMacAddr
- )
- {
- BOOT_PARAMS params;
- int i = 0;
- UINT32 sum = 0;
- char adrs [BOOT_TARGET_ADDR_LEN];
- /* hash sum of specified interface name */
- while ( EOS != ifName[i] )
- sum += ifName[i++];
- /* check boot command */
- if (usrBootLineCrack (BOOT_LINE_ADRS, ¶ms) == OK)
- {
- if ( ( params.ead[0] != EOS ) && ( params.ead[1] != EOS ) &&
- ( params.ead[2] != EOS ) && ( params.ead[3] != EOS ) &&
- ( params.ead[4] != EOS ) && ( params.ead[5] != EOS ) )
- {
- /* OK, use target address */
- *ifMacAddr++ = params.ead[3] + sum + ifUnit;
- *ifMacAddr++ = params.ead[4];
- *ifMacAddr++ = params.ead[5];
- return(1);
- }
- adrs[0] = params.bad[0] + params.had[0] + params.gad[0];
- adrs[1] = params.bad[1] + params.had[1] + params.gad[1];
- adrs[2] = params.bad[2] + params.had[2] + params.gad[2];
- adrs[3] = params.bad[3] + params.had[3] + params.gad[3];
- adrs[4] = params.bad[4] + params.had[4] + params.gad[4];
- adrs[5] = params.bad[5] + params.had[5] + params.gad[5];
- if ( ( adrs[0] != EOS ) && ( adrs[1] != EOS ) &&
- ( adrs[2] != EOS ) && ( adrs[3] != EOS ) &&
- ( adrs[4] != EOS ) && ( adrs[5] != EOS ) )
- {
- /* use host + gateway + backplane */
- *ifMacAddr++ = adrs[0] + adrs[3] + sum + ifUnit;
- *ifMacAddr++ = adrs[1] + adrs[4];
- *ifMacAddr++ = adrs[2] + adrs[5];
- return(1);
- }
- /* hash some strings together */
- for ( i = 0 ; i < BOOT_DEV_LEN ; i++ )
- sum += params.bootDev[i];
- for ( i = 0 ; i < BOOT_HOST_LEN ; i++ )
- sum += params.hostName[i];
- for ( i = 0 ; i < BOOT_HOST_LEN ; i++ )
- sum += params.targetName[i];
- for ( i = 0 ; i < BOOT_FILE_LEN ; i++ )
- sum += params.bootFile[i];
- for ( i = 0 ; i < BOOT_FILE_LEN ; i++ )
- sum += params.startupScript[i];
- for ( i = 0 ; i < BOOT_USR_LEN ; i++ )
- sum += params.usr[i];
- for ( i = 0 ; i < BOOT_PASSWORD_LEN ; i++ )
- sum += params.passwd[i];
- for ( i = 0 ; i < BOOT_OTHER_LEN ; i++ )
- sum += params.other[i];
- adrs[0] = 0;
- adrs[1] = 4;
- adrs[2] = ( sum >> 24 ) & 0x00ff;
- adrs[3] = ( sum >> 16 ) & 0x00ff;
- adrs[4] = ( sum >> 8 ) & 0x00ff;
- adrs[5] = ( sum >> 0 ) & 0x00ff;
- *ifMacAddr++ = adrs[0] + adrs[3] + sum + ifUnit;
- *ifMacAddr++ = adrs[1] + adrs[4];
- *ifMacAddr++ = adrs[2] + adrs[5];
- return(1);
- }
- /*
- * boot command not available, generate address
- * which is as close to random as we can make it.
- * If we get here, there isn't any reasonable way to
- * make a highly unique number, but we'll do the
- * best we reasonably can.
- *
- * NOTE: This is guaranteed to cause problems when
- * booting, unless rommable vxWorks image is used.
- * If we get here, the vxWorks and bootrom images
- * will use different MAC addresses. When the interface
- * changes, vxWorks will correctly send a gratuitous
- * ARP packet. However, some switches will ignore
- * the gratuitous ARP packet which came so quickly
- * after the vxWorks image download. In this case,
- * the target will be able to send traffic out, but
- * until it has done so, no other computer will be able
- * to contact it. To resolve this problem, the target
- * should initiate outbound IP traffic after a suitable
- * delay. This can be a simple ping, or it can be
- * a symbol table download, or whatever.
- */
- sum += tickGet(); /* time component */
- sum += (int)¶ms; /* stack addr: runtime mem use component */
- sum += (int)ifMacAddr; /* data addr: compile-time component */
- adrs[0] = 0;
- adrs[1] = 4;
- adrs[2] = ( sum >> 24 ) & 0x00ff;
- adrs[3] = ( sum >> 16 ) & 0x00ff;
- adrs[4] = ( sum >> 8 ) & 0x00ff;
- adrs[5] = ( sum >> 0 ) & 0x00ff;
- *ifMacAddr++ = adrs[0] + adrs[3] + ifUnit;
- *ifMacAddr++ = adrs[1] + adrs[4];
- *ifMacAddr++ = adrs[2] + adrs[5];
- return(0);
- }
- /*******************************************************************************
- *
- * sEnet - set the device ethernet address
- * This routine checks the passed boot line to see if it can set the
- * MAC address of the requested device. The command line is parsed to
- * extract device name, unit name, and MAC address. All three items
- * are optional. Example command lines follow:
- *
- * M
- * M motfcc
- * M motfcc1
- * M motfcc1 00:01:00
- * M motfcc0 00:A0:1E:00:01:00
- *
- * The first example will invoke a dialog with the user to display
- * current devices and prompt for which device address to change as below.
- * 0 quit
- * 1 motfcc0 00:A0:1E:00:01:1A
- * 2 motscc0 00:A0:1E:00:01:1B
- * Selection :
- *
- * Once a selection is made, the dialog will contine by quiting the dialog
- * if option zero is slected, or prompting for the MAC address for the
- * selected device as show below.
- *
- * 00- 00
- * A0- A0
- * 1E- 1E
- * 00-
- *
- * The first three bytes of the MAC address are fixed and can't be changed
- * using this method. The remaining three subsequent values will be
- * displayed for modification. If no entry is made, the previous value
- * remains unchanged.
- *
- * If the MAC address read from configuration memory does not include the
- * three byte vendor code, it is assumed that the address read is invalid.
- * In this case, a pseudo-random address is generated before the dialog
- * commences. The address generation algorithm uses a hashing method
- * to generate the address based on the sum of various fixed parameters
- * such as the contents of the boot configuration. This method generates
- * an address that is reproducible, given the same build and boot
- * parameters. If the boot record is not valid, a random address is
- * generated that is not reproducible.
- *
- * The second example shows a method used to avoid the first part of
- * the user dialog. In this case, the device is specified on the
- * command line. Since the unit number is not included, unit zero is
- * assumed. The third example shows the command format that should be
- * used to select other than unit zero.
- *
- * The fourth example shows a method used that avoids the user dialog. In
- * this example, the first three bytes of the MAC address will be the WR
- * vendor code. The remaining three bytes will be as specified on the
- * line. This method requires that exactly three bytes of address be
- * supplied.
- *
- * The last example shows a method that can be used to set all six bytes
- * of the MAC address, including the vendor code. If other than the
- * default WR vendor code, care must be taken when using the command
- * shown in the previous examples. These other forms assume that
- * other vendor codes are not valid and will overwrite.
- *
- *
- * RETURNS: void
- *
- * NOMANUAL
- */
- void sEnet
- (
- char * pNum /* Boot line, including unit number. */
- )
- {
- uchar_t curArr [MAX_ADR_SIZE]; /* array to hold current Enet addr */
- int unitNum;
- char *ifName ="n";
- int ifGetStatus;
- /* identify the network device */
- ifGetStatus = ifGet (&ifName, &unitNum, pNum, curArr);
- if (ifGetStatus == IFG_OPR_QUIT)
- return; /* operator abort */
- if (ifGetStatus == IFG_MAC_SUPPLIED)
- {
- if (sysNetMacAddrSet (ifName, unitNum, curArr, MAC_ADRS_LEN) != OK)
- {
- printf ("** error setting address for %s%dn", ifName, unitNum);
- return;
- }
- }
- else
- {
- mEnet (pNum, unitNum, ifName);
- }
- }
- /*******************************************************************************
- *
- * mEnet - modify the last three bytes of the device ethernet address.
- *
- * This routine is called if the command line lacks a network address
- * for the selected device. It initiates a dialog with the user to
- * obtain the address.
- *
- * RETURNS: void
- *
- * NOMANUAL
- */
- void mEnet
- (
- char * pNum, /* Boot line, including unit number. */
- int unitNum, /* array to hold current Enet addr */
- char *ifName
- )
- {
- uchar_t byte [MAX_ADR_SIZE]; /* array to hold new Enet addr */
- uchar_t curArr [MAX_ADR_SIZE]; /* array to hold current Enet addr */
- char line [MAX_LINE + 1];
- char *pEnet; /* dummy variable */
- int *pOffset = NULL; /* dummy variable */
- char *pLine; /* ptr to current position in line */
- int value; /* value found in line */
- STATUS status;
- char excess;
- int ix;
- /* make sure device is valid */
- if (sysMacOffsetGet (ifName, unitNum, &pEnet, pOffset) != OK)
- {
- printf ("** invalid devicen");
- return;
- }
- /* read current value */
- status = sysNetMacNVRamAddrGet (ifName, unitNum, curArr, MAC_ADRS_LEN);
- /* if at first we don't succeed, try second method */
- if (status !=OK)
- sysNetMacAddrGet (ifName, unitNum, curArr, MAC_ADRS_LEN);
- /* if current MAC address is invalid */
- #if _BYTE_ORDER == _BIG_ENDIAN
- if ((status != OK) ||
- (curArr[0] != ((ENET_DEFAULT & 0x0000ff00) >> 8)) ||
- (curArr[1] != ((ENET_DEFAULT & 0x00ff0000) >> 16)) ||
- (curArr[2] != ((ENET_DEFAULT & 0xff000000) >> 24)))
- {
- curArr[0] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
- curArr[1] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
- curArr[2] = ((ENET_DEFAULT & 0xff000000) >> 24);
- #else /* _BYTE_ORDER == _LITTLE_ENDIAN */
- if ((status != OK) ||
- (curArr[0] != ((ENET_DEFAULT & 0x00ff0000) >> 16)) ||
- (curArr[1] != ((ENET_DEFAULT & 0x0000ff00) >> 8)) ||
- (curArr[2] != ((ENET_DEFAULT & 0x000000ff) )))
- {
- curArr[0] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
- curArr[1] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
- curArr[2] = (ENET_DEFAULT & 0x000000ff);
- #endif /* _BYTE_ORDER == _BIG_ENDIAN */
- ix = dynamicMacAddrGen(ifName, unitNum, &curArr[3]);
- printf ("Mac address for %s%d invalid. ", ifName, unitNum);
- if (ix == 1)
- printf ("Using a reproducible random address.n");
- else
- printf ("Using a non-reproducible random address.n");
- }
- printf ("%s%d current Ethernet Address is: ", ifName, unitNum);
- printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[0],
- curArr[1], curArr[2], curArr[3],
- curArr[4], curArr[5]);
- byte[5] = curArr[5];
- byte[4] = curArr[4];
- byte[3] = curArr[3];
- byte[2] = curArr[2];
- byte[1] = curArr[1];
- byte[0] = curArr[0];
- printf ("Modify only the last 3 bytes (board unique portion) of Ethernet Address.n"
- "The first 3 bytes are fixed at manufacturer's default address block.n");
- for (ix = 0; ix < 3; ix++)
- printf ("%02x- %02xn", byte[ix], byte[ix]);
- /* start on fourth byte of enet addr */
- for (ix = 3; ix < 6; ix++)
- {
- /* prompt for substitution */
- printf ("%02x- ", byte[ix]);
- /* get substitution value:
- * skip empty lines (CR only);
- * quit on end of file or invalid input;
- * otherwise put specified value at address */
- if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
- break;
- line [MAX_ADR_SIZE] = EOS; /* make sure input line has EOS */
- for (pLine = line; isspace ((int) *pLine); ++pLine) /* skip leading spaces*/
- ;
- if (*pLine == EOS) /* skip field if just CR */
- continue;
- if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
- break; /* quit if not number */
- byte[ix] = (uchar_t)value; /* assign new value */
- }
- printf ("n");
- if (sysNetMacAddrSet (ifName, unitNum, byte, MAC_ADRS_LEN) != OK)
- {
- printf ("** error setting address for %s%dn", ifName, unitNum);
- return;
- }
- sysNetMacNVRamAddrGet (ifName, unitNum, byte, MAC_ADRS_LEN);
- printf ("New Ethernet Address is: ");
- for (ix = 0; ix < 5; ix++)
- printf ("%02x:", byte[ix]);
- printf ("%02xn", byte[5]);
- }
- #endif /* ETHERNET_MAC_HANDLER */
- #ifdef ETHERNET_ADR_SET
- /*******************************************************************************
- *
- * mEnet - modify the last three bytes of the ethernet address
- *
- * RETURNS: void
- *
- * NOMANUAL
- */
- void mEnet
- (
- char * pNum /* Boot line, including unit number. */
- )
- {
- uchar_t byte [MAX_ADR_SIZE]; /* array to hold new Enet addr */
- uchar_t curArr [MAX_ADR_SIZE]; /* array to hold current Enet addr */
- char line [MAX_LINE + 1];
- char *pLine; /* ptr to current position in line */
- int value; /* value found in line */
- char excess;
- char *buf;
- int unitNum;
- int ix;
- /* Search for unit number of network device. */
- buf = pNum;
- if (bootScanNum (&buf, &unitNum, FALSE) != OK) /* Use 0 if no unit #. */
- unitNum = 0;
- sysEnetAddrGet (unitNum, curArr);
- printf ("Current Ethernet Address is: ");
- #if _BYTE_ORDER == _BIG_ENDIAN
- printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[5],
- curArr[4], curArr[3], curArr[2],
- curArr[1], curArr[0]);
- byte[0] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
- byte[1] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
- byte[2] = ((ENET_DEFAULT & 0xff000000) >> 24);
- byte[3] = curArr[2];
- byte[4] = curArr[1];
- byte[5] = curArr[0];
- #else /* _BYTE_ORDER == _LITTLE_ENDIAN */
- printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[0],
- curArr[1], curArr[2], curArr[3],
- curArr[4], curArr[5]);
- byte[0] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
- byte[1] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
- byte[2] = (ENET_DEFAULT & 0x000000ff);
- byte[3] = curArr[3];
- byte[4] = curArr[4];
- byte[5] = curArr[5];
- #endif /* _BYTE_ORDER == _BIG_ENDIAN */
- printf ("Modify only the last 3 bytes (board unique portion) of Ethernet Address.n");
- printf ("The first 3 bytes are fixed at manufacturer's default address block.n");
- for (ix = 0; ix < 3; ix++)
- printf ("%02x- %02xn", byte[ix], byte[ix]);
- /* start on fourth byte of enet addr */
- for (ix = 3; ix < 6; ix++)
- {
- /* prompt for substitution */
- printf ("%02x- ", byte[ix]);
- /* get substitution value:
- * skip empty lines (CR only);
- * quit on end of file or invalid input;
- * otherwise put specified value at address */
- if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
- break;
- line [MAX_ADR_SIZE] = EOS; /* make sure input line has EOS */
- for (pLine = line; isspace ((int) *pLine); ++pLine) /* skip leading spaces*/
- ;
- if (*pLine == EOS) /* skip field if just CR */
- continue;
- if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
- break; /* quit if not number */
- byte[ix] = (uchar_t)value; /* assign new value */
- }
- printf ("n");
- sysEnetAddrSet (byte[0], byte[1], byte[2], byte[3], byte[4], byte[5]);
- printf ("New Ethernet Address is: ");
- for (ix = 0; ix < 5; ix++)
- printf ("%02x:", byte[ix]);
- printf ("%02xn", byte[5]);
- }
- #endif /* ETHERNET_ADR_SET */
- #ifdef INCLUDE_VXBUS
- LOCAL void vxbFindHend
- (
- VXB_DEVICE_ID pDev,
- void * pArg
- )
- {
- char devStr[END_NAME_MAX];
- int strSize;
- /* Is there an HEnd in the device name */
- if (strstr (pDev->pName, "HEnd") == NULL)
- return;
- strSize = strlen(pDev->pName)-4; /* truncate HEnd */
- if (vxbDevMethodGet(pDev, (UINT32)&muxDevConnect_desc) != NULL)
- {
- strncpy(devStr,pDev->pName,strSize);
- devStr[strSize]=EOS;
- printf(" %s%d",devStr,pDev->unitNumber);
- }
- }
- #endif /* INCLUDE_VXBUS */
- #endif /* INCLUDE_NETWORK */
- /******************************************************************************
- *
- * usrPccardDevShow - Show PC Card clients
- *
- * This routine shows all PC Card clients of the specified type.
- *
- * RETURNS: OK or ERROR.
- *
- */
- #ifdef INCLUDE_PCCARD
- LOCAL void usrPccardDevShow
- (
- UINT16 type
- )
- {
- CS_CHANDLE client;
- STATUS status;
- CS_CLIENT_INFO info;
- char nameString[80];
- char vendorString[80];
- UINT16 attr = type | CS_CLIENT_TYPE;
- info.nameStringMax = 80;
- info.nameString = nameString;
- info.vendorStringMax = 80;
- info.vendorString = vendorString;
- status = csGetFirstClient (&client, 0, 0, attr);
- while (status != ERROR)
- {
- if (csGetClientInfo (client, &info) == OK)
- printf (" %s", info.nameString);
- status = csGetNextClient (&client, 0, 0, attr);
- }
- }
- #endif /* INCLUDE_PCCARD */
- #if (CPU_FAMILY == MIPS)
- UINT32 mmuMipsTlbVecSize = 0x10;
- UINT32 mmuMipsXtlbVecSize = 0x10;
- /****************************************************************************
- *
- * mmuMipsInitialMemoryMap - dummy function
- *
- * This function is a dummy to prevent the linker from calling in the
- * MIPS mmu library for bootroms.
- *
- * RETURNS: OK always.
- *
- */
- STATUS mmuMipsInitialMemoryMapSet
- (
- UINT nTlbEntries,
- ULONG excTlbPageBaseAddress,
- UINT32 localMemLocalAdrs, /* LOCAL_MEM_LOCAL_ADRS */
- UINT32 memTop /* top of memory */
- )
- {
- return OK;
- }
- /****************************************************************************
- *
- * mmuMipsTlbVec - dummy function
- *
- * This function is a dummy to prevent the linker from calling in the
- * MIPS mmu library for bootroms.
- *
- * RETURNS: OK always.
- *
- */
- VOID mmuMipsTlbVec(void)
- {
- WRS_ASM (".set noat");
- WRS_ASM ("la $26, excStub");
- WRS_ASM ("jr $26");
- WRS_ASM (".set at");
- }
- /****************************************************************************
- *
- * mmuMipsXTlbVec - dummy function
- *
- * This function is a dummy to prevent the linker from calling in the
- * MIPS mmu library for bootroms.
- *
- * RETURNS: OK always.
- *
- */
- VOID mmuMipsXtlbVec(void)
- {
- WRS_ASM (".set noat");
- WRS_ASM ("la $26, excStub");
- WRS_ASM ("jr $26");
- WRS_ASM (".set at");
- }
- #endif /* CPU_FAMILY == MIPS */