From 6995d4771f7c07b08948c867f4ec0de309ed925e Mon Sep 17 00:00:00 2001 From: Louis Yung-Chieh Lo Date: Mon, 12 Dec 2011 21:24:48 +0800 Subject: 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 --- common/flash_commands.c | 29 +++++++++++++++++++++++++++-- common/host_command.c | 13 +++++++++---- include/flash_commands.h | 4 ++++ 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 + +/* 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 */ -- cgit v1.2.1