Пример #1
0
static pipeline_t va_pipe_pipeline(pipeline_t result_so_far,
                                   va_list args)
{
    pipe_processor_t proc = va_arg(args, pipe_processor_t);

    if(proc == NULL)
        return result_so_far;

    void*  aux       = va_arg(args, void*);
    size_t pipe_size = va_arg(args, size_t);

    if(pipe_size == 0)
    {
        pipe_consumer_free(result_so_far.out);
        result_so_far.out = NULL;
        return result_so_far;
    }

    pipe_t* pipe = pipe_new(pipe_size, 0);

    pipe_connect(result_so_far.out , proc, aux, pipe_producer_new(pipe));
    result_so_far.out = pipe_consumer_new(pipe);

    pipe_free(pipe);

    return va_pipe_pipeline(result_so_far, args);
}
Пример #2
0
static int pipe_close(FAR struct file *filep)
{
  struct inode      *inode = filep->f_inode;
  struct pipe_dev_s *dev   = inode->i_private;
  int                ret;

  /* Some sanity checking */
#if CONFIG_DEBUG
  if (!dev)
    {
       return -EBADF;
    }
#endif

  /* Perform common close operations */

  ret =  pipecommon_close(filep);
  if (ret == 0 && dev->d_refs == 0)
    {
      /* Release the pipe when there are no further open references to it. */

      pipe_free(dev->d_pipeno);
    }
  return ret;
}
Пример #3
0
/*
 * If called with *pipep = NULL, pipe_new will call pipe_alloc to allocate a
 * pipe control structure and set *pipep to its address.
 * pipe is locked, when pipe_new returns with no error.
 */
static int pipe_new(
  pipe_control_t **pipep
)
{
  pipe_control_t *pipe;
  int err = 0;

  err = pipe_lock();
  if (err)
    return err;

  pipe = *pipep;
  if (pipe == NULL) {
    err = pipe_alloc(&pipe);
    if (err)
      goto out;
  }

  if (! PIPE_LOCK(pipe))
    err = -EINTR;

  if (*pipep == NULL) {
    if (err)
      pipe_free(pipe);
    else
      *pipep = pipe;
  }

out:
  pipe_unlock();
  return err;
}
Пример #4
0
/*
 * If called with *pipep = NULL, pipe_new will call pipe_alloc to allocate a
 * pipe control structure and set *pipep to its address.
 * pipe is locked, when pipe_new returns with no error.
 */
static int pipe_new(
  pipe_control_t **pipep
)
{
  pipe_control_t *pipe;
  int err = 0;

  if (rtems_semaphore_obtain(rtems_pipe_semaphore,
        RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL)
    return -EINTR;

  pipe = *pipep;
  if (pipe == NULL) {
    err = pipe_alloc(&pipe);
    if (err)
      goto out;
  }

  if (! PIPE_LOCK(pipe))
    err = -EINTR;

  if (*pipep == NULL) {
    if (err)
      pipe_free(pipe);
    else
      *pipep = pipe;
  }

out:
  rtems_semaphore_release(rtems_pipe_semaphore);
  return err;
}
Пример #5
0
// internal, get or create a pipe
pipe_t tcp4_pipe(net_tcp4_t net, char *ip, int port)
{
  pipe_t pipe;
  pipe_tcp4_t to;
  char id[23];

  snprintf(id,23,"%s:%d",ip,port);
  pipe = xht_get(net->pipes,id);
  if(pipe) return pipe;

  LOG("new pipe to %s",id);

  // create new tcp4 pipe
  if(!(pipe = pipe_new("tcp4"))) return NULL;
  if(!(pipe->arg = to = malloc(sizeof (struct pipe_tcp4_struct)))) return pipe_free(pipe);
  memset(to,0,sizeof (struct pipe_tcp4_struct));
  to->net = net;
  to->sa.sin_family = AF_INET;
  inet_aton(ip, &(to->sa.sin_addr));
  to->sa.sin_port = htons(port);
  if(!(to->chunks = chunks_new(0))) return tcp4_free(pipe);

  // set up pipe
  pipe->id = strdup(id);
  xht_set(net->pipes,pipe->id,pipe);
  pipe->send = tcp4_send;

  return pipe;
}
Пример #6
0
/*
 * Interface to file system close.
 *
 * *pipep points to pipe control structure. When the last user releases pipe,
 * it will be set to NULL.
 */
int pipe_release(
  pipe_control_t **pipep,
  rtems_libio_t *iop
)
{
  pipe_control_t *pipe = *pipep;
  uint32_t mode;

  rtems_status_code sc;
  sc = rtems_semaphore_obtain(pipe->Semaphore,
                              RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  /* WARN pipe not released! */
  if(sc != RTEMS_SUCCESSFUL)
    rtems_fatal_error_occurred(sc);

  mode = LIBIO_ACCMODE(iop);
  if (mode & LIBIO_FLAGS_READ)
     pipe->Readers --;
  if (mode & LIBIO_FLAGS_WRITE)
     pipe->Writers --;

  sc = rtems_semaphore_obtain(rtems_pipe_semaphore,
                              RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  /* WARN pipe not freed and pipep not set to NULL! */
  if(sc != RTEMS_SUCCESSFUL)
    rtems_fatal_error_occurred(sc);

  PIPE_UNLOCK(pipe);

  if (pipe->Readers == 0 && pipe->Writers == 0) {
#if 0
    /* To delete an anonymous pipe file when all users closed it */
    if (pipe->Anonymous)
      delfile = TRUE;
#endif
    pipe_free(pipe);
    *pipep = NULL;
  }
  else if (pipe->Readers == 0 && mode != LIBIO_FLAGS_WRITE)
    /* Notify waiting Writers that all their partners left */
    PIPE_WAKEUPWRITERS(pipe);
  else if (pipe->Writers == 0 && mode != LIBIO_FLAGS_READ)
    PIPE_WAKEUPREADERS(pipe);

  rtems_semaphore_release(rtems_pipe_semaphore);

#if 0
  if (! delfile)
    return 0;
  if (iop->pathinfo.ops->unlink_h == NULL)
    return 0;

  /* This is safe for IMFS, but how about other FSes? */
  iop->flags &= ~LIBIO_FLAGS_OPEN;
  if(iop->pathinfo.ops->unlink_h(&iop->pathinfo))
    return -errno;
#endif

  return 0;
}
Пример #7
0
/*
 * Interface to file system close.
 *
 * *pipep points to pipe control structure. When the last user releases pipe,
 * it will be set to NULL.
 */
void pipe_release(
  pipe_control_t **pipep,
  rtems_libio_t *iop
)
{
  pipe_control_t *pipe = *pipep;
  uint32_t mode;

  #if defined(RTEMS_DEBUG)
    /* WARN pipe not freed and pipep not set to NULL! */
    if (pipe_lock())
      rtems_fatal_error_occurred(0xdeadbeef);

    /* WARN pipe not released! */
    if (!PIPE_LOCK(pipe))
      rtems_fatal_error_occurred(0xdeadbeef);
  #endif

  mode = LIBIO_ACCMODE(iop);
  if (mode & LIBIO_FLAGS_READ)
     pipe->Readers --;
  if (mode & LIBIO_FLAGS_WRITE)
     pipe->Writers --;

  PIPE_UNLOCK(pipe);

  if (pipe->Readers == 0 && pipe->Writers == 0) {
#if 0
    /* To delete an anonymous pipe file when all users closed it */
    if (pipe->Anonymous)
      delfile = TRUE;
#endif
    pipe_free(pipe);
    *pipep = NULL;
  }
  else if (pipe->Readers == 0 && mode != LIBIO_FLAGS_WRITE)
    /* Notify waiting Writers that all their partners left */
    PIPE_WAKEUPWRITERS(pipe);
  else if (pipe->Writers == 0 && mode != LIBIO_FLAGS_READ)
    PIPE_WAKEUPREADERS(pipe);

  pipe_unlock();

#if 0
  if (! delfile)
    return;
  if (iop->pathinfo.ops->unlink_h == NULL)
    return;

  /* This is safe for IMFS, but how about other FSes? */
  iop->flags &= ~LIBIO_FLAGS_OPEN;
  if(iop->pathinfo.ops->unlink_h(&iop->pathinfo))
    return;
#endif

}
Пример #8
0
pipe_t tcp4_free(pipe_t pipe)
{
  pipe_tcp4_t to;
  if(!pipe) return NULL;
  to = (pipe_tcp4_t)pipe->arg;
  if(!to) return LOG("internal error, invalid pipe, leaking it");

  LOG("removing %d");
  xht_set(to->net->pipes,pipe->id,NULL);
  pipe_free(pipe);
  if(to->client > 0) close(to->client);
  chunks_free(to->chunks);
  free(to);
  return NULL;
}
Пример #9
0
pipeline_t pipe_parallel(size_t           instances,
                         size_t           in_size,
                         pipe_processor_t proc,
                         void*            aux,
                         size_t           out_size)
{
    pipe_t* in  = pipe_new(in_size,  0),
          * out = pipe_new(out_size, 0);

    while(instances--)
        pipe_connect(pipe_consumer_new(in),
                     proc, aux,
                     pipe_producer_new(out));

    pipeline_t ret = {
        .in  = pipe_producer_new(in),
        .out = pipe_consumer_new(out)
    };

    pipe_free(in);
    pipe_free(out);

    return ret;
}
Пример #10
0
pipe_t net_serial_add(net_serial_t net, const char *name, int (*read)(void), int (*write)(uint8_t *buf, size_t len), uint8_t buffer)
{
  pipe_t pipe;
  pipe_serial_t to;

  // just sanity checks
  if(!net || !name || !read || !write) return NULL;

  pipe = xht_get(net->pipes, name);
  if(!pipe)
  {
    if(!(pipe = pipe_new("serial"))) return NULL;
    if(!(pipe->arg = to = malloc(sizeof (struct pipe_serial_struct)))) return pipe_free(pipe);
    memset(to,0,sizeof (struct pipe_serial_struct));
    to->net = net;
    if(!(to->chunks = util_chunks_new(buffer)))
    {
      free(to);
      return pipe_free(pipe);
    }

    // set up pipe
    pipe->id = strdup(name);
    xht_set(net->pipes,pipe->id,pipe);
    pipe->send = serial_send;
    
  }else{
    if(!(to = (pipe_serial_t)pipe->arg)) return NULL;
  }

  // these can be modified
  to->read = read;
  to->write = write;

  return pipe;
}
Пример #11
0
pipeline_t pipe_pipeline(size_t first_size, ...)
{
    va_list va;
    va_start(va, first_size);

    pipe_t* p = pipe_new(first_size, 0);

    pipeline_t ret = va_pipe_pipeline(pipe_trivial_pipeline(p), va);

    pipe_free(p);

    va_end(va);

    return ret;
}
Пример #12
0
int pipe2(int pipefd[2], int flags) {
	struct idesc_table *it;
	struct pipe *pipe;
	int res = 0;

	it = task_resource_idesc_table(task_self());
	assert(it);


	pipe = pipe_alloc();
	if (!pipe) {
		res = ENOMEM;
		goto out_err;
	}


	idesc_pipe_init(&pipe->read_desc, pipe, FS_MAY_READ);
	idesc_pipe_init(&pipe->write_desc, pipe, FS_MAY_WRITE);


	pipefd[0] = idesc_table_add(it, &pipe->read_desc.idesc, flags);
	pipefd[1] = idesc_table_add(it, &pipe->write_desc.idesc, flags);

	if (pipefd[0] < 0 || pipefd[1] < 0) {
		res = ENOMEM;
		goto out_err;
	}

	return 0;

out_err:
	if (pipefd[1] >= 0) {
		idesc_table_del(it, pipefd[1]);
	}
	if (pipefd[0] >= 0) {
		idesc_table_del(it, pipefd[0]);
	}
	if (pipe) {
		pipe_free(pipe);
	}

	SET_ERRNO(res);
	return -1;
}
Пример #13
0
static int pipe_close(FAR struct file *filep)
{
  FAR struct inode *inode    = filep->f_inode;
  FAR struct pipe_dev_s *dev = inode->i_private;
  int ret;

  DEBUGASSERT(dev);

  /* Perform common close operations */

  ret =  pipecommon_close(filep);
  if (ret == 0 && dev->d_refs == 0)
    {
      /* Release the pipe when there are no further open references to it. */

      pipe_free(dev->d_pipeno);
    }

  return ret;
}
Пример #14
0
void net_loopback_free(net_loopback_t pair)
{
  pipe_free(pair->pipe);
  free(pair);
  return;
}
Пример #15
0
int pipe(int fd[2])
{
  FAR struct pipe_dev_s *dev = NULL;
  char devname[16];
  int pipeno;
  int err;
  int ret;

  /* Get exclusive access to the pipe allocation data */

  ret = sem_wait(&g_pipesem);
  if (ret < 0)
    {
      /* sem_wait() will have already set errno */

      return ERROR;
    }

  /* Allocate a minor number for the pipe device */

  pipeno = pipe_allocate();
  if (pipeno < 0)
    {
      (void)sem_post(&g_pipesem);
      err = -pipeno;
      goto errout;
    }

  /* Create a pathname to the pipe device */

  sprintf(devname, "/dev/pipe%d", pipeno);

  /* Check if the pipe device has already been created */

  if ((g_pipecreated & (1 << pipeno)) == 0)
    {
      /* No.. Allocate and initialize a new device structure instance */

      dev = pipecommon_allocdev();
      if (!dev)
        {
          (void)sem_post(&g_pipesem);
          err = ENOMEM;
          goto errout_with_pipe;
        }

      dev->d_pipeno = pipeno;

      /* Register the pipe device */

      ret = register_driver(devname, &pipe_fops, 0666, (FAR void *)dev);
      if (ret != 0)
        {
          (void)sem_post(&g_pipesem);
          err = -ret;
          goto errout_with_dev;
        }

      /* Remember that we created this device */

       g_pipecreated |= (1 << pipeno);
    }

  (void)sem_post(&g_pipesem);

  /* Get a write file descriptor */

  fd[1] = open(devname, O_WRONLY);
  if (fd[1] < 0)
    {
      err = -fd[1];
      goto errout_with_driver;
    }

  /* Get a read file descriptor */

  fd[0] = open(devname, O_RDONLY);
  if (fd[0] < 0)
    {
      err = -fd[0];
      goto errout_with_wrfd;
    }

  return OK;

errout_with_wrfd:
  close(fd[1]);

errout_with_driver:
  unregister_driver(devname);

errout_with_dev:
  if (dev)
    {
      pipecommon_freedev(dev);
    }

errout_with_pipe:
  pipe_free(pipeno);

errout:
  set_errno(err);
  return ERROR;
}
Пример #16
0
wtp_handle_t* wtp_alloc(const char* device, wtp_aslan_msg_cb msg_cb)
{
    if ((!device) || (!msg_cb))
	{
        errno = EINVAL;
		return NULL;
    }

    int ret = -1;

    wtp_handle_t *handle = calloc(1, sizeof(wtp_handle_t));
    if (!handle)
	{
        errno = ENOMEM;
		return NULL;
    }

	handle->wtp_state = WTP_STATE_NONE;
    handle->msg_cb = msg_cb;

    //for testing purposes only
    char hds_ip[] = "192.168.1.10";
    handle->hds_port = ASLAN_PROTOCOL_PORT;
    handle->hello_interval_seconds = 5;

    /* UDP socket */
    int s = -1;
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
        free(handle);
		return NULL;
    }
    handle->udp_socket = s;

	if (pthread_mutex_init(&handle->hello_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    if (pthread_mutex_init(&handle->udp_mutex, NULL) != 0)
    {
		free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->ack_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->sta_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->monitor_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    handle->wtp_sta_hashmap = NULL;

    /* HDS parameters */
    handle->hds_inet_addr.sin_family = AF_INET;
    if (!inet_aton(hds_ip, (struct in_addr*) &(handle->hds_inet_addr.sin_addr.s_addr)))
	{
        errno = EINVAL;
		close_wtp(handle);
		return NULL;
    }
    handle->hds_ip = ntohl(handle->hds_inet_addr.sin_addr.s_addr);

    /* interface name */
    strncpy(handle->device, device, IFNAMSIZ - 1);

    /* interface IP */
    struct ifreq ifr;
    ifr.ifr_addr.sa_family = AF_INET;
    strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
    if (ioctl(handle->udp_socket, SIOCGIFADDR, &ifr) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_ip = ntohl(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr);

    /* HDS sockaddr_in structure */
    handle->hds_inet_addr.sin_addr.s_addr = htonl(handle->hds_ip);
    handle->hds_inet_addr.sin_family  = AF_INET;
    handle->hds_inet_addr.sin_port = htons(handle->hds_port);

    /* UDP socket local port */
    struct sockaddr_in address;
    memset((char*) &address, 0, sizeof(address));
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = 0;
    address.sin_family = AF_INET;
    bind(handle->udp_socket, (struct sockaddr*) &address, sizeof(address));

    struct sockaddr_in sin = {0};
    socklen_t len = sizeof(sin);
    if (getsockname(handle->udp_socket, (struct sockaddr*)&sin, &len) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_port = ntohs(sin.sin_port);
	wpa_printf(MSG_INFO, "INFO: UDP socket for ASLAN messages created, listening on port: %d\n", handle->local_port);

	/* create FIFO pipe producers and consumers */
	pipe_t* recv_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_recv_producer = pipe_producer_new(recv_pipe);
	handle->msg_recv_consumer = pipe_consumer_new(recv_pipe);
	pipe_free(recv_pipe);

	pipe_t* send_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_send_producer = pipe_producer_new(send_pipe);
	handle->msg_send_consumer = pipe_consumer_new(send_pipe);
	pipe_free(send_pipe);

    /* start receiving thread for ASLAN messages */
    if (pthread_create(&(handle->receive_thread), NULL, receive_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: receiving thread for ASLAN messages created\n");

	/* start processing thread for ASLAN messages */
    if (pthread_create(&(handle->process_thread), NULL, process_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: processing thread for ASLAN messages created\n");

	/* start sending thread for ASLAN messages */
    if (pthread_create(&(handle->send_thread), NULL, send_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: sending thread for ASLAN messages created\n");

    /* obtain HDS MAC address by a Hello message */
    if (wtp_send_hello_msg(handle) == -1)
	{
		close_wtp(handle);
		return NULL;
    }

    /* Check ARP cache */
    if (handle->local_ip != handle->hds_ip)
    {
        struct arpreq areq;
        memset(&areq, 0, sizeof(areq));
        struct sockaddr_in* sockaddr = NULL;
        sockaddr = (struct sockaddr_in*) &(areq.arp_pa);
        sockaddr->sin_family = AF_INET;
        sockaddr->sin_addr.s_addr = htonl(handle->hds_ip);
        sockaddr = (struct sockaddr_in*) &(areq.arp_ha);
        sockaddr->sin_family = ARPHRD_ETHER;
        strncpy(areq.arp_dev, device, IFNAMSIZ - 1);

        int i = 0;
        unsigned char mac_loopback[] = {0, 0, 0, 0, 0, 0};

        ioctl(s, SIOCGARP, (caddr_t) &areq);
        while ((i < 5) && (mac_cmp(areq.arp_ha.sa_data, mac_loopback)))
		{
            i++;
            sleep(1);
            ioctl(s, SIOCGARP, (caddr_t) &areq);
        }

        memcpy(handle->hds_mac, areq.arp_ha.sa_data, 6);

        if (mac_cmp(areq.arp_ha.sa_data, mac_loopback)) wpa_printf(MSG_WARNING, "WARNING: HDS MAC address obtaining failed\n");
        else wpa_printf(MSG_INFO, "INFO: HDS MAC address found: "MACSTR"\n", MAC2STR(handle->hds_mac));
    }
    else wpa_printf(MSG_INFO, "INFO: WTP started at loopback\n");

    return handle;
}
Пример #17
0
static void
pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
{
    Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
    Pipe*  pipe   = *lookup;
    CPUOldState* env = cpu_single_env;

    /* Check that we're referring a known pipe channel */
    if (command != PIPE_CMD_OPEN && pipe == NULL) {
        dev->status = PIPE_ERROR_INVAL;
        return;
    }

    /* If the pipe is closed by the host, return an error */
    if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
        dev->status = PIPE_ERROR_IO;
        return;
    }

    switch (command) {
    case PIPE_CMD_OPEN:
        DD("%s: CMD_OPEN channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if (pipe != NULL) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        pipe = pipe_new(dev->channel, dev);
        pipe->next = dev->pipes;
        dev->pipes = pipe;
        dev->status = 0;
        break;

    case PIPE_CMD_CLOSE:
        DD("%s: CMD_CLOSE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        /* Remove from device's lists */
        *lookup = pipe->next;
        pipe->next = NULL;
        pipe_list_remove_waked(&dev->signaled_pipes, pipe);
        pipe_free(pipe);
        break;

    case PIPE_CMD_POLL:
        dev->status = pipe->funcs->poll(pipe->opaque);
        DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
        break;

    case PIPE_CMD_READ_BUFFER: {
        /* Translate virtual address into physical one, into emulator memory. */
        GoldfishPipeBuffer  buffer;
        target_ulong        address = dev->address;
        target_ulong        page    = address & TARGET_PAGE_MASK;
        hwaddr  phys;
        phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page);
#ifdef TARGET_X86_64
        phys = phys & TARGET_PTE_MASK;
#endif
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
		extern int matchMeInPidTid(CPUArchState *);
		extern int getMeContextId(CPUArchState *);
		if(matchMeInPidTid(env))
		{
			printf("%d %s: CMD_READ_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
				getMeContextId(env),
				__FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
				dev->size, dev->status);
		}
        DD("%s: CMD_READ_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
           __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
           dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WRITE_BUFFER: {
        /* Translate virtual address into physical one, into emulator memory. */
        GoldfishPipeBuffer  buffer;
        target_ulong        address = dev->address;
        target_ulong        page    = address & TARGET_PAGE_MASK;
        hwaddr  phys;
        phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page);
#ifdef TARGET_X86_64
        phys = phys & TARGET_PTE_MASK;
#endif
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
		extern int matchMeInPidTid(CPUArchState *);
		extern int getMeContextId(CPUArchState *);
		if(matchMeInPidTid(env))
		{
	        printf("%d %s: CMD_WRITE_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
		       getMeContextId(env),
				__FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
			   dev->size, dev->status);
		}
        DD("%s: CMD_WRITE_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
           __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
           dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WAKE_ON_READ:
        DD("%s: CMD_WAKE_ON_READ channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
            pipe->wanted |= PIPE_WAKE_READ;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    case PIPE_CMD_WAKE_ON_WRITE:
        DD("%s: CMD_WAKE_ON_WRITE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
            pipe->wanted |= PIPE_WAKE_WRITE;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    default:
        D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
    }
}
Пример #18
0
static void
pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
{
    Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
    Pipe*  pipe   = *lookup;
    CPUState* env = cpu_single_env;

    
    if (command != PIPE_CMD_OPEN && pipe == NULL) {
        dev->status = PIPE_ERROR_INVAL;
        return;
    }

    
    if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
        dev->status = PIPE_ERROR_IO;
        return;
    }

    switch (command) {
    case PIPE_CMD_OPEN:
        DD("%s: CMD_OPEN channel=0x%x", __FUNCTION__, dev->channel);
        if (pipe != NULL) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        pipe = pipe_new(dev->channel, dev);
        pipe->next = dev->pipes;
        dev->pipes = pipe;
        dev->status = 0;
        break;

    case PIPE_CMD_CLOSE:
        DD("%s: CMD_CLOSE channel=0x%x", __FUNCTION__, dev->channel);
        
        *lookup = pipe->next;
        pipe->next = NULL;
        pipe_list_remove_waked(&dev->signaled_pipes, pipe);
        pipe_free(pipe);
        break;

    case PIPE_CMD_POLL:
        dev->status = pipe->funcs->poll(pipe->opaque);
        DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
        break;

    case PIPE_CMD_READ_BUFFER: {
        
        GoldfishPipeBuffer  buffer;
        uint32_t            address = dev->address;
        uint32_t            page    = address & TARGET_PAGE_MASK;
        target_phys_addr_t  phys;
        phys = safe_get_phys_page_debug(env, page);
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
        DD("%s: CMD_READ_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
           __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WRITE_BUFFER: {
        
        GoldfishPipeBuffer  buffer;
        uint32_t            address = dev->address;
        uint32_t            page    = address & TARGET_PAGE_MASK;
        target_phys_addr_t  phys;
        phys = safe_get_phys_page_debug(env, page);
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
        DD("%s: CMD_WRITE_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
           __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WAKE_ON_READ:
        DD("%s: CMD_WAKE_ON_READ channel=0x%x", __FUNCTION__, dev->channel);
        if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
            pipe->wanted |= PIPE_WAKE_READ;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    case PIPE_CMD_WAKE_ON_WRITE:
        DD("%s: CMD_WAKE_ON_WRITE channel=0x%x", __FUNCTION__, dev->channel);
        if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
            pipe->wanted |= PIPE_WAKE_WRITE;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    default:
        D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
    }
}