summaryrefslogtreecommitdiff
path: root/rust/gpio.html
diff options
context:
space:
mode:
Diffstat (limited to 'rust/gpio.html')
-rw-r--r--rust/gpio.html147
1 files changed, 147 insertions, 0 deletions
diff --git a/rust/gpio.html b/rust/gpio.html
new file mode 100644
index 0000000..76158e0
--- /dev/null
+++ b/rust/gpio.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="generator" content="AsciiDoc 9.0.0rc1">
+<title>Rust based vhost-user I2C backend</title>
+</head>
+<body>
+<h1>Rust based vhost-user I2C backend</h1>
+<p>
+</p>
+<a name="preamble"></a>
+<p>There is a growing trend towards virtualization in areas other than the
+traditional server environment. The server environment is uniform in nature, but
+as we move towards a richer ecosystem in automotive, medical, general mobile and
+the IoT spaces, more device abstractions and way richer organizations are
+needed. <a href="https://www.linaro.org/projects/#automotive_STR">Linaro&#8217;s Project
+Stratos</a> is working towards developing hypervisor agnostic abstract devices
+leveraging virtio and extending hypervisor interfaces and standards to allow all
+architectures.</p>
+<p>The Virtual Input/Output device (Virtio) standard provides an open interface for
+guest virtual machines (VMs) to access simplified "virtual" devices, such as
+network adapters and block devices, in a paravirtualized environment. Virtio
+provides a straightforward, efficient, standard and extensible mechanism for
+virtual devices, rather than a per-environment or per-OS mechanism.</p>
+<p>The backend (BE) virtio driver, implemented in the hypervisor running on the host,
+exposes the virtio device to the guest OS through a transport method, like PCI
+or MMIO. The virtio device, by design, looks like a physical device to the guest
+OS, which implements a frontend (FE) virtio driver compatible with the virtio
+device exposed by the hypervisor. The virtio device and driver communicate based
+on a set of predefined protocols as defined by the
+<a href="https://github.com/oasis-tcs/virtio-spec">virtio specification</a>, which is
+maintained by <a href="https://www.oasis-open.org/org/">OASIS</a>. The FE driver can
+implement zero or more Virtual queues (virtqueues), as defined by the virtio
+specification. The virtqueues are the mechanism of bulk data transport between
+FE (guest) and BE (host) drivers. These are normally implemented as standard
+ring buffers in the guest physical memory by the FE drivers. The BE drivers
+parse the virtqueues to obtain the request descriptors, process them and queue
+the response descriptors back to the virtqueue.</p>
+<p>The FE virtio driver at the guest and the virtio specification are normally
+independent of where the virtqueue processing happens at the host, in-kernel or
+userspace. The vhost protocol allows the virtio virtqueue processing at the
+host to be offloaded to another element, a user process or a kernel module. The
+vhost protocol when implemented in userspace is called as "vhost-user". Since
+Linaro&#8217;s Project Stratos is targeting hypervisor agnostic BE drivers, we decided
+to work over the existing vhost-user protocol. This article focuses on the Rust
+based vhost-user implementation for I2C devices.</p>
+<hr>
+<h2><a name="_virtio_i2c_specification"></a>Virtio I2C Specification</h2>
+<p>The Virtio
+<a href="https://github.com/oasis-tcs/virtio-spec/blob/master/virtio-i2c.tex">specification</a>
+for I2C and the Linux
+<a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/i2c/busses/i2c-virtio.c">i2c-virtio</a>
+driver are upstreamed by Jie Deng (Intel), who tested his work with the
+<a href="https://projectacrn.org">ACRN</a> hypervisor for IoT development. Both
+specification and driver received updates later on by Viresh Kumar (Linaro), to
+improve buffer management and allow zero-length transactions. Lets go through
+the I2C virtio specification briefly.</p>
+<p>virtio-i2c is a virtual I2C adapter device, which provides a way to flexibly
+organize and use the host I2C controlled devices from the guest. All
+communication between the FE and BE drivers happens over the "requestq"
+virtqueue. It is also mandatory for both the sides to implement the
+<code>VIRTIO_I2C_F_ZERO_LENGTH_REQUEST</code> feature, which allows zero-length transfers
+(like SMBus Quick) to take place. The I2C requests always originate at the guest
+FE driver, where the FE driver puts one or more I2C requests, represented by the
+<code>struct virtio_i2c_req</code>, on the requestq virtqueue. The I2C requests may or may
+not be be interdependent. If multiple requests are received together, then the
+host BE driver must process the requests in the order they are received on the
+virtqueue.</p>
+<table border="0" bgcolor="#e8e8e8" width="100%" cellpadding="4"><tr><td>
+<pre><code>struct virtio_i2c_req {
+ struct virtio_i2c_out_hdr out_hdr;
+ u8 buf[];
+ struct virtio_i2c_in_hdr in_hdr;
+};</code></pre>
+</td></tr></table>
+<p>Each I2C virtio request consists of an <code>out_hdr</code> (set by the FE driver), followed by
+an optional buffer of some length (set by FE or BE driver based on if the
+transaction is write or read), followed by an <code>in_hdr</code> (set by the BE driver). The
+buffer is not sent for zero-length requests, like for the SMBus Quick command
+where no data is required to be sent or received.</p>
+<table border="0" bgcolor="#e8e8e8" width="100%" cellpadding="4"><tr><td>
+<pre><code>struct virtio_i2c_out_hdr {
+ le16 addr;
+ le16 padding;
+ le32 flags;
+};</code></pre>
+</td></tr></table>
+<p>The <code>out_hdr</code> is represented by the <code>struct virtio_i2c_out_hdr</code>. The <code>addr</code>
+field of the header is the address of the I2C controlled device. Both 7-bit and
+10-bit address modes are supported by the specification (though only 7-bit mode
+is supported by the current implementation of the Linux FE driver). The <code>flags</code>
+field is used to mark a request "Read or write" (<code>VIRTIO_I2C_FLAGS_M_RD</code> (bit
+1)) or to show dependency between multiple requests
+(<code>VIRTIO_I2C_FLAGS_FAIL_NEXT</code> (bit 0)).</p>
+<p>As described earlier, the <code>buf</code> is optional. For "write" transactions, it is
+pre-filled by the FE driver and read by the BE driver. For "read" transactions,
+it is filled by the BE driver and read by the FE driver after the response is
+received.</p>
+<table border="0" bgcolor="#e8e8e8" width="100%" cellpadding="4"><tr><td>
+<pre><code>struct virtio_i2c_in_hdr {
+ u8 status;
+};</code></pre>
+</td></tr></table>
+<p>The <code>in_hdr</code> is represented by the <code>struct virtio_i2c_in_hdr</code> and is used by the
+host BE driver to notify the guest with the status of the transfer with
+<code>VIRTIO_I2C_MSG_OK</code> or <code>VIRTIO_I2C_MSG_ERR</code>.</p>
+<p>Please refer the Virtio I2C
+<a href="https://github.com/oasis-tcs/virtio-spec/blob/master/virtio-i2c.tex">specification</a>
+of more details.</p>
+<hr>
+<h2><a name="_rust_i2c_backend_be"></a>Rust I2C backend (BE)</h2>
+<p>Rust is the next big thing disrupting the Linux world and most of us are already
+aware of the <a href="https://github.com/Rust-for-Linux">Rust for Linux</a> project
+slowly making its way into the Linux kernel. Rust is a multi-paradigm,
+general-purpose programming language designed for performance and safety. It
+brings a lot of benefits to the table, especially
+<a href="https://en.wikipedia.org/wiki/Memory_safety">memory-safety</a> and safe
+<a href="https://en.wikipedia.org/wiki/Concurrency_(computer_science)">concurrency</a>.
+It was an easy choice to pick for developing hypervisor agnostic I2C BE driver.</p>
+<p>The <a href="https://github.com/rust-vmm">rust-vmm</a> project, an open-source
+initiative, was started back in late 2018, with the aim to share virtualization
+packages. The rust-vmm project lets one build custom
+<a href="https://en.wikipedia.org/wiki/Hypervisor">Virtual Machine Monitors (VMMs)
+and hypervisors</a>. This empowers other projects to quickly develop virtualization
+solutions, by reusing the components provided by rust-vmm, and better focus on
+key differentiators of their products. The rust-vmm project is organized as a
+shared ownership project that so far includes contributions from Alibaba, AWS,
+Cloud Base, Google, Intel, Linaro, Red Hat and other individual contributors.
+The components provided by rust-vmm are already used by several projects, like
+Amazon&#8217;s <a href="https://github.com/firecracker-microvm/firecracker">Firecracker</a>
+and Intel&#8217;s <a href="https://github.com/cloud-hypervisor/cloud-hypervisor">Cloud
+Hypervisor</a>. The rust-vmm project currently roughly 30 repositories (or Rust
+crates, equivalent of a C library), where each crate plays a special role in the
+development of a fully functioning VMM.</p>
+<p>One such component is the
+<a href="https://crates.io/crates/vhost-user-backend">vhost-user-backend</a> crate,
+which has recently made its way to <a href="https://crates.io/">crates.io</a>, the Rust
+community’s crate registry. The vhost-user-backend crate provides a framework to implement the vhost-user backend services</p>
+<p></p>
+<p></p>
+<hr><p><small>
+Last updated
+ 2022-01-04 12:48:12 IST
+</small></p>
+</body>
+</html>