Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
static void mat_mul_demo(void)
{
	while (1) {
		void *data;
		int len;

		/* wait for data... */
		buffer_pull(&data, &len);

		/* Process incoming message/data */
		if (*(int *)data == SHUTDOWN_MSG) {
			/* disable interrupts and free resources */
			remoteproc_resource_deinit(proc);

			break;
		} else {
			env_memcpy(matrix_array, data, len);

			/* Process received data and multiple matrices. */
			Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result);

			/* Send result back */
			if (RPMSG_SUCCESS != rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix))) {
				xil_printf("Error: rpmsg_send failed\n");
			}
		}
	}
}
Exemplo n.º 3
0
static int qcom_glink_ssr_notify(struct notifier_block *nb, unsigned long event,
				 void *data)
{
	struct glink_ssr *ssr = container_of(nb, struct glink_ssr, nb);
	struct do_cleanup_msg msg;
	char *ssr_name = data;
	int ret;

	ssr->seq_num++;
	reinit_completion(&ssr->completion);

	memset(&msg, 0, sizeof(msg));
	msg.command = cpu_to_le32(GLINK_SSR_DO_CLEANUP);
	msg.seq_num = cpu_to_le32(ssr->seq_num);
	msg.name_len = cpu_to_le32(strlen(ssr_name));
	strlcpy(msg.name, ssr_name, sizeof(msg.name));

	ret = rpmsg_send(ssr->ept, &msg, sizeof(msg));
	if (ret < 0)
		dev_err(ssr->dev, "failed to send cleanup message\n");

	ret = wait_for_completion_timeout(&ssr->completion, HZ);
	if (!ret)
		dev_err(ssr->dev, "timeout waiting for cleanup done message\n");

	return NOTIFY_DONE;
}
Exemplo n.º 4
0
void communication_task(){
	int status;

	rsc_info.rsc_tab = (struct resource_table *)&resources;
	rsc_info.size = sizeof(resources);

	zynqMP_r5_gic_initialize();

	/* Initialize RPMSG framework */
	status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted,
			rpmsg_read_cb ,&proc);
	if (status < 0) {
		return;
	}

#ifdef USE_FREERTOS
	comm_queueset = xQueueCreateSet( 2 );
	xQueueAddToSet( OpenAMPInstPtr.send_queue, comm_queueset);
	xQueueAddToSet( OpenAMPInstPtr.lock, comm_queueset);
#else
	env_create_sync_lock(&OpenAMPInstPtr.lock,LOCKED);
#endif
	env_enable_interrupt(VRING1_IPI_INTR_VECT, 0, 0);
	while (1) {
#ifdef USE_FREERTOS
		QueueSetMemberHandle_t xActivatedMember;
		xActivatedMember = xQueueSelectFromSet( comm_queueset, portMAX_DELAY);
		if( xActivatedMember == OpenAMPInstPtr.lock ) {
			env_acquire_sync_lock(OpenAMPInstPtr.lock);
			process_communication(OpenAMPInstPtr);
		}
		if (xActivatedMember == OpenAMPInstPtr.send_queue) {
			xQueueReceive( OpenAMPInstPtr.send_queue, &send_data, 0 );
			rpmsg_send(app_rp_chnl, send_data.data, send_data.length);
		}
#else
		env_acquire_sync_lock(OpenAMPInstPtr.lock);
		process_communication(OpenAMPInstPtr);
		matrix_mul();
		if(pq_qlength(OpenAMPInstPtr.send_queue) > 0) {
				send_data = pq_dequeue(OpenAMPInstPtr.send_queue);
				/* Send the result of matrix multiplication back to master. */
				rpmsg_send(app_rp_chnl, send_data->data, send_data->length);
		}
#endif
	}
}
Exemplo n.º 5
0
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
                void * priv, unsigned long src) {
    if ((*(int *) data) == SHUTDOWN_MSG) {
        remoteproc_resource_deinit(proc);
    } else {
        /* Send data back to master*/
        rpmsg_send(rp_chnl, data, len);
    }
}
Exemplo n.º 6
0
static void mat_mul_demo(void *unused_arg)
{
	int status = 0;

	(void)unused_arg;

	/* Create buffer to send data between RPMSG callback and processing task */
	buffer_create();

	/* Initialize HW and SW components/objects */
	init_system();

	/* Resource table needs to be provided to remoteproc_resource_init() */
	rsc_info.rsc_tab = (struct resource_table *)&resources;
	rsc_info.size = sizeof(resources);

	/* Initialize OpenAMP framework */
	status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created,
								 rpmsg_channel_deleted, rpmsg_read_cb,
								 &proc);
	if (RPROC_SUCCESS != status) {
		xil_printf("Error: initializing OpenAMP framework\n");
		return;
	}

	/* Stay in data processing loop until we receive a 'shutdown' message */
	while (1) {
		void *data;
		int len;

		/* wait for data... */
		buffer_pull(&data, &len);

		/* Process incoming message/data */
		if (*(int *)data == SHUTDOWN_MSG) {
			/* disable interrupts and free resources */
			remoteproc_resource_deinit(proc);

			/* Terminate this task */
			vTaskDelete(NULL);
			break;
		} else {
			env_memcpy(matrix_array, data, len);

			/* Process received data and multiple matrices. */
			Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result);

			/* Send result back */
			if (RPMSG_SUCCESS != rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix))) {
				xil_printf("Error: rpmsg_send failed\n");
			}
		}
	}
}
Exemplo n.º 7
0
/**
 * rpmsg_ns_callback
 *
 * This callback handles name service announcement from the remote device
 * and creates/deletes rpmsg channels.
 *
 * @param server_chnl - pointer to server channel control block.
 * @param data        - pointer to received messages
 * @param len         - length of received data
 * @param priv        - any private data
 * @param src         - source address
 *
 * @return void
 */
void rpmsg_ns_callback(struct rpmsg_channel *server_chnl, void *data, int len,
                void *priv, unsigned long src) {
    struct remote_device *rdev;
    struct rpmsg_channel *rp_chnl;
    struct rpmsg_ns_msg *ns_msg;
    struct llist *node;

    rdev = (struct remote_device *) priv;

    //FIXME: This assumes same name string size for channel name both on master
    //and remote. If this is not the case then we will have to parse the
    //message contents.

    ns_msg = (struct rpmsg_ns_msg *) data;
    ns_msg->name[len - 1] = '\0';

    if (ns_msg->flags & RPMSG_NS_DESTROY) {
        node = rpmsg_rdev_get_chnl_node_from_id(rdev, ns_msg->name);
        if (node) {
            rp_chnl = (struct rpmsg_channel *) node->data;
            if (rdev->channel_destroyed) {
                rdev->channel_destroyed(rp_chnl);
            }

            rpmsg_destroy_ept(rp_chnl->rp_ept);
            _rpmsg_delete_channel(rp_chnl);
        }
    } else {
        rp_chnl = _rpmsg_create_channel(rdev, ns_msg->name, 0x00, ns_msg->addr);
        if (rp_chnl) {
            rp_chnl->state = RPMSG_CHNL_STATE_ACTIVE;
            /* Create default endpoint for channel */
            rp_chnl->rp_ept = rpmsg_create_ept(rp_chnl, rdev->default_cb, rdev,
                            RPMSG_ADDR_ANY);
            
            if (rp_chnl->rp_ept) {
                rp_chnl->src = rp_chnl->rp_ept->addr;
                /*
                 * Echo back the NS message to remote in order to
                 * complete the connection stage. Remote will know the endpoint
                 * address from this point onward which will enable it to send
                 * message without waiting for any application level message from
                 * master.
                 */
                rpmsg_send(rp_chnl,data,len);
                if (rdev->channel_created) {
                    rdev->channel_created(rp_chnl);
                }
            }
        }
    }
}
Exemplo n.º 8
0
static int rpmsg_rfs_probe(struct rpmsg_channel *rpdev)
{
    int ret = 0;
    struct rpmsg_ns_msg nsm;

    nsm.addr = rpdev->dst;
    memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
    nsm.flags = 0;

    rpmsg_send(rpdev, &nsm, sizeof(nsm));

    return ret;
}
Exemplo n.º 9
0
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
                void * priv, unsigned long src) {
    
    if ((*(int *) data) == SHUTDOWN_MSG)
    {
		shutdown_called  = 1;
    }
    else
    { 
        /* Send data back to master*/	
        rpmsg_send(rp_chnl, data, len);
    }
}
Exemplo n.º 10
0
/**
 * qcom_rpm_smd_write - write @buf to @type:@id
 * @rpm:	rpm handle
 * @type:	resource type
 * @id:		resource identifier
 * @buf:	the data to be written
 * @count:	number of bytes in @buf
 */
int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
		       int state,
		       u32 type, u32 id,
		       void *buf,
		       size_t count)
{
	static unsigned msg_id = 1;
	int left;
	int ret;
	struct {
		struct qcom_rpm_header hdr;
		struct qcom_rpm_request req;
		u8 payload[];
	} *pkt;
	size_t size = sizeof(*pkt) + count;

	/* SMD packets to the RPM may not exceed 256 bytes */
	if (WARN_ON(size >= 256))
		return -EINVAL;

	pkt = kmalloc(size, GFP_KERNEL);
	if (!pkt)
		return -ENOMEM;

	mutex_lock(&rpm->lock);

	pkt->hdr.service_type = cpu_to_le32(RPM_SERVICE_TYPE_REQUEST);
	pkt->hdr.length = cpu_to_le32(sizeof(struct qcom_rpm_request) + count);

	pkt->req.msg_id = cpu_to_le32(msg_id++);
	pkt->req.flags = cpu_to_le32(state);
	pkt->req.type = cpu_to_le32(type);
	pkt->req.id = cpu_to_le32(id);
	pkt->req.data_len = cpu_to_le32(count);
	memcpy(pkt->payload, buf, count);

	ret = rpmsg_send(rpm->rpm_channel, pkt, size);
	if (ret)
		goto out;

	left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
	if (!left)
		ret = -ETIMEDOUT;
	else
		ret = rpm->ack_status;

out:
	kfree(pkt);
	mutex_unlock(&rpm->lock);
	return ret;
}
Exemplo n.º 11
0
/*
 * process requests from remote core
 */
static void rpmsg_rfs_recv(struct rpmsg_channel *rpdev, void *data, int len,
                           void *priv, u32 src)
{
    struct aipc_rfs_msg *msg = (struct aipc_rfs_msg*)data;
    int cmd = msg->msg_type;

    if (cmd < 0 || cmd >= ARRAY_SIZE(msg_handler)) {
        EMSG("unknown rfs command %d\n", cmd);
        return;
    }

    msg_handler[cmd](msg);
    rpmsg_send(rpdev, msg, msg->msg_len);
}
Exemplo n.º 12
0
static int reply( struct imt_rpc_req *req, int cmd, int len, uint32_t rsp )
{
	int ret;
	
	req->cmd = cmd;
	req->len = len;
	req->rsp = rsp;
	
	ret = rpmsg_send(rpdev, req, req->len);
	if (ret) {
		ERR("imt: rpsend failed: %d", ret);
		return 1;
	}
	return 0;
}
Exemplo n.º 13
0
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
			  void *priv, unsigned long src)
{
	if ((*(int *)data) == SHUTDOWN_MSG) {
		remoteproc_resource_deinit(proc);
	} else {
		env_memcpy(matrix_array, data, len);
		/* Process received data and multiple matrices. */
		Matrix_Multiply(&matrix_array[0], &matrix_array[1],
				&matrix_result);

		/* Send the result of matrix multiplication back to master. */
		rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix));
	}
}
Exemplo n.º 14
0
/* Application entry point */
int main() {
	
	int status;
    struct remote_proc *proc;
	int shutdown_msg = SHUTDOWN_MSG;
	int i;

    /* Switch to System Mode */
    SWITCH_TO_SYS_MODE();

    /* Initialize HW system components */
    init_system();

    status = remoteproc_init((void *) fw_name, rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_cb, &proc);
    
    if(!status)
    {
        status = remoteproc_boot(proc);
    }
    
    if(status)
    {
	    return -1;	
	}

    while (1) {
		
		if(shutdown_called == 1)
		{
		    break;
		}
        sleep();
    }

	/* Send shutdown message to remote */
	rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));

    for (i = 0; i < 100000; i++)
    {
	    sleep();
    }
    
	remoteproc_shutdown(proc);
		
	remoteproc_deinit(proc);
		
    return 0;
}
static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
{
	int ret;

	dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
					rpdev->src, rpdev->dst);

	/* send a message to our remote processor */
	ret = rpmsg_send(rpdev, MSG, strlen(MSG));
	if (ret) {
		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
		return ret;
	}

	return 0;
}
Exemplo n.º 16
0
static int connect(void)
{
	char buffer[16];
	struct imt_rpc_req *req = (struct imt_rpc_req*)buffer;
	int ret;
	
	// send a connect msg	
	req->id  = 0x00;
	req->len = 16;
	req->cmd = IMT_CONNECT;
	req->par = 0x42;
	req->rsp = 0x00;
 	
	ret = rpmsg_send(rpdev, req, req->len);
	if (ret) {
		ERR("imt: rpsend failed: %d", ret);
		return ret;
	}
	return 0;
}
static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
						void *priv, u32 src)
{
	int ret;
	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;
	}

	/* send a new message now */
	ret = rpmsg_send(rpdev, MSG, strlen(MSG));
	if (ret)
		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
/* Application entry point */
int main() {

    int status;
    struct remote_proc *proc;
    int i;
	int shutdown_msg = SHUTDOWN_MSG;
    
    /* Switch to System Mode */
    SWITCH_TO_SYS_MODE();

    /* Initialize HW system components */
    init_system();
    
    status = remoteproc_init((void *) fw_name, rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_cb, &proc);
    
    if(!status)
    {
        status = remoteproc_boot(proc);
    }
    
    if(status)
    {
	    return -1;	
	}
    while (1) {
		
        if (int_flag) {
			
			if(shutdown_called == 1)
			{
			    break;	
			}

			 /* Process received data and multiple matrices. */
			Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result);

			/* Send the result of matrix multiplication back to master. */
			rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix));
			
			int_flag = 0;
			
			sleep();
        }
        
        sleep();
    }
    
    /* Send shutdown message to remote */
	rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));

    for (i = 0; i < 100000; i++)
    {
	    sleep();
    }
    
    remoteproc_shutdown(proc);
        
    remoteproc_deinit(proc);

    return 0;
}