📄 usrsmobj.c
字号:
/* usrSmObj.c - shared memory object initialization *//* Copyright 1992-2002 Wind River Systems, Inc. *//*modification history--------------------01e,13feb02,mas fixed staged delay/check for slave node startup (SPR 73189)01d,02oct01,mas added staged delay/check for slave node startup (SPR 62128)01c,13sep01,jws fix smObjSpinTries initialization (SPR68418)01b,20jan99,scb modified to use "sm=" before SM_ANCHOR_ADRS (23035)01a,16feb97,ms based on old 01i version.*//*DESCRIPTIONThis file is used to configure and initialize the VxWorks shared memoryobject support. This file is included by usrConfig.c.SEE ALSO: usrExtra.cNOMANUAL*//******************************************************************************** usrSmObjInit - initialize shared memory objects** This routine initializes the shared memory objects facility. It sets up* the shared memory objects facility if called from processor 0.* Then it initializes a shared memory descriptor and calls smObjAttach()* to attach this CPU to the shared memory object facility.** When the shared memory pool resides on the local CPU dual ported memory,* SM_OBJ_MEM_ADRS must be set to NONE in configAll.h and the shared memory* objects pool is allocated from the VxWorks system pool.** RETURNS: OK, or ERROR if unsuccessful.** 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 usrSmObjInit ( char * bootString /* boot parameter string */ ) { char * smAnchor; /* anchor address */ char * smObjFreeAdrs; /* free pool address */ int smObjMemSize; /* pool size */ BOOT_PARAMS params; /* boot paramters */ BOOL allocatedPool; /* TRUE if pool is maloced */ SM_OBJ_PARAMS smObjParams; /* smObj setup parameters */ char bb; /* bit bucket for vxMemProbe */ int tics; /* SM probe delay period */ UINT temp; /* temp for smUtilMemProbe() */ UINT maxWait = SM_MAX_WAIT; char * cp; SM_OBJ_MEM_HDR * pSmObjHdr = NULL; /* ptr to SMO header */ allocatedPool = FALSE; /* Check for hardware test and set availability */ if (SM_TAS_TYPE != SM_TAS_HARD) { printf ("\nError initializing shared memory objects, "); printf ("hardware test-and-set required.\n"); return (ERROR); } if (smObjLibInit () == ERROR) /* initialize shared memory objects */ { printf("\nERROR smObjLibInit : shared memory objects already initialized.\n"); return (ERROR); } if (bootString == NULL) bootString = BOOT_LINE_ADRS; /* interpret boot command */ if (usrBootLineCrack (bootString, ¶ms) != OK) return (ERROR); /* set processor number: may establish vme bus access, etc. */ if (_procNumWasSet != TRUE) { sysProcNumSet (params.procNum); _procNumWasSet = TRUE; } /* if we booted via the sm device use the same anchor address for smObj */ if (strncmp (params.bootDev, "sm=", 3) == 0) { if (bootBpAnchorExtract (params.bootDev, &smAnchor) < 0) { printf ("\nError initializing shared memory objects, invalid "); printf ("anchor address specified: \"%s\"\n", params.bootDev); return (ERROR); } } else { smAnchor = (char *) SM_ANCHOR_ADRS; /* default anchor */ } /* If we are shared memory master CPU, set up shared memory object (SMO) */ if (params.procNum == SM_MASTER) { smObjFreeAdrs = (char *) SM_OBJ_MEM_ADRS; smObjMemSize = SM_OBJ_MEM_SIZE; /* allocate the shared memory object pool if needed */ if (smObjFreeAdrs == (char *) NONE) { /* check cache configuration - must be read and write coherent */ if (!CACHE_DMA_IS_WRITE_COHERENT() || !CACHE_DMA_IS_READ_COHERENT()) { printf ("usrSmObjInit - cache coherent buffer not available. Giving up. \n"); return (ERROR); } allocatedPool = TRUE; smObjFreeAdrs = (char *) cacheDmaMalloc (SM_OBJ_MEM_SIZE); if (smObjFreeAdrs == NULL) { printf ("usrSmObjInit - cannot allocate shared memory pool. Giving up.\n"); return (ERROR); } } if (!allocatedPool) { /* free memory pool must be behind the anchor */ smObjFreeAdrs += sizeof (SM_ANCHOR); /* adjust pool size */ smObjMemSize = SM_OBJ_MEM_SIZE - sizeof (SM_ANCHOR); } /* probe anchor address */ if (vxMemProbe (smAnchor, VX_READ, sizeof (char), &bb) != OK) { printf ("usrSmObjInit - anchor address %#x unreachable. Giving up.\n", (unsigned int) smAnchor); return (ERROR); } /* probe beginning of shared memory */ if (vxMemProbe (smObjFreeAdrs, VX_WRITE, sizeof (char), &bb) != OK) { printf ("usrSmObjInit - shared memory address %#x unreachable. Giving up.\n", (unsigned int) smObjFreeAdrs); return (ERROR); } /* set up shared memory objects */ smObjSpinTries = SM_OBJ_MAX_TRIES; /* must do before smObjSetup() */ smObjParams.allocatedPool = allocatedPool; smObjParams.pAnchor = (SM_ANCHOR *) smAnchor; smObjParams.smObjFreeAdrs = (char *) smObjFreeAdrs; smObjParams.smObjMemSize = smObjMemSize; smObjParams.maxCpus = DEFAULT_CPUS_MAX; smObjParams.maxTasks = SM_OBJ_MAX_TASK; smObjParams.maxSems = SM_OBJ_MAX_SEM; smObjParams.maxMsgQueues = SM_OBJ_MAX_MSG_Q; smObjParams.maxMemParts = SM_OBJ_MAX_MEM_PART; smObjParams.maxNames = SM_OBJ_MAX_NAME; if (smObjSetup (&smObjParams) != OK) { if (errno == S_smObjLib_SHARED_MEM_TOO_SMALL) printf("\nERROR smObjSetup : shared memory pool too small.\n"); if (allocatedPool) free (smObjFreeAdrs); /* cleanup */ return (ERROR); } } /* * Else, we are not the master CPU, so wait until the anchor and SMO * header regions are accessible (the master CPU has initialized them) * before continuing. */ else { /* first wait for valid anchor region */ tics = params.procNum; for (tics <<= 1; tics < maxWait; tics <<= 1) { smUtilDelay (NULL, tics); if ((smUtilMemProbe (smAnchor, VX_READ, sizeof (UINT), (char *)&temp) == OK) && (ntohl (temp) == SM_READY)) { break; } } if (tics >= maxWait) { printf ("usrSmObjInit: anchor @ %p unreachable. Giving up.\n", smAnchor); return (ERROR); } /* Finally, wait for master to init SM Object facility */ tics = params.procNum; cp = (char *)(&((SM_ANCHOR *)smAnchor)->smObjHeader); for (tics <<= 1; tics < maxWait; tics <<= 1) { if ((smUtilMemProbe (cp, VX_READ, sizeof (UINT), (char *)&temp) == OK) && (temp != (UINT)~0) && (temp != 0)) { break; } smUtilDelay (NULL, tics); } pSmObjHdr = SM_OFFSET_TO_LOCAL (ntohl (temp), (int)smAnchor, SM_OBJ_MEM_HDR *); cp = (char *)(&pSmObjHdr->initDone); for ( ; tics < maxWait; tics <<= 1) { if ((smUtilMemProbe (cp, VX_READ, sizeof (UINT), (char *)&temp) == OK) && (ntohl (temp) == TRUE)) { break; } smUtilDelay (NULL, tics); } if (tics >= maxWait) { printf ("usrSmObjInit: Error: time out awaiting SM Object init\n"); return (ERROR); } } /* * initialize shared memory descriptor * * Note that SM_OBJ_MAX_TRIES is passed to smObjInit(), * and is used to set the global int smObjSpinTries. * This has already been done above to fix SPR68418. */ smObjInit (&smObjDesc, (SM_ANCHOR *) smAnchor, sysClkRateGet (), SM_OBJ_MAX_TRIES, SM_INT_TYPE, SM_INT_ARG1, SM_INT_ARG2, SM_INT_ARG3); /* attach to shared memory object facility */ printf ("Attaching shared memory objects at %#x... ", (int) smAnchor); if (smObjAttach (&smObjDesc) != OK) { printf ("failed: errno = %#x.\n", errno); return (ERROR); } printf ("done\n"); return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -