platform: msm-shared: Add UBI image awareness to fastboot code

Current implementation of flasher in LK just writes the provided image as RAW data.
This is not good enough when writing a UBI image since some UBI META data should
be preserved.

When flashing a UBI image, the flasher should do the following for each non-bad PEB.
- Read the content of this PEB from the UBI image (PEB size bytes) into a buffer.
- Stripe min. I/O units full of 0xFF bytes from the end of the buffer Erase the PEB.
- Change the EC header in the buffer - put the new erase counter value there and
  re-calculate the CRC-32 checksum.
- Write the buffer to the physical eraseblock.

Sometimes the flashed image is smaller than the partition. The remaining PEBs should be
erased and a new ec header written to them.
For each erased PEB a valid ec header should be written.

With the above mentioned changes the first boot time after flashing the image was
reduced by ~50%.

When flashing on an erased partition there is no need to re-erase the blocks. With this
change flashing time was reduced by additional 3%.

Change-Id: Ie131cc2ccbf64e92510a055fb57389ae17a7f45f
diff --git a/include/dev/flash-ubi.h b/include/dev/flash-ubi.h
index 09a7bc0..36e8c8a 100644
--- a/include/dev/flash-ubi.h
+++ b/include/dev/flash-ubi.h
@@ -39,10 +39,50 @@
 #define UBI_MAGIC      "UBI#"
 #define UBI_MAGIC_SIZE 0x04
 
-inline int flash_ubi_img(struct ptentry *ptn, void *data, unsigned size)
-{
-	dprintf(CRITICAL, "ERROR: flash_ubi_img not yet implemented\n");
-	dprintf(CRITICAL, "falling back to flash_write\n");
-	return flash_write(ptn, 0, data, size);
-}
+#define UBI_VERSION 1
+#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF
+#define UBI_IMAGE_SEQ_BASE 0x12345678
+#define UBI_DEF_ERACE_COUNTER 0
+#define UBI_CRC32_INIT 0xFFFFFFFFU
+
+/* Erase counter header fields */
+struct __attribute__ ((packed)) ubi_ec_hdr {
+	uint32_t  magic;
+	uint8_t   version;
+	uint8_t   padding1[3];
+	uint64_t  ec; /* Warning: the current limit is 31-bit anyway! */
+	uint32_t  vid_hdr_offset;
+	uint32_t  data_offset;
+	uint32_t  image_seq;
+	uint8_t   padding2[32];
+	uint32_t  hdr_crc;
+};
+
+#define UBI_EC_HDR_SIZE  sizeof(struct ubi_ec_hdr)
+#define UBI_EC_HDR_SIZE_CRC  (UBI_EC_HDR_SIZE  - sizeof(uint32_t))
+
+/**
+ * struct ubi_scan_info - UBI scanning information.
+ * @ec: erase counters or eraseblock status for all eraseblocks
+ * @mean_ec: mean erase counter
+ * @bad_cnt: count of bad eraseblocks
+ * @good_cnt: count of non-bad eraseblocks
+ * @empty_cnt: count of empty eraseblocks
+ * @vid_hdr_offs: volume ID header offset from the found EC headers (%-1 means
+ *                undefined)
+ * @data_offs: data offset from the found EC headers (%-1 means undefined)
+ * @image_seq: image sequence
+ */
+struct ubi_scan_info {
+	uint64_t *ec;
+	uint64_t mean_ec;
+	int bad_cnt;
+	int good_cnt;
+	int empty_cnt;
+	unsigned vid_hdr_offs;
+	unsigned data_offs;
+	uint32_t  image_seq;
+};
+
+int flash_ubi_img(struct ptentry *ptn, void *data, unsigned size);
 #endif