From 5a4a335aa8d5181e76b6c5fc3c236ac202287cf0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 13 Aug 2019 09:25:27 +0200 Subject: mtd: parsers: Move TI AR7 parser This moves the TI AR7 partition parser down into the parser subdirectory. No functional change. Signed-off-by: Linus Walleij Signed-off-by: Richard Weinberger --- drivers/mtd/parsers/Kconfig | 5 ++ drivers/mtd/parsers/Makefile | 1 + drivers/mtd/parsers/ar7part.c | 129 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 drivers/mtd/parsers/ar7part.c (limited to 'drivers/mtd/parsers') diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index 176b75a375b1..3b3675b8d672 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -1,4 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only +config MTD_AR7_PARTS + tristate "TI AR7 partitioning parser" + help + TI AR7 partitioning parser support + config MTD_PARSER_IMAGETAG tristate "Parser for BCM963XX Image Tag format partitions" depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile index dd566bdd16e2..0bc06386bfcd 100644 --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o diff --git a/drivers/mtd/parsers/ar7part.c b/drivers/mtd/parsers/ar7part.c new file mode 100644 index 000000000000..8cd683711ac6 --- /dev/null +++ b/drivers/mtd/parsers/ar7part.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright © 2007 Eugene Konev + * + * TI AR7 flash partition table. + * Based on ar7 map by Felix Fietkau + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#define AR7_PARTS 4 +#define ROOT_OFFSET 0xe0000 + +#define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) +#define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) + +struct ar7_bin_rec { + unsigned int checksum; + unsigned int length; + unsigned int address; +}; + +static int create_mtd_partitions(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct ar7_bin_rec header; + unsigned int offset; + size_t len; + unsigned int pre_size = master->erasesize, post_size = 0; + unsigned int root_offset = ROOT_OFFSET; + + int retries = 10; + struct mtd_partition *ar7_parts; + + ar7_parts = kcalloc(AR7_PARTS, sizeof(*ar7_parts), GFP_KERNEL); + if (!ar7_parts) + return -ENOMEM; + ar7_parts[0].name = "loader"; + ar7_parts[0].offset = 0; + ar7_parts[0].size = master->erasesize; + ar7_parts[0].mask_flags = MTD_WRITEABLE; + + ar7_parts[1].name = "config"; + ar7_parts[1].offset = 0; + ar7_parts[1].size = master->erasesize; + ar7_parts[1].mask_flags = 0; + + do { /* Try 10 blocks starting from master->erasesize */ + offset = pre_size; + mtd_read(master, offset, sizeof(header), &len, + (uint8_t *)&header); + if (!strncmp((char *)&header, "TIENV0.8", 8)) + ar7_parts[1].offset = pre_size; + if (header.checksum == LOADER_MAGIC1) + break; + if (header.checksum == LOADER_MAGIC2) + break; + pre_size += master->erasesize; + } while (retries--); + + pre_size = offset; + + if (!ar7_parts[1].offset) { + ar7_parts[1].offset = master->size - master->erasesize; + post_size = master->erasesize; + } + + switch (header.checksum) { + case LOADER_MAGIC1: + while (header.length) { + offset += sizeof(header) + header.length; + mtd_read(master, offset, sizeof(header), &len, + (uint8_t *)&header); + } + root_offset = offset + sizeof(header) + 4; + break; + case LOADER_MAGIC2: + while (header.length) { + offset += sizeof(header) + header.length; + mtd_read(master, offset, sizeof(header), &len, + (uint8_t *)&header); + } + root_offset = offset + sizeof(header) + 4 + 0xff; + root_offset &= ~(uint32_t)0xff; + break; + default: + printk(KERN_WARNING "Unknown magic: %08x\n", header.checksum); + break; + } + + mtd_read(master, root_offset, sizeof(header), &len, (u8 *)&header); + if (header.checksum != SQUASHFS_MAGIC) { + root_offset += master->erasesize - 1; + root_offset &= ~(master->erasesize - 1); + } + + ar7_parts[2].name = "linux"; + ar7_parts[2].offset = pre_size; + ar7_parts[2].size = master->size - pre_size - post_size; + ar7_parts[2].mask_flags = 0; + + ar7_parts[3].name = "rootfs"; + ar7_parts[3].offset = root_offset; + ar7_parts[3].size = master->size - root_offset - post_size; + ar7_parts[3].mask_flags = 0; + + *pparts = ar7_parts; + return AR7_PARTS; +} + +static struct mtd_part_parser ar7_parser = { + .parse_fn = create_mtd_partitions, + .name = "ar7part", +}; +module_mtd_part_parser(ar7_parser); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR( "Felix Fietkau , " + "Eugene Konev "); +MODULE_DESCRIPTION("MTD partitioning for TI AR7"); -- cgit v1.2.3-59-g8ed1b