Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
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);
    }
}
Пример #4
0
/*
 * 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;
    }
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
/* 
 * 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"));
}
Пример #7
0
/*
 * 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;
}
Пример #8
0
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;
}
Пример #9
0
void EMBX_OS_PhysMemUnMap(EMBX_VOID *vMem)
{
    EMBX_Info(EMBX_INFO_OS, (">>>>PhysMemUnMap\n"));

    vmem_delete(vMem);

    EMBX_Info(EMBX_INFO_OS, ("<<<<PhysMemUnMap\n"));
}
Пример #10
0
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"));
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
/*
 * 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"));
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
/*
 * 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;
}
Пример #17
0
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);
}
Пример #18
0
/* 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;
}
Пример #19
0
/*
 * 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;
}
Пример #20
0
/*
 * 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;
}
Пример #21
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
0
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;
    }
}
Пример #28
0
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;
    }
}
Пример #29
0
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;
}
Пример #30
0
/*
 * 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;
}