[PATCH v10 1/4] virtio-rtc: Add initial device specification

Peter Hilber <[email protected]>
Newsgroups dev.linux.lists.virtio-comment
Message-ID <[email protected]>
The virtio-rtc device provides information about current time through
one or more clocks. As such, it is a Real-Time Clock (RTC) device.

The normative statements for this device follow in the next patch.

For this device, there is a Linux kernel driver patch series which is
being upstreamed, and a proprietary device implementation.

Miscellaneous
-------------

The spec does not specify how a driver should interpret clock readings,
esp. also not how to perform clock synchronization.

The device uses the former "Timer/Clock" device id which is already part
of the specification. This device id was registered a long time ago and
should be unused according to the author's information. The name "RTC"
was determined to be the best for a device which focuses on current
time.

Signed-off-by: Peter Hilber <[email protected]>
---

Notes:
    v9:
    
    - Restrict implementation-specific id ranges to experimental
      implementations (Michael S. Tsirkin).
    
    - Document that device converts hardware counter value, accounting for
      device/driver differences in offset/multiplier (Michael S. Tsirkin).
    
    - State that an error-free device sets status OK for all requests from a
      well-behaved driver (Michael S. Tsirkin).
    
    - "Mark available"/"use" buffers instead of messages (Michael S.
      Tsirkin).
    
    - Change name to "Real Time Clock" in device type list (Michael S.
      Tsirkin).
    
    - Reword multiple sentences (Matias Ezequiel Vara Larsen).
    
    - Reduce ambiguity in how statements refer to multiple enumeration items
      (Michael S. Tsirkin).
    
    - Use "None currently defined." like other devices (Michael S. Tsirkin).
    
    - Clarify that request structs contain clock ids (Michael S. Tsirkin).
    
    - Add fixes which were mistakenly placed in patch 2 in v8 (Cornelia
      Huck).
    
    - Remove statement implying that device must not check that reserved
      fields are zero.
    
    v8:
    
    - Change word order from "field X" to "the X field" (Matias Ezequiel
      Vara Larsen).
    
    - Split up sentences about implementation-specific definitions (Matias
      Ezequiel Vara Larsen).
    
    v7:
    
    - Remove leap second and performance indications from struct
      virtio_rtc_resp_read_cross. Remove backing definitions.
    
    - Add wording change which was previously mistakenly placed in last
      patch.
    
    v6:
    
    - Make leap second status information optional if the clock smears (or
      might smear) leap seconds.
    
    - Do not use union for leap second indication.
    
    - Improve wording.
    
    - Refer to the new POSIX.1-2024 for UTC epoch definition.
    
    v5:
    
    - Change structure and wording to support adding shared memory like
      vmclock [8].
    
    - Add dedicated clock types for UTC leap second smearing (David
      Woodhouse).
    
    - Extend leap second indications.
    
    - Split UTC-TAI offset and fractional offset due to smearing (David
      Woodhouse).
    
    - Remove requirement that TAI offset must not be a whole second while
      clock is being smeared.
    
    - Align bit widths, and some names, with '[RFC PATCH v4] ptp: Add
      vDSO-style vmclock support' [8].
    
    - Replace VIRTIO_RTC_SUBTYPE_ by VIRTIO_RTC_SMEAR_.
    
    - For Arm Generic Timer, only support Virtual Count Register (David
      Woodhouse).
    
    - Rename MONO clock to MONOTONIC clock.
    
    v4:
    
    - Drop distinction of Arm Generic Timer virtual and physical counter [7].
    
    - Add requirement that device should assume that driver reads clock from
      first vCPU (David Woodhouse) [6].
    
    - Formatting and wording improvements.
    
    v3:
    
    - Address comments from Parav Pandit.
    
    - Split off normative requirements into a second commit [2].
    
    - Merge readq and controlq into requestq [3].
    
    - Don't guard cross-timestamping with feature bit [3].
    
    - Pad request headers to 64 bit [2].
    
    - Rename Virtio status codes to match UNIX error names [2].
    
    - Avoid Virtio status code clashes with net controlq ack values.
    
    - Reword to refer more to "requests", rather than "messages" [2].
    
    - Rephrase some sentences [2].
    
    - Use integer data types without "__" prefixes [2].
    
    - Reduce clock id width to 16 bits [5].
    
    - Make VIRTIO_RTC_FLAG_CROSS_CAP a bit mask rather than a bit index.
    
    v2:
    
    - Address comments from Cornelia Huck.
    
    - Add VIRTIO_RTC_M_CROSS_CAP message [1].
    
    - Fix various minor issues and improve wording [1].
    
    - Add several clarifications regarding device error statuses.
    
    [1] https://lists.oasis-open.org/archives/virtio-comment/202304/msg00523.html
    [2] https://lore.kernel.org/virtio-comment/[email protected]/t/#mffb93800fea11d6dda9e151078abedd6ff1c0f1e
    [3] https://lore.kernel.org/virtio-comment/[email protected]/t/#m94efd0aa9b9c2b96a246b79ef8bfc3bf64ebe791
    [4] https://lore.kernel.org/lkml/[email protected]/T/#m65fa1d715933360498c4e33d7225e4220215a9d6
    [5] https://lore.kernel.org/virtio-comment/[email protected]/t/#mf00ce330228c28556d735eb9597469048c5d8b62
    [6] https://lore.kernel.org/lkml/[email protected]/
    [7] https://lore.kernel.org/all/[email protected]/
    [8] https://lore.kernel.org/lkml/[email protected]/

 content.tex                      |   3 +-
 device-types/rtc/description.tex | 438 +++++++++++++++++++++++++++++++
 introduction.tex                 |   6 +
 3 files changed, 446 insertions(+), 1 deletion(-)
 create mode 100644 device-types/rtc/description.tex

diff --git a/content.tex b/content.tex
index 56b2cb1..5aed40b 100644
--- a/content.tex
+++ b/content.tex
@@ -684,7 +684,7 @@ \chapter{Device Types}\label{sec:Device Types}
 \hline
 16         &   GPU device       \\
 \hline
-17         &   Timer/Clock device \\
+17         &   RTC (Real Time Clock) device \\
 \hline
 18         &   Input device \\
 \hline
@@ -779,6 +779,7 @@ \chapter{Device Types}\label{sec:Device Types}
 \input{device-types/can/description.tex}
 \input{device-types/spi/description.tex}
 \input{device-types/media/description.tex}
+\input{device-types/rtc/description.tex}
 
 \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
 
diff --git a/device-types/rtc/description.tex b/device-types/rtc/description.tex
new file mode 100644
index 0000000..ae4b302
--- /dev/null
+++ b/device-types/rtc/description.tex
@@ -0,0 +1,438 @@
+\section{RTC Device}\label{sec:Device Types / RTC Device}
+
+The RTC (Real Time Clock) device provides information about current
+time. The device can provide different clocks, e.g.\ for the UTC or TAI
+time standards, or for physical time elapsed since some past epoch. The
+driver reads the clocks with simple or more accurate methods.
+
+\subsection{Device ID}\label{sec:Device Types / RTC Device / Device ID}
+
+17
+
+\subsection{Virtqueues}\label{sec:Device Types / RTC Device / Virtqueues}
+
+\begin{description}
+\item[0] requestq
+\end{description}
+
+The driver enqueues requests to the requestq.
+
+\subsection{Feature bits}\label{sec:Device Types / RTC Device / Feature bits}
+
+None currently defined.
+
+\subsection{Device configuration layout}\label{sec:Device Types / RTC Device / Device configuration layout}
+
+None currently defined.
+
+\subsection{Device Initialization}\label{sec:Device Types / RTC Device / Device Initialization}
+
+The device determines the set of clocks. The device provides zero or
+more clocks.
+
+\subsection{Device Operation}\label{sec:Device Types / RTC Device / Device Operation}
+
+The driver makes a request available in the requestq. The device fills
+in the response and uses the buffer. The requestq uses common request
+and response headers.
+
+\begin{lstlisting}
+/* common request header */
+struct virtio_rtc_req_head {
+        le16 msg_type;
+        u8 reserved[6];
+};
+
+/* common response header */
+struct virtio_rtc_resp_head {
+        u8 status;
+        u8 reserved[7];
+};
+\end{lstlisting}
+
+The \field{msg_type} field identifies the message type.
+
+The \field{status} field indicates whether the device successfully
+executed the request. The device sets the \field{status} field to one of
+the following values:
+
+\begin{lstlisting}
+#define VIRTIO_RTC_S_OK         0
+#define VIRTIO_RTC_S_EOPNOTSUPP 2
+#define VIRTIO_RTC_S_ENODEV     3
+#define VIRTIO_RTC_S_EINVAL     4
+#define VIRTIO_RTC_S_EIO        5
+\end{lstlisting}
+
+VIRTIO_RTC_S_OK indicates that the device successfully executed the
+request. If a driver only makes requests according to the device
+capabilities detected by the driver, an error-free device will always
+set status VIRTIO_RTC_S_OK.
+
+If \field{status} is not VIRTIO_RTC_S_OK, the value of other response
+fields is undefined.
+
+VIRTIO_RTC_S_EOPNOTSUPP indicates that the device could not execute the
+specific request due to an implementation limitation. The device also
+returns status VIRTIO_RTC_S_EOPNOTSUPP for requests with unknown values
+in the \field{msg_type} or \field{hw_counter} fields.
+
+VIRTIO_RTC_S_ENODEV indicates that the \field{clock_id} field value
+supplied with the request does not identify a clock.
+
+VIRTIO_RTC_S_EINVAL indicates one or more of the following conditions:
+
+\begin{itemize}
+\item The driver request values are not allowed by the specification.
+\item The device read-only buffer is too small to fit the request.
+\item The device write-only buffer is too small to fit the response.
+\end{itemize}
+
+VIRTIO_RTC_S_EIO indicates that the device did not execute the request
+due to an error which was not caused by invalid input from the driver.
+
+All \field{reserved} fields are written as zero.
+
+The set of clocks does not change after feature negotiation completion,
+until device reset. The set of clocks should not change on device reset
+either (similar to negotiated features). Clock identifiers are
+zero-based, dense indices. In request structures, all fields named
+\field{clock_id} contain clock identifiers.
+
+\subsubsection{Common Definitions}\label{sec:Device Types / RTC Device / Device Operation / Common Definitions}
+
+This section makes common definitions.
+
+\paragraph{Clock Types}\label{sec:Device Types / RTC Device / Device Operation / Common Definitions / Clock Types}
+
+The following clock types are defined:
+
+\begin{lstlisting}
+#define VIRTIO_RTC_CLOCK_UTC                    0
+#define VIRTIO_RTC_CLOCK_TAI                    1
+#define VIRTIO_RTC_CLOCK_MONOTONIC              2
+#define VIRTIO_RTC_CLOCK_UTC_SMEARED            3
+#define VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED      4
+\end{lstlisting}
+
+\begin{description}
+
+\item[VIRTIO_RTC_CLOCK_UTC] uses the UTC (Coordinated Universal Time)
+        time standard. This clock uses the time epoch of January 1,
+        1970, 00:00 UTC. This is the same epoch as \emph{Unix time}. The
+        clock's seconds since the epoch are related to UTC time as
+        defined by \hyperref[intro:EPOCH]{EPOCH}.
+
+        This clock observes positive and negative leap seconds as
+        announced by standard bodies. At the start of leap seconds, the
+        clock steps accordingly.
+
+\item[VIRTIO_RTC_CLOCK_TAI] uses the TAI (International Atomic Time)
+        time standard. This clock uses the time epoch of January 1,
+        1970, 00:00 TAI.
+
+\item[VIRTIO_RTC_CLOCK_MONOTONIC] uses monotonic physical time (SI
+        seconds subdivisions) since some unspecified epoch. The epoch is
+        before or during device reset.
+
+\item[VIRTIO_RTC_CLOCK_UTC_SMEARED] deviates from the UTC standard by
+        smearing time in the vicinity of a leap second. This avoids
+        clock steps due to UTC leap seconds. Otherwise, this clock is
+        similar to VIRTIO_RTC_CLOCK_UTC.
+
+\item[VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED] This clock either
+
+\begin{itemize}
+\item deviates from the UTC standard by smearing time in the vicinity of
+        a leap second (similar to VIRTIO_RTC_CLOCK_UTC_SMEARED), or
+
+\item steps at the start of leap seconds like VIRTIO_RTC_CLOCK_UTC.
+\end{itemize}
+
+A clock of type VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED can change this
+behavior for every leap second.
+
+\end{description}
+
+In the following, \emph{UTC-like clock} designates any clock of type
+VIRTIO_RTC_CLOCK_UTC, VIRTIO_RTC_CLOCK_UTC_SMEARED, or
+VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED.
+
+Additional clock types may be standardized in the future.
+Implementation-specific definitions of clock types are not recommended
+and are reserved for experimental implementations.
+Implementation-specific definitions use ids between 0xF0 and 0xFF.
+
+\paragraph{Smearing Variants}\label{sec:Device Types / RTC Device / Device Operation / Common Definitions / Smearing Variants}
+
+Leap second \emph{smearing variants} describe the deviation from the UTC
+standard in the vicinity of a leap second. The following smearing
+variants are currently defined:
+
+\begin{lstlisting}
+#define VIRTIO_RTC_SMEAR_UNSPECIFIED    0
+#define VIRTIO_RTC_SMEAR_NOON_LINEAR    1
+#define VIRTIO_RTC_SMEAR_UTC_SLS        2
+\end{lstlisting}
+
+\begin{description}
+
+        \item[VIRTIO_RTC_SMEAR_UNSPECIFIED] means that it is unspecified
+                how time is smeared in the vicinity of leap seconds.
+
+        \item[VIRTIO_RTC_SMEAR_NOON_LINEAR] specifies a linear smear
+                from noon prior to the leap second until noon after the
+                leap second.
+
+        \item[VIRTIO_RTC_SMEAR_UTC_SLS] specifies a linear smear as per
+                the \hyperref[intro:UTC-SLS]{UTC-SLS} proposal.
+
+\end{description}
+
+Clocks of type VIRTIO_RTC_CLOCK_UTC_SMEARED always behave according to a
+smearing variant. The smearing variant does not change over the clock's
+lifetime.
+
+For clocks of type VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED, it is unspecified
+whether leap seconds are smeared, and how leap seconds are smeared.
+
+Additional smearing variants may be standardized in the future.
+Implementation-specific definitions of smearing variants are not
+recommended and are reserved for experimental implementations.
+Implementation-specific definitions use ids greater than or equal to
+0xF0.
+
+In the following, \emph{leap smearing clock} designates any of the
+following clocks:
+
+\begin{itemize}
+
+\item any clock of type VIRTIO_RTC_CLOCK_UTC_SMEARED
+
+\item any clock of type VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED at any time
+        when the clock is smearing a leap second.
+
+\end{itemize}
+
+\paragraph{Hardware Counters}\label{sec:Device Types / RTC Device / Device Operation / Common Definitions / Hardware Counters}
+
+The following hardware counter identifiers are specified:
+
+\begin{lstlisting}
+/* Arm Generic Timer Counter-timer Virtual Count Register (CNTVCT_EL0) */
+#define VIRTIO_RTC_COUNTER_ARM_VCT      0
+/* x86 Time-Stamp Counter */
+#define VIRTIO_RTC_COUNTER_X86_TSC      1
+/* Invalid */
+#define VIRTIO_RTC_COUNTER_INVALID   0xFF
+\end{lstlisting}
+
+Additional hardware counter identifiers may be standardized in the
+future. Implementation-specific hardware counter identifiers are not
+recommended and are reserved for experimental implementations.
+Implementation-specific hardware counter identifiers have values between
+0xF0 and 0xFE.
+
+\subsubsection{Control Requests}\label{sec:Device Types / RTC Device / Device Operation / Control Requests}
+
+Through \emph{control requests}, the driver requests information about
+the device capabilities. The driver enqueues control requests in the
+requestq.
+
+\begin{description}
+
+\item[VIRTIO_RTC_REQ_CFG] discovers the number of clocks.
+
+\begin{lstlisting}
+#define VIRTIO_RTC_REQ_CFG 0x1000 /* message type */
+
+struct virtio_rtc_req_cfg {
+        struct virtio_rtc_req_head head;
+        /* no request params */
+};
+
+struct virtio_rtc_resp_cfg {
+        struct virtio_rtc_resp_head head;
+        le16 num_clocks;
+        u8 reserved[6];
+};
+\end{lstlisting}
+
+The \field{num_clocks} field contains the number of clocks. A device
+provides zero or more clocks. Valid clock ids are those smaller than
+\field{num_clocks}.
+
+\item[VIRTIO_RTC_REQ_CLOCK_CAP] discovers the capabilities of the clock
+identified by the \field{clock_id} field.
+
+\begin{lstlisting}
+#define VIRTIO_RTC_REQ_CLOCK_CAP 0x1001 /* message type */
+
+struct virtio_rtc_req_clock_cap {
+        struct virtio_rtc_req_head head;
+        le16 clock_id;
+        u8 reserved[6];
+};
+
+struct virtio_rtc_resp_clock_cap {
+        struct virtio_rtc_resp_head head;
+        u8 type;
+        u8 leap_second_smearing;
+        u8 reserved[6];
+};
+\end{lstlisting}
+
+The \field{type} field identifies the clock type. A device provides
+zero or more clocks for a clock type.
+
+Clocks of type VIRTIO_RTC_CLOCK_UTC_SMEARED indicate the \emph{smearing
+variant} through the \field{leap_second_smearing} field. All other
+clocks set \field{leap_second_smearing} to VIRTIO_RTC_SMEAR_UNSPECIFIED.
+
+\item[VIRTIO_RTC_REQ_CROSS_CAP] discovers whether the device supports
+cross-timestamping for a particular pair of clock and hardware counter.
+
+\begin{lstlisting}
+#define VIRTIO_RTC_REQ_CROSS_CAP 0x1002 /* message type */
+
+struct virtio_rtc_req_cross_cap {
+        struct virtio_rtc_req_head head;
+        le16 clock_id;
+        u8 hw_counter;
+        u8 reserved[5];
+};
+
+
+struct virtio_rtc_resp_cross_cap {
+        struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_FLAG_CROSS_CAP       (1 << 0)
+        u8 flags;
+        u8 reserved[7];
+};
+\end{lstlisting}
+
+The \field{clock_id} field identifies the clock, and the
+\field{hw_counter} field identifies the hardware counter, for which
+cross-timestamp support is probed. The device sets the
+VIRTIO_RTC_FLAG_CROSS_CAP flag in the \field{flags} field if the clock
+supports cross-timestamping for the particular clock and hardware
+counter, and clears the flag otherwise.
+
+\end{description}
+
+\subsubsection{Read Requests}\label{sec:Device Types / RTC Device / Device Operation / Read Requests}
+
+Through \emph{read requests}, the driver requests clock readings from
+the device. The driver enqueues read requests in the requestq. The
+device obtains device-side clock readings and forwards these clock
+readings to the driver. The driver may enhance and interpret the clock
+readings through methods which are beyond the scope of this
+specification.
+
+Once DRIVER_OK has been set, the device should support reading every
+clock, even when a clock may yet have to be aligned to reference time
+sources.
+
+In general,
+
+\begin{itemize}
+\item clocks may jump backwards or forward, and
+\item the clock frequency may change. Clocks may be \emph{slewed},
+        i.e.\ clocks may run at a frequency other than their current
+        best frequency estimate.
+\end{itemize}
+
+As long as a clock does not jump backwards, the driver clock readings
+through read request responses increase monotonically:
+
+\begin{itemize}
+\item As long as a clock does not jump backwards in-between device-side
+        clock readings, the driver-side readings for that clock increase
+        monotonically as well, in the order in which the driver
+        marks read requests as available.
+
+\item The device marks buffers with read requests for the same clock as
+        used in the order in which the buffers are available.
+\end{itemize}
+
+For a clock of type VIRTIO_RTC_CLOCK_MONOTONIC, the device always
+returns monotonically increasing clock readings through read request
+responses.
+
+The unit of all \field{clock_reading} fields is 1
+nanosecond.\footnote{For time epochs in year 1970 or later, this means
+that time until at least year 2553 can be represented in the \field{le64
+clock_reading} fields.}
+
+\begin{description}
+
+\item[VIRTIO_RTC_REQ_READ] reads the clock identified by the
+\field{clock_id} field. The device supports this request for every
+clock.
+
+\begin{lstlisting}
+#define VIRTIO_RTC_REQ_READ 0x0001 /* message type */
+
+struct virtio_rtc_req_read {
+        struct virtio_rtc_req_head head;
+        le16 clock_id;
+        u8 reserved[6];
+};
+
+struct virtio_rtc_resp_read {
+        struct virtio_rtc_resp_head head;
+        le64 clock_reading;
+};
+\end{lstlisting}
+
+\field{clock_reading} is a device-side clock reading obtained after the
+buffer was marked as available.
+
+\item[VIRTIO_RTC_REQ_READ_CROSS] returns a cross-timestamp for the clock
+identified by the \field{clock_id} field.\footnote{Cross-timestamping
+is similar to the ptp_kvm mechanism in the Linux kernel.} This request
+may yield better performance than using VIRTIO_RTC_REQ_READ.
+
+The driver can determine whether the device supports
+VIRTIO_RTC_REQ_READ_CROSS for a specific clock and \field{hw_counter}
+through VIRTIO_RTC_REQ_CROSS_CAP.
+
+\begin{lstlisting}
+#define VIRTIO_RTC_REQ_READ_CROSS 0x0002 /* message type */
+
+struct virtio_rtc_req_read_cross {
+        struct virtio_rtc_req_head head;
+        le16 clock_id;
+        u8 hw_counter;
+        u8 reserved[5];
+};
+
+struct virtio_rtc_resp_read_cross {
+        struct virtio_rtc_resp_head head;
+        le64 clock_reading;
+        le64 counter_cycles;
+};
+\end{lstlisting}
+
+The \field{hw_counter} field specifies the hardware counter for which
+the driver requests a cross-timestamp.
+
+Cross-timestamping returns a \field{clock_reading}, and an associated
+hardware counter value, \field{counter_cycles}. The
+\field{counter_cycles} field is the approximate or precise value which
+the driver would have read at the \field{clock_reading} time instant
+from the hardware counter identified by \field{hw_counter}.
+
+To determine the \field{counter_cycles} value, the device converts the
+hardware counter value the device has read, accounting for any
+differences in counter offsets or counter multipliers between device and
+driver at the time of the reading.
+
+In case hardware counter reads differ among CPUs used by the driver, the
+device should assume that the driver reads the hardware counter from the
+CPU which the driver enumerates as the first.
+
+The hardware counter identifiers are defined in
+\ref{sec:Device Types / RTC Device / Device Operation / Common Definitions / Hardware Counters}.
+
+\end{description}
diff --git a/introduction.tex b/introduction.tex
index 80aa67a..9a9cbde 100644
--- a/introduction.tex
+++ b/introduction.tex
@@ -180,6 +180,12 @@ \section{Normative References}\label{sec:Normative References}
     Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP
     14, RFC 8174, DOI 10.17487/RFC8174, May 2017
         \newline\url{http://www.ietf.org/rfc/rfc8174.txt}\\
+	\phantomsection\label{intro:EPOCH}\textbf{[EPOCH]} &
+    POSIX.1-2024, Base Definitions, Seconds Since the Epoch
+	\newline\url{https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap04.html#tag_04_19}\\
+	\phantomsection\label{intro:UTC-SLS}\textbf{[UTC-SLS]} &
+    UTC with Smoothed Leap Seconds (UTC-SLS)
+	\newline\url{https://www.cl.cam.ac.uk/~mgk25/time/utc-sls/}\\
 \end{longtable}
 
 \section{Non-Normative References}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.