[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: [PATCH v1 2/6] transport-mmio: Split MMIO transport to its own file
Place MMIO transport specification in its own file to better maintain it. Fixes: https://github.com/oasis-tcs/virtio-spec/issues/157 Signed-off-by: Parav Pandit <parav@nvidia.com> --- content.tex | 554 +-------------------------------------------- transport-mmio.tex | 552 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 553 insertions(+), 553 deletions(-) create mode 100644 transport-mmio.tex diff --git a/content.tex b/content.tex index be911e6..80c28df 100644 --- a/content.tex +++ b/content.tex @@ -580,559 +580,7 @@ \chapter{Virtio Transport Options}\label{sec:Virtio Transport Options} into virtio general and bus-specific sections. \input{transport-pci.tex} - -\subsection{MMIO Device Discovery}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO Device Discovery} - -Unlike PCI, MMIO provides no generic device discovery mechanism. For each -device, the guest OS will need to know the location of the registers -and interrupt(s) used. The suggested binding for systems using -flattened device trees is shown in this example: - -\begin{lstlisting} -// EXAMPLE: virtio_block device taking 512 bytes at 0x1e000, interrupt 42. -virtio_block@1e000 { - compatible = "virtio,mmio"; - reg = <0x1e000 0x200>; - interrupts = <42>; -} -\end{lstlisting} - -\subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout} - -MMIO virtio devices provide a set of memory mapped control -registers followed by a device-specific configuration space, -described in the table~\ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout}. - -All register values are organized as Little Endian. - -\newcommand{\mmioreg}[5]{% Name Function Offset Direction Description - {\field{#1}} \newline #3 \newline #4 & {\bf#2} \newline #5 \\ -} - -\newcommand{\mmiodreg}[7]{% NameHigh NameLow Function OffsetHigh OffsetLow Direction Description - {\field{#1}} \newline #4 \newline {\field{#2}} \newline #5 \newline #6 & {\bf#3} \newline #7 \\ -} - -\begin{longtable}{p{0.2\textwidth}p{0.7\textwidth}} - \caption {MMIO Device Register Layout} - \label{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout} \\ - \hline - \mmioreg{Name}{Function}{Offset from base}{Direction}{Description} - \hline - \hline - \endfirsthead - \hline - \mmioreg{Name}{Function}{Offset from the base}{Direction}{Description} - \hline - \hline - \endhead - \endfoot - \endlastfoot - \mmioreg{MagicValue}{Magic value}{0x000}{R}{% - 0x74726976 - (a Little Endian equivalent of the ``virt'' string). - } - \hline - \mmioreg{Version}{Device version number}{0x004}{R}{% - 0x2. - \begin{note} - Legacy devices (see \ref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}) used 0x1. - \end{note} - } - \hline - \mmioreg{DeviceID}{Virtio Subsystem Device ID}{0x008}{R}{% - See \ref{sec:Device Types}~\nameref{sec:Device Types} for possible values. - Value zero (0x0) is used to - define a system memory map with placeholder devices at static, - well known addresses, assigning functions to them depending - on user's needs. - } - \hline - \mmioreg{VendorID}{Virtio Subsystem Vendor ID}{0x00c}{R}{} - \hline - \mmioreg{DeviceFeatures}{Flags representing features the device supports}{0x010}{R}{% - Reading from this register returns 32 consecutive flag bits, - the least significant bit depending on the last value written to - \field{DeviceFeaturesSel}. Access to this register returns - bits $\field{DeviceFeaturesSel}*32$ to $(\field{DeviceFeaturesSel}*32)+31$, eg. - feature bits 0 to 31 if \field{DeviceFeaturesSel} is set to 0 and - features bits 32 to 63 if \field{DeviceFeaturesSel} is set to 1. - Also see \ref{sec:Basic Facilities of a Virtio Device / Feature Bits}~\nameref{sec:Basic Facilities of a Virtio Device / Feature Bits}. - } - \hline - \mmioreg{DeviceFeaturesSel}{Device (host) features word selection.}{0x014}{W}{% - Writing to this register selects a set of 32 device feature bits - accessible by reading from \field{DeviceFeatures}. - } - \hline - \mmioreg{DriverFeatures}{Flags representing device features understood and activated by the driver}{0x020}{W}{% - Writing to this register sets 32 consecutive flag bits, the least significant - bit depending on the last value written to \field{DriverFeaturesSel}. - Access to this register sets bits $\field{DriverFeaturesSel}*32$ - to $(\field{DriverFeaturesSel}*32)+31$, eg. feature bits 0 to 31 if - \field{DriverFeaturesSel} is set to 0 and features bits 32 to 63 if - \field{DriverFeaturesSel} is set to 1. Also see \ref{sec:Basic Facilities of a Virtio Device / Feature Bits}~\nameref{sec:Basic Facilities of a Virtio Device / Feature Bits}. - } - \hline - \mmioreg{DriverFeaturesSel}{Activated (guest) features word selection}{0x024}{W}{% - Writing to this register selects a set of 32 activated feature - bits accessible by writing to \field{DriverFeatures}. - } - \hline - \mmioreg{QueueSel}{Virtual queue index}{0x030}{W}{% - Writing to this register selects the virtual queue that the - following operations on \field{QueueNumMax}, \field{QueueNum}, \field{QueueReady}, - \field{QueueDescLow}, \field{QueueDescHigh}, \field{QueueDriverlLow}, \field{QueueDriverHigh}, - \field{QueueDeviceLow}, \field{QueueDeviceHigh} and \field{QueueReset} apply to. The index - number of the first queue is zero (0x0). - } - \hline - \mmioreg{QueueNumMax}{Maximum virtual queue size}{0x034}{R}{% - Reading from the register returns the maximum size (number of - elements) of the queue the device is ready to process or - zero (0x0) if the queue is not available. This applies to the - queue selected by writing to \field{QueueSel}. - } - \hline - \mmioreg{QueueNum}{Virtual queue size}{0x038}{W}{% - Queue size is the number of elements in the queue. - Writing to this register notifies the device what size of the - queue the driver will use. This applies to the queue selected by - writing to \field{QueueSel}. - } - \hline - \mmioreg{QueueReady}{Virtual queue ready bit}{0x044}{RW}{% - Writing one (0x1) to this register notifies the device that it can - execute requests from this virtual queue. Reading from this register - returns the last value written to it. Both read and write - accesses apply to the queue selected by writing to \field{QueueSel}. - } - \hline - \mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{% - Writing a value to this register notifies the device that - there are new buffers to process in a queue. - - When VIRTIO_F_NOTIFICATION_DATA has not been negotiated, - the value written is the queue index. - - When VIRTIO_F_NOTIFICATION_DATA has been negotiated, - the \field{Notification data} value has the following format: - - \lstinputlisting{notifications-le.c} - - See \ref{sec:Basic Facilities of a Virtio Device / Driver notifications}~\nameref{sec:Basic Facilities of a Virtio Device / Driver notifications} - for the definition of the components. - } - \hline - \mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{% - Reading from this register returns a bit mask of events that - caused the device interrupt to be asserted. - The following events are possible: - \begin{description} - \item[Used Buffer Notification] - bit 0 - the interrupt was asserted - because the device has used a buffer - in at least one of the active virtual queues. - \item [Configuration Change Notification] - bit 1 - the interrupt was - asserted because the configuration of the device has changed. - \end{description} - } - \hline - \mmioreg{InterruptACK}{Interrupt acknowledge}{0x064}{W}{% - Writing a value with bits set as defined in \field{InterruptStatus} - to this register notifies the device that events causing - the interrupt have been handled. - } - \hline - \mmioreg{Status}{Device status}{0x070}{RW}{% - Reading from this register returns the current device status - flags. - Writing non-zero values to this register sets the status flags, - indicating the driver progress. Writing zero (0x0) to this - register triggers a device reset. - See also p. \ref{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization}. - } - \hline - \mmiodreg{QueueDescLow}{QueueDescHigh}{Virtual queue's Descriptor Area 64 bit long physical address}{0x080}{0x084}{W}{% - Writing to these two registers (lower 32 bits of the address - to \field{QueueDescLow}, higher 32 bits to \field{QueueDescHigh}) notifies - the device about location of the Descriptor Area of the queue - selected by writing to \field{QueueSel} register. - } - \hline - \mmiodreg{QueueDriverLow}{QueueDriverHigh}{Virtual queue's Driver Area 64 bit long physical address}{0x090}{0x094}{W}{% - Writing to these two registers (lower 32 bits of the address - to \field{QueueDriverLow}, higher 32 bits to \field{QueueDriverHigh}) notifies - the device about location of the Driver Area of the queue - selected by writing to \field{QueueSel}. - } - \hline - \mmiodreg{QueueDeviceLow}{QueueDeviceHigh}{Virtual queue's Device Area 64 bit long physical address}{0x0a0}{0x0a4}{W}{% - Writing to these two registers (lower 32 bits of the address - to \field{QueueDeviceLow}, higher 32 bits to \field{QueueDeviceHigh}) notifies - the device about location of the Device Area of the queue - selected by writing to \field{QueueSel}. - } - \hline - \mmioreg{SHMSel}{Shared memory id}{0x0ac}{W}{% - Writing to this register selects the shared memory region \ref{sec:Basic Facilities of a Virtio Device / Shared Memory Regions} - following operations on \field{SHMLenLow}, \field{SHMLenHigh}, - \field{SHMBaseLow} and \field{SHMBaseHigh} apply to. - } - \hline - \mmiodreg{SHMLenLow}{SHMLenHigh}{Shared memory region 64 bit long length}{0x0b0}{0x0b4}{R}{% - These registers return the length of the shared memory - region in bytes, as defined by the device for the region selected by - the \field{SHMSel} register. The lower 32 bits of the length - are read from \field{SHMLenLow} and the higher 32 bits from - \field{SHMLenHigh}. Reading from a non-existent - region (i.e. where the ID written to \field{SHMSel} is unused) - results in a length of -1. - } - \hline - \mmiodreg{SHMBaseLow}{SHMBaseHigh}{Shared memory region 64 bit long physical address}{0x0b8}{0x0bc}{R}{% - The driver reads these registers to discover the base address - of the region in physical address space. This address is - chosen by the device (or other part of the VMM). - The lower 32 bits of the address are read from \field{SHMBaseLow} - with the higher 32 bits from \field{SHMBaseHigh}. Reading - from a non-existent region (i.e. where the ID written to - \field{SHMSel} is unused) results in a base address of - 0xffffffffffffffff. - } - \hline - \mmioreg{QueueReset}{Virtual queue reset bit}{0x0c0}{RW}{% - If VIRTIO_F_RING_RESET has been negotiated, writing one (0x1) to this - register selectively resets the queue. Both read and write accesses - apply to the queue selected by writing to \field{QueueSel}. - } - \hline - \mmioreg{ConfigGeneration}{Configuration atomicity value}{0x0fc}{R}{ - Reading from this register returns a value describing a version of the device-specific configuration space (see \field{Config}). - The driver can then access the configuration space and, when finished, read \field{ConfigGeneration} again. - If no part of the configuration space has changed between these two \field{ConfigGeneration} reads, the returned values are identical. - If the values are different, the configuration space accesses were not atomic and the driver has to perform the operations again. - See also \ref {sec:Basic Facilities of a Virtio Device / Device Configuration Space}. - } - \hline - \mmioreg{Config}{Configuration space}{0x100+}{RW}{ - Device-specific configuration space starts at the offset 0x100 - and is accessed with byte alignment. Its meaning and size - depend on the device and the driver. - } - \hline -\end{longtable} - -\devicenormative{\subsubsection}{MMIO Device Register Layout}{Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout} - -The device MUST return 0x74726976 in \field{MagicValue}. - -The device MUST return value 0x2 in \field{Version}. - -The device MUST present each event by setting the corresponding bit in \field{InterruptStatus} from the -moment it takes place, until the driver acknowledges the interrupt -by writing a corresponding bit mask to the \field{InterruptACK} register. Bits which -do not represent events which took place MUST be zero. - -Upon reset, the device MUST clear all bits in \field{InterruptStatus} and ready bits in the -\field{QueueReady} register for all queues in the device. - -The device MUST change value returned in \field{ConfigGeneration} if there is any risk of a -driver seeing an inconsistent configuration state. - -The device MUST NOT access virtual queue contents when \field{QueueReady} is zero (0x0). - -If VIRTIO_F_RING_RESET has been negotiated, the device MUST present a 0 in -\field{QueueReset} on reset. - -If VIRTIO_F_RING_RESET has been negotiated, The device MUST present a 0 in -\field{QueueReset} after the virtqueue is enabled with \field{QueueReady}. - -The device MUST reset the queue when 1 is written to \field{QueueReset}. The -device MUST continue to present 1 in \field{QueueReset} as long as the queue reset -is ongoing. The device MUST present 0 in both \field{QueueReset} and \field{QueueReady} -when queue reset has completed. -(see \ref{sec:Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Reset}). - -\drivernormative{\subsubsection}{MMIO Device Register Layout}{Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout} -The driver MUST NOT access memory locations not described in the -table \ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout} -(or, in case of the configuration space, described in the device specification), -MUST NOT write to the read-only registers (direction R) and -MUST NOT read from the write-only registers (direction W). - -The driver MUST only use 32 bit wide and aligned reads and writes to access the control registers -described in table \ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout}. -For the device-specific configuration space, the driver MUST use 8 bit wide accesses for -8 bit wide fields, 16 bit wide and aligned accesses for 16 bit wide fields and 32 bit wide and -aligned accesses for 32 and 64 bit wide fields. - -The driver MUST ignore a device with \field{MagicValue} which is not 0x74726976, -although it MAY report an error. - -The driver MUST ignore a device with \field{Version} which is not 0x2, -although it MAY report an error. - -The driver MUST ignore a device with \field{DeviceID} 0x0, -but MUST NOT report any error. - -Before reading from \field{DeviceFeatures}, the driver MUST write a value to \field{DeviceFeaturesSel}. - -Before writing to the \field{DriverFeatures} register, the driver MUST write a value to the \field{DriverFeaturesSel} register. - -The driver MUST write a value to \field{QueueNum} which is less than -or equal to the value presented by the device in \field{QueueNumMax}. - -When \field{QueueReady} is not zero, the driver MUST NOT access -\field{QueueNum}, \field{QueueDescLow}, \field{QueueDescHigh}, -\field{QueueDriverLow}, \field{QueueDriverHigh}, \field{QueueDeviceLow}, \field{QueueDeviceHigh}. - -To stop using the queue the driver MUST write zero (0x0) to this -\field{QueueReady} and MUST read the value back to ensure -synchronization. - -The driver MUST ignore undefined bits in \field{InterruptStatus}. - -The driver MUST write a value with a bit mask describing events it handled into \field{InterruptACK} when -it finishes handling an interrupt and MUST NOT set any of the undefined bits in the value. - -If VIRTIO_F_RING_RESET has been negotiated, after the driver writes 1 to -\field{QueueReset} to reset the queue, the driver MUST NOT consider queue -reset to be complete until it reads back 0 in \field{QueueReset}. The driver -MAY re-enable the queue by writing 1 to \field{QueueReady} after ensuring -that other virtqueue fields have been set up correctly. The driver MAY set -driver-writeable queue configuration values to different values than those -that were used before the queue reset. -(see \ref{sec:Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Reset}). - -\subsection{MMIO-specific Initialization And Device Operation}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation} - -\subsubsection{Device Initialization}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization} - -\drivernormative{\paragraph}{Device Initialization}{Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization} - -The driver MUST start the device initialization by reading and -checking values from \field{MagicValue} and \field{Version}. -If both values are valid, it MUST read \field{DeviceID} -and if its value is zero (0x0) MUST abort initialization and -MUST NOT access any other register. - -Drivers not expecting shared memory MUST NOT use the shared -memory registers. - -Further initialization MUST follow the procedure described in -\ref{sec:General Initialization And Device Operation / Device Initialization}~\nameref{sec:General Initialization And Device Operation / Device Initialization}. - -\subsubsection{Virtqueue Configuration}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Virtqueue Configuration} - -The driver will typically initialize the virtual queue in the following way: - -\begin{enumerate} -\item Select the queue writing its index (first queue is 0) to - \field{QueueSel}. - -\item Check if the queue is not already in use: read \field{QueueReady}, - and expect a returned value of zero (0x0). - -\item Read maximum queue size (number of elements) from - \field{QueueNumMax}. If the returned value is zero (0x0) the - queue is not available. - -\item Allocate and zero the queue memory, making sure the memory - is physically contiguous. - -\item Notify the device about the queue size by writing the size to - \field{QueueNum}. - -\item Write physical addresses of the queue's Descriptor Area, - Driver Area and Device Area to (respectively) the - \field{QueueDescLow}/\field{QueueDescHigh}, - \field{QueueDriverLow}/\field{QueueDriverHigh} and - \field{QueueDeviceLow}/\field{QueueDeviceHigh} register pairs. - -\item Write 0x1 to \field{QueueReady}. -\end{enumerate} - -\subsubsection{Available Buffer Notifications}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Available Buffer Notifications} - -When VIRTIO_F_NOTIFICATION_DATA has not been negotiated, -the driver sends an available buffer notification to the device by writing -the 16-bit virtqueue index -of the queue to be notified to \field{QueueNotify}. - -When VIRTIO_F_NOTIFICATION_DATA has been negotiated, -the driver sends an available buffer notification to the device by writing -the following 32-bit value to \field{QueueNotify}: -\lstinputlisting{notifications-le.c} - -See \ref{sec:Basic Facilities of a Virtio Device / Driver notifications}~\nameref{sec:Basic Facilities of a Virtio Device / Driver notifications} -for the definition of the components. - -\subsubsection{Notifications From The Device}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notifications From The Device} - -The memory mapped virtio device is using a single, dedicated -interrupt signal, which is asserted when at least one of the -bits described in the description of \field{InterruptStatus} -is set. This is how the device sends a used buffer notification -or a configuration change notification to the device. - -\drivernormative{\paragraph}{Notifications From The Device}{Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notifications From The Device} -After receiving an interrupt, the driver MUST read -\field{InterruptStatus} to check what caused the interrupt (see the -register description). The used buffer notification bit being set -SHOULD be interpreted as a used buffer notification for each active -virtqueue. After the interrupt is handled, the driver MUST acknowledge -it by writing a bit mask corresponding to the handled events to the -InterruptACK register. - -\subsection{Legacy interface}\label{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface} - -The legacy MMIO transport used page-based addressing, resulting -in a slightly different control register layout, the device -initialization and the virtual queue configuration procedure. - -Table \ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Legacy Register Layout} -presents control registers layout, omitting -descriptions of registers which did not change their function -nor behaviour: - -\begin{longtable}{p{0.2\textwidth}p{0.7\textwidth}} - \caption {MMIO Device Legacy Register Layout} - \label{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Legacy Register Layout} \\ - \hline - \mmioreg{Name}{Function}{Offset from base}{Direction}{Description} - \hline - \hline - \endfirsthead - \hline - \mmioreg{Name}{Function}{Offset from the base}{Direction}{Description} - \hline - \hline - \endhead - \endfoot - \endlastfoot - \mmioreg{MagicValue}{Magic value}{0x000}{R}{} - \hline - \mmioreg{Version}{Device version number}{0x004}{R}{Legacy device returns value 0x1.} - \hline - \mmioreg{DeviceID}{Virtio Subsystem Device ID}{0x008}{R}{} - \hline - \mmioreg{VendorID}{Virtio Subsystem Vendor ID}{0x00c}{R}{} - \hline - \mmioreg{HostFeatures}{Flags representing features the device supports}{0x010}{R}{} - \hline - \mmioreg{HostFeaturesSel}{Device (host) features word selection.}{0x014}{W}{} - \hline - \mmioreg{GuestFeatures}{Flags representing device features understood and activated by the driver}{0x020}{W}{} - \hline - \mmioreg{GuestFeaturesSel}{Activated (guest) features word selection}{0x024}{W}{} - \hline - \mmioreg{GuestPageSize}{Guest page size}{0x028}{W}{% - The driver writes the guest page size in bytes to the - register during initialization, before any queues are used. - This value should be a power of 2 and is used by the device to - calculate the Guest address of the first queue page - (see QueuePFN). - } - \hline - \mmioreg{QueueSel}{Virtual queue index}{0x030}{W}{% - Writing to this register selects the virtual queue that the - following operations on the \field{QueueNumMax}, \field{QueueNum}, \field{QueueAlign} - and \field{QueuePFN} registers apply to. The index - number of the first queue is zero (0x0). -. - } - \hline - \mmioreg{QueueNumMax}{Maximum virtual queue size}{0x034}{R}{% - Reading from the register returns the maximum size of the queue - the device is ready to process or zero (0x0) if the queue is not - available. This applies to the queue selected by writing to - \field{QueueSel} and is allowed only when \field{QueuePFN} is set to zero - (0x0), so when the queue is not actively used. - } - \hline - \mmioreg{QueueNum}{Virtual queue size}{0x038}{W}{% - Queue size is the number of elements in the queue. - Writing to this register notifies the device what size of the - queue the driver will use. This applies to the queue selected by - writing to \field{QueueSel}. - } - \hline - \mmioreg{QueueAlign}{Used Ring alignment in the virtual queue}{0x03c}{W}{% - Writing to this register notifies the device about alignment - boundary of the Used Ring in bytes. This value should be a power - of 2 and applies to the queue selected by writing to \field{QueueSel}. - } - \hline - \mmioreg{QueuePFN}{Guest physical page number of the virtual queue}{0x040}{RW}{% - Writing to this register notifies the device about location of the - virtual queue in the Guest's physical address space. This value - is the index number of a page starting with the queue - Descriptor Table. Value zero (0x0) means physical address zero - (0x00000000) and is illegal. When the driver stops using the - queue it writes zero (0x0) to this register. - Reading from this register returns the currently used page - number of the queue, therefore a value other than zero (0x0) - means that the queue is in use. - Both read and write accesses apply to the queue selected by - writing to \field{QueueSel}. - } - \hline - \mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{} - \hline - \mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{} - \hline - \mmioreg{InterruptACK}{Interrupt acknowledge}{0x064}{W}{} - \hline - \mmioreg{Status}{Device status}{0x070}{RW}{% - Reading from this register returns the current device status - flags. - Writing non-zero values to this register sets the status flags, - indicating the OS/driver progress. Writing zero (0x0) to this - register triggers a device reset. The device - sets \field{QueuePFN} to zero (0x0) for all queues in the device. - Also see \ref{sec:General Initialization And Device Operation / Device Initialization}~\nameref{sec:General Initialization And Device Operation / Device Initialization}. - } - \hline - \mmioreg{Config}{Configuration space}{0x100+}{RW}{} - \hline -\end{longtable} - -The virtual queue page size is defined by writing to \field{GuestPageSize}, -as written by the guest. The driver does this before the -virtual queues are configured. - -The virtual queue layout follows -p. \ref{sec:Basic Facilities of a Virtio Device / Virtqueues / Legacy Interfaces: A Note on Virtqueue Layout}~\nameref{sec:Basic Facilities of a Virtio Device / Virtqueues / Legacy Interfaces: A Note on Virtqueue Layout}, -with the alignment defined in \field{QueueAlign}. - -The virtual queue is configured as follows: -\begin{enumerate} -\item Select the queue writing its index (first queue is 0) to - \field{QueueSel}. - -\item Check if the queue is not already in use: read \field{QueuePFN}, - expecting a returned value of zero (0x0). - -\item Read maximum queue size (number of elements) from - \field{QueueNumMax}. If the returned value is zero (0x0) the - queue is not available. - -\item Allocate and zero the queue pages in contiguous virtual - memory, aligning the Used Ring to an optimal boundary (usually - page size). The driver should choose a queue size smaller than or - equal to \field{QueueNumMax}. - -\item Notify the device about the queue size by writing the size to - \field{QueueNum}. - -\item Notify the device about the used alignment by writing its value - in bytes to \field{QueueAlign}. - -\item Write the physical number of the first page of the queue to - the \field{QueuePFN} register. -\end{enumerate} - -Notification mechanisms did not change. +\input{transport-mmio.tex} \section{Virtio Over Channel I/O}\label{sec:Virtio Transport Options / Virtio Over Channel I/O} diff --git a/transport-mmio.tex b/transport-mmio.tex new file mode 100644 index 0000000..7f2e0c3 --- /dev/null +++ b/transport-mmio.tex @@ -0,0 +1,552 @@ +\subsection{MMIO Device Discovery}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO Device Discovery} + +Unlike PCI, MMIO provides no generic device discovery mechanism. For each +device, the guest OS will need to know the location of the registers +and interrupt(s) used. The suggested binding for systems using +flattened device trees is shown in this example: + +\begin{lstlisting} +// EXAMPLE: virtio_block device taking 512 bytes at 0x1e000, interrupt 42. +virtio_block@1e000 { + compatible = "virtio,mmio"; + reg = <0x1e000 0x200>; + interrupts = <42>; +} +\end{lstlisting} + +\subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout} + +MMIO virtio devices provide a set of memory mapped control +registers followed by a device-specific configuration space, +described in the table~\ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout}. + +All register values are organized as Little Endian. + +\newcommand{\mmioreg}[5]{% Name Function Offset Direction Description + {\field{#1}} \newline #3 \newline #4 & {\bf#2} \newline #5 \\ +} + +\newcommand{\mmiodreg}[7]{% NameHigh NameLow Function OffsetHigh OffsetLow Direction Description + {\field{#1}} \newline #4 \newline {\field{#2}} \newline #5 \newline #6 & {\bf#3} \newline #7 \\ +} + +\begin{longtable}{p{0.2\textwidth}p{0.7\textwidth}} + \caption {MMIO Device Register Layout} + \label{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout} \\ + \hline + \mmioreg{Name}{Function}{Offset from base}{Direction}{Description} + \hline + \hline + \endfirsthead + \hline + \mmioreg{Name}{Function}{Offset from the base}{Direction}{Description} + \hline + \hline + \endhead + \endfoot + \endlastfoot + \mmioreg{MagicValue}{Magic value}{0x000}{R}{% + 0x74726976 + (a Little Endian equivalent of the ``virt'' string). + } + \hline + \mmioreg{Version}{Device version number}{0x004}{R}{% + 0x2. + \begin{note} + Legacy devices (see \ref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}) used 0x1. + \end{note} + } + \hline + \mmioreg{DeviceID}{Virtio Subsystem Device ID}{0x008}{R}{% + See \ref{sec:Device Types}~\nameref{sec:Device Types} for possible values. + Value zero (0x0) is used to + define a system memory map with placeholder devices at static, + well known addresses, assigning functions to them depending + on user's needs. + } + \hline + \mmioreg{VendorID}{Virtio Subsystem Vendor ID}{0x00c}{R}{} + \hline + \mmioreg{DeviceFeatures}{Flags representing features the device supports}{0x010}{R}{% + Reading from this register returns 32 consecutive flag bits, + the least significant bit depending on the last value written to + \field{DeviceFeaturesSel}. Access to this register returns + bits $\field{DeviceFeaturesSel}*32$ to $(\field{DeviceFeaturesSel}*32)+31$, eg. + feature bits 0 to 31 if \field{DeviceFeaturesSel} is set to 0 and + features bits 32 to 63 if \field{DeviceFeaturesSel} is set to 1. + Also see \ref{sec:Basic Facilities of a Virtio Device / Feature Bits}~\nameref{sec:Basic Facilities of a Virtio Device / Feature Bits}. + } + \hline + \mmioreg{DeviceFeaturesSel}{Device (host) features word selection.}{0x014}{W}{% + Writing to this register selects a set of 32 device feature bits + accessible by reading from \field{DeviceFeatures}. + } + \hline + \mmioreg{DriverFeatures}{Flags representing device features understood and activated by the driver}{0x020}{W}{% + Writing to this register sets 32 consecutive flag bits, the least significant + bit depending on the last value written to \field{DriverFeaturesSel}. + Access to this register sets bits $\field{DriverFeaturesSel}*32$ + to $(\field{DriverFeaturesSel}*32)+31$, eg. feature bits 0 to 31 if + \field{DriverFeaturesSel} is set to 0 and features bits 32 to 63 if + \field{DriverFeaturesSel} is set to 1. Also see \ref{sec:Basic Facilities of a Virtio Device / Feature Bits}~\nameref{sec:Basic Facilities of a Virtio Device / Feature Bits}. + } + \hline + \mmioreg{DriverFeaturesSel}{Activated (guest) features word selection}{0x024}{W}{% + Writing to this register selects a set of 32 activated feature + bits accessible by writing to \field{DriverFeatures}. + } + \hline + \mmioreg{QueueSel}{Virtual queue index}{0x030}{W}{% + Writing to this register selects the virtual queue that the + following operations on \field{QueueNumMax}, \field{QueueNum}, \field{QueueReady}, + \field{QueueDescLow}, \field{QueueDescHigh}, \field{QueueDriverlLow}, \field{QueueDriverHigh}, + \field{QueueDeviceLow}, \field{QueueDeviceHigh} and \field{QueueReset} apply to. The index + number of the first queue is zero (0x0). + } + \hline + \mmioreg{QueueNumMax}{Maximum virtual queue size}{0x034}{R}{% + Reading from the register returns the maximum size (number of + elements) of the queue the device is ready to process or + zero (0x0) if the queue is not available. This applies to the + queue selected by writing to \field{QueueSel}. + } + \hline + \mmioreg{QueueNum}{Virtual queue size}{0x038}{W}{% + Queue size is the number of elements in the queue. + Writing to this register notifies the device what size of the + queue the driver will use. This applies to the queue selected by + writing to \field{QueueSel}. + } + \hline + \mmioreg{QueueReady}{Virtual queue ready bit}{0x044}{RW}{% + Writing one (0x1) to this register notifies the device that it can + execute requests from this virtual queue. Reading from this register + returns the last value written to it. Both read and write + accesses apply to the queue selected by writing to \field{QueueSel}. + } + \hline + \mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{% + Writing a value to this register notifies the device that + there are new buffers to process in a queue. + + When VIRTIO_F_NOTIFICATION_DATA has not been negotiated, + the value written is the queue index. + + When VIRTIO_F_NOTIFICATION_DATA has been negotiated, + the \field{Notification data} value has the following format: + + \lstinputlisting{notifications-le.c} + + See \ref{sec:Basic Facilities of a Virtio Device / Driver notifications}~\nameref{sec:Basic Facilities of a Virtio Device / Driver notifications} + for the definition of the components. + } + \hline + \mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{% + Reading from this register returns a bit mask of events that + caused the device interrupt to be asserted. + The following events are possible: + \begin{description} + \item[Used Buffer Notification] - bit 0 - the interrupt was asserted + because the device has used a buffer + in at least one of the active virtual queues. + \item [Configuration Change Notification] - bit 1 - the interrupt was + asserted because the configuration of the device has changed. + \end{description} + } + \hline + \mmioreg{InterruptACK}{Interrupt acknowledge}{0x064}{W}{% + Writing a value with bits set as defined in \field{InterruptStatus} + to this register notifies the device that events causing + the interrupt have been handled. + } + \hline + \mmioreg{Status}{Device status}{0x070}{RW}{% + Reading from this register returns the current device status + flags. + Writing non-zero values to this register sets the status flags, + indicating the driver progress. Writing zero (0x0) to this + register triggers a device reset. + See also p. \ref{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization}. + } + \hline + \mmiodreg{QueueDescLow}{QueueDescHigh}{Virtual queue's Descriptor Area 64 bit long physical address}{0x080}{0x084}{W}{% + Writing to these two registers (lower 32 bits of the address + to \field{QueueDescLow}, higher 32 bits to \field{QueueDescHigh}) notifies + the device about location of the Descriptor Area of the queue + selected by writing to \field{QueueSel} register. + } + \hline + \mmiodreg{QueueDriverLow}{QueueDriverHigh}{Virtual queue's Driver Area 64 bit long physical address}{0x090}{0x094}{W}{% + Writing to these two registers (lower 32 bits of the address + to \field{QueueDriverLow}, higher 32 bits to \field{QueueDriverHigh}) notifies + the device about location of the Driver Area of the queue + selected by writing to \field{QueueSel}. + } + \hline + \mmiodreg{QueueDeviceLow}{QueueDeviceHigh}{Virtual queue's Device Area 64 bit long physical address}{0x0a0}{0x0a4}{W}{% + Writing to these two registers (lower 32 bits of the address + to \field{QueueDeviceLow}, higher 32 bits to \field{QueueDeviceHigh}) notifies + the device about location of the Device Area of the queue + selected by writing to \field{QueueSel}. + } + \hline + \mmioreg{SHMSel}{Shared memory id}{0x0ac}{W}{% + Writing to this register selects the shared memory region \ref{sec:Basic Facilities of a Virtio Device / Shared Memory Regions} + following operations on \field{SHMLenLow}, \field{SHMLenHigh}, + \field{SHMBaseLow} and \field{SHMBaseHigh} apply to. + } + \hline + \mmiodreg{SHMLenLow}{SHMLenHigh}{Shared memory region 64 bit long length}{0x0b0}{0x0b4}{R}{% + These registers return the length of the shared memory + region in bytes, as defined by the device for the region selected by + the \field{SHMSel} register. The lower 32 bits of the length + are read from \field{SHMLenLow} and the higher 32 bits from + \field{SHMLenHigh}. Reading from a non-existent + region (i.e. where the ID written to \field{SHMSel} is unused) + results in a length of -1. + } + \hline + \mmiodreg{SHMBaseLow}{SHMBaseHigh}{Shared memory region 64 bit long physical address}{0x0b8}{0x0bc}{R}{% + The driver reads these registers to discover the base address + of the region in physical address space. This address is + chosen by the device (or other part of the VMM). + The lower 32 bits of the address are read from \field{SHMBaseLow} + with the higher 32 bits from \field{SHMBaseHigh}. Reading + from a non-existent region (i.e. where the ID written to + \field{SHMSel} is unused) results in a base address of + 0xffffffffffffffff. + } + \hline + \mmioreg{QueueReset}{Virtual queue reset bit}{0x0c0}{RW}{% + If VIRTIO_F_RING_RESET has been negotiated, writing one (0x1) to this + register selectively resets the queue. Both read and write accesses + apply to the queue selected by writing to \field{QueueSel}. + } + \hline + \mmioreg{ConfigGeneration}{Configuration atomicity value}{0x0fc}{R}{ + Reading from this register returns a value describing a version of the device-specific configuration space (see \field{Config}). + The driver can then access the configuration space and, when finished, read \field{ConfigGeneration} again. + If no part of the configuration space has changed between these two \field{ConfigGeneration} reads, the returned values are identical. + If the values are different, the configuration space accesses were not atomic and the driver has to perform the operations again. + See also \ref {sec:Basic Facilities of a Virtio Device / Device Configuration Space}. + } + \hline + \mmioreg{Config}{Configuration space}{0x100+}{RW}{ + Device-specific configuration space starts at the offset 0x100 + and is accessed with byte alignment. Its meaning and size + depend on the device and the driver. + } + \hline +\end{longtable} + +\devicenormative{\subsubsection}{MMIO Device Register Layout}{Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout} + +The device MUST return 0x74726976 in \field{MagicValue}. + +The device MUST return value 0x2 in \field{Version}. + +The device MUST present each event by setting the corresponding bit in \field{InterruptStatus} from the +moment it takes place, until the driver acknowledges the interrupt +by writing a corresponding bit mask to the \field{InterruptACK} register. Bits which +do not represent events which took place MUST be zero. + +Upon reset, the device MUST clear all bits in \field{InterruptStatus} and ready bits in the +\field{QueueReady} register for all queues in the device. + +The device MUST change value returned in \field{ConfigGeneration} if there is any risk of a +driver seeing an inconsistent configuration state. + +The device MUST NOT access virtual queue contents when \field{QueueReady} is zero (0x0). + +If VIRTIO_F_RING_RESET has been negotiated, the device MUST present a 0 in +\field{QueueReset} on reset. + +If VIRTIO_F_RING_RESET has been negotiated, The device MUST present a 0 in +\field{QueueReset} after the virtqueue is enabled with \field{QueueReady}. + +The device MUST reset the queue when 1 is written to \field{QueueReset}. The +device MUST continue to present 1 in \field{QueueReset} as long as the queue reset +is ongoing. The device MUST present 0 in both \field{QueueReset} and \field{QueueReady} +when queue reset has completed. +(see \ref{sec:Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Reset}). + +\drivernormative{\subsubsection}{MMIO Device Register Layout}{Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout} +The driver MUST NOT access memory locations not described in the +table \ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout} +(or, in case of the configuration space, described in the device specification), +MUST NOT write to the read-only registers (direction R) and +MUST NOT read from the write-only registers (direction W). + +The driver MUST only use 32 bit wide and aligned reads and writes to access the control registers +described in table \ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Register Layout}. +For the device-specific configuration space, the driver MUST use 8 bit wide accesses for +8 bit wide fields, 16 bit wide and aligned accesses for 16 bit wide fields and 32 bit wide and +aligned accesses for 32 and 64 bit wide fields. + +The driver MUST ignore a device with \field{MagicValue} which is not 0x74726976, +although it MAY report an error. + +The driver MUST ignore a device with \field{Version} which is not 0x2, +although it MAY report an error. + +The driver MUST ignore a device with \field{DeviceID} 0x0, +but MUST NOT report any error. + +Before reading from \field{DeviceFeatures}, the driver MUST write a value to \field{DeviceFeaturesSel}. + +Before writing to the \field{DriverFeatures} register, the driver MUST write a value to the \field{DriverFeaturesSel} register. + +The driver MUST write a value to \field{QueueNum} which is less than +or equal to the value presented by the device in \field{QueueNumMax}. + +When \field{QueueReady} is not zero, the driver MUST NOT access +\field{QueueNum}, \field{QueueDescLow}, \field{QueueDescHigh}, +\field{QueueDriverLow}, \field{QueueDriverHigh}, \field{QueueDeviceLow}, \field{QueueDeviceHigh}. + +To stop using the queue the driver MUST write zero (0x0) to this +\field{QueueReady} and MUST read the value back to ensure +synchronization. + +The driver MUST ignore undefined bits in \field{InterruptStatus}. + +The driver MUST write a value with a bit mask describing events it handled into \field{InterruptACK} when +it finishes handling an interrupt and MUST NOT set any of the undefined bits in the value. + +If VIRTIO_F_RING_RESET has been negotiated, after the driver writes 1 to +\field{QueueReset} to reset the queue, the driver MUST NOT consider queue +reset to be complete until it reads back 0 in \field{QueueReset}. The driver +MAY re-enable the queue by writing 1 to \field{QueueReady} after ensuring +that other virtqueue fields have been set up correctly. The driver MAY set +driver-writeable queue configuration values to different values than those +that were used before the queue reset. +(see \ref{sec:Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Reset}). + +\subsection{MMIO-specific Initialization And Device Operation}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation} + +\subsubsection{Device Initialization}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization} + +\drivernormative{\paragraph}{Device Initialization}{Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Device Initialization} + +The driver MUST start the device initialization by reading and +checking values from \field{MagicValue} and \field{Version}. +If both values are valid, it MUST read \field{DeviceID} +and if its value is zero (0x0) MUST abort initialization and +MUST NOT access any other register. + +Drivers not expecting shared memory MUST NOT use the shared +memory registers. + +Further initialization MUST follow the procedure described in +\ref{sec:General Initialization And Device Operation / Device Initialization}~\nameref{sec:General Initialization And Device Operation / Device Initialization}. + +\subsubsection{Virtqueue Configuration}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Virtqueue Configuration} + +The driver will typically initialize the virtual queue in the following way: + +\begin{enumerate} +\item Select the queue writing its index (first queue is 0) to + \field{QueueSel}. + +\item Check if the queue is not already in use: read \field{QueueReady}, + and expect a returned value of zero (0x0). + +\item Read maximum queue size (number of elements) from + \field{QueueNumMax}. If the returned value is zero (0x0) the + queue is not available. + +\item Allocate and zero the queue memory, making sure the memory + is physically contiguous. + +\item Notify the device about the queue size by writing the size to + \field{QueueNum}. + +\item Write physical addresses of the queue's Descriptor Area, + Driver Area and Device Area to (respectively) the + \field{QueueDescLow}/\field{QueueDescHigh}, + \field{QueueDriverLow}/\field{QueueDriverHigh} and + \field{QueueDeviceLow}/\field{QueueDeviceHigh} register pairs. + +\item Write 0x1 to \field{QueueReady}. +\end{enumerate} + +\subsubsection{Available Buffer Notifications}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Available Buffer Notifications} + +When VIRTIO_F_NOTIFICATION_DATA has not been negotiated, +the driver sends an available buffer notification to the device by writing +the 16-bit virtqueue index +of the queue to be notified to \field{QueueNotify}. + +When VIRTIO_F_NOTIFICATION_DATA has been negotiated, +the driver sends an available buffer notification to the device by writing +the following 32-bit value to \field{QueueNotify}: +\lstinputlisting{notifications-le.c} + +See \ref{sec:Basic Facilities of a Virtio Device / Driver notifications}~\nameref{sec:Basic Facilities of a Virtio Device / Driver notifications} +for the definition of the components. + +\subsubsection{Notifications From The Device}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notifications From The Device} + +The memory mapped virtio device is using a single, dedicated +interrupt signal, which is asserted when at least one of the +bits described in the description of \field{InterruptStatus} +is set. This is how the device sends a used buffer notification +or a configuration change notification to the device. + +\drivernormative{\paragraph}{Notifications From The Device}{Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notifications From The Device} +After receiving an interrupt, the driver MUST read +\field{InterruptStatus} to check what caused the interrupt (see the +register description). The used buffer notification bit being set +SHOULD be interpreted as a used buffer notification for each active +virtqueue. After the interrupt is handled, the driver MUST acknowledge +it by writing a bit mask corresponding to the handled events to the +InterruptACK register. + +\subsection{Legacy interface}\label{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface} + +The legacy MMIO transport used page-based addressing, resulting +in a slightly different control register layout, the device +initialization and the virtual queue configuration procedure. + +Table \ref{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Legacy Register Layout} +presents control registers layout, omitting +descriptions of registers which did not change their function +nor behaviour: + +\begin{longtable}{p{0.2\textwidth}p{0.7\textwidth}} + \caption {MMIO Device Legacy Register Layout} + \label{tab:Virtio Trasport Options / Virtio Over MMIO / MMIO Device Legacy Register Layout} \\ + \hline + \mmioreg{Name}{Function}{Offset from base}{Direction}{Description} + \hline + \hline + \endfirsthead + \hline + \mmioreg{Name}{Function}{Offset from the base}{Direction}{Description} + \hline + \hline + \endhead + \endfoot + \endlastfoot + \mmioreg{MagicValue}{Magic value}{0x000}{R}{} + \hline + \mmioreg{Version}{Device version number}{0x004}{R}{Legacy device returns value 0x1.} + \hline + \mmioreg{DeviceID}{Virtio Subsystem Device ID}{0x008}{R}{} + \hline + \mmioreg{VendorID}{Virtio Subsystem Vendor ID}{0x00c}{R}{} + \hline + \mmioreg{HostFeatures}{Flags representing features the device supports}{0x010}{R}{} + \hline + \mmioreg{HostFeaturesSel}{Device (host) features word selection.}{0x014}{W}{} + \hline + \mmioreg{GuestFeatures}{Flags representing device features understood and activated by the driver}{0x020}{W}{} + \hline + \mmioreg{GuestFeaturesSel}{Activated (guest) features word selection}{0x024}{W}{} + \hline + \mmioreg{GuestPageSize}{Guest page size}{0x028}{W}{% + The driver writes the guest page size in bytes to the + register during initialization, before any queues are used. + This value should be a power of 2 and is used by the device to + calculate the Guest address of the first queue page + (see QueuePFN). + } + \hline + \mmioreg{QueueSel}{Virtual queue index}{0x030}{W}{% + Writing to this register selects the virtual queue that the + following operations on the \field{QueueNumMax}, \field{QueueNum}, \field{QueueAlign} + and \field{QueuePFN} registers apply to. The index + number of the first queue is zero (0x0). +. + } + \hline + \mmioreg{QueueNumMax}{Maximum virtual queue size}{0x034}{R}{% + Reading from the register returns the maximum size of the queue + the device is ready to process or zero (0x0) if the queue is not + available. This applies to the queue selected by writing to + \field{QueueSel} and is allowed only when \field{QueuePFN} is set to zero + (0x0), so when the queue is not actively used. + } + \hline + \mmioreg{QueueNum}{Virtual queue size}{0x038}{W}{% + Queue size is the number of elements in the queue. + Writing to this register notifies the device what size of the + queue the driver will use. This applies to the queue selected by + writing to \field{QueueSel}. + } + \hline + \mmioreg{QueueAlign}{Used Ring alignment in the virtual queue}{0x03c}{W}{% + Writing to this register notifies the device about alignment + boundary of the Used Ring in bytes. This value should be a power + of 2 and applies to the queue selected by writing to \field{QueueSel}. + } + \hline + \mmioreg{QueuePFN}{Guest physical page number of the virtual queue}{0x040}{RW}{% + Writing to this register notifies the device about location of the + virtual queue in the Guest's physical address space. This value + is the index number of a page starting with the queue + Descriptor Table. Value zero (0x0) means physical address zero + (0x00000000) and is illegal. When the driver stops using the + queue it writes zero (0x0) to this register. + Reading from this register returns the currently used page + number of the queue, therefore a value other than zero (0x0) + means that the queue is in use. + Both read and write accesses apply to the queue selected by + writing to \field{QueueSel}. + } + \hline + \mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{} + \hline + \mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{} + \hline + \mmioreg{InterruptACK}{Interrupt acknowledge}{0x064}{W}{} + \hline + \mmioreg{Status}{Device status}{0x070}{RW}{% + Reading from this register returns the current device status + flags. + Writing non-zero values to this register sets the status flags, + indicating the OS/driver progress. Writing zero (0x0) to this + register triggers a device reset. The device + sets \field{QueuePFN} to zero (0x0) for all queues in the device. + Also see \ref{sec:General Initialization And Device Operation / Device Initialization}~\nameref{sec:General Initialization And Device Operation / Device Initialization}. + } + \hline + \mmioreg{Config}{Configuration space}{0x100+}{RW}{} + \hline +\end{longtable} + +The virtual queue page size is defined by writing to \field{GuestPageSize}, +as written by the guest. The driver does this before the +virtual queues are configured. + +The virtual queue layout follows +p. \ref{sec:Basic Facilities of a Virtio Device / Virtqueues / Legacy Interfaces: A Note on Virtqueue Layout}~\nameref{sec:Basic Facilities of a Virtio Device / Virtqueues / Legacy Interfaces: A Note on Virtqueue Layout}, +with the alignment defined in \field{QueueAlign}. + +The virtual queue is configured as follows: +\begin{enumerate} +\item Select the queue writing its index (first queue is 0) to + \field{QueueSel}. + +\item Check if the queue is not already in use: read \field{QueuePFN}, + expecting a returned value of zero (0x0). + +\item Read maximum queue size (number of elements) from + \field{QueueNumMax}. If the returned value is zero (0x0) the + queue is not available. + +\item Allocate and zero the queue pages in contiguous virtual + memory, aligning the Used Ring to an optimal boundary (usually + page size). The driver should choose a queue size smaller than or + equal to \field{QueueNumMax}. + +\item Notify the device about the queue size by writing the size to + \field{QueueNum}. + +\item Notify the device about the used alignment by writing its value + in bytes to \field{QueueAlign}. + +\item Write the physical number of the first page of the queue to + the \field{QueuePFN} register. +\end{enumerate} + +Notification mechanisms did not change. -- 2.26.2
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]