040-v6.1-mtd-parsers-add-Broadcom-s-U-Boot-parser.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. From 002181f5b150e60c77f21de7ad4dd10e4614cd91 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
  3. Date: Mon, 11 Jul 2022 17:30:41 +0200
  4. Subject: [PATCH] mtd: parsers: add Broadcom's U-Boot parser
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Broadcom stores environment variables blocks inside U-Boot partition
  9. itself. This driver finds & registers them.
  10. Signed-off-by: Rafał Miłecki <[email protected]>
  11. Signed-off-by: Miquel Raynal <[email protected]>
  12. Link: https://lore.kernel.org/linux-mtd/[email protected]
  13. ---
  14. drivers/mtd/parsers/Kconfig | 10 ++++
  15. drivers/mtd/parsers/Makefile | 1 +
  16. drivers/mtd/parsers/brcm_u-boot.c | 84 +++++++++++++++++++++++++++++++
  17. 3 files changed, 95 insertions(+)
  18. create mode 100644 drivers/mtd/parsers/brcm_u-boot.c
  19. --- a/drivers/mtd/parsers/Kconfig
  20. +++ b/drivers/mtd/parsers/Kconfig
  21. @@ -20,6 +20,16 @@ config MTD_BCM63XX_PARTS
  22. This provides partition parsing for BCM63xx devices with CFE
  23. bootloaders.
  24. +config MTD_BRCM_U_BOOT
  25. + tristate "Broadcom's U-Boot partition parser"
  26. + depends on ARCH_BCM4908 || COMPILE_TEST
  27. + help
  28. + Broadcom uses a custom way of storing U-Boot environment variables.
  29. + They are placed inside U-Boot partition itself at unspecified offset.
  30. + It's possible to locate them by looking for a custom header with a
  31. + magic value. This driver does that and creates subpartitions for
  32. + each found environment variables block.
  33. +
  34. config MTD_CMDLINE_PARTS
  35. tristate "Command line partition table parsing"
  36. depends on MTD
  37. --- a/drivers/mtd/parsers/Makefile
  38. +++ b/drivers/mtd/parsers/Makefile
  39. @@ -2,6 +2,7 @@
  40. obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
  41. obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
  42. obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
  43. +obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o
  44. obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
  45. obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
  46. obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
  47. --- /dev/null
  48. +++ b/drivers/mtd/parsers/brcm_u-boot.c
  49. @@ -0,0 +1,84 @@
  50. +// SPDX-License-Identifier: GPL-2.0-only
  51. +/*
  52. + * Copyright © 2022 Rafał Miłecki <[email protected]>
  53. + */
  54. +
  55. +#include <linux/module.h>
  56. +#include <linux/kernel.h>
  57. +#include <linux/slab.h>
  58. +#include <linux/mtd/mtd.h>
  59. +#include <linux/mtd/partitions.h>
  60. +
  61. +#define BRCM_U_BOOT_MAX_OFFSET 0x200000
  62. +#define BRCM_U_BOOT_STEP 0x1000
  63. +
  64. +#define BRCM_U_BOOT_MAX_PARTS 2
  65. +
  66. +#define BRCM_U_BOOT_MAGIC 0x75456e76 /* uEnv */
  67. +
  68. +struct brcm_u_boot_header {
  69. + __le32 magic;
  70. + __le32 length;
  71. +} __packed;
  72. +
  73. +static const char *names[BRCM_U_BOOT_MAX_PARTS] = {
  74. + "u-boot-env",
  75. + "u-boot-env-backup",
  76. +};
  77. +
  78. +static int brcm_u_boot_parse(struct mtd_info *mtd,
  79. + const struct mtd_partition **pparts,
  80. + struct mtd_part_parser_data *data)
  81. +{
  82. + struct brcm_u_boot_header header;
  83. + struct mtd_partition *parts;
  84. + size_t bytes_read;
  85. + size_t offset;
  86. + int err;
  87. + int i = 0;
  88. +
  89. + parts = kcalloc(BRCM_U_BOOT_MAX_PARTS, sizeof(*parts), GFP_KERNEL);
  90. + if (!parts)
  91. + return -ENOMEM;
  92. +
  93. + for (offset = 0;
  94. + offset < min_t(size_t, mtd->size, BRCM_U_BOOT_MAX_OFFSET);
  95. + offset += BRCM_U_BOOT_STEP) {
  96. + err = mtd_read(mtd, offset, sizeof(header), &bytes_read, (uint8_t *)&header);
  97. + if (err && !mtd_is_bitflip(err)) {
  98. + pr_err("Failed to read from %s at 0x%zx: %d\n", mtd->name, offset, err);
  99. + continue;
  100. + }
  101. +
  102. + if (le32_to_cpu(header.magic) != BRCM_U_BOOT_MAGIC)
  103. + continue;
  104. +
  105. + parts[i].name = names[i];
  106. + parts[i].offset = offset;
  107. + parts[i].size = sizeof(header) + le32_to_cpu(header.length);
  108. + i++;
  109. + pr_info("offset:0x%zx magic:0x%08x BINGO\n", offset, header.magic);
  110. +
  111. + if (i == BRCM_U_BOOT_MAX_PARTS)
  112. + break;
  113. + }
  114. +
  115. + *pparts = parts;
  116. +
  117. + return i;
  118. +};
  119. +
  120. +static const struct of_device_id brcm_u_boot_of_match_table[] = {
  121. + { .compatible = "brcm,u-boot" },
  122. + {},
  123. +};
  124. +MODULE_DEVICE_TABLE(of, brcm_u_boot_of_match_table);
  125. +
  126. +static struct mtd_part_parser brcm_u_boot_mtd_parser = {
  127. + .parse_fn = brcm_u_boot_parse,
  128. + .name = "brcm_u-boot",
  129. + .of_match_table = brcm_u_boot_of_match_table,
  130. +};
  131. +module_mtd_part_parser(brcm_u_boot_mtd_parser);
  132. +
  133. +MODULE_LICENSE("GPL");