diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2011-12-12 21:24:48 +0800 |
---|---|---|
committer | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2011-12-12 21:24:48 +0800 |
commit | 6995d4771f7c07b08948c867f4ec0de309ed925e (patch) | |
tree | 6ece98c3515b0fa5f6e4e3d4292960f57fd23980 | |
parent | 1eb5417847831c9dda4c8609af67ad21f9bfba42 (diff) | |
download | chrome-ec-6995d4771f7c07b08948c867f4ec0de309ed925e.tar.gz |
Support flash checksum command for re-transmit.
The LPC is not stable enough to test. Kodus Rong. He creates this idea
to checksum the partial content of flash for read/write/erase. This can
improve the robustness of flashrom.
BUG=none
TEST=Tested with flashrom.
Change-Id: I2a2f7b698a94674c03cbd8e3f15caf34f8986399
-rw-r--r-- | common/flash_commands.c | 29 | ||||
-rw-r--r-- | common/host_command.c | 13 | ||||
-rw-r--r-- | include/flash_commands.h | 4 | ||||
-rw-r--r-- | include/lpc_commands.h | 24 |
4 files changed, 64 insertions, 6 deletions
diff --git a/common/flash_commands.c b/common/flash_commands.c index 95f1b9639e..e8e2c9591c 100644 --- a/common/flash_commands.c +++ b/common/flash_commands.c @@ -20,7 +20,7 @@ static int command_flash_info(int argc, char **argv) { - uart_printf("Usable flash size: %d KB\n", flash_get_size()); + uart_printf("Usable flash size: %d B\n", flash_get_size()); return EC_SUCCESS; } @@ -212,6 +212,32 @@ enum lpc_status flash_command_get_info(uint8_t *data) } +#ifdef SUPPORT_CHECKSUM +enum lpc_status flash_command_checksum(uint8_t *data) +{ + struct lpc_params_flash_checksum *p = + (struct lpc_params_flash_checksum *)data; + struct lpc_response_flash_checksum *r = + (struct lpc_response_flash_checksum *)data; + uint8_t cs, byte; + int j; + + for (cs = 0, j = 0; j < p->size; ++j) { + if (flash_read(p->offset + j, 1, &byte)) { + uart_printf("flash_read() error at 0x%02x.\n", + p->offset + j); + return EC_LPC_STATUS_ERROR; + } + BYTE_IN(cs, byte); + } + + r->checksum = cs; + + return EC_LPC_STATUS_SUCCESS; +} +#endif + + enum lpc_status flash_command_read(uint8_t *data) { struct lpc_params_flash_read *p = @@ -322,4 +348,3 @@ int flash_commands_init(void) console_register_commands(&command_group); return EC_SUCCESS; } - diff --git a/common/host_command.c b/common/host_command.c index 12790e4050..578fe33093 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -156,17 +156,22 @@ static void command_process(int slot) lpc_send_host_response(slot, flash_command_erase(data)); return; case EC_LPC_COMMAND_FLASH_WP_ENABLE: - lpc_send_host_response(flash_command_wp_enable(host_data)); + lpc_send_host_response(slot, flash_command_wp_enable(data)); return; case EC_LPC_COMMAND_FLASH_WP_GET_STATE: - lpc_send_host_response(flash_command_wp_get_state(host_data)); + lpc_send_host_response(slot, flash_command_wp_get_state(data)); return; case EC_LPC_COMMAND_FLASH_WP_SET_RANGE: - lpc_send_host_response(flash_command_wp_set_range(host_data)); + lpc_send_host_response(slot, flash_command_wp_set_range(data)); return; case EC_LPC_COMMAND_FLASH_WP_GET_RANGE: - lpc_send_host_response(flash_command_wp_get_range(host_data)); + lpc_send_host_response(slot, flash_command_wp_get_range(data)); return; +#ifdef SUPPORT_CHECKSUM + case EC_LPC_COMMAND_FLASH_CHECKSUM: + lpc_send_host_response(slot, flash_command_checksum(data)); + return; +#endif default: lpc_send_host_response(slot, EC_LPC_STATUS_INVALID_COMMAND); } diff --git a/include/flash_commands.h b/include/flash_commands.h index 230dc4014d..5efc7e2a67 100644 --- a/include/flash_commands.h +++ b/include/flash_commands.h @@ -23,5 +23,9 @@ enum lpc_status flash_command_wp_enable(uint8_t *data); enum lpc_status flash_command_wp_get_state(uint8_t *data); enum lpc_status flash_command_wp_set_range(uint8_t *data); enum lpc_status flash_command_wp_get_range(uint8_t *data); +#ifdef SUPPORT_CHECKSUM +enum lpc_status flash_command_checksum(uint8_t *data); +#endif + #endif /* __CROS_EC_FLASH_COMMANDS_H */ diff --git a/include/lpc_commands.h b/include/lpc_commands.h index 37b54dd380..08b4d9c1d8 100644 --- a/include/lpc_commands.h +++ b/include/lpc_commands.h @@ -10,6 +10,14 @@ #include <stdint.h> + +/* During the development stage, the LPC bus has high error bit rate. + * Using checksum can detect the error and trigger re-transmit. + * FIXME: remove this after mass production. + */ +#define SUPPORT_CHECKSUM + + /* I/O addresses for LPC commands */ #define EC_LPC_ADDR_KERNEL_DATA 0x62 #define EC_LPC_ADDR_KERNEL_CMD 0x66 @@ -180,5 +188,21 @@ struct lpc_response_flash_wp_gpio { uint32_t value; } __attribute__ ((packed)); +#ifdef SUPPORT_CHECKSUM +/* Checksum a range of flash datq */ +#define EC_LPC_COMMAND_FLASH_CHECKSUM 0x1f +struct lpc_params_flash_checksum { + uint32_t offset; /* Byte offset to read */ + uint32_t size; /* Size to read in bytes */ +} __attribute__ ((packed)); +struct lpc_response_flash_checksum { + uint8_t checksum; +} __attribute__ ((packed)); +#define BYTE_IN(sum, byte) do { \ + sum = (sum << 1) | (sum >> 7); \ + sum ^= (byte ^ 0x53); \ + } while (0) +#endif /* SUPPORT_CHECKSUM */ + #endif /* __CROS_EC_LPC_COMMANDS_H */ |