<p>Duncan Laurie has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/29113">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ec/google/wilco: Add Wilco EC mailbox interface<br><br>The Google "Wilco" Embedded Controller is a new embedded controller that<br>will be used in some future devices.  The mailbox interface is simliar<br>to the existing Chromium EC protocol version 3, but not close enough<br>that it was convenient to re-use the full Chrome EC driver.<br><br>This commit adds the basic mailbox interface for ramstage which will be<br>used by future commits to send varous mailbox commands during the boot<br>process.  The IO base addresses for the mailbox interface are defined in<br>Kconfig so they can be changed by the mainboard if needed.<br><br>Change-Id: I8520dadfa982c9d14357cf2aa644e255cef425c2<br>Signed-off-by: Duncan Laurie <dlaurie@google.com><br>---<br>A src/ec/google/wilco/Kconfig<br>A src/ec/google/wilco/Makefile.inc<br>A src/ec/google/wilco/ec.h<br>A src/ec/google/wilco/mailbox.c<br>4 files changed, 352 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/13/29113/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/ec/google/wilco/Kconfig b/src/ec/google/wilco/Kconfig</span><br><span>new file mode 100644</span><br><span>index 0000000..e905d5e</span><br><span>--- /dev/null</span><br><span>+++ b/src/ec/google/wilco/Kconfig</span><br><span>@@ -0,0 +1,47 @@</span><br><span style="color: hsl(120, 100%, 40%);">+config EC_GOOGLE_WILCO</span><br><span style="color: hsl(120, 100%, 40%);">+     bool</span><br><span style="color: hsl(120, 100%, 40%);">+  default n</span><br><span style="color: hsl(120, 100%, 40%);">+     select EC_GOOGLE_COMMON_MEC</span><br><span style="color: hsl(120, 100%, 40%);">+   help</span><br><span style="color: hsl(120, 100%, 40%);">+    Google Wilco Embedded Controller interface.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config EC_BASE_ACPI_DATA</span><br><span style="color: hsl(120, 100%, 40%);">+     hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x930</span><br><span style="color: hsl(120, 100%, 40%);">+ help</span><br><span style="color: hsl(120, 100%, 40%);">+    This option provides the 16-bit IO base address for the ACPI</span><br><span style="color: hsl(120, 100%, 40%);">+          data interface.  This is the standard ACPI EC interface that</span><br><span style="color: hsl(120, 100%, 40%);">+          is used by the ACPI EC drivers in the OS.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config EC_BASE_ACPI_COMMAND</span><br><span style="color: hsl(120, 100%, 40%);">+    hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x934</span><br><span style="color: hsl(120, 100%, 40%);">+ help</span><br><span style="color: hsl(120, 100%, 40%);">+    This option provides the 16-bit IO base address for the ACPI</span><br><span style="color: hsl(120, 100%, 40%);">+          EC command interface.  This is the standard ACPI EC interface</span><br><span style="color: hsl(120, 100%, 40%);">+         that is used by the ACPI EC drivers in the OS.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config EC_BASE_HOST_DATA</span><br><span style="color: hsl(120, 100%, 40%);">+  hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x940</span><br><span style="color: hsl(120, 100%, 40%);">+ help</span><br><span style="color: hsl(120, 100%, 40%);">+    This option provides the 16-bit IO base address for the host</span><br><span style="color: hsl(120, 100%, 40%);">+          data interface.  This is the interface that is used to drive</span><br><span style="color: hsl(120, 100%, 40%);">+          the mailbox protocol.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config EC_BASE_HOST_COMMAND</span><br><span style="color: hsl(120, 100%, 40%);">+        hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x944</span><br><span style="color: hsl(120, 100%, 40%);">+ help</span><br><span style="color: hsl(120, 100%, 40%);">+    This option provides the 16-bit IO base address for the host</span><br><span style="color: hsl(120, 100%, 40%);">+          command interface.  This is the interface that is used to drive</span><br><span style="color: hsl(120, 100%, 40%);">+       the mailbox protocol.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config EC_BASE_PACKET</span><br><span style="color: hsl(120, 100%, 40%);">+      hex</span><br><span style="color: hsl(120, 100%, 40%);">+   default 0x950</span><br><span style="color: hsl(120, 100%, 40%);">+ help</span><br><span style="color: hsl(120, 100%, 40%);">+    This option provides the 16-bit IO base address for the EC</span><br><span style="color: hsl(120, 100%, 40%);">+    mailbox interface data region.  This data buffer is used along</span><br><span style="color: hsl(120, 100%, 40%);">+        with the host command and data registers to drive the EC</span><br><span style="color: hsl(120, 100%, 40%);">+      mailbox interface.  This is also the MEC EMI base address.</span><br><span>diff --git a/src/ec/google/wilco/Makefile.inc b/src/ec/google/wilco/Makefile.inc</span><br><span>new file mode 100644</span><br><span>index 0000000..6130f6f</span><br><span>--- /dev/null</span><br><span>+++ b/src/ec/google/wilco/Makefile.inc</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+ifeq ($(CONFIG_EC_GOOGLE_WILCO),y)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += mailbox.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span>diff --git a/src/ec/google/wilco/ec.h b/src/ec/google/wilco/ec.h</span><br><span>new file mode 100644</span><br><span>index 0000000..7b58473</span><br><span>--- /dev/null</span><br><span>+++ b/src/ec/google/wilco/ec.h</span><br><span>@@ -0,0 +1,50 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Google LLC</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef EC_GOOGLE_WILCO_EC_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_GOOGLE_WILCO_EC_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stddef.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Maximum request or response data size */</span><br><span style="color: hsl(120, 100%, 40%);">+#define WILCO_EC_DATA_MAX             32</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Different supported message types */</span><br><span style="color: hsl(120, 100%, 40%);">+enum wilco_ec_msg_type {</span><br><span style="color: hsl(120, 100%, 40%);">+       WILCO_EC_MSG_RAW,               /* Raw message, do not skip any data */</span><br><span style="color: hsl(120, 100%, 40%);">+       WILCO_EC_MSG_DEFAULT,           /* Skip 1 byte of response data */</span><br><span style="color: hsl(120, 100%, 40%);">+    WILCO_EC_MSG_NO_RESPONSE,       /* EC does not respond to command */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * wilco_ec_mailbox</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Send a command request to the EC mailbox and receive the response.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @type:          Mailbox message type, see enum above</span><br><span style="color: hsl(120, 100%, 40%);">+ * @command:       Command to execute</span><br><span style="color: hsl(120, 100%, 40%);">+ * @request_data:  Request data buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @request_size:  Number of bytes in request data buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @response_data: Response data buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @response_size: Number of bytes in response data buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return number of bytes received, negative error code on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int wilco_ec_mailbox(enum wilco_ec_msg_type type, uint8_t command,</span><br><span style="color: hsl(120, 100%, 40%);">+              const void *request_data, size_t request_size,</span><br><span style="color: hsl(120, 100%, 40%);">+                void *response_data, size_t response_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* EC_GOOGLE_WILCO_EC_H */</span><br><span>diff --git a/src/ec/google/wilco/mailbox.c b/src/ec/google/wilco/mailbox.c</span><br><span>new file mode 100644</span><br><span>index 0000000..c3f393a</span><br><span>--- /dev/null</span><br><span>+++ b/src/ec/google/wilco/mailbox.c</span><br><span>@@ -0,0 +1,250 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Google LLC</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <delay.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/google/common/mec.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "ec.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Mailbox ID */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_ID                 0x00f0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Version of mailbox interface */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_VERSION                0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Command to start mailbox transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_START_COMMAND       0xda</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Version of EC protocol */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_PROTO_VERSION  3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Max number of bytes in protocol data payload */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_DATA_SIZE           WILCO_EC_DATA_MAX</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Number of header bytes to be counted as data bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_DATA_EXTRA            2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Maximum timeout */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_MAILBOX_TIMEOUT_US               USECS_PER_SEC</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* EC response flags */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMDR_DATA          BIT(0)  /* Data ready for host to read */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMDR_PENDING              BIT(1)  /* Write pending to EC */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMDR_BUSY         BIT(2)  /* EC is busy processing a command */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EC_CMDR_CMD              BIT(3)  /* Last host write was a command */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Request to EC */</span><br><span style="color: hsl(120, 100%, 40%);">+struct wilco_ec_request {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t struct_version;         /* version (=3) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t checksum;               /* sum of all bytes must be 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t mailbox_id;            /* mailbox identifier */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t mailbox_version;        /* mailbox version (=0) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t reserved1;              /* unused (=0) */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t data_size;             /* length (data + 2 bytes of header) */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t command;                /* mailbox command */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t reserved2;              /* unused (=0) */</span><br><span style="color: hsl(120, 100%, 40%);">+} __packed;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Response from EC */</span><br><span style="color: hsl(120, 100%, 40%);">+struct wilco_ec_response {</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t struct_version;         /* version (=3) */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t checksum;               /* sum of all bytes must be 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t result;                /* result code */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t data_size;             /* length of data after header */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t reserved[3];            /* unused (=0) */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t data[EC_MAILBOX_DATA_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+} __packed;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct wilco_ec_message {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t command;                /* mailbox command code */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t result;                 /* request result */</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t request_size;            /* bytes to send to the EC */</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t response_size;           /* bytes expected from the EC */</span><br><span style="color: hsl(120, 100%, 40%);">+      enum wilco_ec_msg_type type;    /* message type */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t data[EC_MAILBOX_DATA_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static bool wilco_ec_response_timed_out(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t mask = EC_CMDR_PENDING | EC_CMDR_BUSY;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t time_count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    do {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!(inb(CONFIG_EC_BASE_HOST_COMMAND) & mask))</span><br><span style="color: hsl(120, 100%, 40%);">+                   return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         mdelay(1);</span><br><span style="color: hsl(120, 100%, 40%);">+    } while (time_count++ < EC_MAILBOX_TIMEOUT_US);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printk(BIOS_ERR, "%s: Command timeout\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+        return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t wilco_ec_checksum(void *data, size_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t *data_bytes = (uint8_t *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t checksum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i < size; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+         checksum += data_bytes[i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void wilco_ec_prepare(struct wilco_ec_message *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct wilco_ec_request *rq)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  memset(rq, 0, sizeof(*rq));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Fill in request packet */</span><br><span style="color: hsl(120, 100%, 40%);">+  rq->struct_version = EC_MAILBOX_PROTO_VERSION;</span><br><span style="color: hsl(120, 100%, 40%);">+     rq->mailbox_id = EC_MAILBOX_ID;</span><br><span style="color: hsl(120, 100%, 40%);">+    rq->mailbox_version = EC_MAILBOX_VERSION;</span><br><span style="color: hsl(120, 100%, 40%);">+  rq->data_size = msg->request_size + EC_MAILBOX_DATA_EXTRA;</span><br><span style="color: hsl(120, 100%, 40%);">+      rq->command = msg->command;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Checksum header and data */</span><br><span style="color: hsl(120, 100%, 40%);">+        rq->checksum = wilco_ec_checksum(rq, sizeof(*rq));</span><br><span style="color: hsl(120, 100%, 40%);">+ rq->checksum += wilco_ec_checksum(msg->data, msg->request_size);</span><br><span style="color: hsl(120, 100%, 40%);">+     rq->checksum = -rq->checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int wilco_ec_transfer(struct wilco_ec_message *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct wilco_ec_request rq;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct wilco_ec_response rs;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+     size_t skip_size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Prepare request packet */</span><br><span style="color: hsl(120, 100%, 40%);">+  wilco_ec_prepare(msg, &rq);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Write request header */</span><br><span style="color: hsl(120, 100%, 40%);">+    mec_io_bytes(MEC_IO_WRITE, CONFIG_EC_BASE_PACKET, 0, &rq, sizeof(rq));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Write request data */</span><br><span style="color: hsl(120, 100%, 40%);">+      mec_io_bytes(MEC_IO_WRITE, CONFIG_EC_BASE_PACKET, sizeof(rq),</span><br><span style="color: hsl(120, 100%, 40%);">+              msg->data, msg->request_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Start the command */</span><br><span style="color: hsl(120, 100%, 40%);">+       outb(EC_MAILBOX_START_COMMAND, CONFIG_EC_BASE_HOST_COMMAND);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Wait for it to complete */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (wilco_ec_response_timed_out()) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printk(BIOS_ERR, "%s: response timed out\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Some commands will put the EC into a state where it cannot respond */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (msg->type == WILCO_EC_MSG_NO_RESPONSE) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printk(BIOS_DEBUG, "%s: EC does not respond to this command\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Check result */</span><br><span style="color: hsl(120, 100%, 40%);">+    msg->result = inb(CONFIG_EC_BASE_HOST_DATA);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (msg->result != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printk(BIOS_ERR, "%s: bad response: 0x%02x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                     __func__, msg->result);</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Read back response */</span><br><span style="color: hsl(120, 100%, 40%);">+      checksum = mec_io_bytes(MEC_IO_READ, CONFIG_EC_BASE_PACKET, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                &rs, sizeof(rs));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (checksum) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printk(BIOS_ERR, "%s: bad checksum %02x\n", __func__, checksum);</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     msg->result = rs.result;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* EC always returns EC_MAILBOX_DATA_SIZE bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rs.data_size > EC_MAILBOX_DATA_SIZE) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printk(BIOS_ERR, "%s: packet too long (%d bytes, expected %d)",</span><br><span style="color: hsl(120, 100%, 40%);">+                    __func__, rs.data_size, EC_MAILBOX_DATA_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (msg->response_size > rs.data_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printk(BIOS_ERR, "%s: data too short (%d bytes, expected %zu)",</span><br><span style="color: hsl(120, 100%, 40%);">+                    __func__, rs.data_size, msg->response_size);</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Skip response data bytes as requested */</span><br><span style="color: hsl(120, 100%, 40%);">+   skip_size = (msg->type == WILCO_EC_MSG_DEFAULT) ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(msg->data, rs.data + skip_size, msg->response_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Return actual amount of data received */</span><br><span style="color: hsl(120, 100%, 40%);">+   return msg->response_size;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int wilco_ec_mailbox(enum wilco_ec_msg_type type, uint8_t command,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const void *request_data, size_t request_size,</span><br><span style="color: hsl(120, 100%, 40%);">+                void *response_data, size_t response_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct wilco_ec_message msg;</span><br><span style="color: hsl(120, 100%, 40%);">+  int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (request_size > EC_MAILBOX_DATA_SIZE) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printk(BIOS_ERR, "%s: provided request data too large: %zu\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                     __func__, request_size);</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (response_size > EC_MAILBOX_DATA_SIZE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printk(BIOS_ERR, "%s: expected response data too large: %zu\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    __func__, response_size);</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (request_size && !request_data) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printk(BIOS_ERR, "%s: request data missing\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (response_size && !response_data) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printk(BIOS_ERR, "%s: request data missing\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Prepare message structure */</span><br><span style="color: hsl(120, 100%, 40%);">+       msg.command = command;</span><br><span style="color: hsl(120, 100%, 40%);">+        msg.request_size = request_size;</span><br><span style="color: hsl(120, 100%, 40%);">+      msg.response_size = response_size;</span><br><span style="color: hsl(120, 100%, 40%);">+    msg.type = type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Copy request data if present */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (request_size)</span><br><span style="color: hsl(120, 100%, 40%);">+             memcpy(msg.data, request_data, request_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Do the EC transfer */</span><br><span style="color: hsl(120, 100%, 40%);">+      ret = wilco_ec_transfer(&msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Copy response data if present */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ret > 0 && response_size)</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(response_data, msg.data, response_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Return error if message result is non-zero */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ret >= 0 && msg.result)</span><br><span style="color: hsl(120, 100%, 40%);">+                ret = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/29113">change 29113</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/29113"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8520dadfa982c9d14357cf2aa644e255cef425c2 </div>
<div style="display:none"> Gerrit-Change-Number: 29113 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Duncan Laurie <dlaurie@chromium.org> </div>