EC Host Command

Overview

The host command protocol defines the interface for a host, or application processor, to communicate with a target embedded controller (EC). The EC Host command subsystem implements the target side of the protocol, generating responses to commands sent by the host. The host command protocol interface supports multiple versions, but this subsystem implementation only support protocol version 3.

Architecture

The Host Command subsystem contains a few components:
  • Backend

  • General handler

  • Command handler

The backend is a layer between a peripheral driver and the general handler. It is responsible for sending and receiving commands via chosen peripheral.

The general handler validates data from the backend e.g. check sizes, checksum, etc. If the command is valid and the user has provided a handler for a received command id, the command handler is called.

../../_images/ec_host_cmd.png

SHI (Serial Host Interface) is different to this because it is used olny for communication with a host. SHI does not have API itself, thus the backend and peripheral driver layers are combined into one backend layer.

../../_images/ec_host_cmd_shi.png
The supported backend and peripheral drivers:

Initialization

If the application configures the zephyr,host-cmd-backend chosen node, then the backend automatically initializes the host command subsystem by calling ec_host_cmd_init().

If zephyr,host-cmd-backend is not chosen, the ec_host_cmd_init() function should be called by application code. This way of initialization is useful if a backend is chosen in runtime based on e.g. GPIO state.

Buffers

The host command communication requires buffers for rx and tx. The buffers are be provided by the general handler if CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER > 0 for rx buffer and CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER > 0 for the tx buffer. The shared buffers are useful for applications that use multiple backends. Defining separate buffers by every backend would increase the memory usage. However, some buffers can be defined by a peripheral driver e.g. eSPI. These ones should be reused as much as possible.

API Reference

group ec_host_cmd_interface

EC Host Command Interface.

Defines

EC_HOST_CMD_HANDLER(_id, _function, _version_mask, _request_type, _response_type)

Statically define and register a host command handler.

Helper macro to statically define and register a host command handler that has a compile-time-fixed sizes for its both request and response structures.

Parameters:
  • _id – Id of host command to handle request for.

  • _function – Name of handler function.

  • _version_mask – The bitfield of all versions that the _function supports. E.g. BIT(0) corresponds to version 0.

  • _request_type – The datatype of the request parameters for _function.

  • _response_type – The datatype of the response parameters for _function.

EC_HOST_CMD_HANDLER_UNBOUND(_id, _function, _version_mask)

Statically define and register a host command handler without sizes.

Helper macro to statically define and register a host command handler whose request or response structure size is not known as compile time.

Parameters:
  • _id – Id of host command to handle request for.

  • _function – Name of handler function.

  • _version_mask – The bitfield of all versions that the _function supports. E.g. BIT(0) corresponds to version 0.

Typedefs

typedef int (*ec_host_cmd_backend_api_init)(const struct ec_host_cmd_backend *backend, struct ec_host_cmd_rx_ctx *rx_ctx, struct ec_host_cmd_tx_buf *tx)

Initialize a host command backend.

This routine initializes a host command backend. It includes initialization a device used to communication and setting up buffers. This function is called by the ec_host_cmd_init function.

Param backend:

[in] Pointer to the backend structure for the driver instance.

Param rx_ctx:

[inout] Pointer to the receive context object. These objects are used to receive data from the driver when the host sends data. The buf member can be assigned by the backend.

Param tx:

[inout] Pointer to the transmit buffer object. The buf and len_max members can be assigned by the backend. These objects are used to send data by the backend with the ec_host_cmd_backend_api_send function.

Retval 0:

if successful

typedef int (*ec_host_cmd_backend_api_send)(const struct ec_host_cmd_backend *backend)

Sends data to the host.

Sends data from tx buf that was passed via ec_host_cmd_backend_api_init function.

Param backend:

Pointer to the backed to send data.

Retval 0:

if successful.

typedef enum ec_host_cmd_status (*ec_host_cmd_handler_cb)(struct ec_host_cmd_handler_args *args)

Enums

enum ec_host_cmd_status

Values:

enumerator EC_HOST_CMD_SUCCESS = 0

Host command was successful.

enumerator EC_HOST_CMD_INVALID_COMMAND = 1

The specified command id is not recognized or supported.

enumerator EC_HOST_CMD_ERROR = 2

Generic Error.

enumerator EC_HOST_CMD_INVALID_PARAM = 3

One of more of the input request parameters is invalid.

enumerator EC_HOST_CMD_ACCESS_DENIED = 4

Host command is not permitted.

enumerator EC_HOST_CMD_INVALID_RESPONSE = 5

Response was invalid (e.g. not version 3 of header).

enumerator EC_HOST_CMD_INVALID_VERSION = 6

Host command id version unsupported.

enumerator EC_HOST_CMD_INVALID_CHECKSUM = 7

Checksum did not match.

enumerator EC_HOST_CMD_IN_PROGRESS = 8

A host command is currently being processed.

enumerator EC_HOST_CMD_UNAVAILABLE = 9

Requested information is currently unavailable.

enumerator EC_HOST_CMD_TIMEOUT = 10

Timeout during processing.

enumerator EC_HOST_CMD_OVERFLOW = 11

Data or table overflow.

enumerator EC_HOST_CMD_INVALID_HEADER = 12

Header is invalid or unsupported (e.g. not version 3 of header).

enumerator EC_HOST_CMD_REQUEST_TRUNCATED = 13

Did not receive all expected request data.

enumerator EC_HOST_CMD_RESPONSE_TOO_BIG = 14

Response was too big to send within one response packet.

enumerator EC_HOST_CMD_BUS_ERROR = 15

Error on underlying communication bus.

enumerator EC_HOST_CMD_BUSY = 16

System busy. Should retry later.

enumerator EC_HOST_CMD_INVALID_HEADER_VERSION = 17

Header version invalid.

enumerator EC_HOST_CMD_INVALID_HEADER_CRC = 18

Header CRC invalid.

enumerator EC_HOST_CMD_INVALID_DATA_CRC = 19

Data CRC invalid.

enumerator EC_HOST_CMD_DUP_UNAVAILABLE = 20

Can’t resend response.

enumerator EC_HOST_CMD_MAX = UINT16_MAX

Functions

struct ec_host_cmd_backend *ec_host_cmd_backend_get_espi(const struct device *dev)

Get the eSPI Host Command backend pointer.

Get the eSPI pointer backend and pass a pointer to eSPI device instance that will be used for the Host Command communication.

Parameters:
  • dev – Pointer to eSPI device instance.

Return values:

The – eSPI backend pointer.

struct ec_host_cmd_backend *ec_host_cmd_backend_get_shi_npcx(void)

Get the SHI NPCX Host Command backend pointer.

Return values:

the – SHI NPCX backend pointer

struct ec_host_cmd_backend *ec_host_cmd_backend_get_shi_ite(void)

Get the SHI ITE Host Command backend pointer.

Return values:

the – SHI ITE backend pointer

struct ec_host_cmd_backend *ec_host_cmd_backend_get_uart(const struct device *dev)

Get the UART Host Command backend pointer.

Get the UART pointer backend and pass a pointer to UART device instance that will be used for the Host Command communication.

Parameters:
  • dev – Pointer to UART device instance.

Return values:

The – UART backend pointer.

int ec_host_cmd_init(struct ec_host_cmd_backend *backend)

Initialize the host command subsystem.

This routine initializes the host command subsystem. It includes initialization of a backend and the handler. When the application configures the zephyr,host-cmd-backend chosen node, the chosen backend automatically calls this routine at CONFIG_EC_HOST_CMD_INIT_PRIORITY. Applications that require a run-time selection of the backend must leave zephyr,host-cmd-backend undefined and must explicitly call this routine.

Parameters:
  • backend[in] Pointer to the backend structure to initialize.

Return values:

0 – if successful

struct ec_host_cmd_rx_ctx
#include <backend.h>

Context for host command backend and handler to pass rx data.

Public Members

uint8_t *buf

Buffer to hold received data. The buffer is provided by the handler if CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER > 0. Otherwise, the backend should provide the buffer on its own and overwrites buf pointer in the init function.

size_t len

Number of bytes written to buf by backend.

struct k_sem handler_owns

The backend gives handler_owns, when data in buf are ready. The handler takes handler_owns to read data in buf.

struct ec_host_cmd_tx_buf
#include <backend.h>

Context for host command backend and handler to pass tx data.

Public Members

void *buf

Data to write to the host The buffer is provided by the handler if CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER > 0. Otherwise, the backend should provide the buffer on its own and overwrites buf pointer and len_max in the init function.

size_t len

Number of bytes to write from buf.

size_t len_max

Size of buf.

struct ec_host_cmd_backend_api
#include <backend.h>
struct ec_host_cmd
#include <ec_host_cmd.h>
struct ec_host_cmd_handler_args
#include <ec_host_cmd.h>

Arguments passed into every installed host command handler.

Public Members

void *reserved

Reserved for compatibility.

uint16_t command

Command identifier.

uint8_t version

The version of the host command that is being requested. This will be a value that has been static registered as valid for the handler.

const void *input_buf

The incoming data that can be cast to the handlers request type.

uint16_t input_buf_size

The number of valid bytes that can be read from input_buf.

void *output_buf

The data written to this buffer will be send to the host.

uint16_t output_buf_max

Maximum number of bytes that can be written to the output_buf.

uint16_t output_buf_size

Number of bytes of output_buf to send to the host.

struct ec_host_cmd_handler
#include <ec_host_cmd.h>

Structure use for statically registering host command handlers.

Public Members

ec_host_cmd_handler_cb handler

Callback routine to process commands that match id.

uint16_t id

The numerical command id used as the lookup for commands.

uint16_t version_mask

The bitfield of all versions that the handler supports, where each bit value represents that the handler supports that version. E.g. BIT(0) corresponds to version 0.

uint16_t min_rqt_size

The minimum input_buf_size enforced by the framework before passing to the handler.

uint16_t min_rsp_size

The minimum output_buf_size enforced by the framework before passing to the handler.

struct ec_host_cmd_request_header
#include <ec_host_cmd.h>

Header for requests from host to embedded controller.

Represent the over-the-wire header in LE format for host command requests. This represent version 3 of the host command header. The requests are always sent from host to embedded controller.

Public Members

uint8_t prtcl_ver

Should be 3. The EC will return EC_HOST_CMD_INVALID_HEADER if it receives a header with a version it doesn’t know how to parse.

uint8_t checksum

Checksum of response and data; sum of all bytes including checksum. Should total to 0.

uint16_t cmd_id

Id of command that is being sent.

uint8_t cmd_ver

Version of the specific cmd_id being requested. Valid versions start at 0.

uint8_t reserved

Unused byte in current protocol version; set to 0.

uint16_t data_len

Length of data which follows this header.

struct ec_host_cmd_response_header
#include <ec_host_cmd.h>

Header for responses from embedded controller to host.

Represent the over-the-wire header in LE format for host command responses. This represent version 3 of the host command header. Responses are always sent from embedded controller to host.

Public Members

uint8_t prtcl_ver

Should be 3.

uint8_t checksum

Checksum of response and data; sum of all bytes including checksum. Should total to 0.

uint16_t result

A ec_host_cmd_status response code for specific command.

uint16_t data_len

Length of data which follows this header.

uint16_t reserved

Unused bytes in current protocol version; set to 0.