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

```c
  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).

新しいremote processor handleを確保しますが、まだ登録は行いません。要求されるパラメータは、基礎となるデバイス、このremote processorの名称、プラットフォーク特有のops handlers, このrpocを起動するためのファームウェアの名称、そして、rpoc driverが必要とするprivate dataの長さ(byte単位) です。

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

この関数は、remote processorの初期化している間の、rpoc 実装によって利用されるでしょう。

> 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. 

この関数を用いてrproc handlerを生成した後、準備ができたら、実装ではremote processorの登録を完了するために、rpoc_add()を呼び出します。

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

成功したら、新しいrpocが戻り値になります、失敗したNULLです。

## note::

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

「絶対に」 rpocで直接deallocateしないでください。仮にそれが登録されていなかったとしても、その代わりに、rproc_alloc()を基に戻すためには、rproc_free()を使ってください。

```c
  void rproc_free(struct rproc *rproc)
```

> Free an rproc handle that was allocated by rproc_alloc.

rproc_alloc()で確保したrpoc handleを開放します。

> 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.

この関数は、rprocのrefcountを減らし、rproc_alloc()を基に戻します。これは直接cprocを開放しません。もし、他からrpocが参照されておらず、refcountが0にまで落ち込んだ時だけ、解放します。

```c
  int rproc_add(struct rproc *rproc)
```

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

rproc_alloc()で確保した後、rpocをremoteproc frameworkに登録します。

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

これは、新しいremote processor deviceがprobeされるたびに、platform特有のrpoc実装によって呼び出されます。

> Returns 0 on success and an appropriate error code otherwise. 

成功時には0が、それ以外の場合にはおそらくエラーが戻り値になります。

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

注意：この関数は非同期にfirmware load contextを開始し、rprocのfirmwareがサポートするvirtio deviceを探します。

> 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.

もし見つかった場合、それらのvirtio deviceは生成され追加されます。そのため、このremote processorを登録した結果、追加のvirtio driverが追加されることがあります。

```c
  int rproc_del(struct rproc *rproc)
```

> Unroll rproc_add().

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.

この関数は、platform特有のrpoc実装をproc deviceから削除する時に呼び出します。それは、rpoc_add()が完全に成功した場合にだけ、呼び出す必要ががあります。

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

rproc_del()から処理が戻った後、rprocはまだ有効であり、その最後のrefcountはrpoc_free()を呼び出す事で減少します。

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

成功した場合には0が、有効なrprocではない場合には-EINVALが帰ります。

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

> Report a crash in a remoteproc

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.

この関数は、platform特有のrpoc実装によって、crashが検知されたら毎回呼ばれるべき関数です。これは、remote-proc driver以外から呼ばれるべきではありません。この関数は、atomic/interrupt contextから呼び出すことができます。

# Implementation callbacks

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

これらのコールバックは、platform特有のremoteproc driverによって提供されます。

```c

  /**
   * 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:	電源投入及び起動
   * @stop:	電源切断
   * @kick:	virtqueueを実行（virtqueueはパラメータで与えられる）
   */

  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.

それぞれのremoteproc実装には、->start, ->stop handlerが少なくとも提供されます。もし、rpmsg/virtio 機能がまた必要であれば、->kick handlerもまた提供されます。

> 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は、rproc handleを用い、デバイスの電源を投入し起動します（rpoc->priveを、platform特有のprivate dataとして用います）。起動アドレスが必要な場合には、rptoc->bootaddr()にて見つけることができます（remoteproc coreはこれをELF entry pointとしてセットします）。成功した場合には0が戻り、失敗した場合には適切なエラーコードが入ります。

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

-> stop() handlerは、rpoc handleを伴い、デバイスの電源を切断します。成功した場合には0が戻り、失敗した場合には適切なエラーコードが入ります。

> 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はrpoc handleと、新しいメッセージをとして設定されるvirtqueueのindexを伴います。実装ではremote processorの輪割り込み、messageがpendingされていることを知ります。検索する正確なvirtqueueインデックスをremote processorに通知することはオプションです。既存のvirtqueueを調べて、使用済みのringで新しいbufferを探すのは簡単です（計算コストは高くありません）。

---
もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる（はずの認識）。

> 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