LCOV - code coverage report
Current view: top level - zephyr/mgmt/ec_host_cmd - ec_host_cmd.h Coverage Total Hit
Test: new.info Lines: 87.0 % 54 47
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2020 Google LLC
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_EC_HOST_CMD_H_
       8              : #define ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_EC_HOST_CMD_H_
       9              : 
      10              : /**
      11              :  * @brief EC Host Command Interface
      12              :  * @defgroup ec_host_cmd_interface EC Host Command Interface
      13              :  * @since 2.4
      14              :  * @version 0.1.0
      15              :  * @ingroup device_mgmt
      16              :  * @{
      17              :  */
      18              : 
      19              : #include <stdint.h>
      20              : #include <zephyr/kernel.h>
      21              : #include <zephyr/mgmt/ec_host_cmd/backend.h>
      22              : #include <zephyr/sys/__assert.h>
      23              : #include <zephyr/sys/iterable_sections.h>
      24              : 
      25              : /**
      26              :  * @brief Host command response codes (16-bit).
      27              :  */
      28            0 : enum ec_host_cmd_status {
      29              :         /** Host command was successful. */
      30              :         EC_HOST_CMD_SUCCESS = 0,
      31              :         /** The specified command id is not recognized or supported. */
      32              :         EC_HOST_CMD_INVALID_COMMAND = 1,
      33              :         /** Generic Error. */
      34              :         EC_HOST_CMD_ERROR = 2,
      35              :         /** One of more of the input request parameters is invalid. */
      36              :         EC_HOST_CMD_INVALID_PARAM = 3,
      37              :         /** Host command is not permitted. */
      38              :         EC_HOST_CMD_ACCESS_DENIED = 4,
      39              :         /** Response was invalid (e.g. not version 3 of header). */
      40              :         EC_HOST_CMD_INVALID_RESPONSE = 5,
      41              :         /** Host command id version unsupported. */
      42              :         EC_HOST_CMD_INVALID_VERSION = 6,
      43              :         /** Checksum did not match. */
      44              :         EC_HOST_CMD_INVALID_CHECKSUM = 7,
      45              :         /** A host command is currently being processed. */
      46              :         EC_HOST_CMD_IN_PROGRESS = 8,
      47              :         /** Requested information is currently unavailable. */
      48              :         EC_HOST_CMD_UNAVAILABLE = 9,
      49              :         /** Timeout during processing. */
      50              :         EC_HOST_CMD_TIMEOUT = 10,
      51              :         /** Data or table overflow. */
      52              :         EC_HOST_CMD_OVERFLOW = 11,
      53              :         /** Header is invalid or unsupported (e.g. not version 3 of header). */
      54              :         EC_HOST_CMD_INVALID_HEADER = 12,
      55              :         /** Did not receive all expected request data. */
      56              :         EC_HOST_CMD_REQUEST_TRUNCATED = 13,
      57              :         /** Response was too big to send within one response packet. */
      58              :         EC_HOST_CMD_RESPONSE_TOO_BIG = 14,
      59              :         /** Error on underlying communication bus. */
      60              :         EC_HOST_CMD_BUS_ERROR = 15,
      61              :         /** System busy. Should retry later. */
      62              :         EC_HOST_CMD_BUSY = 16,
      63              :         /** Header version invalid. */
      64              :         EC_HOST_CMD_INVALID_HEADER_VERSION = 17,
      65              :         /** Header CRC invalid. */
      66              :         EC_HOST_CMD_INVALID_HEADER_CRC = 18,
      67              :         /** Data CRC invalid. */
      68              :         EC_HOST_CMD_INVALID_DATA_CRC = 19,
      69              :         /** Can't resend response. */
      70              :         EC_HOST_CMD_DUP_UNAVAILABLE = 20,
      71              : 
      72              :         EC_HOST_CMD_MAX = UINT16_MAX /* Force enum to be 16 bits. */
      73              : } __packed;
      74              : 
      75              : /**
      76              :  * @brief Host command log levels
      77              :  */
      78            1 : enum ec_host_cmd_log_level {
      79              :         EC_HOST_CMD_DEBUG_OFF,    /**< No Host Command debug output */
      80              :         EC_HOST_CMD_DEBUG_NORMAL, /**< Normal output mode; skips repeated commands */
      81              :         EC_HOST_CMD_DEBUG_EVERY,  /**< Print every command */
      82              :         EC_HOST_CMD_DEBUG_PARAMS, /**< ... and print params for request/response */
      83              :         EC_HOST_CMD_DEBUG_MODES   /**< Number of host command debug modes */
      84              : };
      85              : 
      86              : /**
      87              :  * @brief Host command state
      88              :  */
      89            1 : enum ec_host_cmd_state {
      90              :         EC_HOST_CMD_STATE_DISABLED = 0, /**< Host command subsystem is disabled */
      91              :         EC_HOST_CMD_STATE_RECEIVING,    /**< Receiving command data from host */
      92              :         EC_HOST_CMD_STATE_PROCESSING,   /**< Processing received command */
      93              :         EC_HOST_CMD_STATE_SENDING,      /**< Sending response to host */
      94              : };
      95              : 
      96              : /**
      97              :  * @brief User callback function type for host command reception
      98              :  *
      99              :  * This callback is invoked after a host command is received and validated
     100              :  * but before command processing begins. It allows user code to perform
     101              :  * custom actions based on the received command.
     102              :  *
     103              :  * @param rx_ctx Pointer to the receive context containing command data
     104              :  * @param user_data User-defined data pointer passed during callback registration
     105              :  */
     106            1 : typedef void (*ec_host_cmd_user_cb_t)(const struct ec_host_cmd_rx_ctx *rx_ctx, void *user_data);
     107              : 
     108              : /**
     109              :  * @brief In-progress callback function type
     110              :  *
     111              :  * This callback is executed asynchronously for commands that return
     112              :  * EC_HOST_CMD_IN_PROGRESS status. It allows long-running operations
     113              :  * to complete in the background.
     114              :  *
     115              :  * @param user_data User-provided data passed to the callback
     116              :  * @return Final status code for the command
     117              :  */
     118              : typedef enum ec_host_cmd_status (*ec_host_cmd_in_progress_cb_t)(void *user_data);
     119              : 
     120              : /**
     121              :  * Host command context structure
     122              :  */
     123            1 : struct ec_host_cmd {
     124            0 :         struct ec_host_cmd_rx_ctx rx_ctx;
     125            0 :         struct ec_host_cmd_tx_buf tx;
     126            0 :         struct ec_host_cmd_backend *backend;
     127              :         /**
     128              :          * The backend gives rx_ready (by calling the ec_host_cmd_send_receive function),
     129              :          * when data in rx_ctx are ready. The handler takes rx_ready to read data in rx_ctx.
     130              :          */
     131            1 :         struct k_sem rx_ready;
     132              :         /** Status of the rx data checked in the ec_host_cmd_send_received function. */
     133            1 :         enum ec_host_cmd_status rx_status;
     134              :         /**
     135              :          * User callback after receiving a command. It is called by the ec_host_cmd_send_received
     136              :          * function.
     137              :          */
     138            1 :         ec_host_cmd_user_cb_t user_cb;
     139            0 :         void *user_data;
     140            0 :         enum ec_host_cmd_state state;
     141              : #ifdef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
     142              :         struct k_thread thread;
     143              : #endif /* CONFIG_EC_HOST_CMD_DEDICATED_THREAD */
     144              : };
     145              : 
     146              : /**
     147              :  * @brief Arguments passed into every installed host command handler
     148              :  */
     149            1 : struct ec_host_cmd_handler_args {
     150              :         /** Reserved for compatibility. */
     151            1 :         void *reserved;
     152              :         /** Command identifier. */
     153            1 :         uint16_t command;
     154              :         /**
     155              :          * The version of the host command that is being requested. This will
     156              :          * be a value that has been static registered as valid for the handler.
     157              :          */
     158            1 :         uint8_t version;
     159              :         /** The incoming data that can be cast to the handlers request type. */
     160            1 :         const void *input_buf;
     161              :         /** The number of valid bytes that can be read from @a input_buf. */
     162            1 :         uint16_t input_buf_size;
     163              :         /** The data written to this buffer will be send to the host. */
     164            1 :         void *output_buf;
     165              :         /** Maximum number of bytes that can be written to the @a output_buf. */
     166            1 :         uint16_t output_buf_max;
     167              :         /** Number of bytes of @a output_buf to send to the host. */
     168            1 :         uint16_t output_buf_size;
     169              : };
     170              : 
     171              : /**
     172              :  * @brief Host command handler callback function type
     173              :  *
     174              :  * This callback is invoked to process a host command that matches the handler's
     175              :  * command ID and version. The handler processes the incoming command data and
     176              :  * generates a response.
     177              :  *
     178              :  * @param args Pointer to an @ref ec_host_cmd_handler_args structure containing command data and
     179              :  *             buffers
     180              :  * @return Status code indicating the result of command processing
     181              :  */
     182              : typedef enum ec_host_cmd_status (*ec_host_cmd_handler_cb)(struct ec_host_cmd_handler_args *args);
     183              : 
     184              : /**
     185              :  * @brief Structure use for statically registering host command handlers
     186              :  */
     187            1 : struct ec_host_cmd_handler {
     188              :         /** Callback routine to process commands that match @a id. */
     189            1 :         ec_host_cmd_handler_cb handler;
     190              :         /** The numerical command id used as the lookup for commands. */
     191            1 :         uint16_t id;
     192              :         /**
     193              :          * The bitfield of all versions that the @a handler supports, where
     194              :          * each bit value represents that the @a handler supports that version.
     195              :          * E.g. BIT(0) corresponds to version 0.
     196              :          */
     197            1 :         uint16_t version_mask;
     198              :         /**
     199              :          * The minimum @a input_buf_size enforced by the framework before
     200              :          * passing to the handler.
     201              :          */
     202            1 :         uint16_t min_rqt_size;
     203              :         /**
     204              :          * The minimum @a output_buf_size enforced by the framework before
     205              :          * passing to the handler.
     206              :          */
     207            1 :         uint16_t min_rsp_size;
     208              : };
     209              : 
     210              : /**
     211              :  * @brief Statically define and register a host command handler.
     212              :  *
     213              :  * Helper macro to statically define and register a host command handler that
     214              :  * has a compile-time-fixed sizes for its both request and response structures.
     215              :  *
     216              :  * @param _id Id of host command to handle request for.
     217              :  * @param _function Name of handler function.
     218              :  * @param _version_mask The bitfield of all versions that the @a _function
     219              :  *        supports. E.g. BIT(0) corresponds to version 0.
     220              :  * @param _request_type The datatype of the request parameters for @a _function.
     221              :  * @param _response_type The datatype of the response parameters for
     222              :  *        @a _function.
     223              :  */
     224            1 : #define EC_HOST_CMD_HANDLER(_id, _function, _version_mask, _request_type, _response_type)          \
     225              :         const STRUCT_SECTION_ITERABLE(ec_host_cmd_handler, __cmd##_id) = {                         \
     226              :                 .handler = _function,                                                              \
     227              :                 .id = _id,                                                                         \
     228              :                 .version_mask = _version_mask,                                                     \
     229              :                 .min_rqt_size = sizeof(_request_type),                                             \
     230              :                 .min_rsp_size = sizeof(_response_type),                                            \
     231              :         }
     232              : 
     233              : /**
     234              :  * @brief Statically define and register a host command handler without sizes.
     235              :  *
     236              :  * Helper macro to statically define and register a host command handler whose
     237              :  * request or response structure size is not known as compile time.
     238              :  *
     239              :  * @param _id Id of host command to handle request for.
     240              :  * @param _function Name of handler function.
     241              :  * @param _version_mask The bitfield of all versions that the @a _function
     242              :  *        supports. E.g. BIT(0) corresponds to version 0.
     243              :  */
     244            1 : #define EC_HOST_CMD_HANDLER_UNBOUND(_id, _function, _version_mask)                                 \
     245              :         const STRUCT_SECTION_ITERABLE(ec_host_cmd_handler, __cmd##_id) = {                         \
     246              :                 .handler = _function,                                                              \
     247              :                 .id = _id,                                                                         \
     248              :                 .version_mask = _version_mask,                                                     \
     249              :                 .min_rqt_size = 0,                                                                 \
     250              :                 .min_rsp_size = 0,                                                                 \
     251              :         }
     252              : 
     253              : /**
     254              :  * @brief Header for requests from host to embedded controller
     255              :  *
     256              :  * Represent the over-the-wire header in LE format for host command requests.
     257              :  * This represent version 3 of the host command header. The requests are always
     258              :  * sent from host to embedded controller.
     259              :  */
     260            1 : struct ec_host_cmd_request_header {
     261              :         /**
     262              :          * Should be 3. The EC will return EC_HOST_CMD_INVALID_HEADER if it
     263              :          * receives a header with a version it doesn't know how to parse.
     264              :          */
     265            1 :         uint8_t prtcl_ver;
     266              :         /**
     267              :          * Checksum of response and data; sum of all bytes including checksum.
     268              :          * Should total to 0.
     269              :          */
     270            1 :         uint8_t checksum;
     271              :         /** Id of command that is being sent. */
     272            1 :         uint16_t cmd_id;
     273              :         /**
     274              :          * Version of the specific @a cmd_id being requested. Valid
     275              :          * versions start at 0.
     276              :          */
     277            1 :         uint8_t cmd_ver;
     278              :         /** Unused byte in current protocol version; set to 0. */
     279            1 :         uint8_t reserved;
     280              :         /** Length of data which follows this header. */
     281            1 :         uint16_t data_len;
     282              : } __packed;
     283              : 
     284              : /**
     285              :  * @brief Header for responses from embedded controller to host
     286              :  *
     287              :  * Represent the over-the-wire header in LE format for host command responses.
     288              :  * This represent version 3 of the host command header. Responses are always
     289              :  * sent from embedded controller to host.
     290              :  */
     291            1 : struct ec_host_cmd_response_header {
     292              :         /** Should be 3. */
     293            1 :         uint8_t prtcl_ver;
     294              :         /**
     295              :          * Checksum of response and data; sum of all bytes including checksum.
     296              :          * Should total to 0.
     297              :          */
     298            1 :         uint8_t checksum;
     299              :         /** A @a ec_host_cmd_status response code for specific command. */
     300            1 :         uint16_t result;
     301              :         /** Length of data which follows this header. */
     302            1 :         uint16_t data_len;
     303              :         /** Unused bytes in current protocol version; set to 0. */
     304            1 :         uint16_t reserved;
     305              : } __packed;
     306              : 
     307              : /**
     308              :  * @brief Initialize the host command subsystem
     309              :  *
     310              :  * This routine initializes the host command subsystem. It includes initialization
     311              :  * of a backend and the handler.
     312              :  * When the application configures the zephyr,host-cmd-espi-backend/zephyr,host-cmd-shi-backend/
     313              :  * zephyr,host-cmd-uart-backend chosen node and @kconfig{CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT} is
     314              :  * set, the chosen backend automatically calls this routine at
     315              :  * @kconfig{CONFIG_EC_HOST_CMD_INIT_PRIORITY}. Applications that require a run-time selection of the
     316              :  * backend must set @kconfig{CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT} to n and must explicitly call
     317              :  * this routine.
     318              :  *
     319              :  * @param[in] backend        Pointer to the backend structure to initialize.
     320              :  *
     321              :  * @retval 0 if successful
     322              :  */
     323            1 : int ec_host_cmd_init(struct ec_host_cmd_backend *backend);
     324              : 
     325              : /**
     326              :  * @brief Send the host command response
     327              :  *
     328              :  * This routine sends the host command response. It should be used to send IN_PROGRESS status or
     329              :  * if the host command handler doesn't return e.g. reboot command.
     330              :  *
     331              :  * @param[in] status        Host command status to be sent.
     332              :  * @param[in] args          Pointer of a structure passed to the handler.
     333              :  *
     334              :  * @retval 0 if successful.
     335              :  */
     336            1 : int ec_host_cmd_send_response(enum ec_host_cmd_status status,
     337              :                               const struct ec_host_cmd_handler_args *args);
     338              : 
     339              : /**
     340              :  * @brief Signal a new host command
     341              :  *
     342              :  * Signal that a new host command has been received. The function should be called by a backend
     343              :  * after copying data to the rx buffer and setting the length.
     344              :  */
     345            1 : void ec_host_cmd_rx_notify(void);
     346              : 
     347              : /**
     348              :  * @brief Install a user callback for receiving a host command
     349              :  *
     350              :  * It allows installing a custom procedure needed by a user after receiving a command.
     351              :  *
     352              :  * @param[in] cb          A callback to be installed.
     353              :  * @param[in] user_data   User data to be passed to the callback.
     354              :  */
     355            1 : void ec_host_cmd_set_user_cb(ec_host_cmd_user_cb_t cb, void *user_data);
     356              : 
     357              : /**
     358              :  * @brief Get the main ec host command structure
     359              :  *
     360              :  * This routine returns a pointer to the main host command structure.
     361              :  * It allows the application code to get inside information for any reason e.g.
     362              :  * the host command thread id.
     363              :  *
     364              :  * @retval A pointer to the main host command structure
     365              :  */
     366            1 : const struct ec_host_cmd *ec_host_cmd_get_hc(void);
     367              : 
     368              : #ifndef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
     369              : /**
     370              :  * @brief The thread function for Host Command subsystem
     371              :  *
     372              :  * This routine calls the Host Command thread entry function. If
     373              :  * @kconfig{CONFIG_EC_HOST_CMD_DEDICATED_THREAD} is not defined, a new thread is not created,
     374              :  * and this function has to be called by application code. It doesn't return.
     375              :  */
     376            1 : FUNC_NORETURN void ec_host_cmd_task(void);
     377              : #endif
     378              : 
     379              : #if defined(CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS) || defined(__DOXYGEN__)
     380              : /**
     381              :  * @brief Check if a Host Command that sent @ref EC_HOST_CMD_IN_PROGRESS status has ended.
     382              :  *
     383              :  * A Host Command that sends @ref EC_HOST_CMD_IN_PROGRESS status doesn't send a final result.
     384              :  * The final result can be obtained with the @ref ec_host_cmd_send_in_progress_status function.
     385              :  *
     386              :  * @kconfig_dep{CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS}
     387              :  *
     388              :  * @retval true if the Host Command endded
     389              :  */
     390            1 : bool ec_host_cmd_send_in_progress_ended(void);
     391              : 
     392              : /**
     393              :  * @brief Get final result of a last Host Command that has sent @ref EC_HOST_CMD_IN_PROGRESS status.
     394              :  *
     395              :  * A Host Command that sends @ref EC_HOST_CMD_IN_PROGRESS status doesn't send a final result.
     396              :  * Get the saved status with this function. The status can be obtained only once. Further calls
     397              :  * return @ref EC_HOST_CMD_UNAVAILABLE.
     398              :  *
     399              :  * Saving status of Host Commands that send response data is not supported.
     400              :  *
     401              :  * @kconfig_dep{CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS}
     402              :  *
     403              :  * @retval The final status or EC_HOST_CMD_UNAVAILABLE if not available.
     404              :  */
     405            1 : enum ec_host_cmd_status ec_host_cmd_send_in_progress_status(void);
     406              : 
     407              : /**
     408              :  * @brief Continue processing a handler in callback after returning @ref EC_HOST_CMD_IN_PROGRESS.
     409              :  *
     410              :  * A Host Command handler may return the @ref EC_HOST_CMD_IN_PROGRESS, but needs to continue work.
     411              :  * This function should be called before returning @ref EC_HOST_CMD_IN_PROGRESS with a callback that
     412              :  * will be executed. The return status of the callback will be stored and can be obtained with the
     413              :  * @ref ec_host_cmd_send_in_progress_status function. The @ref ec_host_cmd_send_in_progress_ended
     414              :  * function can be used to check if the callback has ended.
     415              :  *
     416              :  * @kconfig_dep{CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS}
     417              :  *
     418              :  * @param[in] cb          A callback to be called after returning from a command handler.
     419              :  * @param[in] user_data   User data to be passed to the callback.
     420              :  *
     421              :  * @retval EC_HOST_CMD_BUSY if any command is already in progress, EC_HOST_CMD_SUCCESS otherwise
     422              :  */
     423            1 : enum ec_host_cmd_status ec_host_cmd_send_in_progress_continue(ec_host_cmd_in_progress_cb_t cb,
     424              :                                                               void *user_data);
     425              : #endif /* CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS */
     426              : 
     427              : /**
     428              :  * @brief Add a suppressed command.
     429              :  *
     430              :  * Suppressed commands are not logged. Add a command to be suppressed.
     431              :  *
     432              :  * @param[in] cmd_id        A command id to be suppressed.
     433              :  *
     434              :  * @retval 0 if successful, -EIO if exceeded max number of suppressed commands.
     435              :  */
     436            1 : int ec_host_cmd_add_suppressed(uint16_t cmd_id);
     437              : 
     438              : /**
     439              :  * @}
     440              :  */
     441              : 
     442              : #endif /* ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_EC_HOST_CMD_H_ */
        

Generated by: LCOV version 2.0-1