Virtio-GPIO

virtio-gpio provides a virtual GPIO controller, which will map part of native GPIOs to User VM, User VM can perform GPIO operations through it, including setting values, including set/get value, set/get direction and set configuration (only Open Source and Open Drain types are currently supported). GPIOs quite often be used as IRQs, typically for wakeup events, virtio-gpio supports level and edge interrupt trigger modes.

The virtio-gpio architecture is shown below

../../_images/virtio-gpio-1.png

Figure 281 Virtio-gpio Architecture

Virtio-gpio is implemented as a virtio legacy device in the ACRN device model (DM), and is registered as a PCI virtio device to the guest OS. No changes are required in the frontend Linux virtio-gpio except that the guest (User VM) kernel should be built with CONFIG_VIRTIO_GPIO=y.

There are three virtqueues used between FE and BE, one for gpio operations, one for IRQ request and one for IRQ event notification.

Virtio-gpio FE driver will register a gpiochip and irqchip when it is probed, the base and number of gpio are generated by the BE. Each gpiochip or irqchip operation(e.g. get_direction of gpiochip or irq_set_type of irqchip) will trigger a virtqueue_kick on its own virtqueue. If some gpio has been set to interrupt mode, the interrupt events will be handled within the IRQ virtqueue callback.

GPIO Mapping

../../_images/virtio-gpio-2.png

Figure 282 GPIO mapping

  • Each User VM has only one GPIO chip instance, its number of GPIO is based on acrn-dm command line and GPIO base always start from 0.

  • Each GPIO is exclusive, User VM can’t map the same native gpio.

  • Each acrn-dm maximum number of GPIO is 64.

Usage

Add the following parameters into the command line:

-s <slot>,virtio-gpio,<@controller_name{offset|name[=mapping_name]:offset|name[=mapping_name]:...}@controller_name{...}...]>
  • controller_name: Input ls /sys/bus/gpio/devices to check native gpio controller information. Usually, the devices represent the controller_name, you can use it as controller_name directly. You can also input cat /sys/bus/gpio/device/XXX/dev to get device id that can be used to match /dev/XXX, then use XXX as the controller_name. On MRB and Intel NUC platforms, the controller_name are gpiochip0, gpiochip1, gpiochip2.gpiochip3.

  • offset|name: you can use gpio offset or its name to locate one native gpio within the gpio controller.

  • mapping_name: This is optional, if you want to use a customized name for a FE gpio, you can set a new name for a FE virtual gpio.

Example

  • Map three native gpio to User VM, they are native gpiochip0 with offset of 1 and 6, and with the name reset. In User VM, the three gpio has no name, and base from 0.:

    -s 10,virtio-gpio,@gpiochip0{1:6:reset}
    
  • Map four native gpio to User VM, native gpiochip0’s gpio with offset 1 and offset 6 map to FE virtual gpio with offset 0 and offset 1 without names, native gpiochip0’s gpio with name reset maps to FE virtual gpio with offset 2 and its name is shutdown, native gpiochip1’s gpio with offset 0 maps to FE virtual gpio with offset 3 and its name is reset

    -s 10,virtio-gpio,@gpiochip0{1:6:reset=shutdown}@gpiochip1{0=reset}