generated from rust-vmm/crate-template
-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vhost-device-spi: Add initial implementation
This program is a vhost-user backend that emulates a VirtIO SPI bus. This program takes the layout of the spi bus and its devices on the host OS and then talks to them via the /dev/spidevX.Y interface when a request comes from the guest OS for a SPI device. The implementation corresponds with the specification: https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi Signed-off-by: Haixu Cui <[email protected]>
- Loading branch information
1 parent
7efcb34
commit d12bf98
Showing
14 changed files
with
3,219 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"coverage_score": 77.63, | ||
"coverage_score": 75.76, | ||
"exclude_path": "", | ||
"crate_features": "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Changelog | ||
## [Unreleased] | ||
|
||
### Added | ||
|
||
### Changed | ||
|
||
### Fixed | ||
|
||
### Deprecated | ||
|
||
## [0.1.0] | ||
|
||
First release | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[package] | ||
name = "vhost-device-spi" | ||
version = "0.1.0" | ||
authors = ["Haixu Cui <[email protected]>"] | ||
description = "vhost spi backend device" | ||
repository = "https://github.com/rust-vmm/vhost-device" | ||
readme = "README.md" | ||
keywords = ["spi", "vhost", "virt", "backend"] | ||
categories = ["virtualization"] | ||
license = "Apache-2.0 OR BSD-3-Clause" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[features] | ||
xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] | ||
|
||
[dependencies] | ||
clap = { version = "4.5", features = ["derive"] } | ||
env_logger = "0.11" | ||
libc = "0.2" | ||
log = "0.4" | ||
thiserror = "1.0" | ||
vhost = { version = "0.11", features = ["vhost-user-backend"] } | ||
vhost-user-backend = "0.15" | ||
virtio-bindings = "0.2.2" | ||
virtio-queue = "0.12" | ||
vm-memory = "0.14.1" | ||
vmm-sys-util = "0.12" | ||
bitflags = "2.4.0" | ||
|
||
[dev-dependencies] | ||
assert_matches = "1.5" | ||
virtio-queue = { version = "0.12", features = ["test-utils"] } | ||
vm-memory = { version = "0.14.1", features = ["backend-mmap", "backend-atomic"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../LICENSE-APACHE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../LICENSE-BSD-3-Clause |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# vhost-device-spi - SPI emulation backend daemon | ||
|
||
## Description | ||
This program is a vhost-user backend that emulates a VirtIO SPI bus. | ||
This program takes the layout of the spi bus and its devices on the host | ||
OS and then talks to them via the `/dev/spidevX.Y` interface when a request | ||
comes from the guest OS for a SPI device. | ||
|
||
## Synopsis | ||
|
||
```shell | ||
vhost-device-spi [OPTIONS] | ||
``` | ||
|
||
## Options | ||
```text | ||
-h, --help | ||
Print help. | ||
-s, --socket-path=PATH | ||
Location of vhost-user Unix domain sockets, this path will be suffixed with | ||
0,1,2..socket_count-1. | ||
-c, --socket-count=INT | ||
Number of guests (sockets) to attach to, default set to 1. | ||
-l, --device=SPI-DEVICES | ||
Spi device full path at the host OS in the format: | ||
/dev/spidevX.Y | ||
Here, | ||
X: is spi controller's bus number. | ||
Y: is chip select index. | ||
``` | ||
|
||
## Examples | ||
|
||
### Dependencies | ||
For testing the device the required dependencies are: | ||
- Linux: | ||
- Integrate *virtio-spi* driver: | ||
- https://lwn.net/Articles/966715/ | ||
- Set `CONFIG_SPI_VIRTIO=y` | ||
- QEMU: | ||
- Integrate vhost-user-spi QEMU device: | ||
- https://lore.kernel.org/all/[email protected]/ | ||
|
||
### Test the device | ||
First start the daemon on the host machine:: | ||
|
||
````suggestion | ||
```console | ||
vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0" | ||
``` | ||
```` | ||
|
||
The QEMU invocation needs to create a chardev socket the device spi | ||
use to communicate as well as share the guests memory over a memfd. | ||
|
||
````suggestion | ||
```console | ||
qemu-system-aarch64 -m 1G \ | ||
-chardev socket,path=/home/root/vspi.sock0,id=vspi \ | ||
-device vhost-user-spi-pci,chardev=vspi,id=spi \ | ||
-object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \ | ||
-numa node,memdev=mem \ | ||
... | ||
``` | ||
```` | ||
|
||
## License | ||
|
||
This project is licensed under either of | ||
|
||
- [Apache License](http://www.apache.org/licenses/LICENSE-2.0), Version 2.0 | ||
- [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Linux SPI bindings | ||
// | ||
// Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. | ||
// Haixu Cui <[email protected]> | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause | ||
|
||
use bitflags::bitflags; | ||
use vmm_sys_util::{ioctl_ioc_nr, ioctl_ior_nr, ioctl_iow_nr}; | ||
|
||
/// Describes a single SPI transfer | ||
#[derive(Debug)] | ||
#[repr(C)] | ||
pub struct SpiIocTransfer { | ||
/// Holds pointer to userspace buffer with transmit data, or null | ||
pub tx_buf: u64, | ||
/// Holds pointer to userspace buffer for receive data, or null. | ||
pub rx_buf: u64, | ||
/// Length of tx and rx buffers, in bytes. | ||
pub len: u32, | ||
/// Temporary override of the device's bitrate. | ||
pub speed_hz: u32, | ||
/// If nonzero, how long to delay after the last bit transfer | ||
/// before optionally deselecting the device before the next transfer. | ||
pub delay_usecs: u16, | ||
/// Temporary override of the device's wordsize. | ||
pub bits_per_word: u8, | ||
/// True to deselect device before starting the next transfer. | ||
pub cs_change: u8, | ||
/// Number of bits used for writing. | ||
pub tx_nbits: u8, | ||
/// Number of bits used for reading. | ||
pub rx_nbits: u8, | ||
/// If nonzero, how long to wait between words within one | ||
/// transfer. This property needs explicit support in the SPI controller, | ||
/// otherwise it is silently ignored | ||
pub word_delay_usecs: u8, | ||
pub _padding: u8, | ||
} | ||
|
||
/// Linux SPI definitions | ||
/// IOCTL commands, refer Linux's Documentation/spi/spidev.rst for further details. | ||
const _IOC_SIZEBITS: u32 = 14; | ||
const _IOC_SIZESHIFT: u32 = 16; | ||
const SPI_IOC_MESSAGE_BASE: u32 = 0x40006b00; | ||
|
||
ioctl_ior_nr!(SPI_IOC_RD_BITS_PER_WORD, 107, 3, u8); | ||
ioctl_iow_nr!(SPI_IOC_WR_BITS_PER_WORD, 107, 3, u8); | ||
ioctl_ior_nr!(SPI_IOC_RD_MAX_SPEED_HZ, 107, 4, u32); | ||
ioctl_iow_nr!(SPI_IOC_WR_MAX_SPEED_HZ, 107, 4, u32); | ||
ioctl_ior_nr!(SPI_IOC_RD_MODE32, 107, 5, u32); | ||
ioctl_iow_nr!(SPI_IOC_WR_MODE32, 107, 5, u32); | ||
|
||
// Corresponds to the SPI_IOC_MESSAGE macro in Linux | ||
pub fn spi_ioc_message(n: u32) -> u64 { | ||
let mut size: u32 = 0; | ||
if n * 32 < (1 << _IOC_SIZEBITS) { | ||
size = n * 32; | ||
} | ||
(SPI_IOC_MESSAGE_BASE | (size << _IOC_SIZESHIFT)) as u64 | ||
} | ||
|
||
bitflags! { | ||
pub struct LnxSpiMode: u32 { | ||
const CPHA = 1 << 0; | ||
const CPOL = 1 << 1; | ||
const CS_HIGH = 1 << 2; | ||
const LSB_FIRST = 1 << 3; | ||
const LOOP = 1 << 5; | ||
const TX_DUAL = 1 << 8; | ||
const TX_QUAD = 1 << 9; | ||
const TX_OCTAL = 1 << 13; | ||
const RX_DUAL = 1 << 10; | ||
const RX_QUAD = 1 << 11; | ||
const RX_OCTAL = 1 << 14; | ||
} | ||
} |
Oops, something went wrong.