EMBX_VOID *EMBX_OS_PhysMemMap(EMBX_UINT pMem, int size, int cached) { EMBX_VOID *vaddr = NULL; unsigned mode; EMBX_Info(EMBX_INFO_OS, (">>>>PhysMemMap(0x%08x, %d)\n", (unsigned int) pMem, size)); mode = VMEM_CREATE_READ|VMEM_CREATE_WRITE; if (cached) mode |= VMEM_CREATE_CACHED; else mode |= VMEM_CREATE_UNCACHED | VMEM_CREATE_NO_WRITE_BUFFER; vaddr = vmem_create((EMBX_VOID *)pMem, size, NULL, mode); if (NULL == vaddr) { EMBX_DebugMessage(("PhysMemMap: pMem %p size %d cached %d failed\n", pMem, size, cached)); } EMBX_Info(EMBX_INFO_OS, ("PhysMemMap: *vMem = %p\n", vaddr)); EMBX_Info(EMBX_INFO_OS, ("<<<<PhysMemMap\n")); return vaddr; }
static int parseEmpiString(char *str, EMBXSHM_EMPIMailboxConfig_t *empi) { int err; const char *field[6]; EMBX_Info(EMBX_INFO_FACTORY, (">>>parseEmpiString(\"%s\", ...)\n", str)); EMBX_Assert(str && empi); if (5 != splitString(str, ':', 6, field)) { EMBX_Info(EMBX_INFO_FACTORY, ("<<<parseEmpiString() = -EINVAL:1\n")); return -EINVAL; } err = parseNumber(field[0], (EMBX_UINT *) &(empi->empiAddr)); err += parseNumber(field[1], (EMBX_UINT *) &(empi->mailboxAddr)); err += parseNumber(field[2], (EMBX_UINT *) &(empi->sysconfAddr)); err += parseNumber(field[3], &(empi->sysconfMaskSet)); err += parseNumber(field[4], &(empi->sysconfMaskClear)); if (0 != err) { EMBX_Info(EMBX_INFO_FACTORY, ("<<<parseEmpiString() = -EINVAL:2\n")); return -EINVAL; } EMBX_Info(EMBX_INFO_FACTORY, ("<<<parseEmpiString() = 0\n")); return 0; }
/* * Notification routine to inform us that a local port has been * closed. We need to invalidate all our remote port */ void EMBXSHM_portClosedNotification (EMBXSHM_Transport_t *tpshm) { EMBX_Info(EMBX_INFO_REMOTEPORT, (">>>EMBXSHM_portClosedNotification\n")); EMBX_Assert (tpshm); /* * Wait for notification of a local port closing, * then look for it and service it */ while (1) { EMBX_BOOL signalPending; EMBX_Info(EMBX_INFO_REMOTEPORT, (" waiting for port closed notification\n")); signalPending = EMBX_OS_EVENT_WAIT (&tpshm->closedPortEvent); EMBX_Info(EMBX_INFO_REMOTEPORT, (" received port closed notification\n")); /* * If we've been told to die, then do so */ if (signalPending || tpshm->closedPortDieFlag) { EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<EMBXSHM_portClosedNotification\n")); return; } /* Close the port */ EMBXSHM_portClose(tpshm); } }
/* * Transport method to open a handle */ static EMBX_ERROR openHandle (EMBX_Transport_t *tp, EMBX_TransportHandle_t **tph) { EMBXSHM_TransportHandle_t *handle; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>openHandle()\n")); EMBX_Assert (tp); EMBX_Assert (tph); /* * Allocate memory for handle */ handle = (EMBXSHM_TransportHandle_t *)EMBX_OS_MemAlloc (sizeof (EMBXSHM_TransportHandle_t)); if (handle != NULL) { /* * Copy default structure contents. */ memcpy (handle, &EMBXSHM_transportHandleTemplate, sizeof (EMBXSHM_TransportHandle_t)); *tph = (EMBX_TransportHandle_t *)handle; EMBX_OS_MODULE_REF(); EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<openHandle = EMBX_SUCCESS\n")); return EMBX_SUCCESS; } else { EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<openHandle = EMBX_NOMEM\n")); return EMBX_NOMEM; } }
/* * Helper routine to locate the object referred to by a handle. */ EMBXSHM_Object_t *EMBXSHM_findObject (EMBXSHM_Transport_t *tpshm, EMBX_HANDLE handle) { EMBXSHM_Object_t *obj = 0; EMBX_UINT index; EMBX_Info (EMBX_INFO_INTERRUPT, (">>>EMBXSHM_findObject(0x%08x, 0x%08x)\n", (unsigned) tpshm, (unsigned) handle)); EMBX_Assert (tpshm); EMBX_Assert (tpshm->tcb); EMBX_Assert (tpshm->tcb->objectTable); if ((index = (handle & EMBXSHM_OBJECT_INDEX_MASK)) < tpshm->objectTableSize) { obj = (EMBXSHM_Object_t *)BUS_TO_LOCAL (tpshm->tcb->objectTable + index, tpshm->pointerWarp); EMBX_Assert (obj && EMBXSHM_ALIGNED_TO_CACHE_LINE(obj)); EMBXSHM_READS(obj); if (!obj->valid) { obj = 0; } } EMBX_Info (EMBX_INFO_INTERRUPT, ("<<<EMBXSHM_findObject = 0x%08x\n", (unsigned)obj)); return obj; }
/* * Routine to invalidate all the local ports on a transport, * and this transport itself. */ static EMBX_VOID doInvalidateHandle (EMBXSHM_TransportHandle_t *th) { EMBX_LocalPortList_t *phl; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>doInvalidateHandle()\n")); EMBX_Assert (th); /* * In this transport we can simply call the invalidate * method on each local port. This will implicitly invalidate * any remote ports, which must be connected to a local port. * It will also wake up any tasks waiting to receive data. Transports * involving multiple CPUs may need to do more work to invalidate * remote ports connected to a different CPU. */ phl = th->localPorts; for (phl = th->localPorts; phl; phl = phl->next) { /* * Making this call assumes that invalidate_port does not * require any transport resources that we already have * locked. In this transport that is the case. */ phl->port->methods->invalidate_port (phl->port); } th->state = EMBX_HANDLE_INVALID; EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<doInvalidateHandle\n")); }
/* * Routine to see if any participants in the transport * are left. */ static EMBX_BOOL activeParticipants (EMBXSHM_Transport_t *tpshm, EMBXSHM_TCB_t *tcb) { EMBX_UINT i; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>activeParticipants()\n")); EMBX_Assert(tpshm); EMBX_Assert(tcb && EMBXSHM_ALIGNED_TO_CACHE_LINE(tcb)); EMBXSHM_READS(&tcb->activeCPUs); /* this function is called in a tight busy wait loop * so we must ensure any buffers are cleared */ tpshm->buffer_flush(tpshm, (void *) &(tcb->activeCPUs[0].marker)); for (i=0; i<EMBXSHM_MAX_CPUS; i++) { if (tcb->activeCPUs[i].marker) { EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<activeParticipants = EMBX_TRUE\n")); return EMBX_TRUE; } } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<activeParticipants = EMBX_FALSE\n")); return EMBX_FALSE; }
EMBX_ERROR EMBX_RemoveProcessor(EMBX_TRANSPORT htp, EMBX_UINT cpuID) { EMBX_ERROR res = EMBX_INVALID_TRANSPORT; EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_RemoveProcessor(htp=0x%08lx,cpu=%d)\n",(unsigned long)htp, cpuID)); EMBX_DebugOn(EMBX_INFO_TRANSPORT); if(!_embx_dvr_ctx.isLockInitialized) { EMBX_DebugMessage((_driver_uninit_error)); goto exit; } if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT)) { res = EMBX_INVALID_TRANSPORT; goto exit; } EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock); if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED && _embx_dvr_ctx.state != EMBX_DVR_IN_SHUTDOWN ) { EMBX_DebugMessage((_driver_uninit_error)); res = EMBX_INVALID_TRANSPORT; } else { EMBX_TransportHandle_t *tph; tph = (EMBX_TransportHandle_t *)EMBX_HANDLE_GETOBJ(&_embx_handle_manager, htp); if( (tph == 0) || (tph->state != EMBX_HANDLE_VALID) ) { EMBX_DebugMessage(("Failed 'transport handle is not valid'\n")); res = EMBX_INVALID_TRANSPORT; } else { EMBX_Transport_t *tp = tph->transport; EMBX_Assert(tp); EMBX_Assert(tp->methods->remove_processor); /* Call the transport specific removal function */ res = tp->methods->remove_processor(tp, cpuID); } } EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock); exit: EMBX_DebugOff(EMBX_INFO_TRANSPORT); EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_RemoveProcessor(htp=0x%08lx,cpu=%d) = %d\n", (unsigned long)htp, cpuID, res)); return res; }
void EMBX_OS_PhysMemUnMap(EMBX_VOID *vMem) { EMBX_Info(EMBX_INFO_OS, (">>>>PhysMemUnMap\n")); vmem_delete(vMem); EMBX_Info(EMBX_INFO_OS, ("<<<<PhysMemUnMap\n")); }
void EMBX_OS_ContigMemFree(EMBX_VOID *addr, EMBX_UINT size) { EMBX_Info(EMBX_INFO_OS, (">>>>ContigMemFree\n")); free(addr); EMBX_Info(EMBX_INFO_OS, ("<<<<ContigMemFree\n")); }
EMBX_ERROR EMBX_FindTransport(const EMBX_CHAR *name, EMBX_TPINFO *tpinfo) { EMBX_ERROR res; EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_FindTransport(%s)\n",(name==0?"(NULL)":name))); EMBX_DebugOn(EMBX_INFO_TRANSPORT); if(!_embx_dvr_ctx.isLockInitialized) { EMBX_DebugMessage((_driver_uninit_error)); res = EMBX_DRIVER_NOT_INITIALIZED; goto exit; } if((name == 0) || (tpinfo == 0)) { res = EMBX_INVALID_ARGUMENT; goto exit; } EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock); if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED) { EMBX_DebugMessage((_driver_uninit_error)); res = EMBX_DRIVER_NOT_INITIALIZED; } else { EMBX_TransportList_t *tpl; tpl = EMBX_find_transport_entry(name); if(tpl != 0) { EMBX_Info(EMBX_INFO_TRANSPORT,("Found transport\n")); *tpinfo = tpl->transport->transportInfo; res = EMBX_SUCCESS; } else { EMBX_Info(EMBX_INFO_TRANSPORT,("Could not find transport\n")); res = EMBX_INVALID_TRANSPORT; } } EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock); exit: EMBX_DebugOff(EMBX_INFO_TRANSPORT); EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_FindTransport(%s) = %d\n",(name==0?"(NULL)":name), res)); return res; }
static EMBX_ERROR virtToPhys (EMBX_Transport_t *tp, EMBX_VOID *addr, EMBX_UINT *paddrp) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; int res; EMBX_Assert(tp); EMBX_Assert(addr); /* First check to see if this is an EMBXSHM heap address */ if (addr >= tpshm->heap && addr < (void *)((unsigned) tpshm->heap + tpshm->heapSize)) { *paddrp = (EMBX_UINT) LOCAL_TO_BUS(addr, tpshm->pointerWarp); #ifdef EMBXSHM_CACHED_HEAP res = EMBX_INCOHERENT_MEMORY; #else res = EMBX_SUCCESS; #endif } else { EMBX_UINT paddr; /* Do an OS specific lookup of the virtual address */ res = EMBX_OS_VirtToPhys(addr, &paddr); EMBX_Info(EMBX_INFO_TRANSPORT, (" virtToPhys: addr %p -> 0x%08x : %d\n", addr, paddr, res)); if (res != EMBX_INVALID_ARGUMENT) { /* MULTICOM_32BIT_SUPPORT: Support two disjoint Warp ranges */ if (((EMBX_UINT)tpshm->warpRangeAddr <= paddr && ((EMBX_UINT)tpshm->warpRangeAddr + tpshm->warpRangeSize) >= paddr) || ((EMBX_UINT)tpshm->warpRangeAddr2 <= paddr && ((EMBX_UINT)tpshm->warpRangeAddr2 + tpshm->warpRangeSize2) >= paddr)) { *paddrp = paddr; EMBX_Info(EMBX_INFO_TRANSPORT, (" Zero Copy: addr %p paddr 0x%08x mode %d\n", addr, paddr, res)); } else { EMBX_Info(EMBX_INFO_TRANSPORT, (" paddr 0x%08x missed warp 0x%08x-0x%08x warp2 0x%08x-0x%08x\n", paddr, (EMBX_UINT)tpshm->warpRangeAddr, (EMBX_UINT)tpshm->warpRangeAddr + tpshm->warpRangeSize, (EMBX_UINT)tpshm->warpRangeAddr2, (EMBX_UINT)tpshm->warpRangeAddr2 + tpshm->warpRangeSize2)); res = EMBX_INVALID_ARGUMENT; } } } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<virtToPhys(0x%08x, 0x%08x) -> 0x%08x = %d\n", (unsigned) tp, (unsigned) addr, *paddrp, res)); return res; }
/* * Transport method called when a deferred closedown is interrupted. */ static EMBX_VOID closeInterrupt (EMBX_Transport_t *tp) { EMBX_Info (EMBX_INFO_TRANSPORT, (">>>closeInterrupt()\n")); EMBX_Assert (tp); /* As this transport doesn't return EMBX_BLOCK from closedown * this has nothing to do. */ EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<closeInterrupt()\n")); }
EMBX_ERROR EMBX_GetTransportInfo(EMBX_TRANSPORT htp, EMBX_TPINFO *tpinfo) { EMBX_ERROR res = EMBX_INVALID_TRANSPORT; EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_GetTransportInfo(htp=0x%08lx)\n",(unsigned long)htp)); EMBX_DebugOn(EMBX_INFO_TRANSPORT); if(!_embx_dvr_ctx.isLockInitialized) { EMBX_DebugMessage((_driver_uninit_error)); goto exit; } if(tpinfo == 0) { res = EMBX_INVALID_ARGUMENT; goto exit; } if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT)) { goto exit; } EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock); if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED) { EMBX_DebugMessage((_driver_uninit_error)); } else { EMBX_TransportHandle_t *tph; tph = (EMBX_TransportHandle_t *)EMBX_HANDLE_GETOBJ(&_embx_handle_manager, htp); if( (tph != 0) && (tph->state == EMBX_HANDLE_VALID) ) { *tpinfo = tph->transport->transportInfo; EMBX_Info(EMBX_INFO_TRANSPORT, ("Returning transport '%s'\n",tpinfo->name)); res = EMBX_SUCCESS; } } EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock); exit: EMBX_DebugOff(EMBX_INFO_TRANSPORT); EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_GetTransportInfo(htp=0x%08lx) = %d\n",(unsigned long)htp, res)); return res; }
EMBX_ERROR EMBX_GetFirstTransport(EMBX_TPINFO *tpinfo) { EMBX_ERROR res; EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_GetFirstTransport\n")); EMBX_DebugOn(EMBX_INFO_TRANSPORT); if(!_embx_dvr_ctx.isLockInitialized) { EMBX_DebugMessage((_driver_uninit_error)); res = EMBX_DRIVER_NOT_INITIALIZED; goto exit; } if(tpinfo == 0) { res = EMBX_INVALID_ARGUMENT; goto exit; } EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock); if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED) { EMBX_DebugMessage((_driver_uninit_error)); res = EMBX_DRIVER_NOT_INITIALIZED; } else { if(_embx_dvr_ctx.transports == 0) { res = EMBX_INVALID_STATUS; } else { *tpinfo = _embx_dvr_ctx.transports->transport->transportInfo; EMBX_Info(EMBX_INFO_TRANSPORT, ("Returning transport '%s'\n",tpinfo->name)); res = EMBX_SUCCESS; } } EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock); exit: EMBX_DebugOff(EMBX_INFO_TRANSPORT); EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_GetFirstTransport = %d\n", res)); return res; }
/* * Transport method to deregister an object. */ static EMBX_ERROR deregisterObject (EMBX_Transport_t *tp, EMBX_HANDLE handle) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBX_ERROR res = EMBX_INVALID_ARGUMENT; EMBXSHM_Object_t *obj; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>deregisterObject(0x%08x, 0x%08x)\n", (unsigned) tp, (unsigned) handle)); EMBX_Assert (tpshm); /* * Lock the table */ EMBXSHM_takeSpinlock (tpshm, &tpshm->objectTableMutex, tpshm->objectTableSpinlock); if ((obj = EMBXSHM_findObject (tpshm, handle)) != 0) { EMBX_Assert(EMBXSHM_ALIGNED_TO_CACHE_LINE(obj)); EMBXSHM_READS(obj); if (obj->owningCPU == tpshm->cpuID) { if (obj->shadow) { EMBXSHM_free(tpshm, (EMBX_VOID *) BUS_TO_LOCAL(obj->sharedData, tpshm->pointerWarp)); obj->shadow = 0; } obj->valid = 0; obj->owningCPU = -1; obj->size = 0; obj->sharedData = 0; obj->localData = 0; obj->mode = 0; EMBXSHM_WROTE(obj); res = EMBX_SUCCESS; } } /* * We can unlock the table now */ EMBXSHM_releaseSpinlock (tpshm, &tpshm->objectTableMutex, tpshm->objectTableSpinlock); EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<deregisterObject = %d\n", res)); return res; }
static int parseNumber(const char *str, EMBX_UINT *num) { int base; char *endp; EMBX_Info(EMBX_INFO_FACTORY, (">>>parseNumber(\"%s\", ...)\n", str)); /* lazy evaulation will prevent us illegally accessing str[1] */ base = (str[0] == '0' && str[1] == 'x' ? str += 2, 16 : 10); *num = simple_strtoul(str, &endp, base); EMBX_Info(EMBX_INFO_FACTORY, ("<<<parseNumber(..., %d) = %s\n", *num, ('\0' != *str && '\0' == *endp ? "0" : "-EINVAL"))); return ('\0' != *str && '\0' == *endp ? 0 : -EINVAL); }
/* Optional transport method to return the state of a memory address (is it or it it not * cache coherent */ static EMBX_ERROR testState (EMBX_Transport_t *tp, EMBX_VOID *addr) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; int res; EMBX_Assert(tp); EMBX_Assert(addr); /* First check to see if this is an EMBXSHM heap address */ if (addr >= tpshm->heap && addr < (void *)((unsigned) tpshm->heap + tpshm->heapSize)) { #ifdef EMBXSHM_CACHED_HEAP res = EMBX_INCOHERENT_MEMORY; #else res = EMBX_SUCCESS; #endif } else { EMBX_UINT paddr; /* Do an OS specific translation of the virtual address, * return code gives the cache mode, i.e. EMBX_SUCCESS or EMBX_INCOHERENT_MEMORY */ res = EMBX_OS_VirtToPhys(addr, &paddr); } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<testState(0x%08x, 0x%08x) = %s\n", (unsigned) tp, (unsigned) addr, res == EMBX_SUCCESS ? "COHERENT" : "INCOHERENT")); return res; }
/* * Transport method to close an open handle */ static EMBX_ERROR closeHandle (EMBX_Transport_t *tp, EMBX_TransportHandle_t *tph) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBX_EventState_t *es, *next; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>closeHandle()\n")); EMBX_Assert (tpshm); EMBX_Assert (tph); EMBX_OS_MUTEX_TAKE (&tpshm->connectionListMutex); /* * Unblock processes waiting for a connection through the closing handle */ for (es = tpshm->connectionRequests; es; es = next) { EMBXSHM_ConnectBlockState_t *cbs = es->data; /* match with CBS IN DATA */ next = es->next; if (cbs->requestingHandle == tph) { EMBX_EventListRemove(&tpshm->connectionRequests, es); EMBX_OS_MemFree (cbs); es->result = EMBX_TRANSPORT_CLOSED; EMBX_OS_EVENT_POST (&es->event); } } EMBX_OS_MUTEX_RELEASE (&tpshm->connectionListMutex); /* * Make key handle structures invalid to help catch use after close */ tph->state = EMBX_HANDLE_CLOSED; tph->transport = 0; EMBX_OS_MemFree (tph); EMBX_OS_MODULE_UNREF(); EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<closeHandle = EMBX_SUCCESS\n")); return EMBX_SUCCESS; }
/* * Transport method to return the data buffer and size of an object */ static EMBX_ERROR getObject (EMBX_Transport_t *tp, EMBX_HANDLE handle, EMBX_VOID **object, EMBX_UINT *size) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBX_ERROR res = EMBX_SUCCESS; EMBXSHM_Object_t *obj; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>getObject(0x%08x, 0x%08x, ...)\n", (unsigned) tp, (unsigned) handle)); EMBX_Assert (tpshm); EMBX_Assert (object); EMBX_Assert (size); if ((obj = EMBXSHM_findObject (tpshm, handle)) != 0) { /* EMBXSHM_READS(obj); */ /* already performed by EMBXSHM_findObject */ if (obj->owningCPU == tpshm->cpuID) { *object = obj->localData; } else { #if 0 *object = BUS_TO_LOCAL (obj->sharedData, tpshm->pointerWarp); #else #ifdef __TDT__ /* stm24 prob */ res = tp->methods->phys_to_virt_alt (tp, (EMBX_UINT)obj->sharedData, object); #else res = tp->methods->phys_to_virt (tp, (EMBX_UINT)obj->sharedData, object); #endif #endif } *size = obj->size; } else { res = EMBX_INVALID_ARGUMENT; } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<getObject(*object = 0x%08x, *size = %d) = %d\n", (unsigned) *object, *size, res)); return res; }
static int splitString(char *str, char c, int n, const char **split) { int i; char *p; EMBX_Info(EMBX_INFO_FACTORY, (">>>splitString(\"%s\", '%c', %d, ...)\n", str, c, n)); EMBX_Assert(n > 0); split[0] = str; for (p = strchr(str, c), i=1; p && i<n; p = strchr(p, c), i++) { *p++ = '\0'; split[i] = p; } EMBX_Info(EMBX_INFO_FACTORY, ("<<<splitString() = %d\n", i)); return i; }
EMBX_VOID *EMBX_OS_ContigMemAlloc(EMBX_UINT size, EMBX_UINT align) { void **alignedAddr = NULL; EMBX_Info(EMBX_INFO_OS, (">>>>ContigMemAlloc(size=%u, align=%u)\n",size,align)); /* allocate an carefully aligned block of memory */ alignedAddr = memalign(align, size); #if defined(__sh__) if (alignedAddr) { /* ensure there are no cache entries covering this address */ cache_invalidate_data(alignedAddr, size); } #endif EMBX_Info(EMBX_INFO_OS, ("<<<<ContigMemAlloc = 0x%08x\n", (unsigned) alignedAddr)); return (EMBX_VOID *)alignedAddr; }
EMBX_ERROR EMBX_OS_ThreadDelete(EMBX_THREAD thread) { EMBX_Info(EMBX_INFO_OS, (">>>>EMBX_OS_ThreadDelete\n")); if(thread == EMBX_INVALID_THREAD) { EMBX_Info(EMBX_INFO_OS, ("<<<<EMBX_OS_ThreadDelete = EMBX_SUCCESS (invalid task)\n")); return EMBX_SUCCESS; } if(task_wait(&thread, 1, TIMEOUT_INFINITY) != 0) { EMBX_DebugMessage(("EMBX_OS_ThreadDelete: task_wait failed.\n")); return EMBX_SYSTEM_INTERRUPT; } task_delete(thread); EMBX_Info(EMBX_INFO_OS, ("<<<<EMBX_OS_ThreadDelete = EMBX_SUCCESS\n")); return EMBX_SUCCESS; }
EMBX_THREAD EMBX_OS_ThreadCreate(void (*thread)(void *), void *param, EMBX_INT priority, const EMBX_CHAR *name) { task_t *t; EMBX_Info(EMBX_INFO_OS, (">>>>ThreadCreate\n")); if(name == EMBX_DEFAULT_THREAD_NAME) { name = get_default_name(); } t = task_create(thread, param, EMBX_DEFAULT_THREAD_STACK_SIZE, priority, name, 0); if(t == EMBX_INVALID_THREAD) { EMBX_DebugMessage(("ThreadCreate: task_create failed.\n")); } EMBX_Info(EMBX_INFO_OS, ("<<<<ThreadCreate\n")); return t; }
EMBX_ERROR EMBX_CloseTransport(EMBX_TRANSPORT htp) { EMBX_ERROR res = EMBX_INVALID_TRANSPORT; EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_CloseTransport(htp=0x%08lx)\n",(unsigned long)htp)); EMBX_DebugOn(EMBX_INFO_TRANSPORT); if(!_embx_dvr_ctx.isLockInitialized) { EMBX_DebugMessage((_driver_uninit_error)); goto exit; } if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT)) { goto exit; } EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock); if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED && _embx_dvr_ctx.state != EMBX_DVR_IN_SHUTDOWN ) { EMBX_DebugMessage((_driver_uninit_error)); } else { res = do_close_transport(htp); } EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock); exit: EMBX_DebugOff(EMBX_INFO_TRANSPORT); EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_CloseTransport(htp=0x%08lx) = %d\n",(unsigned long)htp, res)); return res; }
static EMBX_ERROR physToVirt (EMBX_Transport_t *tp, EMBX_UINT paddr, EMBX_VOID **vaddrp) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBX_VOID *vaddr; int res; EMBX_Assert(tp); EMBX_Assert(paddr); /* MULTICOM_32BIT_SUPPORT: Support two disjoint Warp ranges */ if (((EMBX_UINT)tpshm->warpRangeAddr <= paddr && ((EMBX_UINT)tpshm->warpRangeAddr + tpshm->warpRangeSize) > paddr)) { vaddr = BUS_TO_LOCAL(paddr, tpshm->pointerWarp); } else if (((EMBX_UINT)tpshm->warpRangeAddr2 <= paddr && ((EMBX_UINT)tpshm->warpRangeAddr2 + tpshm->warpRangeSize2) > paddr)) { vaddr = BUS_TO_LOCAL(paddr, tpshm->pointerWarp2); } else return EMBX_INVALID_ARGUMENT; /* * Found a vaddr, now work out its cache mode */ *vaddrp = vaddr; /* First check to see if this is an EMBXSHM heap address */ if (vaddr >= tpshm->heap && vaddr < (void *)((unsigned) tpshm->heap + tpshm->heapSize)) { #ifdef EMBXSHM_CACHED_HEAP res = EMBX_INCOHERENT_MEMORY; #else res = EMBX_SUCCESS; #endif } else { EMBX_UINT paddr; /* Translate virtual back to physical to get the cache mode */ res = EMBX_OS_VirtToPhys(vaddr, &paddr); } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<physToVirt(0x%08x, 0x%08x -> %p) = %d\n", (unsigned) tp, (unsigned) paddr, *vaddrp, res)); return res; }
void deinit_thread(void *param) { EMBX_TRANSPORT tp = (EMBX_TRANSPORT)param; EMBX_ERROR res; EMBX_OS_Delay((unsigned long)param); res = EMBX_Deinit(); if(res != EMBX_SUCCESS) { EMBX_Info(EMBX_TRUE, ("deinit_thread(%ld) failed, res = %s\n", (unsigned long)param, error_strings[res])); return; } }
void send_thread(void *param) { EMBX_PORT port = (EMBX_PORT)param; EMBX_ERROR res; EMBX_VOID *buffer; EMBX_OS_Delay(5000); EMBX_Alloc(tp,BUFFER_SIZE,&buffer); res = EMBX_SendMessage(port,buffer,BUFFER_SIZE); if(res != EMBX_SUCCESS) { EMBX_Info(EMBX_TRUE, ("port_thread failed, res = %s\n",error_strings[res])); return; } }
EMBX_VOID *EMBX_OS_PhysMemMap(EMBX_UINT pMem, int size, int cached) { EMBX_VOID *vaddr = NULL; EMBX_Info(EMBX_INFO_OS, (">>>>PhysMemMap(0x%08x, %d)\n", (unsigned int) pMem, size)); /* Test the weak symbol for being non NULL, if true we are linked against a vmem capable OS21 */ if (vmem_create) { unsigned mode; mode = VMEM_CREATE_READ|VMEM_CREATE_WRITE; if (cached) mode |= VMEM_CREATE_CACHED; else mode |= VMEM_CREATE_UNCACHED | VMEM_CREATE_NO_WRITE_BUFFER; vaddr = vmem_create((EMBX_VOID *)pMem, size, NULL, mode); } else { #if defined __ST231__ /* This assumes that pMem is a true physical address */ vaddr = mmap_translate_virtual((EMBX_VOID *)pMem); vaddr = (cached ? mmap_translate_cached(vaddr) : mmap_translate_uncached(vaddr)); if (!vaddr) { /* Failed to find a current translation, so create our own */ EMBX_UINT page_size = 0x10000000; /* Map 256MB pages unconditionally */ EMBX_UINT pMem_base = pMem & ~(page_size-1); EMBX_UINT pMem_size = (size + (page_size-1)) & ~(page_size-1); vaddr = mmap_create((void *)pMem_base, pMem_size, mmap_protect_rwx, (cached ? mmap_cached : mmap_uncached), page_size); /* Adjust the returned vaddr accordingly */ if (vaddr) vaddr = (void *) ((EMBX_UINT) vaddr + (pMem - pMem_base)); } #elif defined __sh__ if (cached) vaddr = ST40_P1_ADDR(pMem); else vaddr = ST40_P2_ADDR(pMem); #endif /* defined __ST231__ */ if (NULL == vaddr) { EMBX_DebugMessage(("PhysMemMap: pMem %p size %d cached %d failed\n", pMem, size, cached)); } } EMBX_Info(EMBX_INFO_OS, ("PhysMemMap: *vMem = %p\n", vaddr)); EMBX_Info(EMBX_INFO_OS, ("<<<<PhysMemMap\n")); return vaddr; }
/* * Remote port method to perform an object update */ static EMBX_ERROR updateObject (EMBX_RemotePortHandle_t *ph, EMBX_HANDLE handle, EMBX_UINT offset, EMBX_UINT size) { EMBXSHM_RemotePortHandle_t *remotePortHandle = (EMBXSHM_RemotePortHandle_t *)ph; EMBXSHM_Transport_t *tpshm; EMBXSHM_Object_t *obj; EMBX_ERROR err = EMBX_SUCCESS; EMBX_Info(EMBX_INFO_REMOTEPORT, (">>>updateObject(0x%08x, ...)\n", (unsigned) ph)); EMBX_Assert (ph); EMBX_Assert (ph->transportHandle); tpshm = (EMBXSHM_Transport_t *)ph->transportHandle->transport; EMBX_Assert (tpshm); /* * Do some up front sanity checks */ obj = EMBXSHM_findObject (tpshm, handle); if ((obj == 0) || ((offset+size) > obj->size)) { EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<updateObject = EMBX_INVALID_ARGUMENT\n")); return EMBX_INVALID_ARGUMENT; } EMBX_Assert(EMBXSHM_ALIGNED_TO_CACHE_LINE(obj)); /* * See if this is a local or remote send/update */ if (remotePortHandle->destinationCPU == tpshm->cpuID) { /* * A local update, so we're all done */ EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<updateObject = EMBX_SUCCESS\n")); return EMBX_SUCCESS; } else { /* * This is an object update to a port owned by another CPU. * We may need to copy shadowed data around, and possibly * send an update message to the other guy. */ EMBXSHM_PipeElement_t element; EMBX_VOID *dst = BUS_TO_LOCAL (obj->sharedData, tpshm->pointerWarp); /* * Update the shared copy of this object is it is shadowed from a master * copy on this CPU. */ if (obj->owningCPU == tpshm->cpuID && obj->shadow) { memcpy ((void*)((size_t)dst+offset), (void*)((size_t)obj->localData+offset), size); } /* * Ensure the object data is not held in our own cache. */ if (obj->mode == EMBX_INCOHERENT_MEMORY) EMBX_OS_FlushCache((char *)dst+offset, size); /* * Under the protection of the accessMutex, check the port state * is still OK. If it is, then the local port we're pointing to * is still OK too. By the time the message gets to the other * side (could be another CPU), then the local port could could * have been closed out - he will drop it on the floor. */ EMBX_OS_MUTEX_TAKE (&remotePortHandle->accessMutex); if (remotePortHandle->port.state != EMBX_HANDLE_VALID) { EMBX_OS_MUTEX_RELEASE (&remotePortHandle->accessMutex); return EMBX_INVALID_STATUS; } EMBX_Assert (remotePortHandle->destination.sharedPort->owningCPU == remotePortHandle->destinationCPU); /* * Now inform the partner CPU that the object has been updated. */ element.control = EMBXSHM_PIPE_CTRL_OBJ_UPDATE; element.data.msg_send.port = (EMBXSHM_LocalPortShared_t*) LOCAL_TO_BUS ( remotePortHandle->destination.sharedPort, tpshm->pointerWarp); element.data.obj_send.handle = handle; element.data.obj_send.data = obj->sharedData; element.data.obj_send.offset = offset; element.data.obj_send.size = size; err = EMBXSHM_enqueuePipeElement (tpshm, remotePortHandle->destinationCPU, &element); EMBX_OS_MUTEX_RELEASE (&remotePortHandle->accessMutex); } EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<sendObject = %d\n", err)); return err; }