summaryrefslogtreecommitdiff
path: root/util/comm-lpc.c
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2013-05-29 18:00:03 -0700
committerChromeBot <chrome-bot@google.com>2013-06-05 14:12:23 -0700
commitd0d1564434ae991ac99a6ce54f6f3360f47017a8 (patch)
tree68ce6707147fbf828fef543222fcde756da1acf2 /util/comm-lpc.c
parent26475135b551a742f2d148d426c4aa18b338f5ca (diff)
downloadchrome-ec-d0d1564434ae991ac99a6ce54f6f3360f47017a8.tar.gz
ectool prefers /dev/cros_ec, then falls back to i2c, lpc
This is preparation for the common userspace EC interface. If/when that appears, this will be ready. BUG=chromium:239197 BRANCH=all TEST=manual Build, install, run it. Shouldn't be any change. Change-Id: I9fa78515ec5443ba659f10a66bbaadcb7f4802b0 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/56131
Diffstat (limited to 'util/comm-lpc.c')
-rw-r--r--util/comm-lpc.c155
1 files changed, 77 insertions, 78 deletions
diff --git a/util/comm-lpc.c b/util/comm-lpc.c
index dbae5a7ecc..3548f4eb29 100644
--- a/util/comm-lpc.c
+++ b/util/comm-lpc.c
@@ -14,59 +14,6 @@
#define INITIAL_UDELAY 5 /* 5 us */
#define MAXIMUM_UDELAY 10000 /* 10 ms */
-int comm_init(void)
-{
- int i;
- int byte = 0xff;
-
- /* Request I/O privilege */
- if (iopl(3) < 0) {
- perror("Error getting I/O privilege");
- return -3;
- }
-
- /*
- * Test if the I/O port has been configured for Chromium EC LPC
- * interface. If all the bytes are 0xff, very likely that Chromium EC
- * is not present.
- *
- * TODO: (crosbug.com/p/10963) Should only need to look at the command
- * byte, since we don't support ACPI burst mode and thus bit 4 should
- * be 0.
- */
- byte &= inb(EC_LPC_ADDR_HOST_CMD);
- byte &= inb(EC_LPC_ADDR_HOST_DATA);
- for (i = 0; i < EC_HOST_PARAM_SIZE && byte == 0xff; ++i)
- byte &= inb(EC_LPC_ADDR_HOST_PARAM + i);
- if (byte == 0xff) {
- fprintf(stderr, "Port 0x%x,0x%x,0x%x-0x%x are all 0xFF.\n",
- EC_LPC_ADDR_HOST_CMD, EC_LPC_ADDR_HOST_DATA,
- EC_LPC_ADDR_HOST_PARAM,
- EC_LPC_ADDR_HOST_PARAM + EC_HOST_PARAM_SIZE - 1);
- fprintf(stderr,
- "Very likely this board doesn't have a Chromium EC.\n");
- return -4;
- }
-
- /*
- * Test if LPC command args are supported.
- *
- * The cheapest way to do this is by looking for the memory-mapped
- * flag. This is faster than sending a new-style 'hello' command and
- * seeing whether the EC sets the EC_HOST_ARGS_FLAG_FROM_HOST flag
- * in args when it responds.
- */
- if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) != 'E' ||
- inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) != 'C' ||
- !(inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS) &
- EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED)) {
- fprintf(stderr, "EC doesn't support command args.\n");
- return -5;
- }
-
- return 0;
-}
-
/*
* Wait for the EC to be unbusy. Returns 0 if unbusy, non-zero if
* timeout.
@@ -97,9 +44,10 @@ static int wait_for_ec(int status_addr, int timeout_usec)
return -1; /* Timeout */
}
-int ec_command(int command, int version, const void *indata, int insize,
- void *outdata, int outsize) {
-
+static int ec_command_lpc(int command, int version,
+ const void *outdata, int outsize,
+ void *indata, int insize)
+{
struct ec_lpc_host_args args;
const uint8_t *d;
uint8_t *dout;
@@ -109,13 +57,13 @@ int ec_command(int command, int version, const void *indata, int insize,
/* Fill in args */
args.flags = EC_HOST_ARGS_FLAG_FROM_HOST;
args.command_version = version;
- args.data_size = insize;
+ args.data_size = outsize;
/* Initialize checksum */
csum = command + args.flags + args.command_version + args.data_size;
/* Write data and update checksum */
- for (i = 0, d = (uint8_t *)indata; i < insize; i++, d++) {
+ for (i = 0, d = (uint8_t *)outdata; i < outsize; i++, d++) {
outb(*d, EC_LPC_ADDR_HOST_PARAM + i);
csum += *d;
}
@@ -153,7 +101,7 @@ int ec_command(int command, int version, const void *indata, int insize,
return -EC_RES_INVALID_RESPONSE;
}
- if (args.data_size > outsize) {
+ if (args.data_size > insize) {
fprintf(stderr, "EC returned too much data\n");
return -EC_RES_INVALID_RESPONSE;
}
@@ -162,7 +110,7 @@ int ec_command(int command, int version, const void *indata, int insize,
csum = command + args.flags + args.command_version + args.data_size;
/* Read response and update checksum */
- for (i = 0, dout = (uint8_t *)outdata; i < args.data_size;
+ for (i = 0, dout = (uint8_t *)indata; i < args.data_size;
i++, dout++) {
*dout = inb(EC_LPC_ADDR_HOST_PARAM + i);
csum += *dout;
@@ -179,31 +127,82 @@ int ec_command(int command, int version, const void *indata, int insize,
}
-uint8_t read_mapped_mem8(uint8_t offset)
+static int ec_readmem_lpc(int offset, int bytes, void *dest)
{
- return inb(EC_LPC_ADDR_MEMMAP + offset);
-}
+ int i = offset;
+ char *s = dest;
+ int cnt = 0;
+
+ if (offset >= EC_MEMMAP_SIZE - bytes)
+ return -1;
+
+ if (bytes) { /* fixed length */
+ for (; cnt < bytes; i++, s++, cnt++)
+ *s = inb(EC_LPC_ADDR_MEMMAP + i);
+ } else { /* string */
+ for (; i < EC_MEMMAP_SIZE; i++, s++) {
+ *s = inb(EC_LPC_ADDR_MEMMAP + i);
+ cnt++;
+ if (!*s)
+ break;
+ }
+ }
-uint16_t read_mapped_mem16(uint8_t offset)
-{
- return inw(EC_LPC_ADDR_MEMMAP + offset);
+ return cnt;
}
-uint32_t read_mapped_mem32(uint8_t offset)
+int comm_init_lpc(void)
{
- return inl(EC_LPC_ADDR_MEMMAP + offset);
-}
+ int i;
+ int byte = 0xff;
-int read_mapped_string(uint8_t offset, char *buf)
-{
- int c;
+ /* Request I/O privilege */
+ if (iopl(3) < 0) {
+ perror("Error getting I/O privilege");
+ return -3;
+ }
+
+ /*
+ * Test if the I/O port has been configured for Chromium EC LPC
+ * interface. If all the bytes are 0xff, very likely that Chromium EC
+ * is not present.
+ *
+ * TODO: (crosbug.com/p/10963) Should only need to look at the command
+ * byte, since we don't support ACPI burst mode and thus bit 4 should
+ * be 0.
+ */
+ byte &= inb(EC_LPC_ADDR_HOST_CMD);
+ byte &= inb(EC_LPC_ADDR_HOST_DATA);
+ for (i = 0; i < EC_HOST_PARAM_SIZE && byte == 0xff; ++i)
+ byte &= inb(EC_LPC_ADDR_HOST_PARAM + i);
+ if (byte == 0xff) {
+ fprintf(stderr, "Port 0x%x,0x%x,0x%x-0x%x are all 0xFF.\n",
+ EC_LPC_ADDR_HOST_CMD, EC_LPC_ADDR_HOST_DATA,
+ EC_LPC_ADDR_HOST_PARAM,
+ EC_LPC_ADDR_HOST_PARAM + EC_HOST_PARAM_SIZE - 1);
+ fprintf(stderr,
+ "Very likely this board doesn't have a Chromium EC.\n");
+ return -4;
+ }
- for (c = 0; c < EC_MEMMAP_TEXT_MAX; c++) {
- buf[c] = inb(EC_LPC_ADDR_MEMMAP + offset + c);
- if (buf[c] == 0)
- return c;
+ /*
+ * Test if LPC command args are supported.
+ *
+ * The cheapest way to do this is by looking for the memory-mapped
+ * flag. This is faster than sending a new-style 'hello' command and
+ * seeing whether the EC sets the EC_HOST_ARGS_FLAG_FROM_HOST flag
+ * in args when it responds.
+ */
+ if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) != 'E' ||
+ inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) != 'C' ||
+ !(inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS) &
+ EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED)) {
+ fprintf(stderr, "EC doesn't support command args.\n");
+ return -5;
}
- buf[EC_MEMMAP_TEXT_MAX - 1] = 0;
- return EC_MEMMAP_TEXT_MAX - 1;
+ /* Okay, this works */
+ ec_command = ec_command_lpc;
+ ec_readmem = ec_readmem_lpc;
+ return 0;
}