diff options
author | Bill Richardson <wfrichar@chromium.org> | 2013-05-29 18:00:03 -0700 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-06-05 14:12:23 -0700 |
commit | d0d1564434ae991ac99a6ce54f6f3360f47017a8 (patch) | |
tree | 68ce6707147fbf828fef543222fcde756da1acf2 /util/comm-lpc.c | |
parent | 26475135b551a742f2d148d426c4aa18b338f5ca (diff) | |
download | chrome-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.c | 155 |
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; } |