static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) { int err; if (latency) { dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!, len %d\n", rpdev->src, rpdev->dst, strlen(MSG_LAT)); ttc_base = ioremap(0xf8002000, PAGE_SIZE); /* TTC base addr */ if (!ttc_base) { pr_err("TTC Ioremap failed\n"); return -1; } start = get_jiffies_64(); __raw_writel(0x10, ttc_base + 0x10); /* Start TTC */ err = rpmsg_sendto(rpdev, MSG_LAT, strlen(MSG_LAT), 50); } else { dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!, len %d\n", rpdev->src, rpdev->dst, strlen(MSG)); err = rpmsg_sendto(rpdev, MSG, strlen(MSG), 50); } if (err) { pr_err("rpmsg_send failed: %d\n", err); return err; } return 0; }
static int rpmsg_dev_remove(struct device *dev) { struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); struct virtproc_info *vrp = rpdev->vrp; int err = 0; /* tell remote processor's name service we're removing this channel */ if (rpdev->announce && virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { struct rpmsg_ns_msg nsm; strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); nsm.addr = rpdev->src; nsm.flags = RPMSG_NS_DESTROY; err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); if (err) dev_err(dev, "failed to announce service %d\n", err); } rpdrv->remove(rpdev); rpmsg_destroy_ept(rpdev->ept); return err; }
static int rpmsg_pingpong_probe(struct rpmsg_channel *rpdev) { int err; dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n", rpdev->src, rpdev->dst); /* * send a message to our remote processor, and tell remote * processor about this channel */ err = rpmsg_send(rpdev, MSG, strlen(MSG)); if (err) { dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", err); return err; } rpmsg_pingpong = 0; rx_count = 0; err = rpmsg_sendto(rpdev, (void *)(&rpmsg_pingpong), 4, rpdev->dst); if (err) { dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", err); return err; } return 0; }
static ssize_t rpmsg_dev_write(struct file *filp, const char __user *ubuff, size_t len, loff_t *p_off) { struct _rpmsg_device *_prpmsg_device = (struct _rpmsg_device *)filp->private_data; struct _rpmsg_params *local = ( struct _rpmsg_params *)&_prpmsg_device->rpmsg_params; int err; unsigned int size; if (len < MAX_RPMSG_BUFF_SIZE) size = len; else size = MAX_RPMSG_BUFF_SIZE; if (copy_from_user(local->tx_buff, ubuff, size)) { pr_err("%s: user to kernel buff copy error.\n", __func__); return -1; } err = rpmsg_sendto(local->rpmsg_chnl, local->tx_buff, size, local->endpt); if (err) { pr_err("rpmsg_sendto (size = %d) error: %d\n", size, err); size = 0; } return size; }
static int rpmsg_echo_test_kern_app_probe(struct rpmsg_channel *rpdev) { struct _rpmsg_dev_params *local; dev_info(&rpdev->dev, "%s", __func__); local = devm_kzalloc(&rpdev->dev, sizeof(struct _rpmsg_dev_params), GFP_KERNEL); if (!local) { dev_err(&rpdev->dev, "Failed to allocate memory for rpmsg user dev.\n"); return -ENOMEM; } memset(local, 0x0, sizeof(struct _rpmsg_dev_params)); /* Initialize mutex */ mutex_init(&local->sync_lock); local->rpmsg_chnl = rpdev; dev_set_drvdata(&rpdev->dev, local); sprintf(local->tx_buff, RPMG_INIT_MSG); if (rpmsg_sendto(local->rpmsg_chnl, local->tx_buff, sizeof(RPMG_INIT_MSG), rpdev->dst)) { dev_err(&rpdev->dev, "Failed to send init_msg to target 0x%x.", local->rpmsg_dst); goto error0; } dev_info(&rpdev->dev, "Sent init_msg to target 0x%x.", local->rpmsg_dst); dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n", rpdev->src, rpdev->dst); INIT_WORK(&local->rpmsg_work, rpmsg_echo_test_kern_app_work_func); #if 0 if (rpmsg_echo_test_kern_app_echo_test(local) <= 0) { pr_err("Failed to send echo test message to remote.\n"); return -1; } #else schedule_work(&local->rpmsg_work); #endif goto out; error0: return -ENODEV; out: return 0; }
static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) { int err; dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n", rpdev->src, rpdev->dst); err = rpmsg_sendto(rpdev, MSG, strlen(MSG), 50); if (err) { pr_err("rpmsg_send failed: %d\n", err); return err; } return 0; }
static int rpmsgtty_write(struct tty_struct *tty, const unsigned char *buf, int total) { int count, ret = 0; const unsigned char *tbuf; struct rpmsgtty_port *rptty_port = container_of(tty->port, struct rpmsgtty_port, port); struct rpmsg_channel *rpmsg_chnl = rptty_port->rpmsg_chnl; if (NULL == buf) { pr_err("buf shouldn't be null.\n"); return -ENOMEM; } count = total; tbuf = buf; do { /* pr_info("%s lentx=%d\n", __FUNCTION__, total); print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,buf, total, true); */ /* send a message to our remote processor */ ret = rpmsg_sendto(rpmsg_chnl, (void *)tbuf, count > RPMSG_MAX_SIZE ? RPMSG_MAX_SIZE : count, rptty_port->endpt); if (ret) { dev_err(&rpmsg_chnl->dev, "rpmsg_send failed: %d\n", ret); return ret; } if (count > RPMSG_MAX_SIZE) { count -= RPMSG_MAX_SIZE; tbuf += RPMSG_MAX_SIZE; } else { count = 0; } } while (count > 0); return total; }
static int rpmsg_dev_probe(struct device *dev) { struct rpmsg_channel *rpdev = to_rpmsg_channel(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); struct virtproc_info *vrp = rpdev->vrp; struct rpmsg_endpoint *ept; int err; ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, rpdev->src); if (!ept) { dev_err(dev, "failed to create endpoint\n"); err = -ENOMEM; goto out; } rpdev->ept = ept; rpdev->src = ept->addr; err = rpdrv->probe(rpdev); if (err) { dev_err(dev, "%s: failed: %d\n", __func__, err); rpmsg_destroy_ept(ept); goto out; } /* need to tell remote processor's name service about this channel ? */ if (rpdev->announce && virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) { struct rpmsg_ns_msg nsm; strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE); nsm.addr = rpdev->src; nsm.flags = RPMSG_NS_CREATE; err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR); if (err) dev_err(dev, "failed to announce service %d\n", err); } out: return err; }
static void rpmsg_pingpong_cb(struct rpmsg_channel *rpdev, void *data, int len, void *priv, u32 src) { int err; /* reply */ rpmsg_pingpong = *(unsigned int *)data; pr_info("get %d (src: 0x%x)\n", rpmsg_pingpong, src); rx_count++; /* pingpongs should not live forever */ if (rx_count >= MSG_LIMIT) { dev_info(&rpdev->dev, "goodbye!\n"); return; } rpmsg_pingpong++; err = rpmsg_sendto(rpdev, (void *)(&rpmsg_pingpong), 4, src); if (err) dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", err); }
static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, void *priv, u32 src) { int err; static int rx_count; dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src); print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1, data, len, true); /* samples should not live forever */ if (rx_count >= MSG_LIMIT) { dev_info(&rpdev->dev, "goodbye!\n"); return; } /* reply */ err = rpmsg_sendto(rpdev, MSG, strlen(MSG), src); if (err) pr_err("rpmsg_send failed: %d\n", err); }
int send_rpc(void *data, int len) { int retval; retval = rpmsg_sendto(rpc_data->rpmsg_chnl, data, len, PROXY_ENDPOINT); return retval; }
static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, void *priv, u32 src) { int err; static int rx_count; if (latency) { static u32 min = 0x10000000; static u32 max; static u32 average; u32 value = __raw_readl(ttc_base + 0x1c); /* Read value */ __raw_writel(0x11, ttc_base + 0x10); /* Stop TTC */ if (value < min) min = value; if (value > max) max = value; average += value; /* count messages */ ++rx_count; if (rx_count >= MSG_LAT_LIMIT) { u64 end = get_jiffies_64(); u32 time = end - start; u32 timeps = ((1000000 / MSG_LAT_LIMIT) * time) / HZ; printk(KERN_INFO "actual value %d ns, min %d ns, max %d" " ns, average %d ns\n", value * TTC_HZ, min * TTC_HZ, max * TTC_HZ, (average/rx_count) * TTC_HZ); printk(KERN_INFO "Start/end jiffies %llx/%llx, " "messages %d. Time: %d s, " "Messages per second %d\n", end, start, rx_count, time/HZ, 1000000 / timeps); dev_info(&rpdev->dev, "goodbye!\n"); return; } __raw_writel(0x10, ttc_base + 0x10); /* Start TTC */ /* reply */ err = rpmsg_sendto(rpdev, MSG_LAT, strlen(MSG_LAT), src); } else { dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src); print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1, data, len, true); /* samples should not live forever */ if (rx_count >= MSG_LIMIT) { dev_info(&rpdev->dev, "goodbye!\n"); return; } err = rpmsg_sendto(rpdev, MSG, strlen(MSG), src); /* reply */ } if (err) pr_err("rpmsg_send failed: %d\n", err); }
int main() { struct remote_proc *proc; int uninit = 0; struct ept_cmd_data *ept_data; #ifdef ZYNQ7_BAREMETAL /* Switch to System Mode */ SWITCH_TO_SYS_MODE(); #endif /* Initialize HW system components */ init_system(); rsc_info.rsc_tab = (struct resource_table *)&resources; rsc_info.size = sizeof(resources); /* This API creates the virtio devices for this remote node and initializes other relevant resources defined in the resource table */ remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_default_cb, &proc); for (;;) { if (intr_flag) { struct command *cmd = (struct command *)r_buffer; if (cmd->comm_start == CMD_START) { unsigned int cm_code = cmd->comm_code; void *data = cmd->data; switch (cm_code) { case CREATE_EPT: ept_data = (struct ept_cmd_data *)data; rp_ept = rpmsg_create_ept(app_rp_chnl, rpmsg_read_ept_cb, RPMSG_NULL, ept_data->dst); if (rp_ept) { /* Send data back to ack. */ rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); } break; case DELETE_EPT: rpmsg_destroy_ept(rp_ept); rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); break; case CREATE_CHNL: break; case DELETE_CHNL: rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); remoteproc_resource_deinit(proc); uninit = 1; break; case QUERY_FW_NAME: rpmsg_send(app_rp_chnl, &firmware_name[0], strlen(firmware_name) + 1); break; default: rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); break; } } else { rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); } intr_flag = 0; if (uninit) break; } sleep(); } return 0; }