[LINUX] Remote Processor Framework (2/3)

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/remoteproc.txt

Remote Processor Framework

API for implementors

  struct rproc *rproc_alloc(struct device *dev, const char *name,
				const struct rproc_ops *ops,
				const char *firmware, int len)

Allocate a new remote processor handle, but don't register it yet. Required parameters are the underlying device, the name of this remote processor, platform-specific ops handlers, the name of the firmware to boot this rproc with, and the length of private data needed by the allocating rproc driver (in bytes).

Reserve a new remote processor handle, but have not registered yet. The required parameters are the underlying device, the name of this remote processor, platform-specific ops handlers, the name of the firmware to boot this rpoc, and the length of private data required by the rpoc driver (byte). Unit).

This function should be used by rproc implementations during initialization of the remote processor.

This function will be used by the rpoc implementation during the initialization of the remote processor.

After creating an rproc handle using this function, and when ready, implementations should then call rproc_add() to complete the registration of the remote processor.

After using this function to generate the rproc handler, when ready, the implementation calls rpoc_add () to complete the remote processor registration.

On success, the new rproc is returned, and on failure, NULL.

If successful, the new rpoc will be the return value, a null that failed.

note::

never directly deallocate @rproc, even if it was not registered yet. Instead, when you need to unroll rproc_alloc(), use rproc_free().

Do not "absolutely" deallocate directly with rpoc. If it wasn't registered, use rproc_free () instead to revert to rproc_alloc ().

  void rproc_free(struct rproc *rproc)

Free an rproc handle that was allocated by rproc_alloc.

Release the rpoc handle allocated by rproc_alloc ().

This function essentially unrolls rproc_alloc(), by decrementing the rproc's refcount. It doesn't directly free rproc; that would happen only if there are no other references to rproc and its refcount now dropped to zero.

This function reduces rproc's refcount and reverts to rproc_alloc (). This does not release cproc directly. It is released only when rpoc is not referenced by others and refcount drops to 0.

  int rproc_add(struct rproc *rproc)

Register @rproc with the remoteproc framework, after it has been allocated with rproc_alloc().

After allocating with rproc_alloc (), register rpoc with remoteproc framework.

This is called by the platform-specific rproc implementation, whenever a new remote processor device is probed.

This is called by the platform-specific rpoc implementation every time a new remote processor device is probed.

Returns 0 on success and an appropriate error code otherwise.

Returns 0 on success, otherwise an error is probably the return value.

Note: this function initiates an asynchronous firmware loading context, which will look for virtio devices supported by the rproc's firmware.

Note: This function starts the firmware load context asynchronously and looks for the virtio device supported by the firmware in rproc.

If found, those virtio devices will be created and added, so as a result of registering this remote processor, additional virtio drivers might get probed.

If found, those virtio devices will be generated and added. Therefore, as a result of registering this remote processor, additional virtio drivers may be added.

  int rproc_del(struct rproc *rproc)

Unroll rproc_add().

Revert to rproc_add ().

This function should be called when the platform specific rproc implementation decides to remove the rproc device. it should only be called if a previous invocation of rproc_add() has completed successfully.

This function is called when removing the platform-specific rpoc implementation from the proc device. It should only be called if rpoc_add () is completely successful.

After rproc_del() returns, @rproc is still valid, and its last refcount should be decremented by calling rproc_free().

After processing returns from rproc_del (), rproc is still valid and its final refcount is decremented by calling rpoc_free ().

Returns 0 on success and -EINVAL if @rproc isn't valid.

Returns 0 on success, -EINVAL on non-valid rproc.

  void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type)

Report a crash in a remoteproc

Report a remoteproc crash.

This function must be called every time a crash is detected by the platform specific rproc implementation. This should not be called from a non-remoteproc driver. This function can be called from atomic/interrupt context.

This function should be called every time a crash is detected by the platform-specific rpoc implementation. It should only be called by the remote-proc driver. This function can be called from the atomic / interrupt context.

Implementation callbacks

These callbacks should be provided by platform-specific remoteproc drivers::

These callbacks are provided by the platform-specific remoteproc driver.


  /**
   * struct rproc_ops - platform-specific device handlers
   * @start:	power on the device and boot it
   * @stop:	power off the device
   * @kick:	kick a virtqueue (virtqueue id given as a parameter)
   */
  /**
   * struct rproc_ops - platform-specific device handlers
   * @start:Power on and start
   * @stop:Power off
   * @kick:Execute virtqueue (virtqueue is given as a parameter)
   */

  struct rproc_ops {
	int (*start)(struct rproc *rproc);
	int (*stop)(struct rproc *rproc);
	void (*kick)(struct rproc *rproc, int vqid);
  };

Every remoteproc implementation should at least provide the ->start and ->stop handlers. If rpmsg/virtio functionality is also desired, then the ->kick handler should be provided as well.

Each remoteproc implementation is provided with at least-> start,-> stop handlers. If you also need the rpmsg / virtio feature,-> kick handler is also provided.

The ->start() handler takes an rproc handle and should then power on the device and boot it (use rproc->priv to access platform-specific private data). The boot address, in case needed, can be found in rproc->bootaddr (remoteproc core puts there the ELF entry point). On success, 0 should be returned, and on failure, an appropriate error code.

-> start () handler uses rproc handle to power on and start the device (use rpoc-> private as platform-specific private data). If you need the boot address, you can find it with rptoc-> bootaddr () (remoteproc core sets this as the ELF entry point). If it succeeds, it returns 0, and if it fails, it contains the appropriate error code.

The ->stop() handler takes an rproc handle and powers the device down.  On success, 0 is returned, and on failure, an appropriate error code.

The-> stop () handler turns off the device with the rpoc handle. If it succeeds, it returns 0, and if it fails, it contains the appropriate error code.

The ->kick() handler takes an rproc handle, and an index of a virtqueue where new message was placed in. Implementations should interrupt the remote processor and let it know it has pending messages. Notifying remote processors the exact virtqueue index to look in is optional: it is easy (and not too expensive) to go through the existing virtqueues and look for new buffers in the used rings.

-> kick () handler involves rpoc handle and index of virtqueue set as new message. In the implementation, we know that the remote processor's ring interrupt, message, is pending. Notifying the remote processor of the exact virtqueue index to look up is optional. It's easy to look at an existing virt queue to find a new buffer in a used ring (not expensive to compute).


Originally, it is a part of the Linux Kernel source code, so it will be treated as GPLv2 (recognition that it should be).

https://www.kernel.org/doc/html/latest/index.html

Licensing documentation

The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.

https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

Recommended Posts

Remote Processor Framework (3/3)
Remote Processor Framework (1/3)
Remote Processor Framework (2/3)