Signed-off-by: Patrick Delaunay
Reviewed-by: Christophe KERELLO
---
Changes in v5:
- solve warning and error
(dont' include linux/mtd/mtd.h in part.h)
Changes in v4: None
Changes in v3: None
Changes in v2: None
disk/Kconfig| 17 ++
disk/Makefile | 1 +
disk/part_efi_mtd.c | 457
doc/README.gpt.mtd | 189 ++
include/part.h | 15 +-
5 files changed, 677 insertions(+), 2 deletions(-)
create mode 100644 disk/part_efi_mtd.c
create mode 100644 doc/README.gpt.mtd
diff --git a/disk/Kconfig b/disk/Kconfig
index 9396562..886a089 100644
--- a/disk/Kconfig
+++ b/disk/Kconfig
@@ -96,6 +96,23 @@ config SPL_EFI_PARTITION
depends on SPL && PARTITIONS
default y if EFI_PARTITION
+config EFI_PARTITION_MTD
+ bool "Support EFI GPT over MTD"
+ depends on EFI_PARTITION
+ help
+ The GPT partition is normally defined only for block device with
+ built-in controller which manage flash translation layer
+ This option activate the GPT partition support over RAW device
+ using the MTD framework
+ - manage partition over MTD devices (as flash: NOR and NAND)
+ - extract MTD information
+ - update command gpt, mtdparts and part
+
+config SPL_EFI_PARTITION_MTD
+ bool "Enable EFI GPT over MTD for SPL"
+ depends on SPL_EFI_PARTITION
+ default y if EFI_PARTITION_MTD
+
config PARTITION_UUIDS
bool "Enable support of UUID for partition"
depends on PARTITIONS
diff --git a/disk/Makefile b/disk/Makefile
index 12c0531..0d01160 100644
--- a/disk/Makefile
+++ b/disk/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_$(SPL_)DOS_PARTITION) += part_dos.o
obj-$(CONFIG_$(SPL_)ISO_PARTITION) += part_iso.o
obj-$(CONFIG_$(SPL_)AMIGA_PARTITION) += part_amiga.o
obj-$(CONFIG_$(SPL_)EFI_PARTITION) += part_efi.o
+obj-$(CONFIG_$(SPL_)EFI_PARTITION_MTD) += part_efi_mtd.o
diff --git a/disk/part_efi_mtd.c b/disk/part_efi_mtd.c
new file mode 100644
index 000..e4c63cf
--- /dev/null
+++ b/disk/part_efi_mtd.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2016 STMicroelectronics .
+ * Patrick Delaunay
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "part_efi_int.h"
+
+static int is_primary_gpt_valid_mtd(struct mtd_info *mtd,
+ lbaint_t lba,
+ void **buf,
+ gpt_header **pgpt_head,
+ gpt_entry **pgpt_pte)
+{
+ gpt_header *gpt_h;
+ gpt_entry *gpt_e;
+ uint32_t size;
+ uint64_t offset;
+ int ret;
+ size_t retlen;
+ lbaint_t my_lba;
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+ MTD_LBA_SIZE);
+
+ size = gpt_e_size + 2 * MTD_LBA_SIZE;
+ /* skip bad block */
+ offset = 0;
+ while (mtd_block_isbad(mtd, offset)) {
+ printf("bad block at 0x%llx\n", offset);
+ offset += mtd->erasesize;
+ if (offset >= mtd->size) {
+ printf("*** ERROR: too many bad block ***\n");
+ return -1;
+ }
+ }
+
+ debug("primary offset = 0x%llx\n", offset);
+ /* Read primary GPT from device */
+ ret = mtd_read(mtd, offset, size, , *buf);
+ if (ret || (retlen != size)) {
+ printf("*** ERROR: Can't read primary GPT ***\n");
+ return -1;
+ }
+
+ /* determine start of GPT Header & Entries in the buffer */
+ gpt_h = *buf + (1 * MTD_LBA_SIZE);
+ gpt_e = *buf + (2 * MTD_LBA_SIZE);
+ my_lba = lldiv(offset, MTD_LBA_SIZE) + GPT_PRIMARY_PARTITION_TABLE_LBA;
+
+ if (!validate_gpt_header(gpt_h, my_lba, lba) &&
+ !validate_gpt_entries(gpt_h, gpt_e)) {
+ *pgpt_head = gpt_h;
+ *pgpt_pte = gpt_e;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int is_secondary_gpt_valid_mtd(struct mtd_info *mtd,
+ lbaint_t lba,
+ void **buf,
+ gpt_header **pgpt_head,
+ gpt_entry **pgpt_pte)
+{
+ gpt_header *gpt_h;
+ gpt_entry *gpt_e;
+ uint32_t size;
+ uint64_t offset;
+ int ret;
+ size_t retlen;
+ lbaint_t my_lba;
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+ MTD_LBA_SIZE);
+
+ size = gpt_e_size + 2 * MTD_LBA_SIZE;
+ /* skip bad block */
+ offset = mtd->size;
+ while (mtd_block_isbad(mtd, offset - mtd->erasesize)) {
+ offset -=