LCOV - code coverage report
Current view: top level - zephyr/mgmt/ec_host_cmd - ec_host_cmd.h Hit Total Coverage
Test: new.info Lines: 40 51 78.4 %
Date: 2024-12-21 18:13:37

          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 io_interfaces
      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           0 : enum ec_host_cmd_log_level {
      76             :         EC_HOST_CMD_DEBUG_OFF, /* No Host Command debug output */
      77             :         EC_HOST_CMD_DEBUG_NORMAL, /* Normal output mode; skips repeated commands */
      78             :         EC_HOST_CMD_DEBUG_EVERY, /* Print every command */
      79             :         EC_HOST_CMD_DEBUG_PARAMS, /* ... and print params for request/response */
      80             :         EC_HOST_CMD_DEBUG_MODES /* Number of host command debug modes */
      81             : };
      82             : 
      83           0 : enum ec_host_cmd_state {
      84             :         EC_HOST_CMD_STATE_DISABLED = 0,
      85             :         EC_HOST_CMD_STATE_RECEIVING,
      86             :         EC_HOST_CMD_STATE_PROCESSING,
      87             :         EC_HOST_CMD_STATE_SENDING,
      88             : };
      89             : 
      90           0 : typedef void (*ec_host_cmd_user_cb_t)(const struct ec_host_cmd_rx_ctx *rx_ctx, void *user_data);
      91             : typedef enum ec_host_cmd_status (*ec_host_cmd_in_progress_cb_t)(void *user_data);
      92             : 
      93           0 : struct ec_host_cmd {
      94           0 :         struct ec_host_cmd_rx_ctx rx_ctx;
      95           0 :         struct ec_host_cmd_tx_buf tx;
      96           0 :         struct ec_host_cmd_backend *backend;
      97             :         /**
      98             :          * The backend gives rx_ready (by calling the ec_host_cmd_send_receive function),
      99             :          * when data in rx_ctx are ready. The handler takes rx_ready to read data in rx_ctx.
     100             :          */
     101           1 :         struct k_sem rx_ready;
     102             :         /** Status of the rx data checked in the ec_host_cmd_send_received function. */
     103           1 :         enum ec_host_cmd_status rx_status;
     104             :         /**
     105             :          * User callback after receiving a command. It is called by the ec_host_cmd_send_received
     106             :          * function.
     107             :          */
     108           1 :         ec_host_cmd_user_cb_t user_cb;
     109           0 :         void *user_data;
     110           0 :         enum ec_host_cmd_state state;
     111             : #ifdef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
     112             :         struct k_thread thread;
     113             : #endif /* CONFIG_EC_HOST_CMD_DEDICATED_THREAD */
     114             : };
     115             : 
     116             : /**
     117             :  * @brief Arguments passed into every installed host command handler
     118             :  */
     119           1 : struct ec_host_cmd_handler_args {
     120             :         /** Reserved for compatibility. */
     121           1 :         void *reserved;
     122             :         /** Command identifier. */
     123           1 :         uint16_t command;
     124             :         /**
     125             :          * The version of the host command that is being requested. This will
     126             :          * be a value that has been static registered as valid for the handler.
     127             :          */
     128           1 :         uint8_t version;
     129             :         /** The incoming data that can be cast to the handlers request type. */
     130           1 :         const void *input_buf;
     131             :         /** The number of valid bytes that can be read from @a input_buf. */
     132           1 :         uint16_t input_buf_size;
     133             :         /** The data written to this buffer will be send to the host. */
     134           1 :         void *output_buf;
     135             :         /** Maximum number of bytes that can be written to the @a output_buf. */
     136           1 :         uint16_t output_buf_max;
     137             :         /** Number of bytes of @a output_buf to send to the host. */
     138           1 :         uint16_t output_buf_size;
     139             : };
     140             : 
     141             : typedef enum ec_host_cmd_status (*ec_host_cmd_handler_cb)(struct ec_host_cmd_handler_args *args);
     142             : /**
     143             :  * @brief Structure use for statically registering host command handlers
     144             :  */
     145           1 : struct ec_host_cmd_handler {
     146             :         /** Callback routine to process commands that match @a id. */
     147           1 :         ec_host_cmd_handler_cb handler;
     148             :         /** The numerical command id used as the lookup for commands. */
     149           1 :         uint16_t id;
     150             :         /**
     151             :          * The bitfield of all versions that the @a handler supports, where
     152             :          * each bit value represents that the @a handler supports that version.
     153             :          * E.g. BIT(0) corresponds to version 0.
     154             :          */
     155           1 :         uint16_t version_mask;
     156             :         /**
     157             :          * The minimum @a input_buf_size enforced by the framework before
     158             :          * passing to the handler.
     159             :          */
     160           1 :         uint16_t min_rqt_size;
     161             :         /**
     162             :          * The minimum @a output_buf_size enforced by the framework before
     163             :          * passing to the handler.
     164             :          */
     165           1 :         uint16_t min_rsp_size;
     166             : };
     167             : 
     168             : /**
     169             :  * @brief Statically define and register a host command handler.
     170             :  *
     171             :  * Helper macro to statically define and register a host command handler that
     172             :  * has a compile-time-fixed sizes for its both request and response structures.
     173             :  *
     174             :  * @param _id Id of host command to handle request for.
     175             :  * @param _function Name of handler function.
     176             :  * @param _version_mask The bitfield of all versions that the @a _function
     177             :  *        supports. E.g. BIT(0) corresponds to version 0.
     178             :  * @param _request_type The datatype of the request parameters for @a _function.
     179             :  * @param _response_type The datatype of the response parameters for
     180             :  *        @a _function.
     181             :  */
     182           1 : #define EC_HOST_CMD_HANDLER(_id, _function, _version_mask, _request_type, _response_type)          \
     183             :         const STRUCT_SECTION_ITERABLE(ec_host_cmd_handler, __cmd##_id) = {                         \
     184             :                 .handler = _function,                                                              \
     185             :                 .id = _id,                                                                         \
     186             :                 .version_mask = _version_mask,                                                     \
     187             :                 .min_rqt_size = sizeof(_request_type),                                             \
     188             :                 .min_rsp_size = sizeof(_response_type),                                            \
     189             :         }
     190             : 
     191             : /**
     192             :  * @brief Statically define and register a host command handler without sizes.
     193             :  *
     194             :  * Helper macro to statically define and register a host command handler whose
     195             :  * request or response structure size is not known as compile time.
     196             :  *
     197             :  * @param _id Id of host command to handle request for.
     198             :  * @param _function Name of handler function.
     199             :  * @param _version_mask The bitfield of all versions that the @a _function
     200             :  *        supports. E.g. BIT(0) corresponds to version 0.
     201             :  */
     202           1 : #define EC_HOST_CMD_HANDLER_UNBOUND(_id, _function, _version_mask)                                 \
     203             :         const STRUCT_SECTION_ITERABLE(ec_host_cmd_handler, __cmd##_id) = {                         \
     204             :                 .handler = _function,                                                              \
     205             :                 .id = _id,                                                                         \
     206             :                 .version_mask = _version_mask,                                                     \
     207             :                 .min_rqt_size = 0,                                                                 \
     208             :                 .min_rsp_size = 0,                                                                 \
     209             :         }
     210             : 
     211             : /**
     212             :  * @brief Header for requests from host to embedded controller
     213             :  *
     214             :  * Represent the over-the-wire header in LE format for host command requests.
     215             :  * This represent version 3 of the host command header. The requests are always
     216             :  * sent from host to embedded controller.
     217             :  */
     218           1 : struct ec_host_cmd_request_header {
     219             :         /**
     220             :          * Should be 3. The EC will return EC_HOST_CMD_INVALID_HEADER if it
     221             :          * receives a header with a version it doesn't know how to parse.
     222             :          */
     223           1 :         uint8_t prtcl_ver;
     224             :         /**
     225             :          * Checksum of response and data; sum of all bytes including checksum.
     226             :          * Should total to 0.
     227             :          */
     228           1 :         uint8_t checksum;
     229             :         /** Id of command that is being sent. */
     230           1 :         uint16_t cmd_id;
     231             :         /**
     232             :          * Version of the specific @a cmd_id being requested. Valid
     233             :          * versions start at 0.
     234             :          */
     235           1 :         uint8_t cmd_ver;
     236             :         /** Unused byte in current protocol version; set to 0. */
     237           1 :         uint8_t reserved;
     238             :         /** Length of data which follows this header. */
     239           1 :         uint16_t data_len;
     240             : } __packed;
     241             : 
     242             : /**
     243             :  * @brief Header for responses from embedded controller to host
     244             :  *
     245             :  * Represent the over-the-wire header in LE format for host command responses.
     246             :  * This represent version 3 of the host command header. Responses are always
     247             :  * sent from embedded controller to host.
     248             :  */
     249           1 : struct ec_host_cmd_response_header {
     250             :         /** Should be 3. */
     251           1 :         uint8_t prtcl_ver;
     252             :         /**
     253             :          * Checksum of response and data; sum of all bytes including checksum.
     254             :          * Should total to 0.
     255             :          */
     256           1 :         uint8_t checksum;
     257             :         /** A @a ec_host_cmd_status response code for specific command. */
     258           1 :         uint16_t result;
     259             :         /** Length of data which follows this header. */
     260           1 :         uint16_t data_len;
     261             :         /** Unused bytes in current protocol version; set to 0. */
     262           1 :         uint16_t reserved;
     263             : } __packed;
     264             : 
     265             : /**
     266             :  * @brief Initialize the host command subsystem
     267             :  *
     268             :  * This routine initializes the host command subsystem. It includes initialization
     269             :  * of a backend and the handler.
     270             :  * When the application configures the zephyr,host-cmd-espi-backend/zephyr,host-cmd-shi-backend/
     271             :  * zephyr,host-cmd-uart-backend chosen node and @kconfig{CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT} is
     272             :  * set, the chosen backend automatically calls this routine at
     273             :  * @kconfig{CONFIG_EC_HOST_CMD_INIT_PRIORITY}. Applications that require a run-time selection of the
     274             :  * backend must set @kconfig{CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT} to n and must explicitly call
     275             :  * this routine.
     276             :  *
     277             :  * @param[in] backend        Pointer to the backend structure to initialize.
     278             :  *
     279             :  * @retval 0 if successful
     280             :  */
     281           1 : int ec_host_cmd_init(struct ec_host_cmd_backend *backend);
     282             : 
     283             : /**
     284             :  * @brief Send the host command response
     285             :  *
     286             :  * This routine sends the host command response. It should be used to send IN_PROGRESS status or
     287             :  * if the host command handler doesn't return e.g. reboot command.
     288             :  *
     289             :  * @param[in] status        Host command status to be sent.
     290             :  * @param[in] args          Pointer of a structure passed to the handler.
     291             :  *
     292             :  * @retval 0 if successful.
     293             :  */
     294           1 : int ec_host_cmd_send_response(enum ec_host_cmd_status status,
     295             :                               const struct ec_host_cmd_handler_args *args);
     296             : 
     297             : /**
     298             :  * @brief Signal a new host command
     299             :  *
     300             :  * Signal that a new host command has been received. The function should be called by a backend
     301             :  * after copying data to the rx buffer and setting the length.
     302             :  */
     303           1 : void ec_host_cmd_rx_notify(void);
     304             : 
     305             : /**
     306             :  * @brief Install a user callback for receiving a host command
     307             :  *
     308             :  * It allows installing a custom procedure needed by a user after receiving a command.
     309             :  *
     310             :  * @param[in] cb          A callback to be installed.
     311             :  * @param[in] user_data   User data to be passed to the callback.
     312             :  */
     313           1 : void ec_host_cmd_set_user_cb(ec_host_cmd_user_cb_t cb, void *user_data);
     314             : 
     315             : /**
     316             :  * @brief Get the main ec host command structure
     317             :  *
     318             :  * This routine returns a pointer to the main host command structure.
     319             :  * It allows the application code to get inside information for any reason e.g.
     320             :  * the host command thread id.
     321             :  *
     322             :  * @retval A pointer to the main host command structure
     323             :  */
     324           1 : const struct ec_host_cmd *ec_host_cmd_get_hc(void);
     325             : 
     326             : #ifndef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
     327             : /**
     328             :  * @brief The thread function for Host Command subsystem
     329             :  *
     330             :  * This routine calls the Host Command thread entry function. If
     331             :  * @kconfig{CONFIG_EC_HOST_CMD_DEDICATED_THREAD} is not defined, a new thread is not created,
     332             :  * and this function has to be called by application code. It doesn't return.
     333             :  */
     334           1 : FUNC_NORETURN void ec_host_cmd_task(void);
     335             : #endif
     336             : 
     337             : #ifdef CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS
     338             : /**
     339             :  * @brief Check if a Host Command that sent EC_HOST_CMD_IN_PROGRESS status has ended.
     340             :  *
     341             :  * A Host Command that sends EC_HOST_CMD_IN_PROGRESS status doesn't send a final result.
     342             :  * The final result can be get with the ec_host_cmd_send_in_progress_status function.
     343             :  *
     344             :  * @retval true if the Host Command endded
     345             :  */
     346             : bool ec_host_cmd_send_in_progress_ended(void);
     347             : 
     348             : /**
     349             :  * @brief Get final result of a last Host Command that has sent EC_HOST_CMD_IN_PROGRESS status.
     350             :  *
     351             :  * A Host Command that sends EC_HOST_CMD_IN_PROGRESS status doesn't send a final result.
     352             :  * Get the saved status with this function. The status can be get only once. Further calls return
     353             :  * EC_HOST_CMD_UNAVAILABLE.
     354             :  *
     355             :  * Saving status of Host Commands that send response data is not supported.
     356             :  *
     357             :  * @retval The final status or EC_HOST_CMD_UNAVAILABLE if not available.
     358             :  */
     359             : enum ec_host_cmd_status ec_host_cmd_send_in_progress_status(void);
     360             : 
     361             : /**
     362             :  * @brief Continue processing a handler in callback after returning EC_HOST_CMD_IN_PROGRESS.
     363             :  *
     364             :  * A Host Command handler may return the EC_HOST_CMD_IN_PROGRESS, but needs to continue work.
     365             :  * This function should be called before returning EC_HOST_CMD_IN_PROGRESS with a callback that
     366             :  * will be executed. The return status of the callback will be stored and can be get with the
     367             :  * ec_host_cmd_send_in_progress_status function. The ec_host_cmd_send_in_progress_ended function
     368             :  * can be used to check if the callback has ended.
     369             :  *
     370             :  * @param[in] cb          A callback to be called after returning from a command handler.
     371             :  * @param[in] user_data   User data to be passed to the callback.
     372             :  *
     373             :  * @retval EC_HOST_CMD_BUSY if any command is already in progress, EC_HOST_CMD_SUCCESS otherwise
     374             :  */
     375             : enum ec_host_cmd_status ec_host_cmd_send_in_progress_continue(ec_host_cmd_in_progress_cb_t cb,
     376             :                                                               void *user_data);
     377             : #endif /* CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS */
     378             : 
     379             : /**
     380             :  * @brief Add a suppressed command.
     381             :  *
     382             :  * Suppressed commands are not logged. Add a command to be suppressed.
     383             :  *
     384             :  * @param[in] cmd_id        A command id to be suppressed.
     385             :  *
     386             :  * @retval 0 if successful, -EIO if exceeded max number of suppressed commands.
     387             :  */
     388           1 : int ec_host_cmd_add_suppressed(uint16_t cmd_id);
     389             : 
     390             : /**
     391             :  * @}
     392             :  */
     393             : 
     394             : #endif /* ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_EC_HOST_CMD_H_ */

Generated by: LCOV version 1.14