diff options
Diffstat (limited to 'chip')
-rw-r--r-- | chip/mt_scp/ipi.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/chip/mt_scp/ipi.c b/chip/mt_scp/ipi.c index 91e46740c9..a8bfce0a11 100644 --- a/chip/mt_scp/ipi.c +++ b/chip/mt_scp/ipi.c @@ -41,6 +41,9 @@ static struct ipc_shared_obj *const scp_send_obj = static struct ipc_shared_obj *const scp_recv_obj = (struct ipc_shared_obj *)(CONFIG_IPC_SHARED_OBJ_ADDR + sizeof(struct ipc_shared_obj)); +#ifdef HAS_TASK_HOSTCMD +static struct host_packet ipi_packet; +#endif /* Check if SCP to AP IPI is in use. */ static inline int is_ipi_busy(void) @@ -141,6 +144,75 @@ void ipi_inform_ap(void) ccprintf("Failed to send initialization IPC messages.\n"); } +#ifdef HAS_TASK_HOSTCMD +static void ipi_send_response_packet(struct host_packet *pkt) +{ + int ret; + + ret = ipi_send(IPI_HOST_COMMAND, pkt->response, pkt->response_size, 0); + if (ret) + CPRINTS("#ERR IPI HOSTCMD %d", ret); +} + +static void ipi_hostcmd_handler(int32_t id, void *buf, uint32_t len) +{ + uint8_t *in_msg = buf; + struct ec_host_request *r = (struct ec_host_request *)in_msg; + int i; + + if (in_msg[0] != EC_HOST_REQUEST_VERSION) { + CPRINTS("ERROR: Protocol V2 is not supported!"); + CPRINTF("in_msg=["); + for (i = 0; i < len; i++) + CPRINTF("%02x ", in_msg[i]); + CPRINTF("]\n"); + return; + } + + /* Protocol version 3 */ + + ipi_packet.send_response = ipi_send_response_packet; + + /* + * Just assign the buffer to request, host_packet_receive + * handles the buffer copy. + */ + ipi_packet.request = (void *)r; + ipi_packet.request_temp = NULL; + ipi_packet.request_max = IPI_MAX_REQUEST_SIZE; + ipi_packet.request_size = host_request_expected_size(r); + + ipi_packet.response = scp_send_obj->buffer; + /* Reserve space for the preamble and trailing byte */ + ipi_packet.response_max = IPI_MAX_RESPONSE_SIZE; + ipi_packet.response_size = 0; + + ipi_packet.driver_result = EC_RES_SUCCESS; + + host_packet_receive(&ipi_packet); +} +DECLARE_IPI(IPI_HOST_COMMAND, ipi_hostcmd_handler, 0); + +/* + * Get protocol information + */ +static int ipi_get_protocol_info(struct host_cmd_handler_args *args) +{ + struct ec_response_get_protocol_info *r = args->response; + + memset(r, 0, sizeof(*r)); + r->protocol_versions |= (1 << 3); + r->max_request_packet_size = IPI_MAX_REQUEST_SIZE; + r->max_response_packet_size = IPI_MAX_RESPONSE_SIZE; + + args->response_size = sizeof(*r); + + return EC_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO, ipi_get_protocol_info, + EC_VER_MASK(0)); +#endif + static void ipi_enable_ipc0_deferred(void) { /* Clear IPC0 IRQs. */ |