cros_ec: Add a function for decoding the Chrome OS EC flashmap
authorSimon Glass <sjg@chromium.org>
Thu, 27 Feb 2014 20:26:03 +0000 (13:26 -0700)
committerSimon Glass <sjg@chromium.org>
Tue, 18 Mar 2014 02:05:46 +0000 (20:05 -0600)
In order to talk to the EC properly we need to be able to understand the
layout of its internal flash memory. This permits emulation of the EC
for sandbox, and also software update in a system with a real EC.

Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/misc/cros_ec.c
include/cros_ec.h

index 301e8ebbf57babe28ff1de3b218ceab7b11c0024..1998653754bdb0e075396a3985851e40e755a943 100644 (file)
@@ -958,6 +958,56 @@ int cros_ec_decode_region(int argc, char * const argv[])
        return -1;
 }
 
+int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config)
+{
+       int flash_node, node;
+
+       node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC);
+       if (node < 0) {
+               debug("Failed to find chrome-ec node'\n");
+               return -1;
+       }
+
+       flash_node = fdt_subnode_offset(blob, node, "flash");
+       if (flash_node < 0) {
+               debug("Failed to find flash node\n");
+               return -1;
+       }
+
+       if (fdtdec_read_fmap_entry(blob, flash_node, "flash",
+                                  &config->flash)) {
+               debug("Failed to decode flash node in chrome-ec'\n");
+               return -1;
+       }
+
+       config->flash_erase_value = fdtdec_get_int(blob, flash_node,
+                                                   "erase-value", -1);
+       for (node = fdt_first_subnode(blob, flash_node); node >= 0;
+            node = fdt_next_subnode(blob, node)) {
+               const char *name = fdt_get_name(blob, node, NULL);
+               enum ec_flash_region region;
+
+               if (0 == strcmp(name, "ro")) {
+                       region = EC_FLASH_REGION_RO;
+               } else if (0 == strcmp(name, "rw")) {
+                       region = EC_FLASH_REGION_RW;
+               } else if (0 == strcmp(name, "wp-ro")) {
+                       region = EC_FLASH_REGION_WP_RO;
+               } else {
+                       debug("Unknown EC flash region name '%s'\n", name);
+                       return -1;
+               }
+
+               if (fdtdec_read_fmap_entry(blob, node, "reg",
+                                          &config->region[region])) {
+                       debug("Failed to decode flash region in chrome-ec'\n");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 /**
  * Perform a flash read or write command
  *
index 22eae906050c14e7746a8276f35fc91e025c8c3f..999c3c90c50a58f4271c434cf966d8a46e0c452c 100644 (file)
@@ -63,6 +63,17 @@ struct mbkp_keyscan {
        uint8_t data[CROS_EC_KEYSCAN_COLS];
 };
 
+/* Holds information about the Chrome EC */
+struct fdt_cros_ec {
+       struct fmap_entry flash;        /* Address and size of EC flash */
+       /*
+        * Byte value of erased flash, or -1 if not known. It is normally
+        * 0xff but some flash devices use 0 (e.g. STM32Lxxx)
+        */
+       int flash_erase_value;
+       struct fmap_entry region[EC_FLASH_REGION_COUNT];
+};
+
 /**
  * Read the ID of the CROS-EC device
  *
@@ -449,4 +460,12 @@ int cros_ec_board_init(void);
  */
 int cros_ec_get_error(void);
 
+/**
+ * Returns information from the FDT about the Chrome EC flash
+ *
+ * @param blob         FDT blob to use
+ * @param config       Structure to use to return information
+ */
+int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config);
+
 #endif