[PATCH 00/18] Feedback: conformance clauses and normative statements.

From
Pawel Moll <>
Date
2014-02-20T10:09:00+00:00
ID
Thread
[PATCH 00/18] Feedback: conformance clauses and normative statements.
On Wed, 2014-02-19 at 06:39 +0000, Rusty Russell wrote:
> The section on initialization is now non-normative.
>
> Signed-off-by: Rusty Russell <>
> ---
>  content.tex | 134 +++++++++++++++++++++++++++++++++

---------------------------
>  1 file changed, 74 insertions(+), 60 deletions(-)
>
> diff --git a/content.tex b/content.tex
> index b8e5cc8..b3dfccf 100644
> --- a/content.tex
> +++ b/content.tex
> @@ -1694,14 +1694,9 @@ virtio_block@1e000 {
>  MMIO virtio devices provides 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}.
> -Driver MUST NOT access memory locations not explicitly described in the
> -table (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).
>
>  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 \\
>  }
> @@ -1726,23 +1721,20 @@ All register values are organized as Little Endian.
>
\endfoot
>
\endlastfoot
>
\mmioreg{MagicValue}{Magic value}{0x000}{R}{%
> -
Device MUST return value 0x74726976
> +
0x74726976
>
(a Little Endian equivalent of the "virt" string).
> -
Driver MUST ignore device returning other values,
> -
although it MAY report an error.
>
}
>
\hline
>
\mmioreg{Version}{Device version number}{0x004}{R}{%
> -
Devices compliant with this specification MUST return value 0x2.
> -
Legacy device (see \ref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}) MAY return value 0x1.
> -
Driver MUST ignore device returning other values,
> -
although it MAY report an error.
> +
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 invalid and driver MUST ignore such device
> -
but MUST NOT report any error. This behaviour can be used to
> +
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.
> @@ -1762,9 +1754,7 @@ All register values are organized as Little Endian.
>
\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}. The driver
> -
MUST write a value to \field{DeviceFeaturesSel} before
> -
reading from \field{DeviceFeatures}.
> +
accessible by reading from \field{DeviceFeatures}.
>
}
>
\hline
>
\mmioreg{DriverFeatures}{Flags representing device features understood and activated by the driver}{0x020}{W}{%
> @@ -1779,8 +1769,6 @@ All register values are organized as Little Endian.
>
\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}.
> -
The driver MUST write a value to the \field{DriverFeaturesSel}
> -
register before writing to the \field{DriverFeatures} register.
>
}
>
\hline
>
\mmioreg{QueueSel}{Virtual queue index}{0x030}{W}{%
> @@ -1795,9 +1783,7 @@ All register values are organized as Little Endian.
>
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}. The driver MUST NOT
> -
access this register when the queue is in use (so when \field{QueueReady}
> -
is not zero).
> +
queue selected by writing to \field{QueueSel}.
>
}
>
\hline
>
\mmioreg{QueueNum}{Virtual queue size}{0x038}{W}{%
> @@ -1805,8 +1791,7 @@ All register values are organized as Little Endian.
>
of the Descriptor Table and both Available and Used rings.
>
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}. The driver MUST NOT access this register when
> -
the queue is in use (so when \field{QueueReady} is not zero).
> +
writing to \field{QueueSel}.
>
}
>
\hline
>
\mmioreg{QueueReady}{Virtual queue ready bit}{0x044}{RW}{%
> @@ -1814,9 +1799,6 @@ All register values are organized as Little Endian.
>
virtual queue is ready to be used. 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}.
> -
When the driver wants to stop using the queue it MUST write
> -
zero (0x0) to this register and MUST read the value back to
> -
ensure synchronization.
>
}
>
\hline
>
\mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{%
> @@ -1827,11 +1809,6 @@ All register values are organized as Little Endian.
>
\mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{%
>
Reading from this register returns a bit mask of events that
>
caused the device interrupt to be asserted.
> -
From a moment when any of these events takes place, the
> -
device MUST be returning a value with the related
> -
bits set, ie. equal one (1), and all other bits cleared,
> -
ie. equal zero (0), until the driver acknowledges the interrupt
> -
by writing a corresponding bit mask to the InterruptACK register.
>
The following events are possible:
>
\begin{description}
>
\item[Used Ring Update] - bit 0 - the interrupt was asserted
> @@ -1840,17 +1817,11 @@ All register values are organized as Little Endian.
>
\item [Configuration Change] - bit 1 - the interrupt was
>
asserted because the configuration of the device has changed.
>
\end{description}
> -
Other bits of the value are reserved for future use and the
> -
driver MUST ignore them.
>
}
>
\hline
>
\mmioreg{InterruptACK}{Interrupt acknowledge}{0x064}{W}{%
>
Writing to this register notifies the device that the interrupt
> -
has been handled.
> -
When the driver finishes handling an interrupt, it MUST write
> -
a value to this register with bits corresponding to the handled
> -
events (as defined for \field{InterruptStatus}) set, ie.
> -
equal one (1), and all other bits cleared, ie. equal zero (0).
> +
has been handled, as per values for {InterruptStatus}.
>
}
>
\hline
>
\mmioreg{Status}{Device status}{0x070}{RW}{%
> @@ -1858,9 +1829,7 @@ All register values are organized as Little Endian.
>
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, including clearing all
> -
bits in \field{InterruptStatus} and ready bits in the
> -
\field{QueueReady} register for all queues in the device.
> +
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
> @@ -1868,34 +1837,25 @@ All register values are organized as Little Endian.
>
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 Table of the queue
> -
selected by writing to \field{QueueSel} register. The driver MUST NOT
> -
access this register when the queue is in use (so when \field{QueueReady}
> -
is not zero).
> +
selected by writing to \field{QueueSel} register.
>
}
>
\hline
>
\mmiodreg{QueueAvailLow}{QueueAvailHigh}{Virtual queue's Available Ring 64 bit long physical address}{0x090}{0x094}{W}{%
>
Writing to these two registers (lower 32 bits of the address
>
to \field{QueueAvailLow}, higher 32 bits to \field{QueueAvailHigh}) notifies
>
the device about location of the Available Ring of the queue
> -
selected by writing to \field{QueueSel}. The driver MUST NOT
> -
access this register when the queue is in use (so when \field{QueueReady}
> -
is not zero).
> +
selected by writing to \field{QueueSel}.
>
}
>
\hline
>
\mmiodreg{QueueUsedLow}{QueueUsedHigh}{Virtual queue's Used Ring 64 bit long physical address}{0x0a0}{0x0a4}{W}{%
>
Writing to these two registers (lower 32 bits of the address
>
to \field{QueueUsedLow}, higher 32 bits to \field{QueueUsedHigh}) notifies
>
the device about location of the Used Ring of the queue
> -
selected by writing to \field{QueueSel}. The driver MUST NOT
> -
access this register when the queue is in use (so when \field{QueueReady}
> -
is not zero).
> +
selected by writing to \field{QueueSel}.
>
}
>
\hline
>
\mmioreg{ConfigGeneration}{Configuration atomicity value}{0x0fc}{R}{
> -
Changes every time the configuration noticeably changes. This
> -
means the device may only change the value after a configuration
> -
read operation, but it MUST change if there is any risk of a
> -
device seeing an inconsistent configuration state.
> +
Changes every time the configuration noticeably changes (see \ref {sec:Basic Facilities of a Virtio Device / Device Configuration Space}.
>
}
>
\hline
>
\mmioreg{Config}{Configuration space}{0x100+}{RW}{
> @@ -1906,10 +1866,65 @@ All register values are organized as Little Endian.
>
\hline
>  \end{longtable}
>
> +\devicenormative{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 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 \field{ConfigGeneration} if there is any risk of a
> +device seeing an inconsistent configuration state, but it MAY only change the value
> +after a configuration read operation.
> +
> +\drivernormative{Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout}
> +The driver MUST NOT access memory locations not explicitly described in the
> +table (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 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.
> +
> +When \field{QueueReady} is not zero, the driver MUST NOT access
> +\field{QueueNum}, \field{QueueDescLow}, \field{QueueDescHigh},
> +\field{QueueAvailLow}, \field{QueueAvailHigh}, \field{QueueUsedLow}, \field{QueueUsedHigh}
> +
> +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 MUST write the events it handled into \field{InterruptACK} when
> +it finishes handling an interrupt.
> +
>  \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{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}
> @@ -1921,7 +1936,7 @@ Further initialization MUST follow the procedure described in
>
>  \subsubsection{Virtqueue Configuration}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Virtqueue Configuration}
>
> -The driver MUST initialize the virtual queue in the following way:
> +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
> @@ -1937,8 +1952,6 @@ The driver MUST initialize the virtual queue in the following way:
>  \item Allocate and zero the queue pages, making sure the memory
>
is physically contiguous. It is recommended to align the
>
Used Ring to an optimal boundary (usually the page size).
> -
Size of the allocated queue MUST be smaller than or equal to
> -
the maximum size returned by the device.
>
>  \item Notify the device about the queue size by writing the size to
>
\field{QueueNum}.
> @@ -1954,7 +1967,7 @@ The driver MUST initialize the virtual queue in the following way:
>
>  \subsubsection{Notifying The Device}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notifying The Device}
>
> -The driver MUST notify the device about new buffers being available in
> +The driver notifies the device about new buffers being available in
>  a queue by writing the index of the updated queue to \field{QueueNotify}.
>
>  \subsubsection{Notifications From The Device}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notifications From The Device}
> @@ -1962,10 +1975,11 @@ a queue by writing the index of the updated queue to \field{QueueNotify}.
>  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 way the device may notify the
> +is set. This is how the device notifies the
>  driver about a new used buffer being available in the queue
>  or about a change in the device configuration.
>
> +\drivernormative{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). After the interrupt is handled,
> --
> 1.8.3.2

Acked-by: Pawel Moll <>

Cheers!

Pawel