Exemple #1
0
/**
 * remoteproc_resource_init
 *
 * Initializes resources for remoteproc remote configuration. Only
 * remoteproc remote applications are allowed to call this function.
 *
 * @param rsc_info          - pointer to resource table info control
 * 							  block
 * @param channel_created   - callback function for channel creation
 * @param channel_destroyed - callback function for channel deletion
 * @param default_cb        - default callback for channel I/O
 * @param rproc_handle      - pointer to new remoteproc instance
 *
 * @param returns - status of function execution
 *
 */
int remoteproc_resource_init(struct rsc_table_info *rsc_info,
                rpmsg_chnl_cb_t channel_created, rpmsg_chnl_cb_t channel_destroyed,
                rpmsg_rx_cb_t default_cb, struct remote_proc** rproc_handle) {

    struct remote_proc *rproc;
    int status;

    if(!rsc_info) {
        return RPROC_ERR_PARAM;
    }

    /* Initialize environment component */
    status = env_init();
    if (status != RPROC_SUCCESS) {
        return status;
    }

    rproc = env_allocate_memory(sizeof(struct remote_proc));
    if (rproc) {
        env_memset(rproc, 0x00, sizeof(struct remote_proc));
        /* There can be only one master for remote configuration so use the
         * rsvd cpu id for creating hil proc */
        rproc->proc = hil_create_proc(HIL_RSVD_CPU_ID);
        if (rproc->proc) {
            /* Parse resource table */
            status = handle_rsc_table(rproc, rsc_info->rsc_tab, rsc_info->size);
            if (status == RPROC_SUCCESS) {
                /* Initialize RPMSG "messaging" component */
                *rproc_handle = rproc;
                status = rpmsg_init(rproc->proc->cpu_id, &rproc->rdev,
                                channel_created, channel_destroyed, default_cb,
                                RPMSG_MASTER);
            } else {
                status = RPROC_ERR_NO_RSC_TABLE;
            }
        } else {
            status = RPROC_ERR_CPU_ID;
        }
    } else {
        status = RPROC_ERR_NO_MEM;
    }

    /* Cleanup in case of error */
    if (status != RPROC_SUCCESS) {
         *rproc_handle = 0;
        (void) remoteproc_resource_deinit(rproc);
        return status;
    }
    return status;
}
Exemple #2
0
/**
 * remoteproc_init
 *
 * Initializes resources for remoteproc master configuration. Only
 * remoteproc master applications are allowed to call this function.
 *
 * @param fw_name           - name of frimware
 * @param channel_created   - callback function for channel creation
 * @param channel_destroyed - callback function for channel deletion
 * @param default_cb        - default callback for channel I/O
 * @param rproc_handle      - pointer to new remoteproc instance
 *
 * @param returns - status of function execution
 *
 */
int remoteproc_init(char *fw_name, rpmsg_chnl_cb_t channel_created,
                rpmsg_chnl_cb_t channel_destroyed, rpmsg_rx_cb_t default_cb,
                struct remote_proc** rproc_handle) {

    struct remote_proc *rproc;
    struct resource_table *rsc_table;
    unsigned int fw_addr, fw_size, rsc_size;
    int status, cpu_id;

    if (!fw_name) {
        return RPROC_ERR_PARAM;
    }

    /* Initialize environment component */
    status = env_init();
    if (status != RPROC_SUCCESS) {
        return status;
    }

    rproc = env_allocate_memory(sizeof(struct remote_proc));
    if (rproc) {
        env_memset((void *) rproc, 0x00, sizeof(struct remote_proc));
        /* Get CPU ID for the given firmware name */
        cpu_id = hil_get_cpuforfw(fw_name);
        if (cpu_id >= 0) {
            /* Create proc instance */
            rproc->proc = hil_create_proc(cpu_id);
            if (rproc->proc) {
                /* Retrieve firmware attributes */
                status = hil_get_firmware(fw_name, &fw_addr, &fw_size);
                if (!status) {
                    /* Initialize ELF loader - currently only ELF format is supported */
                    rproc->loader = remoteproc_loader_init(ELF_LOADER);
                    if (rproc->loader) {
                        /* Attach the given firmware with the ELF parser/loader */
                        status = remoteproc_loader_attach_firmware(
                                        rproc->loader, (void *) fw_addr);
                    } else {
                        status = RPROC_ERR_LOADER;
                    }
                }
            } else {
                status = RPROC_ERR_NO_MEM;
            }
        } else {
            status = RPROC_ERR_INVLD_FW;
        }
    } else {
        status = RPROC_ERR_NO_MEM;
    }

    if (!status) {
        rproc->role = RPROC_MASTER;

        /* Get resource table from firmware */
        rsc_table = remoteproc_loader_retrieve_resource_section(rproc->loader,
                        &rsc_size);
        if (rsc_table) {
            /* Parse resource table */
            status = handle_rsc_table(rproc, rsc_table, rsc_size);
        } else {
            status = RPROC_ERR_NO_RSC_TABLE;
        }
    }

    /* Cleanup in case of error */
    if (status != RPROC_SUCCESS) {
        (void) remoteproc_deinit(rproc);
        return status;
    }

    rproc->channel_created = channel_created;
    rproc->channel_destroyed = channel_destroyed;
    rproc->default_cb = default_cb;

    *rproc_handle = rproc;

    return status;
}
Exemple #3
0
/**
 * rpmsg_rdev_init
 *
 * This function creates and initializes the remote device. The remote device
 * encapsulates virtio device.
 *
 * @param rdev              - pointer to newly created remote device
 * @param dev-id            - ID of device to create , remote cpu id
 * @param role              - role of the other device, Master or Remote
 * @param channel_created   - callback function for channel creation
 * @param channel_destroyed - callback function for channel deletion
 * @param default_cb        - default callback for channel
 *
 * @return - status of function execution
 *
 */
int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,
		    rpmsg_chnl_cb_t channel_created,
		    rpmsg_chnl_cb_t channel_destroyed, rpmsg_rx_cb_t default_cb)
{

	struct remote_device *rdev_loc;
	struct virtio_device *virt_dev;
	struct hil_proc *proc;
	struct proc_shm *shm;
	int status;

	/* Initialize HIL data structures for given device */
	proc = hil_create_proc(dev_id);

	if (!proc) {
		return RPMSG_ERR_DEV_ID;
	}

	/* Create software representation of remote processor. */
	rdev_loc =
	    (struct remote_device *)
	    env_allocate_memory(sizeof(struct remote_device));

	if (!rdev_loc) {
		return RPMSG_ERR_NO_MEM;
	}

	env_memset(rdev_loc, 0x00, sizeof(struct remote_device));
	status = env_create_mutex(&rdev_loc->lock, 1);

	if (status != RPMSG_SUCCESS) {

		/* Cleanup required in case of error is performed by caller */
		return status;
	}

	rdev_loc->proc = proc;
	rdev_loc->role = role;
	rdev_loc->channel_created = channel_created;
	rdev_loc->channel_destroyed = channel_destroyed;
	rdev_loc->default_cb = default_cb;

	/* Restrict the ept address - zero address can't be assigned */
	rdev_loc->bitmap[0] = 1;

	/* Initialize the virtio device */
	virt_dev = &rdev_loc->virt_dev;
	virt_dev->device = proc;
	virt_dev->func = &rpmsg_rdev_config_ops;
	if (virt_dev->func->set_features != RPMSG_NULL) {
		virt_dev->func->set_features(virt_dev, proc->vdev.dfeatures);
	}

	if (rdev_loc->role == RPMSG_REMOTE) {
		/*
		 * Since device is RPMSG Remote so we need to manage the
		 * shared buffers. Create shared memory pool to handle buffers.
		 */
		shm = hil_get_shm_info(proc);
		rdev_loc->mem_pool =
		    sh_mem_create_pool(shm->start_addr, shm->size,
				       RPMSG_BUFFER_SIZE);

		if (!rdev_loc->mem_pool) {
			return RPMSG_ERR_NO_MEM;
		}
	}

	/* Initialize channels for RPMSG Remote */
	status = rpmsg_rdev_init_channels(rdev_loc);

	if (status != RPMSG_SUCCESS) {
		return status;
	}

	*rdev = rdev_loc;

	return RPMSG_SUCCESS;
}