OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

virtio-dev message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: [PATCH v4 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]