void rpmsg_service_register(struct service *serv) { unsigned int ret; struct rpmsg_ns_msg *ns_msg; struct rpmsg_hdr *hdr; struct virtqueue_buf virtq_buf; unsigned int *dst; /* get a free buffer on the Tx virtqueue */ ret = virtqueue_get_avail_buf(&virtqueue_list[0], &virtq_buf); hdr = (struct rpmsg_hdr *)virtq_buf.buf_ptr; ns_msg = (struct rpmsg_ns_msg *)&hdr->data; hdr->src = serv->port; hdr->dst = 53; hdr->len = sizeof(struct rpmsg_ns_msg); hdr->flags = 0; hdr->reserved = 0; strncpy(ns_msg->name, serv->name , 32); ns_msg->addr = serv->port; ns_msg->flags = RPMSG_NS_CREATE; virtqueue_add_used_buf(&virtqueue_list[0], virtq_buf.head); /* register the service in the service list */ strncpy(service_list[service_id].name, serv->name, 32); service_list[service_id].port = serv->port; service_list[service_id].queue = serv->queue; service_id++; /* send mailbox msg to host */ mailbox_send(M3_TO_HOST_MBX, 0x0); }
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); }
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); }