static EMBX_ERROR removeProcessor (EMBX_Transport_t *tp, EMBX_UINT cpuID) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBXSHM_TCB_t *tcb; if (0 == cpuID) { EMBX_DebugMessage(("Failed 'cannot remove host processor'\n")); return EMBX_INVALID_ARGUMENT; } if (cpuID >= EMBXSHM_MAX_CPUS) { EMBX_DebugMessage(("Failed 'CPU ID is too large'\n")); return EMBX_INVALID_ARGUMENT; } tcb = tpshm->tcb; EMBXSHM_READS(tcb); /* mark the processor as inactive */ tcb->activeCPUs[cpuID].marker = 0; EMBXSHM_WROTE(&tcb->activeCPUs[cpuID]); /* update the local participants map used to determine when to send port * open/close notifications. for remote processors this will be performed * automatically [see update updateLocalParticipantsMap()] but we don't * want to needlessly deadlock if the dead processors comms. pipe * overflows. */ tpshm->participants[cpuID] = 0; return EMBX_SUCCESS; }
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; }
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; }
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; }
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; }
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 grow_port_table(EMBXLB_Transport_t *tplb, EMBX_INT *freeSlot) { EMBXLB_LocalPortHandle_t **newTable; EMBX_UINT newTableSize; EMBX_UINT nBytes; *freeSlot = tplb->portTableSize; newTableSize = tplb->portTableSize * 2; if(newTableSize < tplb->portTableSize) { EMBX_DebugMessage(("EMBXLB::grow_port_table 'table size overflowed!!!'\n")); return EMBX_NOMEM; } nBytes = newTableSize*sizeof(EMBXLB_LocalPortHandle_t *); newTable = (EMBXLB_LocalPortHandle_t **)EMBX_OS_MemAlloc(nBytes); if(newTable != 0) { memset(newTable, 0, nBytes); memcpy(newTable, tplb->portTable, tplb->portTableSize*sizeof(EMBXLB_LocalPortHandle_t *)); EMBX_OS_MemFree(tplb->portTable); tplb->portTable = newTable; tplb->portTableSize = newTableSize; EMBX_DebugMessage(("EMBXLB::grow_port_table 'new port table size = %u'\n", newTableSize)); return EMBX_SUCCESS; } EMBX_DebugMessage(("EMBXLB::grow_port_table 'could not grow port table'\n")); return EMBX_NOMEM; }
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_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; }
EMBX_ERROR EMBX_Address(EMBX_TRANSPORT htp, EMBX_INT offset, EMBX_VOID **address) { EMBX_ERROR res = EMBX_INVALID_TRANSPORT; EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_Address(offset=0x%08x)\n", offset)); EMBX_DebugOn(EMBX_INFO_TRANSPORT); #if !defined(EMBX_LEAN_AND_MEAN) if(!_embx_dvr_ctx.isLockInitialized) { EMBX_DebugMessage((_driver_uninit_error)); goto exit; } if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT)) { goto exit; } #endif /* EMBX_LEAN_AND_MEAN */ 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) ) { EMBX_Transport_t *tp = tph->transport; if( tp->state == EMBX_TP_INITIALIZED) { if (tp->transportInfo.usesZeroCopy) { /* MULTICOM_32BIT_SUPPORT: The Warp range is now a physical address range */ #ifdef __TDT__ /* stm24 prob */ res = tp->methods->phys_to_virt_alt(tp, offset, address); #else res = tp->methods->phys_to_virt(tp, offset, address); #endif } else if (tp->transportInfo.allowsPointerTranslation) { EMBX_VOID *addr = (EMBX_VOID *)((unsigned long)(tp->transportInfo.memStart)+offset); if(tp->transportInfo.memStart <= addr && tp->transportInfo.memEnd >= addr) { *address = addr; res = (0 == tp->methods->test_state ? EMBX_SUCCESS : tp->methods->test_state(tp, addr)); } else { res = EMBX_INVALID_ARGUMENT; } } } } } EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock); exit: EMBX_DebugOff(EMBX_INFO_TRANSPORT); EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_Address(offset=0x%08x) = %d\n", offset, res)); return res; }
static EMBX_ERROR do_close_transport(EMBX_TRANSPORT htp) { EMBX_ERROR res = EMBX_INVALID_TRANSPORT; EMBX_TransportHandle_t *tph; tph = (EMBX_TransportHandle_t *)EMBX_HANDLE_GETOBJ(&_embx_handle_manager, htp); if(tph != 0) { EMBX_Transport_t *tp; EMBX_TransportHandleList_t *handleList; if( (tph->state != EMBX_HANDLE_VALID) && (tph->state != EMBX_HANDLE_INVALID) ) { EMBX_DebugMessage(("Failed 'transport handle state is corrupted'\n")); return EMBX_INVALID_TRANSPORT; } if( (tph->localPorts != 0) || (tph->remotePorts != 0) ) { EMBX_DebugMessage(("Failed 'transport still has open ports'\n")); return EMBX_PORTS_STILL_OPEN; } tp = tph->transport; handleList = tp->transportHandles; while(handleList) { if(handleList->transportHandle == tph) break; handleList = handleList->next; } #if defined(EMBX_VERBOSE) if(handleList == 0) { EMBX_DebugMessage(("Unable to find transport handle (0x%08lx) on transport (0x%08lx) handle list!\n",(unsigned long)tph,(unsigned long)tp)); } #endif /* EMBX_VERBOSE */ res = tp->methods->close_handle(tp, tph); if(res == EMBX_SUCCESS) { /* At this point tph has been freed by the transport * so we must not use it again. */ EMBX_HANDLE_FREE(&_embx_handle_manager, htp); tp->transportInfo.nrOpenHandles--; /* Unhook the transport handle list entry */ if(handleList != 0) { if(handleList->prev != 0) handleList->prev->next = handleList->next; else tp->transportHandles = handleList->next; if(handleList->next != 0) handleList->next->prev = handleList->prev; EMBX_OS_MemFree(handleList); } if(tp->closeEvent != 0 && tp->transportHandles == 0) { /* Another thread is waiting for the last handle to * close on this transport. Signal it now this has * happened. */ EMBX_OS_EVENT_POST(&tp->closeEvent->event); } } } return res; }