📄 if_bp.c
字号:
* 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 + -