Exemplo n.º 1
0
static void IpcTask (void * pvParameters)
{
	unsigned int msg, *local_vq_buf;
	int ret;
	struct virtqueue_buf virtq_buf;

	virtqueue_init();
	nvic_enable_irq(MAILBOX_IRQ);
	enable_mailbox_irq();

	for (;;) {
		xQueueReceive(MboxQueue, &msg, portMAX_DELAY);
		trace_printf("msg from mailbox : ");
		trace_value(msg);

		switch(msg) {

		case RP_MBOX_ECHO_REQUEST :
			mailbox_send(M3_TO_HOST_MBX, RP_MBOX_ECHO_REPLY);
			break;

		case HOST_TO_M3_VRING :
			ret = virtqueue_get_avail_buf(&virtqueue_list[msg], &virtq_buf);

			/* make a local copy of the buffer */
			local_vq_buf = pvPortMalloc(RP_MSG_BUF_SIZE);
			memcpy(local_vq_buf, virtq_buf.buf_ptr, RP_MSG_BUF_SIZE);

			virtqueue_add_used_buf(&virtqueue_list[msg], virtq_buf.head);

			/* dispatch to the service queue */
			rpmsg_dispatch_msg(local_vq_buf);

			break;

		case M3_TO_HOST_VRING :
			trace_printf("kick on vq0, dropping it \n");
			xSemaphoreGive(InitDoneSemaphore);
			break;
		}
	}
	vTaskDelete(NULL);
}
Exemplo n.º 2
0
static void IpcTask (void * pvParameters)
{
	unsigned int msg, *local_vq_buf;
	int ret;
	struct virtqueue_buf virtq_buf;
    portTickType LastWake;

	trace_append("%s: starting task\n", __func__);

    /* Workaround
     *
     * We can't enable interrupts in U-Boot. Let's wait until Linux is booted
     * on CPU. Linux remoteproc framework sends a ping to IPU via mailbox when
     * its initialization is completed. This ping is a good indicator for IPU
     * that Linux and its remoteproc/rpmsg subsystems are up an running.
     */

    while (1) {
        msg = mailbox_read();

        if (msg == HOST_ECHO_REQUEST) {
            trace_append("%s: received echo request [0x%x] from CPU\n", __func__, msg);
            break;
        }

        trace_append("%s: host-to-m3 mailbox [0x%x]\n", __func__, msg);
        LastWake = xTaskGetTickCount();
        vTaskDelayUntil(&LastWake, 5000);
    }

	virtqueue_init();
	nvic_enable_irq(MAILBOX_IRQ);
	enable_mailbox_irq();

	trace_append("%s: start main loop\n", __func__);

	for (;;) {
		xQueueReceive(MboxQueue, &msg, portMAX_DELAY);

		switch(msg) {

		case RP_MBOX_ECHO_REQUEST :
			mailbox_send(M3_TO_HOST_MBX, RP_MBOX_ECHO_REPLY);
			break;

		case HOST_TO_M3_VRING :
			ret = virtqueue_get_avail_buf(&virtqueue_list[msg], &virtq_buf);

			/* make a local copy of the buffer */
			local_vq_buf = pvPortMalloc(RP_MSG_BUF_SIZE);
			memcpy(local_vq_buf, virtq_buf.buf_ptr, RP_MSG_BUF_SIZE);
			virtqueue_add_used_buf(&virtqueue_list[msg], virtq_buf.head);

			/* dispatch to the service queue */
			rpmsg_dispatch_msg(local_vq_buf);

			break;

		case M3_TO_HOST_VRING :
			xSemaphoreGive(InitDoneSemaphore);
			break;

        default:
	        trace_append("%s: unknown message\n", __func__);
            break;
		}
	}

	vTaskDelete(NULL);
}
Exemplo n.º 3
0
Arquivo: epiphany.c Projeto: cpehle/oh
static long epiphany_ioctl(struct file *file, unsigned int cmd,
                           unsigned long arg)
{
    int retval = 0;
    int err = 0;
    epiphany_alloc_t *ealloc = NULL;
    mailbox_notifier_t notifier;

    if (_IOC_TYPE(cmd) != EPIPHANY_IOC_MAGIC) {
        return -ENOTTY;
    }

    if (_IOC_NR(cmd) > EPIPHANY_IOC_MAXNR) {
        return -ENOTTY;
    }

    if (_IOC_DIR(cmd) & _IOC_READ) {
        err =
            !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
    } else if (_IOC_DIR(cmd) & _IOC_WRITE) {
        err =
            !access_ok(VERIFY_WRITE, (void __user *)arg,
                       _IOC_SIZE(cmd));
    }

    if (err) {
        return -EFAULT;
    }

    switch (cmd) {
    case EPIPHANY_IOC_GETSHM:
        ealloc = (epiphany_alloc_t *) (arg);
        if (copy_to_user(ealloc, &global_shm, sizeof(*ealloc))) {
            printk(KERN_ERR "EPIPHANY_IOC_GETSHM - failed\n");
            retval = -EACCES;
        }

        break;

    case EPIPHANY_IOC_MB_ENABLE:
        enable_mailbox_irq();
        break;

    case EPIPHANY_IOC_MB_DISABLE:
        disable_mailbox_irq();
        break;

    case EPIPHANY_IOC_MB_NOTIFIER:
        // TODO lock access
        if (copy_from_user(&notifier, (void __user *)arg, sizeof(mailbox_notifier_t)))
        {
            printk(KERN_ERR "EPIPHANY_IOC_MB_NOTIFIER - failed\n");
            retval = -EACCES;
        }

        if (notifier.old_notifier != mailbox_notifier)
        {
            printk(KERN_ERR "EPIPHANY_IOC_MB_NOTIFIER - %d != %d\n", notifier.old_notifier, mailbox_notifier);
            retval = -EACCES;
        }
        else
        {
            // flush the queue
            flush_workqueue(irq_workqueue);
            mailbox_notifier = notifier.new_notifier;
        }

        if (0 < mailbox_notifier)
        {
            // Save the userspace task for later use
            mailbox.irq_work.userspace_task = pid_task(find_vpid(current->pid), PIDTYPE_PID);
        }

        // TODO unlock
        break;


    default:		/* Redundant, cmd was checked against MAXNR */
        return -ENOTTY;
    }

    return retval;
}