diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-02-28 12:25:44 -0800 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-02-28 13:02:17 -0800 |
commit | e84fc7b11034bf17dace0f611e37300058691d5f (patch) | |
tree | 766e680d4cce1d9e042af0d72149220a92142620 /common | |
parent | b4edad69221f5ec910ef8740c76fe60ddf571005 (diff) | |
download | chrome-ec-e84fc7b11034bf17dace0f611e37300058691d5f.tar.gz |
Add persistent host storage in EC EEPROM
Signed-off-by: Randall Spangler <rspangler@chromium.org>
BUG=chrome-os-partner:8247
TEST=manual
from root shell on host:
ectool pstoreinfo --> should print PstoreSize 1024 AccessSize 4
echo testing 1 2 3 4 > /tmp/infile
ectool pstorewrite 8 /tmp/infile
ectool pstoreread 8 /tmp/outfile
diff /tmp/infile /tmp/outfile
Change-Id: I565e580307584f7def36c5e53d360c1a897d67d2
Diffstat (limited to 'common')
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/host_command.c | 18 | ||||
-rw-r--r-- | common/pstore_commands.c | 109 |
3 files changed, 125 insertions, 3 deletions
diff --git a/common/build.mk b/common/build.mk index 9c4a6fb6d5..34952d410b 100644 --- a/common/build.mk +++ b/common/build.mk @@ -14,6 +14,7 @@ common-$(CONFIG_TASK_I8042CMD)+=i8042.o keyboard.o common-$(CONFIG_TASK_X86POWER)+=x86_power.o common-$(CONFIG_TASK_GAIAPOWER)+=gaia_power.o common-$(CONFIG_FLASH)+=flash_commands.o +common-$(CONFIG_PSTORE)+=pstore_commands.o common-$(CONFIG_PWM)+=pwm_commands.o common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o common-$(CONFIG_TMP006)+=tmp006.o diff --git a/common/host_command.c b/common/host_command.c index 1314a0cfe1..f52c6095ad 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -5,19 +5,20 @@ /* Host command module for Chrome EC */ +#include "board.h" #include "config.h" #include "console.h" #include "flash_commands.h" #include "host_command.h" -#include "pwm_commands.h" -#include "usb_charge_commands.h" #include "lpc.h" #include "lpc_commands.h" +#include "pstore_commands.h" +#include "pwm_commands.h" #include "system.h" #include "task.h" #include "timer.h" #include "uart.h" -#include "registers.h" +#include "usb_charge_commands.h" #include "util.h" static int host_command[2]; @@ -192,6 +193,17 @@ static void command_process(int slot) case EC_LPC_COMMAND_USB_CHARGE_SET_MODE: lpc_send_host_response(slot, usb_charge_command_set_mode(data)); return; +#ifdef CONFIG_PSTORE + case EC_LPC_COMMAND_PSTORE_INFO: + lpc_send_host_response(slot, pstore_command_get_info(data)); + return; + case EC_LPC_COMMAND_PSTORE_READ: + lpc_send_host_response(slot, pstore_command_read(data)); + return; + case EC_LPC_COMMAND_PSTORE_WRITE: + lpc_send_host_response(slot, pstore_command_write(data)); + return; +#endif default: lpc_send_host_response(slot, EC_LPC_STATUS_INVALID_COMMAND); } diff --git a/common/pstore_commands.c b/common/pstore_commands.c new file mode 100644 index 0000000000..24ce7c7878 --- /dev/null +++ b/common/pstore_commands.c @@ -0,0 +1,109 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Persistent storage commands for Chrome EC */ + +#include "board.h" +#include "eeprom.h" +#include "lpc_commands.h" +#include "pstore_commands.h" +#include "uart.h" +#include "util.h" + +/* TODO: move these to board.h */ +#ifdef CONFIG_PSTORE +/* Start block and block count for host persistent storage in EC EEPROM */ +#define PSTORE_EEPROM_BLOCK_START 16 +#define PSTORE_EEPROM_BLOCK_COUNT 16 +#endif + +enum lpc_status pstore_command_get_info(uint8_t *data) +{ + struct lpc_response_pstore_info *r = + (struct lpc_response_pstore_info *)data; + + uart_printf("ee block size=%d, count=%d\n", + eeprom_get_block_size(), eeprom_get_block_count()); + + ASSERT(PSTORE_EEPROM_BLOCK_START + PSTORE_EEPROM_BLOCK_COUNT <= + eeprom_get_block_count()); + + r->pstore_size = PSTORE_EEPROM_BLOCK_COUNT * eeprom_get_block_size(); + r->access_size = sizeof(uint32_t); + return EC_LPC_STATUS_SUCCESS; +} + + +enum lpc_status pstore_command_read(uint8_t *data) +{ + struct lpc_params_pstore_read *p = + (struct lpc_params_pstore_read *)data; + struct lpc_response_pstore_read *r = + (struct lpc_response_pstore_read *)data; + char *dest = r->data; + int block_size = eeprom_get_block_size(); + int block = p->offset / block_size + PSTORE_EEPROM_BLOCK_COUNT; + int offset = p->offset % block_size; + int bytes_left = p->size; + + if (p->size > sizeof(r->data)) + return EC_LPC_STATUS_ERROR; + + while (bytes_left) { + /* Read what we can from the current block */ + int bytes_this = MIN(bytes_left, block_size - offset); + + if (block >= + PSTORE_EEPROM_BLOCK_START + PSTORE_EEPROM_BLOCK_COUNT) + return EC_LPC_STATUS_ERROR; + + if (eeprom_read(block, offset, bytes_this, dest)) + return EC_LPC_STATUS_ERROR; + + /* Continue to the next block if necessary */ + offset = 0; + block++; + bytes_left -= bytes_this; + dest += bytes_this; + } + + return EC_LPC_STATUS_SUCCESS; +} + + +enum lpc_status pstore_command_write(uint8_t *data) +{ + struct lpc_params_pstore_write *p = + (struct lpc_params_pstore_write *)data; + + const char *src = p->data; + int block_size = eeprom_get_block_size(); + int block = p->offset / block_size + PSTORE_EEPROM_BLOCK_COUNT; + int offset = p->offset % block_size; + int bytes_left = p->size; + + if (p->size > sizeof(p->data)) + return EC_LPC_STATUS_ERROR; + + while (bytes_left) { + /* Write what we can to the current block */ + int bytes_this = MIN(bytes_left, block_size - offset); + + if (block >= + PSTORE_EEPROM_BLOCK_START + PSTORE_EEPROM_BLOCK_COUNT) + return EC_LPC_STATUS_ERROR; + + if (eeprom_write(block, offset, bytes_this, src)) + return EC_LPC_STATUS_ERROR; + + /* Continue to the next block if necessary */ + offset = 0; + block++; + bytes_left -= bytes_this; + src += bytes_this; + } + + return EC_LPC_STATUS_SUCCESS; +} |