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

📄 if_bp.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	 *   arg1 = bus address space	 *   arg2 = address	 *   arg3 = value	 */	    if (sysBusToLocalAdrs (BP_NTOHL(pCpu->cd_intArg1),				   (char *) BP_NTOHL(pCpu->cd_intArg2),				   &pMailbox) == OK)		{#ifdef	UNIX		bpPoke (pMailbox, intType, BP_NTOHL(pCpu->cd_intArg3),			BP_NTOHL(pCpu->cd_cpuNum));#else	/* UNIX */		if (intType == BP_INT_MAILBOX_R1)		    bpBitBucket = * (char *)pMailbox;		else		    *pMailbox = BP_NTOHL(pCpu->cd_intArg3);#endif	/* UNIX */		}	    else		{		logMsg ("bp%d: bpIntGen bad mailbox interrupt, addr space = 0x%x, addr = 0x%x\n",		     pCpu->cd_unit, BP_NTOHL(pCpu->cd_intArg1),		     BP_NTOHL(pCpu->cd_intArg2), 0,0,0);		}	    break;	case BP_INT_MAILBOX_2:	case BP_INT_MAILBOX_R2:	    if (sysBusToLocalAdrs (BP_NTOHL(pCpu->cd_intArg1),				   (char *) BP_NTOHL(pCpu->cd_intArg2),				   &pMailbox) == OK)		{#ifdef	UNIX		bpPoke (pMailbox, intType, BP_NTOHL(pCpu->cd_intArg3),			BP_NTOHL(pCpu->cd_cpuNum));#else	/* UNIX */		if (intType == BP_INT_MAILBOX_R2)		    bpBitBucket = * (short *)pMailbox;		else		    * (short *) pMailbox = BP_NTOHL(pCpu->cd_intArg3);#endif	/* UNIX */		}	    else		{		logMsg (    "bp%d: bpIntGen bad mailbox interrupt, addr space = 0x%x, addr = 0x%x\n",		     pCpu->cd_unit, BP_NTOHL(pCpu->cd_intArg1),		     BP_NTOHL(pCpu->cd_intArg2), 0, 0, 0);		}	    break;	case BP_INT_MAILBOX_4:	case BP_INT_MAILBOX_R4:	    if (sysBusToLocalAdrs (BP_NTOHL(pCpu->cd_intArg1),				   (char *) BP_NTOHL(pCpu->cd_intArg2),				   &pMailbox) == OK)		{#ifdef	UNIX		bpPoke (pMailbox, intType, BP_NTOHL(pCpu->cd_intArg3),			BP_NTOHL(pCpu->cd_cpuNum));#else	/* UNIX */		if (intType == BP_INT_MAILBOX_R4)		    bpBitBucket = * (long *)pMailbox;		else		    * (long *) pMailbox = BP_NTOHL(pCpu->cd_intArg3);#endif	/* UNIX */		}	    else		{		logMsg (    "bp%d: bpIntGen bad mailbox interrupt, addr space = 0x%x, addr = 0x%x\n",		     pCpu->cd_unit, BP_NTOHL(pCpu->cd_intArg1),		     BP_NTOHL(pCpu->cd_intArg2), 0, 0, 0);		}	    break;	case BP_INT_BUS:	/* bus interrupt:	 *   arg1 = level	 *   arg2 = vector	 */#ifndef	UNIX	    if (sysBusIntGen (BP_NTOHL(pCpu->cd_intArg1),			BP_NTOHL(pCpu->cd_intArg2)) == ERROR)		{		logMsg (		"bp%d: bpIntGen interrupt failed (level=%d vector=0x%x)\n",		     pCpu->cd_unit, BP_NTOHL(pCpu->cd_intArg1),		     BP_NTOHL(pCpu->cd_intArg2), 0, 0, 0);		}	    break;#endif	/* UNIX */	/* UNIX drops through */	default:	    logMsg ("bp%d: bpIntGen bad interrupt type: proc = %d, type = %d\n",		     pCpu->cd_unit, BP_NTOHL(pCpu->cd_cpuNum),		     intType, 0, 0, 0);	    break;	}    }#ifdef	UNIX/********************************************************************************* sysBusToLocalAdrs - convert bus address to local address** Given a VME memory address, this routine returns the local address* that would have to be accessed to get to that byte.** RETURNS: OK, or ERROR if the address space is unknown.** SEE ALSO: sysLocalToBusAdrs()** NOMANUAL*/STATUS sysBusToLocalAdrs (adrsSpace, busAdrs, pLocalAdrs)    int adrsSpace;      /* bus address space in which busAdrs resides,     */                        /* use address modifier codes as defined in vme.h, */                        /* such as VME_AM_STD_SUP_DATA                     */    char *busAdrs;      /* bus address to convert                          */    char **pLocalAdrs;  /* where to return local address                   */    {    switch (adrsSpace)        {        case VME_AM_SUP_SHORT_IO:        case VME_AM_USR_SHORT_IO:            *pLocalAdrs = (char *) (0xffff0000 | (int) busAdrs);            return (OK);        case VME_AM_STD_SUP_ASCENDING:        case VME_AM_STD_SUP_PGM:        case VME_AM_STD_SUP_DATA:        case VME_AM_STD_USR_ASCENDING:        case VME_AM_STD_USR_PGM:        case VME_AM_STD_USR_DATA:            *pLocalAdrs = (char *) (0xff000000 | (int) busAdrs);            return (OK);        case VME_AM_EXT_SUP_ASCENDING:        case VME_AM_EXT_SUP_PGM:        case VME_AM_EXT_SUP_DATA:        case VME_AM_EXT_USR_ASCENDING:        case VME_AM_EXT_USR_PGM:        case VME_AM_EXT_USR_DATA:            *pLocalAdrs = busAdrs; /* XXX check if on board memory? */            return (OK);        default:            return (ERROR);        }    }#endif	/* UNIX *//********************************************************************************* bpHeartbeat -*/LOCAL void bpHeartbeat    (    FAST BP_ANCHOR *pAnchor    )    {    pAnchor->an_heartbeat =		(UINT)BP_HTONL((UINT)BP_NTOHL(pAnchor->an_heartbeat) + 1);#ifdef	UNIX    timeout (bpHeartbeat, (caddr_t) pAnchor, bpHeartbeatRate);#else	/* UNIX */    wdStart (pAnchor->an_wdog, bpHeartbeatRate, (FUNCPTR) bpHeartbeat,             (int) pAnchor);#endif	/* UNIX */    }/********************************************************************************* bpSizeMem - size shared memory pool** RETURNS: amount of available memory*/LOCAL int bpSizeMem    (    caddr_t memAdrs,    /* address of start of pool to start probing */    int memSize         /* max size of memory pool */    )    {    FAST int size;    for (size = 0; size < memSize; size += 4096)	{#ifdef	UNIX        if ((*bpProbeType) ((char *)(memAdrs + size), 0) == -1)#else	/* UNIX */	char bitBucket;	if (vxMemProbe (memAdrs + size, bpProbeType, 1, &bitBucket) != OK)#endif	/* UNIX */	    break;	}    if (bpParity)	bzero (memAdrs, memSize);    /* return the amount of memory found */    return (size);    }/********************************************************************************* bpIoctl - process an ioctl request** RETURNS: 0 if successful, errno otherwise (as per network requirements)*/LOCAL int bpIoctl    (    FAST struct ifnet *pIf,    int cmd,    caddr_t data    )    {    int error = 0;    int unit  = pIf->if_unit;    FAST BP_SOFTC *bs = BP_SOFTC_P [unit];    int level = splimp ();    switch (cmd)	{	case SIOCSIFADDR:#ifdef	UNIX            error = set_if_addr (pIf, data, &bs->bs_enaddr);#else	/* UNIX */            ((struct arpcom *)pIf)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (pIf, &IA_SIN (data)->sin_addr);#endif	/* UNIX */	    break;	case SIOCGIFADDR:#ifdef	UNIX	    bcopy ((caddr_t) &bs->bs_enaddr,		  (caddr_t) &((struct ifreq *)data)->ifr_addr.sa_data[0],		  sizeof (struct ether_addr));#else	/* UNIX */	    bcopy ((caddr_t) bs->bs_enaddr,		  (caddr_t) &((struct ifreq *)data)->ifr_addr.sa_data[0],		  6);#endif	/* UNIX */	    break;        case SIOCGIFFLAGS:            *(short *)data = pIf->if_flags;            break;        case SIOCSIFFLAGS:            {            short flags = *(short *)data;            /* Sanity check - make sure IFF_RUNNING and IFF_UP flags match. */                          if (pIf->if_flags & IFF_UP)                flags |= (IFF_UP|IFF_RUNNING);            else                flags &= ~(IFF_UP|IFF_RUNNING);            pIf->if_flags = flags;	    }	break;	default:	    printf ("bp%d: ioctl 0x%x not implemented\n", unit, cmd);	    error = EINVAL;	    break;	}    (void) splx (level);    return (error);    }/********************************************************************************* ringinit -** Initialize the ring pointed to by "rp" to contain "size" slots.* The ring is set up to be empty and unlocked.* Size had better be a power of 2!*/LOCAL void ringinit    (    FAST RING *rp,    short size    )    {    rp->r_tas = rp->r_rdidx = rp->r_wrtidx = 0;    rp->r_size = BP_HTONS(size);    }/********************************************************************************* ringput -** Add a new entry "v" to the ring "rp".* Returns 0 if ring was full, else the new number of entries in the ring.* Uses test-and-set routine, allowing multi-processor interlocked access* to the ring IF the ring is in VME memory.* Masks all interrupts, in order to prevent reentrancy and to* minimize ring lockout.** RETURNS: new number of entries, or 0 if ring was full*/LOCAL int ringput    (    FAST RING *rp,    int v    )    {    FAST int x = DELAY_COUNT;	/* don't wait forever for lock */    FAST int s;    for (;;)	{	/* disable interrupts, then lock the ring */	s = intLock ();	if (TAS(&rp->r_tas))	    break;	intUnlock (s);	if (--x == 0)	    return (0);	/* ring is stuck! */	}    if ((x = (BP_NTOHS(rp->r_wrtidx) + 1) &	    (BP_NTOHS(rp->r_size) - 1)) != BP_NTOHS(rp->r_rdidx))	{	rp->r_slot[BP_NTOHS(rp->r_wrtidx)] = v;	rp->r_wrtidx = BP_HTONS(x);	}			/* if x == rdidx then ring is full */    if ((x -= BP_NTOHS(rp->r_rdidx)) < 0)	x += BP_NTOHS(rp->r_size);#if     (CPU_FAMILY==MIPS)    TAS_CLEAR(rp->r_tas);               /* unlock ring */#else   /* CPU_FAMILY==MIPS */    rp->r_tas = 0;                      /* unlock ring */#endif  /* CPU_FAMILY==MIPS */    intUnlock (s);    return (x);    }/********************************************************************************* ringget -** Extract next entry from the ring "rp".* Uses test-and-set routine, allowing multi-processor interlocked access* to the ring IF the ring is in VME memory.* Masks all interrupts, in order to prevent reentrancy and to* minimize ring lockout.** RETURNS: 0 if ring is empty, else the extracted entry*/LOCAL int ringget    (    FAST RING *rp    )    {    FAST int x = DELAY_COUNT;	/* don't wait forever for lock */    FAST int s;    for (;;)	{	/* disable interrupts, then lock the ring */	s = intLock ();	if (TAS(&rp->r_tas))	    break;	intUnlock (s);	if (--x == 0)	    return (0);	/* ring is stuck! */	}    if (rp->r_rdidx != rp->r_wrtidx)	{	x = rp->r_slot[BP_NTOHS(rp->r_rdidx)];	rp->r_rdidx = BP_HTONS(		(BP_NTOHS(rp->r_rdidx) + 1) & (BP_NTOHS(rp->r_size) - 1));	}    else	x = 0;#if     (CPU_FAMILY==MIPS)    TAS_CLEAR(rp->r_tas);               /* unlock ring */#else   /* CPU_FAMILY==MIPS */    rp->r_tas = 0;                      /* unlock ring */#endif  /* CPU_FAMILY==MIPS */    intUnlock (s);    return (x);    }/******************************************************************************** ringcount - get number of entries in ring*/LOCAL int ringcount    (    FAST RING *pRing    )    {    int n = BP_NTOHS(pRing->r_wrtidx) - BP_NTOHS(pRing->r_rdidx);    if (n < 0)	n += BP_NTOHS(pRing->r_size);    return (n);    }/********************************************************************************* vxTasac - test-and-set-and-check** This routine provides quick and dirty test and set when hardware isn't up to* the tas.** RETURNS:*   TRUE if value had been not set (but now is),*   FALSE if value was already set.*/LOCAL BOOL vxTasac    (    FAST char *address          /* address to be tested */    )    {    FAST int tasWait = 10;    FAST int count;    FAST int value = 0x80 + sysProcNumGet ();    int oldLevel = intLock ();    /* check for lock available */    if (*address != 0)        {        intUnlock (oldLevel);        return (FALSE);        }    /* lock available - take it */    *address = value;    /* check that we got it and nobody stepped on it, several times */    for (count = 0; count < tasWait; count++)        {        if (* (unsigned char *) address != value)            {            intUnlock (oldLevel);            return (FALSE);            }        }    intUnlock (oldLevel);    return (TRUE);    }/********************************************************************************* bpShow - display information about the backplane network** This routine shows information about the different CPUs configured* in the backplane network.** EXAMPLE* .CS*     -> bpShow*     Anchor at 0x800000*     heartbeat = 705, header at 0x800010, free pkts = 237.**     cpu int type    arg1       arg2     

⌨️ 快捷键说明

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