📄 smnetlib.c
字号:
/* smNetLib.c - VxWorks interface to shared memory network (backplane) driver*//* Copyright 1984-2002 Wind River Systems, Inc. *//*modification history--------------------01v,05apr02,mas added volatile pointers and bridge flushing reads (SPRs 68334, 68844)01u,13feb02,mas fixed staged delay/check for slave node startup (SPR 73163)01t,24oct01,mas fixed diab warnings (SPR 71120); doc update (SPR 71149)01s,02oct01,mas added staged delay/check for slave node startup in new smNetAttach2() routine (SPR 4547)01r,15may95,vin fixed parameter to build_cluster().01q,30sep93,rrr Added missing 01p modhist.01p,30sep93,rrr Fixed smNetIntr from using an uninialized variable if intType==SM_INT_BUS.01o,21nov92,jdi documentation cleanup.01n,13oct92,jcf added a hack to protect from bus error during attach.01m,20oct92,pme made smNetInit return ERROR instead of disabling data cache if cache coherent buffer cannot be allocated.01l,09sep92,gae doc tweaks.01k,31jul92,dnw Changed to new cacheLib.01j,27jul92,elh Moved smNetShow to smNetShow.c01i,26jul92,gae fixed number of parameters to logMsg().01h,24jul92,elh added caching, ripple effect of moving heartbeat.01g,15jun92,elh changed parameter to smNetInetGet.01f,02jun92,elh the tree shuffle -changed includes to have absolute path from h/01e,27may92,elh Incorperated the changes caused from restructuring the shared memory libraries.01d,17may92,elh renamed from smVxLib to smNetLib01c,01may92,elh added mask, if_resolve hook and smNetAddrResolve.01b,12apr92,elh added support for sequential addressing.01a,17nov90,elh written.*//*DESCRIPTIONThis library implements the VxWorks-specific portions of the shared memorynetwork interface driver. It provides the interface between VxWorks andthe network driver modules (e.g., how the OS initializes and attachesthe driver, interrupt handling, etc.), as well as VxWorks-dependentsystem calls. There are no user-callable routines.The backplane master initializes the backplane shared memory and networkstructures by first calling smNetInit(). Once the backplane has beeninitialized, all processors can be attached to the shared memory network viathe smNetAttach() routine. Both smNetInit() and smNetAttach() are calledautomatically during system initialization when backplane parameters arespecified in the boot line.For detailed information refer to \tb VxWorks Network Programmer's Guide: Data Link Layer Network Compnents.INTERNALThis file used to correspond to the smNetLib for SunOS. SunOS is no longersupported. The smNetInetGet() routine gets the Internet address associated with abackplane interface.Refer to if_sm.c for more information about the layering of backplane modules.INCLUDE FILES: smNetLib.h, smPktLib.h, smUtilLib.hSEE ALSO: ifLib, if_sm,\tb VxWorks Network Programmer's GuideNOROUTINES*//* includes */#include "vxWorks.h"#include "net/if.h"#include "netinet/if_ether.h"#include "net/mbuf.h"#include "arpLib.h"#include "wdLib.h"#include "sysLib.h"#include "iv.h"#include "vxLib.h"#include "taskLib.h"#include "stdlib.h"#include "intLib.h"#include "stdio.h"#include "logLib.h"#include "netLib.h"#include "cacheLib.h"#include "drv/netif/if_sm.h"#include "drv/netif/smNetLib.h"#include "smPktLib.h"#include "smUtilLib.h"/* globals */int smNetVerbose = FALSE; /* debug aide */int smNetMaxBytesDefault = DEFAULT_PKT_SIZE; /* packet size */int smNetLoanNum = 0; /* buffers to loan */SM_SOFTC * sm_softc [NSM] = { NULL }; /* soft_c structures *//* forward declarations */LOCAL STATUS smNetAddrResolve (struct ifnet * pIf, struct in_addr * pIpDest, u_char * pHwDest, int * usetrailers);LOCAL void smNetIntr (int intType);LOCAL void smNetPulse (SM_PKT_MEM_HDR * pSmPktHdr);LOCAL STATUS smNetProbe ( void * ptr, /* location to probe */ UINT maxTicsWait, /* max system clock ticks period to wait */ BOOL tstEqVal, /* TRUE: test probe value == val */ int val /* specific value for operation */ );/* externs */IMPORT void if_dettach (struct ifnet *);/******************************************************************************** smNetInit - initialize the shared memory network driver** This routine is called once by the backplane master. It sets up and * initializes the shared memory region of the shared memory network and * starts the shared memory heartbeat. ** The <pAnchor> parameter is the local memory address by which the master* CPU accesses the shared memory anchor. <pMem> contains either the local* address of shared memory or the value NONE (-1), which implies that shared* memory is to be allocated dynamically. <memSize> is the size, in bytes,* of the shared memory region.** The <tasType> parameter specifies the test-and-set operation to be used to* obtain exclusive access to the shared data structures. It is preferable* to use a genuine test-and-set instruction, if the hardware permits it. In* this case, <tasType> should be SM_TAS_HARD. If any of the CPUs on the* backplane network do not support the test-and-set instruction, <tasType>* should be SM_TAS_SOFT.** The <maxCpus> parameter specifies the maximum number of CPUs that may* use the shared memory region.** The <maxPktBytes> parameter specifies the size, in bytes, of the data* buffer in shared memory packets. This is the largest amount of data* that may be sent in a single packet. If this value is not an exact* multiple of 4 bytes, it will be rounded up to the next multiple of 4.** The <startAddr> parameter is only applicable if sequential addressing is* desired. If <startAddr> is non-zero, it specifies the starting address to* use for sequential addressing on the backplane. If <startAddr> is zero,* sequential addressing is disabled.** RETURNS: OK, or ERROR if the shared memory network cannot be initialized.** NOMANUAL*/STATUS smNetInit ( SM_ANCHOR * pAnchor, /* local addr of anchor */ char * pMem, /* local addr of shared memory */ int memSize, /* size of shared memory */ BOOL tasType, /* TRUE = hardware supports TAS */ int cpuMax, /* max numbers of cpus */ int maxPktBytes, /* size of data packets */ u_long startAddr /* beginning address */ ) { SM_ANCHOR volatile * pAnchorv = (SM_ANCHOR volatile *) pAnchor; SM_PKT_MEM_HDR volatile * pSmPktHdr; /* packet header */ WDOG_ID beatWd; BOOL malloced = FALSE; /* malloced memory here! */ /* validate parameters */ if ((pAnchor == NULL) || (pMem == NULL)) { logMsg ("smNetInit: invalid %s\n", (pAnchor == NULL) ? (int) "pAnchor" : (int) "pMem", 0, 0, 0, 0, 0); return (ERROR); } if (sysProcNumGet () != SM_MASTER) { logMsg ("smNetInit:called by cpu [%d] non-master\n", sysProcNumGet(), 0, 0, 0, 0, 0); return (ERROR); } maxPktBytes = (maxPktBytes == 0) ? smNetMaxBytesDefault : maxPktBytes; if ((startAddr != 0) && (smNetVerbose)) logMsg ("smNetInit:sequential addressing activated (0x%x) \n", startAddr, 0, 0, 0, 0, 0); if (pMem == (char *) NONE) /* allocate the shared memory */ { if (!CACHE_DMA_IS_WRITE_COHERENT () || !CACHE_DMA_IS_READ_COHERENT ()) { logMsg ("smNetInit - cache coherent buffer not available. Giving up. \n", 0, 0, 0, 0, 0, 0); return (ERROR); } if ((pMem = (char *) cacheDmaMalloc (memSize)) == NULL) return (ERROR); malloced = TRUE; } else { if (pMem == (char *) pAnchor) { pMem += sizeof (SM_ANCHOR); memSize -= sizeof (SM_ANCHOR); } } if (smNetVerbose) logMsg ("smNetInit: anchor:[0x%x] memory:[0x%x] size:%d \n", (int) pAnchor, (int) pMem, memSize, 0, 0, 0); /* set up shared memory region */ if ((smPktSetup (pAnchor, pMem, memSize, tasType, cpuMax, maxPktBytes + SIZEOF_ETHERHEADER) == OK) && ((beatWd = wdCreate ()) != NULL)) { pSmPktHdr = SM_OFFSET_TO_LOCAL(ntohl (pAnchorv->smPktHeader), (int)pAnchor, SM_PKT_MEM_HDR volatile *); pSmPktHdr->reserved1 = htonl (startAddr); pSmPktHdr->reserved2 = (int) beatWd; CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ maxPktBytes = pSmPktHdr->maxPktBytes; /* BRIDGE FLUSH [SPR 68334] */ /* start heartbeat */ smNetPulse ((SM_PKT_MEM_HDR *)pSmPktHdr); return (OK); } if (malloced) (void) free (pMem); return (ERROR); }/******************************************************************************** smNetAttach2 - attach the shared memory network interface** This routine attaches the shared memory interface to the network. It is* called once by each CPU on the shared memory network. The <unit> parameter* specifies the backplane unit number.** The <pAnchor> parameter is the local address by which the local CPU may* access the shared memory anchor.** The <maxInputPkts> parameter specifies the maximum number of incoming* shared memory packets which may be queued to this CPU at one time.** The <intType>, <intArg1>, <intArg2>, and <intArg3> parameters allow a* CPU to announce the method by which it is to be notified of input packets* which have been queued to it.** The <masterCpu> parameter specifies the CPU number of the shared memory* master node.** The <maxTicsWait> parameter sets the maximum wait interval allowed during* probing of shared memory locations prior to attaching. If equal to zero,* a default value of 3000 is used.** RETURNS: OK, or ERROR if the shared memory interface cannot be attached.** INTERNAL* The delayed start for slave processors used below is required. The anchor* may not yet be mapped to the bus. So, probing of shared memory locations is* used to overcome Bus Errors which occur on many boards if the slave accesses* shared memory (SM) before the master has finished initializing it. The code* here simply delays access to the SM region until the SM master has finished* initializing it.** The method used is to repetitively probe key locations in the SM region* after delay periods until valid values are detected or a time-out occurs.* The initial delay period is set based on processor number. (The master* processor does not delay.) If the first probe of a location fails, an* exponential increase in delay period is used to reduce bus contention on* subsequent probes.** This method is no better than receiving raw BERRs and does reduce bus* contention and the number of BERRs.** NOMANUAL*/STATUS smNetAttach2 ( int unit, /* interface unit number */ SM_ANCHOR * pAnchor, /* addr of anchor */ int maxInputPkts, /* max queued packets */ int intType, /* interrupt method */ int intArg1, /* interrupt argument #1 */ int intArg2, /* interrupt argument #2 */ int intArg3, /* interrupt argument #3 */ int masterCpu, /* master CPU number */ int maxTicsWait /* max clock ticks to wait */ ) { SM_SOFTC * xs; /* softc pointer */ SM_ANCHOR volatile * pAnchorv = (SM_ANCHOR volatile *) pAnchor; SM_PKT_MEM_HDR volatile * pSmPktHdr; /* SM packet header */ SM_PKT_CPU_DESC volatile * pPktCpuDesc; int tmp; /* temp storage */ BOOL cont = FALSE; if (unit >= NSM) { return (ERROR); } if ((xs = (SM_SOFTC *) calloc (sizeof (SM_SOFTC), 1)) == NULL) { return (ERROR); } if (maxTicsWait == 0) { maxTicsWait = 3000; } sm_softc [unit] = xs; if (smIfAttach (unit, pAnchor, maxInputPkts, intType, intArg1, intArg2, intArg3, sysClkRateGet (), smNetLoanNum) == OK) { /* * If we are on master CPU, do not delay in probing shared memory, * else, use delayed probe of key locations to wait for master to * finish initialization of shared memory. Slaves must wait because * all subsequent steps assume that the master has completed its * initialization of shared memory. */ if (smUtilProcNumGet () != masterCpu) { /* First wait for valid anchor region */ if (smNetProbe (pAnchor, maxTicsWait, TRUE, SM_READY) == ERROR) { printf ("smNetAttach2: Error: SM probe 1 time out\n"); } /* Now wait for valid SM packet memory header area */ else if (smNetProbe ((void *)&pAnchorv->smPktHeader, maxTicsWait, FALSE, 0) == ERROR) { printf ("smNetAttach2: Error: SM probe 2 time out\n"); } /* * Wait for master to finish initializing packet memory header * before continuing. */ else if (((pSmPktHdr = SM_OFFSET_TO_LOCAL (ntohl (pAnchorv->smPktHeader), (unsigned)pAnchor, SM_PKT_MEM_HDR volatile *)) == NULL) || (smNetProbe ((void *)&pSmPktHdr->pktCpuTbl, maxTicsWait, FALSE, 0) != OK)) { printf ("smNetAttach2: Error: SM probe 3 time out\n"); } /* Finally, wait for master to attach to SM backplane network */ else if (((pPktCpuDesc = SM_OFFSET_TO_LOCAL (ntohl (pSmPktHdr->pktCpuTbl), (unsigned)pAnchor, SM_PKT_CPU_DESC volatile *))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -