aboutsummaryrefslogtreecommitdiffstats
path: root/libflashrom.c
diff options
context:
space:
mode:
Diffstat (limited to 'libflashrom.c')
-rw-r--r--libflashrom.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/libflashrom.c b/libflashrom.c
index 5447bae9..1176e020 100644
--- a/libflashrom.c
+++ b/libflashrom.c
@@ -31,6 +31,8 @@
#include "flash.h"
#include "programmer.h"
#include "layout.h"
+#include "hwaccess.h"
+#include "ich_descriptors.h"
#include "libflashrom.h"
/**
@@ -305,6 +307,86 @@ int flashrom_layout_include_region(struct flashrom_layout *const layout, const c
}
/**
+ * @brief Read a layout from the Intel ICH descriptor in the flash.
+ *
+ * Optionally verify that the layout matches the one in the given
+ * descriptor dump.
+ *
+ * @param[out] layout Points to a struct flashrom_layout pointer that
+ * gets set if the descriptor is read and parsed
+ * successfully.
+ * @param[in] flashctx Flash context to read the descriptor from flash.
+ * @param[in] dump The descriptor dump to compare to or NULL.
+ * @param[in] len The length of the descriptor dump.
+ *
+ * @return 0 on success,
+ * 6 if descriptor parsing isn't implemented for the host,
+ * 5 if the descriptors don't match,
+ * 4 if the descriptor dump couldn't be parsed,
+ * 3 if the descriptor on flash couldn't be parsed,
+ * 2 if the descriptor on flash couldn't be read,
+ * 1 on any other error.
+ */
+int flashrom_layout_read_from_ifd(struct flashrom_layout **const layout, struct flashctx *const flashctx,
+ const void *const dump, const size_t len)
+{
+#ifndef __FLASHROM_LITTLE_ENDIAN__
+ return 6;
+#else
+ struct ich_layout dump_layout;
+ int ret = 1;
+
+ void *const desc = malloc(0x1000);
+ struct ich_layout *const chip_layout = malloc(sizeof(*chip_layout));
+ if (!desc || !chip_layout) {
+ msg_gerr("Out of memory!\n");
+ goto _free_ret;
+ }
+
+ if (prepare_flash_access(flashctx, true, false, false, false))
+ goto _free_ret;
+
+ msg_cinfo("Reading ich descriptor... ");
+ if (flashctx->chip->read(flashctx, desc, 0, 0x1000)) {
+ msg_cerr("Read operation failed!\n");
+ msg_cinfo("FAILED.\n");
+ ret = 2;
+ goto _finalize_ret;
+ }
+ msg_cinfo("done.\n");
+
+ if (layout_from_ich_descriptors(chip_layout, desc, 0x1000)) {
+ ret = 3;
+ goto _finalize_ret;
+ }
+
+ if (dump) {
+ if (layout_from_ich_descriptors(&dump_layout, dump, len)) {
+ ret = 4;
+ goto _finalize_ret;
+ }
+
+ if (chip_layout->base.num_entries != dump_layout.base.num_entries ||
+ memcmp(chip_layout->entries, dump_layout.entries, sizeof(dump_layout.entries))) {
+ ret = 5;
+ goto _finalize_ret;
+ }
+ }
+
+ *layout = (struct flashrom_layout *)chip_layout;
+ ret = 0;
+
+_finalize_ret:
+ finalize_flash_access(flashctx);
+_free_ret:
+ if (ret)
+ free(chip_layout);
+ free(desc);
+ return ret;
+#endif
+}
+
+/**
* @brief Free a layout.
*
* @param layout Layout to free.