mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: nvs asynchronous control interface 1.0.0
Add asynchronous control interface for the GPU scheduler. The interface consists of: - General FIFO specification - General message send/receive procedures - The initial set of command messages for handshake, domain switching, and error responses JIRA GCSS-1892 Change-Id: Ib86baf470d9fdf2e45f4391faf247006d9b80f0b Signed-off-by: Sami Kiminki <skiminki@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2675369 Reviewed-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-by: Ankur Kishore <ankkishore@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
b1d7c77d8e
commit
9bc405dbbd
340
nvsched/include/nvs/nvs-control-interface.h
Normal file
340
nvsched/include/nvs/nvs-control-interface.h
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* NVIDIA Corporation and its licensors retain all intellectual property
|
||||||
|
* and proprietary rights in and to this software, related documentation
|
||||||
|
* and any modifications thereto. Any use, reproduction, disclosure or
|
||||||
|
* distribution of this software and related documentation without an express
|
||||||
|
* license agreement from NVIDIA Corporation is strictly prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NVS_CONTROL_INTERFACE_H
|
||||||
|
#define NVS_CONTROL_INTERFACE_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief <b>NVIDIA GPU domain scheduler asynchronous messaging interface</b>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nvs-control-messages.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#include <cstdint>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Value for nvs_domain_msg_fifo_control::get to indicate disabled
|
||||||
|
* flow control.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_FIFO_CONTROL_GET_FLOW_CTRL_DISABLED (0xFFFFFFFFU)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Least significant bit of field PUT in nvs_domain_msg_fifo_control::put_revolutions
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_PUT_LSB (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Most significant bit of field PUT in nvs_domain_msg_fifo_control::put_revolutions
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_PUT_MSB (31U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Least significant bit of field REVOLUTIONS in nvs_domain_msg_fifo_control::put_revolutions
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_REVOLUTIONS_LSB (32U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Most significant bit of field REVOLUTIONS in nvs_domain_msg_fifo_control::put_revolutions
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_REVOLUTIONS_MSB (63U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The FIFO ring buffer control block
|
||||||
|
*
|
||||||
|
* FIFO ring buffer initialization
|
||||||
|
* -------------------------------
|
||||||
|
*
|
||||||
|
* The FIFO ring buffer control block should be initialized on allocation as
|
||||||
|
* follows:
|
||||||
|
* - client --> scheduler:
|
||||||
|
* - all zeroes
|
||||||
|
* - scheduler --> client:
|
||||||
|
* - nvs_domain_msg_fifo_control::get =
|
||||||
|
* #NVS_DOMAIN_MSG_FIFO_CONTROL_GET_FLOW_CTRL_DISABLED.
|
||||||
|
* - everything else zeroes
|
||||||
|
*
|
||||||
|
* The FIFO size in entries is calculated as follows from the buffer size:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* num_messages = (buffer_size - sizeof(nvs_domain_msg_fifo_control)) / sizeof(nvs_domain_message)
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* With the current data structure layouts, this formula with sizeof substitutions is as:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* num_messages = (buffer_size - 128U) / 64U
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* For example, the number of messages in the FIFO is 1022 for a buffer of size 64K.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Adding a message in the FIFO ring buffer
|
||||||
|
* ----------------------------------------
|
||||||
|
*
|
||||||
|
* The sender is suggested to maintain the following variables locally:
|
||||||
|
* - @c local_put --- local copy of put index
|
||||||
|
* - @c local_revolution_count --- local copy of revolution count
|
||||||
|
* - @c local_num_dropped_messages --- local copy of number of dropped messages
|
||||||
|
* - @c local_fifo_size_entries --- local copy of the FIFO ring buffer size
|
||||||
|
*
|
||||||
|
* When the sender is initialized, the local variables should be initialized
|
||||||
|
* from the fields in #nvs_domain_msg_fifo_control, except for the FIFO size. The
|
||||||
|
* FIFO size is received from nvgpu-rm as part of the physical buffer
|
||||||
|
* parameters.
|
||||||
|
*
|
||||||
|
* The sequence for adding a message in the FIFO ring buffer is as follows:
|
||||||
|
*
|
||||||
|
* 1. Read nvs_domain_msg_fifo_control::get as @c get
|
||||||
|
* 2. Determine whether there is space for the message. There are two cases:
|
||||||
|
* - @c get == #NVS_DOMAIN_MSG_FIFO_CONTROL_GET_FLOW_CTRL_DISABLED: flow control disabled, space always available
|
||||||
|
* - otherwise: space is available when
|
||||||
|
* <tt>((local_put + 1) % local_fifo_size_entries) != get</tt>
|
||||||
|
* 3. If out of space, then:
|
||||||
|
* - increment @c local_num_dropped_messages
|
||||||
|
* - write it to nvs_domain_msg_fifo_control::num_dropped_messages
|
||||||
|
* - do not proceed with this sequence
|
||||||
|
* - Notes:
|
||||||
|
* - scheduler --> client: nvs_domain_msg_fifo_control::num_dropped_messages
|
||||||
|
* indicates that messages were dropped. Logging an
|
||||||
|
* overflow event may be applicable.
|
||||||
|
* - client --> scheduler: The usermode client should return an error.
|
||||||
|
* 4. Read-write memory barrier
|
||||||
|
* 5. Write the message to nvs_domain_msg_fifo::messages[local_put]
|
||||||
|
* - NOTE: if the message size is less than the size of the array entry, it
|
||||||
|
* should be appended with 0 to fill the entry. This allows extending the
|
||||||
|
* messages with new fields in later protocol versions in a backwards
|
||||||
|
* compatible manner.
|
||||||
|
* - NOTE: this update does not need to be atomic
|
||||||
|
* 6. Write memory barrier
|
||||||
|
* 7. Increment @c local_put (modulo fifo size). In case of a wrap-around,
|
||||||
|
* increment also @c local_revolution_count
|
||||||
|
* 8. Write <tt>local_put | (local_revolution_count << 32)</tt>
|
||||||
|
* to nvs_domain_msg_fifo_control::put_revolutions. This write
|
||||||
|
* should be atomic 64-bit write.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Receiving a message in the FIFO ring buffer (read-write access client)
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The receiver is suggested to maintain the following variables locally:
|
||||||
|
* - @c local_get --- local copy of get index
|
||||||
|
* - @c local_fifo_size_entries --- local copy of the FIFO ring buffer size
|
||||||
|
*
|
||||||
|
* When the reader is initialized, it should:
|
||||||
|
*
|
||||||
|
* 1. atomic read nvs_domain_msg_fifo_control::put_revolutions and store the
|
||||||
|
* 32-bit lower bits as @c local_get
|
||||||
|
* 2. store @c local_get to nvs_domain_msg_fifo_control::get. This enables
|
||||||
|
* flow control.
|
||||||
|
*
|
||||||
|
* When the reader exits, it should write
|
||||||
|
* #NVS_DOMAIN_MSG_FIFO_CONTROL_GET_FLOW_CTRL_DISABLED in
|
||||||
|
* nvs_domain_msg_fifo_control::get. This disables flow control. Further,
|
||||||
|
* nvgpu-rm should also write
|
||||||
|
* #NVS_DOMAIN_MSG_FIFO_CONTROL_GET_FLOW_CTRL_DISABLED in
|
||||||
|
* nvs_domain_msg_fifo_control::get when the R/W reader client exits. This
|
||||||
|
* is to ensure that abnormal client exit (e.g., process crash) disables flow
|
||||||
|
* control.
|
||||||
|
*
|
||||||
|
* The sequence for reading a message:
|
||||||
|
*
|
||||||
|
* 1. Atomic read the bottom 32 bits (or whole field) of
|
||||||
|
* nvs_domain_msg_fifo_control::put_revolutions as @c put
|
||||||
|
* 2. If local_get == put, there are no more messages. Exit this
|
||||||
|
* sequence.
|
||||||
|
* 3. Read memory barrier
|
||||||
|
* 4. Read the message from nvs_domain_msg_fifo::messages[local_get]
|
||||||
|
* (non-atomic read ok)
|
||||||
|
* 5. Read-write memory barrier
|
||||||
|
* 6. Increment local_get (mod FIFO size)
|
||||||
|
* 7. Atomic write nvs_domain_msg_fifo_control::get
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Receiving a message in the FIFO ring buffer (read-only access client)
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* <b>NOTE:</b> The read-only reader client should not be used for
|
||||||
|
* safety-critical operation. It does not have flow control and it is subject to
|
||||||
|
* FIFO overruns. The read-only client is intended for diagnostics and tracing.
|
||||||
|
*
|
||||||
|
* The receiver is suggested to maintain the following variables locally:
|
||||||
|
* - @c local_get --- local copy of get index
|
||||||
|
* - @c local_revolutions --- local copy of FIFO revolutions
|
||||||
|
* - @c local_fifo_size_entries --- local copy of the FIFO ring buffer size
|
||||||
|
*
|
||||||
|
* When the reader is initialized, it should:
|
||||||
|
*
|
||||||
|
* 1. atomic read nvs_domain_msg_fifo_control::put_revolutions and store the
|
||||||
|
* lower 32 bits as @c local_get, and the upper 32 bits as @c
|
||||||
|
* local_revolutions
|
||||||
|
*
|
||||||
|
* The sequence for reading a message:
|
||||||
|
*
|
||||||
|
* 1. Atomic read nvs_domain_msg_fifo_control::put_revolutions as @c put and
|
||||||
|
* @c revolutions
|
||||||
|
* 2. Determine whether the reader is more than a full revolution behind the
|
||||||
|
* writer. One way to do this is to calculate the total number of messages
|
||||||
|
* read and written, and then calculate the cyclic difference of the
|
||||||
|
* totals.
|
||||||
|
* @code
|
||||||
|
* cycleSize = FIFO_entries * (1 << 32) ; num messages until 'revolutions' wraps around
|
||||||
|
* messagesRead = local_get + (local_revolutions * FIFO_entries)
|
||||||
|
* messagesWritten = put + (revolutions * FIFO_entries)
|
||||||
|
* unreadMessages = (messagesWritten - messagesRead) mod cycleSize
|
||||||
|
* @endcode
|
||||||
|
* In case <tt>unreadMessages > FIFO_entries</tt>, a FIFO overrun has
|
||||||
|
* occurred. Note that in this formulation, care must be taken to avoid
|
||||||
|
* integer overflows during computation.
|
||||||
|
*
|
||||||
|
* It is up to the implementation what to do on FIFO overflow. Possibly,
|
||||||
|
* report an error and reset <tt>local_revolutions = revolutions</tt> and
|
||||||
|
* <tt>local_get = @c put</tt>.
|
||||||
|
* 3. If <tt>local_get == put</tt>, the are no unread messages. Exit this
|
||||||
|
* sequence.
|
||||||
|
* 4. Read memory barrier
|
||||||
|
* 5. Read the message from nvs_domain_msg_fifo::messages[local_get]
|
||||||
|
* (non-atomic read ok)
|
||||||
|
* 6. Read memory barrier
|
||||||
|
* 7. Atomic read nvs_domain_msg_fifo_control::put_revolutions as @c put and
|
||||||
|
* @c revolutions
|
||||||
|
* 8. Perform the FIFO overrun check again as in step 2. In case overrun is
|
||||||
|
* detected, then the message read on step 5 may have been overwritten
|
||||||
|
* while reading.
|
||||||
|
*
|
||||||
|
* It is up to the implementation what to do on FIFO overflow. Possibly,
|
||||||
|
* report an error and reset <tt>local_revolutions = revolutions</tt> and
|
||||||
|
* <tt>local_get = @c put</tt>.
|
||||||
|
* 9. Increment <tt>local_get (mod FIFO_entries)</tt>. If there is a wrap-around,
|
||||||
|
* increment @c local_revolutions.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_fifo_control {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get index (updated by the RW consumer)
|
||||||
|
*
|
||||||
|
* @remark Special value
|
||||||
|
* #NVS_DOMAIN_MSG_FIFO_CONTROL_GET_FLOW_CTRL_DISABLED means no flow
|
||||||
|
* control (scheduler --> client buffers only)
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint32_t get;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Padding to fill up 64B
|
||||||
|
*/
|
||||||
|
uint32_t reserved0[15];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Message put index and revolution count (updated by the producer)
|
||||||
|
*
|
||||||
|
* This member consists of two fields:
|
||||||
|
*
|
||||||
|
* - The lower 32 bits is the put index
|
||||||
|
* - The upper 32 bits is the revolution count, i.e., how many times the
|
||||||
|
* put index has wrapped around
|
||||||
|
*
|
||||||
|
* For example, this field would be incremented as follows for a FIFO of size 5:
|
||||||
|
*
|
||||||
|
* - 0x0000'0000'0000'0000 (initial value)
|
||||||
|
* - 0x0000'0000'0000'0001
|
||||||
|
* - 0x0000'0000'0000'0002
|
||||||
|
* - 0x0000'0000'0000'0003
|
||||||
|
* - 0x0000'0000'0000'0004
|
||||||
|
* - 0x0000'0001'0000'0000 (wrap-around, revolution count incremented)
|
||||||
|
* - 0x0000'0001'0000'0001
|
||||||
|
*
|
||||||
|
* The intention of the revolution count is to provide read-only
|
||||||
|
* observers a mechanism to detect dropped messages.
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_PUT_LSB
|
||||||
|
* @sa NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_PUT_MSB
|
||||||
|
* @sa NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_REVOLUTIONS_LSB
|
||||||
|
* @sa NVS_DOMAIN_MSG_FIFO_CONTROL_PUT_REVOLUTIONS_REVOLUTIONS_MSB
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint64_t put_revolutions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of dropped messages due to overrun (updated by the
|
||||||
|
* producer)
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint64_t num_dropped_messages; // number of lost messages due to buffer overrun
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Padding to fill up 64B
|
||||||
|
*/
|
||||||
|
uint32_t reserved1[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (defined(__cplusplus) && (__cplusplus >= 201103L))
|
||||||
|
/* Double-check that the example in the documentation is correct */
|
||||||
|
static_assert(
|
||||||
|
sizeof(nvs_domain_msg_fifo_control) == 128U,
|
||||||
|
"Verify the documented substitution (1)");
|
||||||
|
static_assert(
|
||||||
|
sizeof(nvs_domain_message) == 64U,
|
||||||
|
"Verify the documented substitution (2)");
|
||||||
|
static_assert(
|
||||||
|
(65536U - sizeof(nvs_domain_msg_fifo_control)) / sizeof(nvs_domain_message) == 1022U,
|
||||||
|
"Verify the documented example");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The general FIFO ring buffer format
|
||||||
|
*
|
||||||
|
* The following FIFO ring buffers are specified:
|
||||||
|
*
|
||||||
|
* - client --> scheduler control request messages
|
||||||
|
* - scheduler --> client control response messages
|
||||||
|
*
|
||||||
|
* The FIFO must be aligned by 64 bytes.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_fifo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Message ring buffer control
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_fifo_control control;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Message ring buffer data
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_message messages[];
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
438
nvsched/include/nvs/nvs-control-messages.h
Normal file
438
nvsched/include/nvs/nvs-control-messages.h
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* NVIDIA Corporation and its licensors retain all intellectual property
|
||||||
|
* and proprietary rights in and to this software, related documentation
|
||||||
|
* and any modifications thereto. Any use, reproduction, disclosure or
|
||||||
|
* distribution of this software and related documentation without an express
|
||||||
|
* license agreement from NVIDIA Corporation is strictly prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NVS_CONTROL_MESSAGES_H
|
||||||
|
#define NVS_CONTROL_MESSAGES_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief <b>NVIDIA GPU domain scheduler asynchronous message definitions</b>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#include <cstdint>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Communication error
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_error_resp
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_TYPE_CTRL_ERROR (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unknown/undefined error
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_error_resp::error_code
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_CTRL_ERROR_UNKNOWN (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unhandled message
|
||||||
|
*
|
||||||
|
* The scheduler received a message that it does not know how to handle.
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_error_resp::error_code
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_CTRL_ERROR_UNHANDLED_MESSAGE (1U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Communication error
|
||||||
|
*
|
||||||
|
* This control message is sent as a response to an erroneous request.
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_TYPE_CTRL_ERROR
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_error_resp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Communication error code
|
||||||
|
*
|
||||||
|
* See NVS_DOMAIN_MSG_CTRL_ERROR_* error codes.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint32_t error_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler capability query
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_get_caps_req
|
||||||
|
* @sa nvs_domain_msg_ctrl_get_caps_resp
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_TYPE_CTRL_GET_CAPS_INFO (1U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler capability query request
|
||||||
|
*
|
||||||
|
* The client version is used by the scheduler to check the client
|
||||||
|
* compatibility, following the semantic versioning specification. (See
|
||||||
|
* #NVS_DOMAIN_SCHED_VERSION_MAJOR for details.)
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_TYPE_CTRL_GET_CAPS_INFO
|
||||||
|
* @sa nvs_domain_msg_ctrl_get_caps_resp::client_version_status
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_get_caps_req {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client major version
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t client_version_major;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client minor version
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t client_version_minor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client patch level
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t client_version_patch;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Major version of the domain scheduler interface
|
||||||
|
*
|
||||||
|
* The versioning scheme follows the Semantic Versioning 2.0.0
|
||||||
|
* specification. See https://semver.org/spec/v2.0.0.html
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_SCHED_VERSION_MAJOR (1U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minor version of the domain scheduler interface
|
||||||
|
*
|
||||||
|
* The versioning scheme follows the Semantic Versioning 2.0.0
|
||||||
|
* specification. See https://semver.org/spec/v2.0.0.html
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_SCHED_VERSION_MINOR (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Patch version of the domain scheduler interface
|
||||||
|
*
|
||||||
|
* The versioning scheme follows the Semantic Versioning 2.0.0
|
||||||
|
* specification. See https://semver.org/spec/v2.0.0.html
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_SCHED_VERSION_PATCH (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client version check failed
|
||||||
|
*
|
||||||
|
* The client should not proceed with scheduler communication. The
|
||||||
|
* scheduler is not expected to be compatible.
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_CTRL_GET_CAPS_RESP_CLIENT_VERSION_STATUS_FAILED (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client version check passed
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_CTRL_GET_CAPS_RESP_CLIENT_VERSION_STATUS_OK (1U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler capability query response
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_TYPE_CTRL_GET_CAPS_INFO
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_get_caps_resp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler major version
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t sched_version_major;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler minor version
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t sched_version_minor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler patch level
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t sched_version_patch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client version check status
|
||||||
|
*
|
||||||
|
* This field indicates the scheduler-side check for client
|
||||||
|
* version compatibility. In general, the version numbering
|
||||||
|
* scheme follows the semantic versioning specification (see
|
||||||
|
* #NVS_DOMAIN_SCHED_VERSION_MAJOR). Additionally, the scheduler is
|
||||||
|
* allowed to fail this check for known incompatible or otherwise bad
|
||||||
|
* versions of the client.
|
||||||
|
*
|
||||||
|
* In general:
|
||||||
|
* - When the client and scheduler major version numbers match,
|
||||||
|
* #NVS_DOMAIN_MSG_CTRL_GET_CAPS_RESP_CLIENT_VERSION_STATUS_OK
|
||||||
|
* is returned.
|
||||||
|
* - When the client and scheduler major versions do not match,
|
||||||
|
* #NVS_DOMAIN_MSG_CTRL_GET_CAPS_RESP_CLIENT_VERSION_STATUS_FAILED
|
||||||
|
* is returned. Future note: If the client supports multiple
|
||||||
|
* scheduler major versions, the client is allowed to send
|
||||||
|
* #nvs_domain_msg_ctrl_get_caps_req again with a compatible
|
||||||
|
* version number.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t client_version_status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Switch to another domain
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_switch_domain_req
|
||||||
|
* @sa nvs_domain_msg_ctrl_switch_domain_resp
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_TYPE_CTRL_SWITCH_DOMAIN (2U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pseudo-domain ID for all TSGs over all domains
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_switch_domain_req::domain_id
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_CTRL_DOMAIN_ID_ALL (~(uint64_t)0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler domain switch request
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_TYPE_CTRL_SWITCH_DOMAIN
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_switch_domain_req {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Domain id
|
||||||
|
*
|
||||||
|
* @remark Domain id #NVS_DOMAIN_CTRL_DOMAIN_ID_ALL has a special meaning. This
|
||||||
|
* is a request to switch to a runlist that contains all TSGs in all domains.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint64_t domain_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler domain switch succeeded
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_msg_ctrl_switch_domain_resp::status
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MSG_TYPE_CTRL_SWITCH_DOMAIN_STATUS_SUCCESS (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler domain switch response
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_TYPE_CTRL_SWITCH_DOMAIN
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_switch_domain_resp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Domain switch status
|
||||||
|
*
|
||||||
|
* @remark The domain scheduler may return a status code that
|
||||||
|
* is not listed below. In this case, domain switch failed and
|
||||||
|
* the status code is returned for diagnostic and debugging
|
||||||
|
* purposes.
|
||||||
|
*
|
||||||
|
* @sa NVS_DOMAIN_MSG_TYPE_CTRL_SWITCH_DOMAIN_STATUS_SUCCESS
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Padding to ensure 8B alignment for the next field
|
||||||
|
* for 32/64-bit compatibility
|
||||||
|
*/
|
||||||
|
uint8_t reserved[7];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time it took to preempt and switch to the new domain (nanoseconds)
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint64_t switch_ns;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum payload size for #nvs_domain_message.
|
||||||
|
*
|
||||||
|
* @sa nvs_domain_message::payload
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
#define NVS_DOMAIN_MESSAGE_MAX_PAYLOAD_SIZE (48U)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Payload union
|
||||||
|
*
|
||||||
|
* Union that contains all defined messages.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
union nvs_domain_msg_payload_union {
|
||||||
|
/**
|
||||||
|
* @brief Control response message: communication error
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_error_resp resp_error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Control request message: get_caps
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_get_caps_req req_get_caps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Control response message: get_caps
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_get_caps_resp resp_get_caps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Control request message: switch_domain
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_switch_domain_req req_switch_domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Control response message: switch_domain
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_msg_ctrl_switch_domain_resp resp_switch_domain;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raw message data
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint8_t raw_data[NVS_DOMAIN_MESSAGE_MAX_PAYLOAD_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (defined(__cplusplus) && (__cplusplus >= 201103L))
|
||||||
|
static_assert(
|
||||||
|
sizeof(nvs_domain_msg_payload_union) == NVS_DOMAIN_MESSAGE_MAX_PAYLOAD_SIZE,
|
||||||
|
"Check for expected payload size");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The generic NVS domain message envelope
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
struct nvs_domain_message {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FIFO-specific message type
|
||||||
|
*
|
||||||
|
* Message type defines:
|
||||||
|
* - control messages: NVS_DOMAIN_MSG_TYPE_CTRL_*
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint32_t type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Client-provided message tag
|
||||||
|
*
|
||||||
|
* - **Request-response messages.** The client provides a tag
|
||||||
|
* which the scheduler copies to the corresponding
|
||||||
|
* response.
|
||||||
|
*
|
||||||
|
* @remark It is recommended that the client uses a sequence
|
||||||
|
* to generate the tags for easier request/response tracing.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint32_t sequence_tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Message timestamp (nanoseconds)
|
||||||
|
*
|
||||||
|
* client --> scheduler: host CPU time (CLOCK_MONOTONIC)
|
||||||
|
*
|
||||||
|
* scheduler --> client: scheduler local time
|
||||||
|
*
|
||||||
|
* @remark The timestamp field is primarily intended for
|
||||||
|
* message tracing purposes for allowing the reconstruction of
|
||||||
|
* the timeline of events. For operational purposes such as
|
||||||
|
* measuring the request/response round-trips as a health
|
||||||
|
* indicator, the usermode software should use local CPU
|
||||||
|
* host-side clock sampling, instead. The GSP clock is not
|
||||||
|
* guaranteed to use the same time domain with the host
|
||||||
|
* CPU. Further, drift may occur between the host CPU and GSP
|
||||||
|
* time domains.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
uint64_t timestamp_ns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Payload union
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
union nvs_domain_msg_payload_union payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user