⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysln97xend.c

📁 VxWorks的bootloader实现
💻 C
字号:
/* sysLn97xEnd.c - system configuration module for ln97xEnd */ /* Copyright 1984 - 1999 Wind River Systems, Inc. */ /*modification history--------------------01b,07mar02,kab  SPR 70817: *EndLoad returns NULL on failure01a,10oct99,mtl   written from yk 750 by teamF1*//*DESCRIPTIONThis is the WRS-supplied configuration module for the VxWorks ln97xEnd (lnPci) END driver.  It performs the dynamic parameterization of the ln97xEnd driver.  This technique of 'just-in-time' parameterization allows driver parameter values to be declared as any other defined constants rather than as static strings. */ /* includes */#if (defined (INCLUDE_LN_97X_END) && defined (INCLUDE_NETWORK) \     && defined (INCLUDE_END))#include "vxWorks.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "end.h"#include "config.h"#include "drv/end/ln97xEnd.h"  /* defines */ /* AMD 7997x 10/100Base-TX Board type */ #define LN_TYPE_970             1 /* AMD 97c970 PCI Ethernet PCNet */#define LN_TYPE_971             2 /* AMD 97c970 PCI Ethernet PCNet Fast */#define LN_TYPE_972             3 /* AMD 97c970 PCI Ethernet PCNet Fast+ */#define LN_TYPE_7990            4 #define LN97X_MAX_UNITS         4 /* number of board types */ /* LN970 driver user flags */ #define LN_USR_FLAGS_970        0#define LN_USR_FLAGS_971        0#define LN_USR_FLAGS_972        0#define LN_USR_FLAGS_7990       0 /* PCI vendor/device Ids and rev mask */ #define LN97X_PCI_VENDOR_ID     0x1022  /* AMD */#define LN97X_PCI_DEVICE_ID     0x2000  /* PCI device ID */#define LN7990_PCI_DEVICE_ID    0x0000  /* PCI device ID */#define LN970_PCI_REV_MASK      0x10    /* 79970 pci rev mask */#define LN971_PCI_REV_MASK      0x20    /* 79971 pci rev mask */#define LN972_PCI_REV_MASK      0x30    /* 79972 pci rev mask */#define LN97X_CSR3_VALUE        0       /* csr3 value */ /* * default values if PCI_CFG_TYPE defined to be PCI_CFG_FORCE * note: memory addresses must be aligned on MMU page boundaries */ #define LN97X_IO_ADR0           0xf400#define LN97X_MEM_ADR0          0xfd000000#define LN97X_INT_LVL0          0x03#define LN97X_INT_VEC0          0x03 #define LN97X_IO_ADR1           0xf420#define LN97X_MEM_ADR1          0xfd200000#define LN97X_INT_LVL1          0x02#define LN97X_INT_VEC1          0x02 #define LN97X_IO_ADR2           0xf440#define LN97X_MEM_ADR2          0xfd300000#define LN97X_INT_LVL2          0x01#define LN97X_INT_VEC2          0x01 #define LN97X_IO_ADR3           0xf460#define LN97X_MEM_ADR3          0xfd400000#define LN97X_INT_LVL3          0x0#define LN97X_INT_VEC3          0 #define LN97X_MAX_DEV           4 #define NET_END_USER_FLAGS      LN_USR_FLAGS_972#define NET_ADAPTER_VENDOR_ID   LN97X_PCI_VENDOR_ID#define NET_ADAPTER_DEVICE_ID   LN97X_PCI_DEVICE_ID #define LN_97X_LOAD_FUNC        ln97xEndLoad /* externs */IMPORT END_OBJ* ln97xEndLoad (char *);/* typedefs */ typedef struct ln97xPciRsrc             /* LN97X_PCI_RSRC */    {    UINT32      iobaseCsr;              /* Base Address Register 0 */    UINT32      membaseCsr;             /* Base Address Register 1 */    char        irq;                    /* Interrupt Request Level */    UINT32      irqvec;                 /* Interrupt Request vector */    UINT32      configType;             /* type of configuration */    UINT32      boardType;              /* type of LAN board this unit is */    UINT32      pciBus;                 /* PCI Bus number */    UINT32      pciDevice;              /* PCI Device number */    UINT32      pciFunc;                /* PCI Function number */    } LN97X_PCI_RSRC; typedef struct boardResource            /* LN97X_BRD_RSRC */    {    UINT32      type;                   /* type of the board */    UINT32      vendorId;               /* Vendor ID */    UINT32      deviceId;               /* Device ID */    UINT32      lnUsrFlags;             /* LN driver user flags */    FUNCPTR     mediaSelectFunc;        /* media select routine */    } LN97X_BRD_RSRC; /* locals */LOCAL     int                 ln97XUnits = 0;LOCAL     LN97X_PCI_RSRC *    pRsrc;          /* pointer board resources */ /* * This array defines the board-specific PCI resources, the base address * register configuration mode and the Ethernet adapter type. It's indexed * using the device number returned from pciFindDevice(). */ LOCAL LN97X_PCI_RSRC ln97xPciRsrcs [LN97X_MAX_DEV] =    {    {LN97X_IO_ADR0, LN97X_MEM_ADR0, LN97X_INT_LVL0, LN97X_INT_VEC0,          PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0},    {LN97X_IO_ADR1, LN97X_MEM_ADR1, LN97X_INT_LVL1, LN97X_INT_VEC1,          PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0},    {LN97X_IO_ADR2, LN97X_MEM_ADR2, LN97X_INT_LVL2, LN97X_INT_VEC2,          PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0},    {LN97X_IO_ADR3, LN97X_MEM_ADR3, LN97X_INT_LVL3, LN97X_INT_VEC3,          PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0},    }; /* * This array defines board-specific vendor and device ids, flags to pass to * the drive load routine and the function used to select the media. */ LOCAL LN97X_BRD_RSRC ln97xBrdRsrc [LN97X_MAX_UNITS] =    {    {LN_TYPE_970, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_970,     NULL},    {LN_TYPE_971, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_971,     NULL},    {LN_TYPE_972, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_972,     NULL},    {LN_TYPE_7990, LN97X_PCI_VENDOR_ID, LN7990_PCI_DEVICE_ID,     LN_USR_FLAGS_7990, NULL},    };/******************************************************************************** sysLn97xEndLoad - load and create load string, for a ln97x (lnPci) device.** This routine loads the lnPci device with initial parameters. ** RETURNS: pointer to END object or NULL.** SEE ALSO: ln97xEndLoad()*/ END_OBJ * sysLn97xEndLoad    (    char * pParamStr,   /* ptr to initialization parameter string */    void * unused       /* unused optional argument */    )    {    /*     * The ln97xEnd driver END_LOAD_STRING should be:     * <unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecNum>:<intLvl>:<memAdrs>:     * <memSize>:<memWidth>:<csr3b>:<offset>:<flags>     *     * Note that ln97xEnd unit number is prepended in muxDevLoad, so we      * don't put it here!     */    char * cp; 			    char paramStr [END_INIT_STR_MAX];   /* from end.h */    END_OBJ * pEnd;    static char ln97xParamTemplate[] = 			"0x%x:0x%x:0x%x:%d:%d:-1:-1:-1:0x%x:%d:0x%x";    if (strlen (pParamStr) == 0)        {        /*          * muxDevLoad() calls us twice.  If the string is         * zero length, then this is the first time through         * this routine, so we just return.         */        pEnd = ln97xEndLoad (pParamStr);        }    else	{        /*         * On the second pass though here, we actually create          * the initialization parameter string on the fly.            * Note that we will be handed our unit number on the          * second pass through and we need to preserve that information.         * So we use the unit number handed from the input string.         */        cp = strcpy (paramStr, pParamStr); /* cp points to paramStr */        /* Now, we advance cp, by finding the end the string */        cp += strlen (paramStr);                /* finish off the initialization parameter string */	sprintf (cp, ln97xParamTemplate,                      /* device memory Io base */                     (UINT) PCI_MEMIO2LOCAL (pRsrc->membaseCsr),                      /* device Io base */                     (UINT) PCI_IO2LOCAL (pRsrc->iobaseCsr),                      (UINT) PCI_SLV_MEM_LOCAL,         /* pciMemBase */                     pRsrc->irqvec,             /* interrupt IRQ vector */                     pRsrc->irq,                /* interrupt irq number */                     LN97X_CSR3_VALUE,          /* csr3 register value */                     0,                         /* offset */                     NET_END_USER_FLAGS         /* flags */                     );        if ((pEnd = ln97xEndLoad (paramStr)) == (END_OBJ *)NULL)	    {            printf ("Error: device failed ln97xEndLoad routine.\n");	    }	}    return (pEnd);    } /********************************************************************************* sysLan97xPciInit - prepare LAN adapter for LN97X initialization** This routine finds out the PCI device, maps its memory and IO address.* It must be done prior to initializing the LN970, sysLn97XInit().  Also* must be done prior to MMU initialization, usrMmuInit().** RETURNS: OK/ERROR*/ STATUS sysLan97xPciInit (void)    {    UINT32              membaseCsr;    UINT32              iobaseCsr;    char                irq;    int                 pciBus;    int                 pciDevice;    int                 pciFunc;    int                 unit;    int                 found = 0;     /* for all the support lan devices find if some of them exist */     for (unit = 0; unit < LN97X_MAX_UNITS; unit++)        {        if (pciFindDevice (ln97xBrdRsrc [unit].vendorId,                           ln97xBrdRsrc [unit].deviceId,                           unit, &pciBus, &pciDevice, &pciFunc) == OK)            {             /* board detected */             /* for now, we're ignoring the possibility of duplicates */             found = TRUE;              /* load up the PCI device table */              pRsrc = ln97xPciRsrcs + ln97XUnits; /* get the pci entry */              pRsrc->pciBus    = pciBus;             pRsrc->pciDevice = pciDevice;             pRsrc->pciFunc   = pciFunc;              ln97XUnits++;      /* number of units found */             }        }     if ((found != TRUE) || (pciDevice > PCI_MAX_DEV))        return (ERROR);     /* Now initialize all the units we found */     for (unit = 0; unit < ln97XUnits; unit++)        {        /* Fill in the resource entry */         pRsrc = ln97xPciRsrcs + unit;         if (pRsrc->configType == PCI_CFG_FORCE)            {            /* write the iobase, membase, and irq */             pciConfigOutLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                              PCI_CFG_BASE_ADDRESS_0, pRsrc->iobaseCsr |                             PCI_BASE_IO);            pciConfigOutLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                              PCI_CFG_BASE_ADDRESS_1, pRsrc->membaseCsr);            pciConfigOutByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                              PCI_CFG_DEV_INT_LINE, pRsrc->irq);            }         /*         * get memory base address and IO base address         * Note: we read it in again, even if we just wrote it out because the         * device can change what we wrote         */         pciConfigInLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                         PCI_CFG_BASE_ADDRESS_0, &iobaseCsr);        pciConfigInLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                         PCI_CFG_BASE_ADDRESS_1, &membaseCsr);        pciConfigInByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                         PCI_CFG_DEV_INT_LINE, &irq);         /*         * mask off registers. IO base needs to be masked off because bit0         * will always be set to 1         */         membaseCsr   &= PCI_MEMBASE_MASK;        iobaseCsr    &= PCI_IOBASE_MASK;        /* over write the resource table with values read */         pRsrc->membaseCsr   = membaseCsr;        pRsrc->iobaseCsr    = iobaseCsr;        pRsrc->irq          = irq;        pRsrc->irqvec       = IVEC_TO_INUM(irq);         /* enable mapped memory and IO addresses */         pciConfigOutWord (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                          PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE |                          PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE);         /* disable sleep mode */         pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_MODE,                          SLEEP_MODE_DIS);        }     return (OK);    }/********************************************************************************* sysLan97xIntEnable - enable Lan97x interrupts** This routine enables ln7997x interrupts.  This may involve operations on* interrupt control hardware.** RETURNS: OK or ERROR for invalid arguments.*/ STATUS sysLan97xIntEnable    (    int level           /* level number */    )    {    return (intEnable (level));    } /********************************************************************************* sysLan97xIntDisable - disable ln970 interrupts** This routine disables ln970 interrupts.  This may involve operations on* interrupt control hardware.** RETURNS: OK or ERROR for invalid arguments.*/ STATUS sysLan97xIntDisable    (    int level           /* level number */    )    {    return (intDisable(level));    } /********************************************************************************* sysLan97xEnetAddrGet - get Ethernet address** This routine provides a target-specific interface for accessing a* device Ethernet address.** -- Specific to 971 ldt** RETURNS: OK or ERROR if could not be obtained.*/ STATUS sysLan97xEnetAddrGet    (    LN_97X_DRV_CTRL *  pDrvCtrl,   /* Driver control */    char *             enetAdrs    )    {    char        aprom [LN_97X_APROM_SIZE]; /* copy of address prom space */    char *      ioaddr;    int         ix;     /* get IO address of unit */    ioaddr = (char *)(pDrvCtrl->devAdrs);     /* load aprom into an array */    for (ix=0; ix<32; ix++)        {        aprom [ix] = sysInByte((int)(ioaddr + ix));        }     /* check for 'w's at end of list */    if ((aprom [0xe] != 'W') || (aprom [0xf] != 'W'))        {        /* should set errno here ? ldt */        logMsg ("sysLn97XEnetAddrGet W's not stored in aprom\n",                0, 1, 2, 3, 4, 5);        return ERROR;        }     bcopy (aprom, enetAdrs, 6);     return (OK);    }#endif /* defined (INCLUDE_LN_97X_END) && defined (INCLUDE_NETWORK) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -