summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorGerrit <chrome-bot@google.com>2012-02-28 13:34:37 -0800
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2012-02-28 13:34:37 -0800
commite632029ed045e2b4922e3131898b0137d3a79972 (patch)
tree90c391945805f38e75fc2084833bedd972729a8a /common
parent7e40bacb1bbf99deac444712a271a264cd62b5b9 (diff)
parente84fc7b11034bf17dace0f611e37300058691d5f (diff)
downloadchrome-ec-e632029ed045e2b4922e3131898b0137d3a79972.tar.gz
Merge "Add persistent host storage in EC EEPROM"
Diffstat (limited to 'common')
-rw-r--r--common/build.mk1
-rw-r--r--common/host_command.c18
-rw-r--r--common/pstore_commands.c109
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;
+}