VirtioLib provides an API for simple, synchronous (request/response-style)
virtio communication. The guest driver builds one descriptor chain, link
for link, with VirtioPrepare() and VirtioAppendDesc(), then submits the
chain, and awaits the processing, with VirtioFlush().
The descriptor chain is always built at the beginning of the descriptor
area, with the head descriptor having descriptor index 0.
In order to submit the descriptor chain to the host, the guest always
pushes a new "available element" to the Available Ring, in genuine
queue-like fashion, with the new element referencing the head descriptor
(which always has index 0, see above).
In turn, after processing, the host always pushes a new "used element" to
the Used Ring, in genuine queue-like fashion, with the new element
referencing the head descriptor of the chain that was just processed. The
same element also reports the number of bytes that the host wrote,
consecutively across the host-writeable buffers that were linked by the
descriptors.
(See "OvmfPkg/VirtioNetDxe/TechNotes.txt" for a diagram about the
descriptor area and the rings.)
Because at most one descriptor chain can be in flight with VirtioLib at
any time,
- the Available Ring and the Used Ring proceed in lock-step,
- and the head descriptor that the new "available" and "used" elements can
ever reference has index 0.
Based on the above, we can modify VirtioFlush() to return the number of
bytes written by the host across the descriptor chain. The virtio-block
and virtio-scsi drivers don't care (they have other ways to parse the data
produced by the host), while the virtio-net driver doesn't use
VirtioFlush() at all (it employs VirtioLib only to set up its rings).
However, the virtio entropy device, to be covered in the upcoming
patches, reports the amount of randomness produced by the host only
through this quantity.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
(1) VirtioLib allocates the virtio ring in EfiBootServicesData memory.
(This is intentional.) Code that executes after ExitBootServices() is
permitted to reuse such memory.
(2) The hypervisor is allowed to look at, and act upon, a live virtio ring
at any time, even without explicit virtio kicks from the guest.
Should boot loader code or kernel code, running between ExitBootServices()
and the kernel's own virtio drivers resetting the device, overwrite the
pages that used to contain the virtio ring before ExitBootServices(), QEMU
could theoretically interpret that unrelated data as garbage ring
contents, and abort the guest.
Although we have seen no such reports, better be prudent and reset the
device in an ExitBootServices() event handler. Among other things, this
causes QEMU to forget about the device's virtio ring.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18623 6f19259b-4bc3-4df7-8a09-765794883524
"Lun" has type UINT64 in this function. The result of the expression
(UINT8) ((Lun >> 8) | 0x40)
depends only on bits [15:8] of "Lun", therefore we can cast "Lun" to
UINT32 before shifting it.
This eliminates an intrinsic when building with VS2010 for Ia32 / NOOPT.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <scott@notabs.org>
[lersek@redhat.com: added commit message]
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Build-tested-by: Scott Duplichan <scott@notabs.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16386 6f19259b-4bc3-4df7-8a09-765794883524
These functions did not provide much more than the new protocol functions
VIRTIO_DEVICE_PROTOCOL.ReadDevice() / VIRTIO_DEVICE_PROTOCOL.WriteDevice().
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14968 6f19259b-4bc3-4df7-8a09-765794883524
This change replaces the accesses to the PCI bus from the Block, Scsi and Net drivers by
the use of the new VIRTIO_DEVICE_PROTOCOL protocol that abstracts the transport layer.
It means these drivers can be used on PCI and MMIO transport layer.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
v5:
- VirtioFlush(): update comment block in VirtioLib.[hc]; error code is
propagated from VirtIo->SetQueueNotify().
- VirtioBlkInit(): jump to Failed label if SetPageSize() fails
- VirtioBlkInit(): fixup comment, and add error handling, near
SetQueueNum() call
- VirtioBlkDriverBindingStart(): remove redundant (always false) check for
a subsystem device ID different from VIRTIO_SUBSYSTEM_BLOCK_DEVICE;
VirtioBlkDriverBindingSupported() handles it already
- VirtioNetGetFeatures(): update stale comment block
- VirtioNetGetFeatures(): retrieve MAC address byte for byte (open-coded
loop)
- VirtioNetDriverBindingStart(): remove redundant (always false) check for
a subsystem device ID different from VIRTIO_SUBSYSTEM_NETWORK_CARD;
VirtioNetDriverBindingSupported() handles it already
- VirtioNetInitRing(): call SetQueueNum() and SetQueueAlign() for proper
MMIO operation
- VirtioNetInitialize(): fix destination error label for when
SetPageSize() fails
- VirtioScsi.c: fix comment block of VIRTIO_CFG_WRITE()/VIRTIO_CFG_READ()
- VirtioScsiInit(): fix destination error label for when SetPageSize()
fails
- VirtioScsiInit(): call SetQueueNum() and SetQueueAlign() for proper MMIO
operation
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14966 6f19259b-4bc3-4df7-8a09-765794883524
Structures should not be directly assigned in EDK II
code, since this leads to different behaviours on various
compilers.
Instead, use ZeroMem to zero out the structures.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13878 6f19259b-4bc3-4df7-8a09-765794883524