uboot-mediatek: sync mtk-openwrt open source u-boot patches
authorShiji Yang <yangshiji66@qq.com>
Sat, 11 Jan 2025 13:09:20 +0000 (21:09 +0800)
committerDaniel Golle <daniel@makrotopia.org>
Sun, 9 Feb 2025 21:50:58 +0000 (21:50 +0000)
Synchronize the latest MTK u-boot patches[1]. Some patches have
been amended since last synchronization.

Changes:
* Minor NMBM layer fixes and improvements.
* A new bootmenu shortkey implementation.
* New SPI flash support for en25qx128.

[1] https://github.com/mtk-openwrt/u-boot/tree/mtksoc-20230719

Signed-off-by: Shiji Yang <yangshiji66@qq.com>
package/boot/uboot-mediatek/patches/100-06-mtd-add-core-facility-code-of-NMBM.patch
package/boot/uboot-mediatek/patches/100-11-env-add-support-for-NMBM-upper-MTD-layer.patch
package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
package/boot/uboot-mediatek/patches/100-21-mtd-spi-nor-add-more-flash-ids.patch
package/boot/uboot-mediatek/patches/100-26-env-ubi-add-support-to-create-environment-volume-if-.patch
package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch

index 30d21b0e49c55b1c04bcd65955bfaf2c372a46f3..cbf6faf8c66d96658652f26b573b27c26ebc252f 100644 (file)
@@ -13,13 +13,13 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
  drivers/mtd/Makefile            |    1 +
  drivers/mtd/nmbm/Kconfig        |   29 +
  drivers/mtd/nmbm/Makefile       |    5 +
- drivers/mtd/nmbm/nmbm-core.c    | 2936 +++++++++++++++++++++++++++++++
+ drivers/mtd/nmbm/nmbm-core.c    | 3040 +++++++++++++++++++++++++++++++
  drivers/mtd/nmbm/nmbm-debug.h   |   37 +
  drivers/mtd/nmbm/nmbm-debug.inl |   39 +
  drivers/mtd/nmbm/nmbm-private.h |  137 ++
- include/nmbm/nmbm-os.h          |   66 +
- include/nmbm/nmbm.h             |  102 ++
- 10 files changed, 3354 insertions(+)
+ include/nmbm/nmbm-os.h          |   68 +
+ include/nmbm/nmbm.h             |  105 ++
+ 10 files changed, 3463 insertions(+)
  create mode 100644 drivers/mtd/nmbm/Kconfig
  create mode 100644 drivers/mtd/nmbm/Makefile
  create mode 100644 drivers/mtd/nmbm/nmbm-core.c
@@ -31,15 +31,15 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 
 --- a/drivers/mtd/Kconfig
 +++ b/drivers/mtd/Kconfig
-@@ -282,6 +282,8 @@ source "drivers/mtd/ubi/Kconfig"
- source "drivers/mtd/nvmxip/Kconfig"
+@@ -276,6 +276,8 @@ config SYS_NAND_MAX_CHIPS
+       help
+         The maximum number of NAND chips per device to be supported.
  
 +source "drivers/mtd/nmbm/Kconfig"
 +
- endif
+ source "drivers/mtd/spi/Kconfig"
  
- endmenu
+ source "drivers/mtd/ubi/Kconfig"
 --- a/drivers/mtd/Makefile
 +++ b/drivers/mtd/Makefile
 @@ -42,3 +42,4 @@ obj-$(CONFIG_SPL_UBI) += ubispl/
@@ -89,10 +89,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +obj-$(CONFIG_NMBM) += nmbm-core.o
 --- /dev/null
 +++ b/drivers/mtd/nmbm/nmbm-core.c
-@@ -0,0 +1,2936 @@
+@@ -0,0 +1,3040 @@
 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 +/*
-+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
++ * Copyright (C) 2021 MediaTek Inc. All Rights Reserved.
 + *
 + * Author: Weijie Gao <weijie.gao@mediatek.com>
 + */
@@ -349,6 +349,37 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +}
 +
 +/*
++ * nmbm_panic_write_phys_page - Panic write page with retry
++ * @ni: NMBM instance structure
++ * @addr: linear address where the data will be written to
++ * @data: the main data to be written
++ *
++ * Write a page for at most NMBM_TRY_COUNT times.
++ */
++static bool nmbm_panic_write_phys_page(struct nmbm_instance *ni, uint64_t addr,
++                                     const void *data)
++{
++      int tries, ret;
++
++      if (ni->lower.flags & NMBM_F_READ_ONLY) {
++              nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
++              return false;
++      }
++
++      for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
++              ret = ni->lower.panic_write_page(ni->lower.arg, addr, data);
++              if (!ret)
++                      return true;
++
++              nmbm_reset_chip(ni);
++      }
++
++      nlog_err(ni, "Panic page write failed at address 0x%08llx\n", addr);
++
++      return false;
++}
++
++/*
 + * nmbm_erase_phys_block - Erase a block with retry
 + * @ni: NMBM instance structure
 + * @addr: Linear address
@@ -752,7 +783,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      addr = ba2addr(ni, ba);
 +
 +      for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              ret = nmbm_read_phys_page(ni, addr + off, ni->page_cache, NULL,
 +                                        NMBM_MODE_PLACE_OOB);
@@ -791,7 +822,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      bool success;
 +
 +      while (ba < limit) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
 +                      goto next_block;
@@ -842,7 +873,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      addr = ba2addr(ni, ba);
 +
 +      for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              /* Prepare page data. fill 0xff to unused region */
 +              memcpy(ni->page_cache, data, size);
@@ -886,7 +917,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      bool success;
 +
 +      while (ba > limit) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
 +                      goto next_block;
@@ -941,7 +972,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      int ret;
 +
 +      while (sizeremain) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              leading = off & ni->writesize_mask;
 +              chunksize = ni->lower.writesize - leading;
@@ -991,7 +1022,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      int ret;
 +
 +      while (sizeremain) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              leading = off & ni->writesize_mask;
 +              chunksize = ni->lower.writesize - leading;
@@ -1047,7 +1078,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      bool success;
 +
 +      while (sizeremain && ba < limit) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              chunksize = sizeremain;
 +              if (chunksize > ni->lower.erasesize)
@@ -1309,7 +1340,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +
 +      /* Try to write new info table next to the existing table */
 +      while (write_ba >= ni->mapping_blocks_ba) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              success = nmbm_write_info_table(ni, write_ba,
 +                                              ni->mapping_blocks_top_ba,
@@ -1428,7 +1459,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +
 +      /* Try to write temporary info table into spare unmapped blocks */
 +      while (write_ba >= ni->mapping_blocks_ba) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              success = nmbm_write_info_table(ni, write_ba,
 +                                              ni->mapping_blocks_top_ba,
@@ -1514,7 +1545,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +
 +      /* Write new backup info table. */
 +      while (write_ba >= main_table_end_ba) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              success = nmbm_write_info_table(ni, write_ba,
 +                                              ni->mapping_blocks_top_ba,
@@ -1903,7 +1934,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      int ret;
 +
 +      while (sizeremain && ba < limit) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
 +                      goto next_block;
@@ -1996,7 +2027,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      bool success;
 +
 +      while (ba < limit - size2blk(ni, ni->info_table_size)) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              success = nmbm_try_load_info_table(ni, ba, table_end_ba,
 +                                                 write_count,
@@ -2208,7 +2239,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +              limit = block_count - ni->lower.max_reserved_blocks;
 +
 +      while (ba >= limit) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              ba--;
 +              addr = ba2addr(ni, ba);
@@ -2222,7 +2253,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +               */
 +              for (off = 0; off < ni->lower.erasesize;
 +                   off += ni->lower.writesize) {
-+                      schedule();
++                      WATCHDOG_RESET();
 +
 +                      ret = nmbn_read_data(ni, addr + off, &sig,
 +                                           sizeof(sig));
@@ -2281,7 +2312,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +              return false;
 +      }
 +
-+      if (!nld->oobsize || !is_power_of_2(nld->oobsize)) {
++      if (!nld->oobsize) {
 +              nmbm_log_lower(nld, NMBM_LOG_ERR,
 +                             "Page spare size %u is not valid\n", nld->oobsize);
 +              return false;
@@ -2594,7 +2625,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      end_ba = addr2ba(ni, addr + size - 1);
 +
 +      while (start_ba <= end_ba) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              ret = nmbm_erase_logic_block(ni, start_ba);
 +              if (ret) {
@@ -2726,7 +2757,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      }
 +
 +      while (sizeremain) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              leading = off & ni->writesize_mask;
 +              chunksize = ni->lower.writesize - leading;
@@ -2822,6 +2853,53 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +}
 +
 +/*
++ * nmbm_panic_write_logic_page - Panic write page based on logic address
++ * @ni: NMBM instance structure
++ * @addr: logic linear address
++ * @data: buffer contains main data. optional.
++ */
++static int nmbm_panic_write_logic_page(struct nmbm_instance *ni, uint64_t addr,
++                                     const void *data)
++{
++      uint32_t lb, pb, offset;
++      uint64_t paddr;
++      bool success;
++
++      /* Extract block address and in-block offset */
++      lb = addr2ba(ni, addr);
++      offset = addr & ni->erasesize_mask;
++
++      /* Map logic block to physical block */
++      pb = ni->block_mapping[lb];
++
++      /* Whether the logic block is good (has valid mapping) */
++      if ((int32_t)pb < 0) {
++              nlog_debug(ni, "Logic block %u is a bad block\n", lb);
++              return -EIO;
++      }
++
++      /* Fail if physical block is marked bad */
++      if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD)
++              return -EIO;
++
++      /* Assemble new address */
++      paddr = ba2addr(ni, pb) + offset;
++
++      success = nmbm_panic_write_phys_page(ni, paddr, data);
++      if (success)
++              return 0;
++
++      /*
++       * Do not remap bad block here. Just mark this block in state table.
++       * Remap this block on erasing.
++       */
++      nmbm_set_block_state(ni, pb, BLOCK_ST_NEED_REMAP);
++      nmbm_update_info_table(ni);
++
++      return -EIO;
++}
++
++/*
 + * nmbm_write_single_page - Write one page based on logic address
 + * @ni: NMBM instance structure
 + * @addr: logic linear address
@@ -2851,6 +2929,32 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +}
 +
 +/*
++ * nmbm_panic_write_single_page - Panic write one page based on logic address
++ * @ni: NMBM instance structure
++ * @addr: logic linear address
++ * @data: buffer contains main data. optional.
++ */
++int nmbm_panic_write_single_page(struct nmbm_instance *ni, uint64_t addr,
++                               const void *data)
++{
++      if (!ni)
++              return -EINVAL;
++
++      /* Sanity check */
++      if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
++              nlog_debug(ni, "Device is forced read-only\n");
++              return -EROFS;
++      }
++
++      if (addr >= ba2addr(ni, ni->data_block_count)) {
++              nlog_err(ni, "Address 0x%llx is invalid\n", addr);
++              return -EINVAL;
++      }
++
++      return nmbm_panic_write_logic_page(ni, addr, data);
++}
++
++/*
 + * nmbm_write_range - Write data without oob
 + * @ni: NMBM instance structure
 + * @addr: logic linear address
@@ -2893,7 +2997,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +      }
 +
 +      while (sizeremain) {
-+              schedule();
++              WATCHDOG_RESET();
 +
 +              leading = off & ni->writesize_mask;
 +              chunksize = ni->lower.writesize - leading;
@@ -3250,7 +3354,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +#endif /* _NMBM_PRIVATE_H_ */
 --- /dev/null
 +++ b/include/nmbm/nmbm-os.h
-@@ -0,0 +1,66 @@
+@@ -0,0 +1,68 @@
 +/* SPDX-License-Identifier: GPL-2.0 */
 +/*
 + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@@ -3265,7 +3369,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +
 +#include <div64.h>
 +#include <stdbool.h>
-+#include <watchdog.h>
++#include <cyclic.h>
 +#include <u-boot/crc.h>
 +#include <linux/errno.h>
 +#include <linux/log2.h>
@@ -3316,10 +3420,12 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +#define NMBM_DEFAULT_LOG_LEVEL                1
 +#endif
 +
++#define WATCHDOG_RESET                        schedule
++
 +#endif /* _NMBM_OS_H_ */
 --- /dev/null
 +++ b/include/nmbm/nmbm.h
-@@ -0,0 +1,102 @@
+@@ -0,0 +1,105 @@
 +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 +/*
 + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@@ -3374,6 +3480,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +       */
 +      int (*read_page)(void *arg, uint64_t addr, void *buf, void *oob, enum nmbm_oob_mode mode);
 +      int (*write_page)(void *arg, uint64_t addr, const void *buf, const void *oob, enum nmbm_oob_mode mode);
++      int (*panic_write_page)(void *arg, uint64_t addr, const void *buf);
 +      int (*erase_block)(void *arg, uint64_t addr);
 +
 +      int (*is_bad_block)(void *arg, uint64_t addr);
@@ -3410,6 +3517,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +int nmbm_write_single_page(struct nmbm_instance *ni, uint64_t addr,
 +                         const void *data, const void *oob,
 +                         enum nmbm_oob_mode mode);
++int nmbm_panic_write_single_page(struct nmbm_instance *ni, uint64_t addr,
++                               const void *data);
 +int nmbm_write_range(struct nmbm_instance *ni, uint64_t addr, size_t size,
 +                   const void *data, enum nmbm_oob_mode mode,
 +                   size_t *retlen);
index a196589efa822bc9a1ec6aedf1ab6d58d772ce4a..fd95cc2a8b02e1ac1da9599a38d7740d4879d3f0 100644 (file)
@@ -7,29 +7,29 @@ Add an env driver for NMBM upper MTD layer
 
 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 ---
- cmd/nvedit.c           |   3 +-
  env/Kconfig            |  19 ++++-
  env/Makefile           |   1 +
  env/env.c              |   3 +
  env/nmbm.c             | 155 +++++++++++++++++++++++++++++++++++++++++
  include/env_internal.h |   1 +
  tools/Makefile         |   1 +
7 files changed, 180 insertions(+), 3 deletions(-)
6 files changed, 178 insertions(+), 2 deletions(-)
  create mode 100644 env/nmbm.c
 
 --- a/env/Kconfig
 +++ b/env/Kconfig
-@@ -59,6 +59,7 @@ config ENV_IS_DEFAULT
-       def_bool y if !ENV_IS_IN_EEPROM && !ENV_IS_IN_EXT4 && \
-                    !ENV_IS_IN_FAT && !ENV_IS_IN_FLASH && \
+@@ -61,7 +61,7 @@ config ENV_IS_DEFAULT
                     !ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \
-+                   !ENV_IS_IN_NMBM && \
                     !ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \
                     !ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \
-                    !ENV_IS_IN_UBI && !ENV_IS_IN_MTD
-@@ -315,6 +316,21 @@ config ENV_RANGE
-         Specifying a range with more erase blocks than are needed to hold
-         CONFIG_ENV_SIZE allows bad blocks within the range to be avoided.
+-                   !ENV_IS_IN_UBI && !ENV_IS_IN_MTD
++                   !ENV_IS_IN_UBI && !ENV_IS_IN_NMBM && !ENV_IS_IN_MTD
+       select ENV_IS_NOWHERE
+ config ENV_IS_NOWHERE
+@@ -305,6 +305,21 @@ config ENV_IS_IN_NAND
+         Currently, CONFIG_ENV_OFFSET_REDUND is not supported when
+         using CONFIG_ENV_OFFSET_OOB.
  
 +config ENV_IS_IN_NMBM
 +      bool "Environment in a NMBM upper MTD layer"
@@ -46,10 +46,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 +        area within the first NAND device.  CONFIG_ENV_OFFSET must be
 +        aligned to an erase block boundary.
 +
- config ENV_IS_IN_NVRAM
-       bool "Environment in a non-volatile RAM"
-       depends on !CHAIN_OF_TRUST
-@@ -591,7 +607,7 @@ config ENV_MTD_NAME
+ config ENV_RANGE
+       hex "Length of the region in which the environment can be written"
+       depends on ENV_IS_IN_NAND
+@@ -591,7 +606,7 @@ config ENV_MTD_NAME
  config ENV_OFFSET
        hex "Environment offset"
        depends on ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
index 47e158b521cecab6562e46a45d8094f435a58539..7daae5c4845849a303b9028f40c5f120074ae674 100644 (file)
@@ -7,48 +7,24 @@ Add ability to use shortkey to select item for bootmenu command
 
 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 ---
- cmd/bootmenu.c | 34 ++++++++++++++++++++++++-----
- common/menu.c  | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--
- include/menu.h | 12 +++++++----
- 3 files changed, 93 insertions(+), 11 deletions(-)
+ cmd/bootmenu.c | 28 +++++++++++++++++++++++---
+ common/menu.c  | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/cli.h  |  2 ++
+ include/menu.h |  3 +++
+ 4 files changed, 84 insertions(+), 3 deletions(-)
 
 --- a/cmd/bootmenu.c
 +++ b/cmd/bootmenu.c
-@@ -88,6 +88,7 @@ static char *bootmenu_choice_entry(void
-       struct bootmenu_data *menu = data;
-       struct bootmenu_entry *iter;
-       enum bootmenu_key key = BKEY_NONE;
-+      int choice = -1;
-       int i;
-       cli_ch_init(cch);
-@@ -95,10 +96,10 @@ static char *bootmenu_choice_entry(void
-       while (1) {
-               if (menu->delay >= 0) {
-                       /* Autoboot was not stopped */
--                      key = bootmenu_autoboot_loop(menu, cch);
-+                      key = bootmenu_autoboot_loop(menu, cch, &choice);
-               } else {
-                       /* Some key was pressed, so autoboot was stopped */
--                      key = bootmenu_loop(menu, cch);
-+                      key = bootmenu_loop(menu, cch, &choice);
-               }
-               switch (key) {
-@@ -114,6 +115,12 @@ static char *bootmenu_choice_entry(void
+@@ -114,6 +114,8 @@ static char *bootmenu_choice_entry(void
                                ++menu->active;
                        /* no menu key selected, regenerate menu */
                        return NULL;
 +              case BKEY_CHOICE:
-+                      menu->active = choice;
-+                      if (!menu->last_choiced) {
-+                              menu->last_choiced = true;
-+                              return NULL;
-+                      }
++                      menu->active = cch->choice;
                case BKEY_SELECT:
                        iter = menu->first;
                        for (i = 0; i < menu->active; ++i)
-@@ -182,6 +189,9 @@ static int prepare_bootmenu_entry(struct
+@@ -182,6 +184,9 @@ static int prepare_bootmenu_entry(struct
        unsigned short int i = *index;
        struct bootmenu_entry *entry = NULL;
        struct bootmenu_entry *iter = *current;
@@ -58,24 +34,28 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
  
        while ((option = bootmenu_getoption(i))) {
  
-@@ -196,11 +206,24 @@ static int prepare_bootmenu_entry(struct
+@@ -196,11 +201,28 @@ static int prepare_bootmenu_entry(struct
                if (!entry)
                        return -ENOMEM;
  
 -              entry->title = strndup(option, sep - option);
-+              /* Add KEY_CHOICE support: '%d. %s\0' : len --> len + 4 */
++              /* Add BKEY_CHOICE support: '%c. %s\0' : len --> len + 4 */
 +              len = sep - option + 4;
++
 +              choice_option = malloc(len);
 +              if (!choice_option) {
 +                      free(entry->title);
 +                      free(entry);
 +                      return -ENOMEM;
 +              }
++
 +              if (!get_choice_char(i, &choice_char))
 +                      len = snprintf(choice_option, len, "%c. %s", choice_char, option);
 +              else
 +                      len = snprintf(choice_option, len, "   %s", option);
++
 +              entry->title = strndup(choice_option, len);
++
                if (!entry->title) {
                        free(entry);
                        return -ENOMEM;
@@ -84,15 +64,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
  
                entry->command = strdup(sep + 1);
                if (!entry->command) {
-@@ -347,6 +370,7 @@ static struct bootmenu_data *bootmenu_cr
-       menu->active = 0;
-       menu->last_active = -1;
-       menu->first = NULL;
-+      menu->last_choiced = false;
-       default_str = env_get("bootmenu_default");
-       if (default_str)
-@@ -382,9 +406,9 @@ static struct bootmenu_data *bootmenu_cr
+@@ -382,9 +404,9 @@ static struct bootmenu_data *bootmenu_cr
  
                /* Add Quit entry if exiting bootmenu is disabled */
                if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
@@ -106,7 +78,15 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
                        free(entry);
 --- a/common/menu.c
 +++ b/common/menu.c
-@@ -49,6 +49,33 @@ struct menu {
+@@ -8,6 +8,7 @@
+ #include <cli.h>
+ #include <malloc.h>
+ #include <errno.h>
++#include <linux/ctype.h>
+ #include <linux/delay.h>
+ #include <linux/list.h>
+ #include <watchdog.h>
+@@ -49,6 +50,33 @@ struct menu {
        int item_cnt;
  };
  
@@ -140,185 +120,87 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
  /*
   * An iterator function for menu items. callback will be called for each item
   * in m, with m, a pointer to the item, and extra being passed to callback. If
-@@ -437,7 +464,7 @@ int menu_destroy(struct menu *m)
- }
- enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
--                                       struct cli_ch_state *cch)
-+                                       struct cli_ch_state *cch, int *choice)
+@@ -441,6 +469,7 @@ enum bootmenu_key bootmenu_autoboot_loop
  {
        enum bootmenu_key key = BKEY_NONE;
        int i, c;
-@@ -472,6 +499,19 @@ enum bootmenu_key bootmenu_autoboot_loop
-                               break;
-                       default:
-                               key = BKEY_NONE;
-+                              if (cch->esc_len || !choice)
-+                                      break;
-+
-+                              *choice = find_choice(c);
-+                              if ((*choice >= 0 &&
-+                                   *choice < menu->count - 1)) {
-+                                      key = BKEY_CHOICE;
-+                              } else if (c == '0') {
-+                                      *choice = menu->count - 1;
-+                                      key = BKEY_CHOICE;
-+                              } else {
-+                                      key = BKEY_NONE;
-+                              }
-                               break;
-                       }
-                       break;
-@@ -492,7 +532,8 @@ enum bootmenu_key bootmenu_autoboot_loop
-       return key;
- }
--enum bootmenu_key bootmenu_conv_key(int ichar)
-+enum bootmenu_key bootmenu_conv_key(struct bootmenu_data *menu, int ichar,
-+                                  int *choice)
- {
-       enum bootmenu_key key;
-@@ -524,6 +565,20 @@ enum bootmenu_key bootmenu_conv_key(int
-       case ' ':
-               key = BKEY_SPACE;
-               break;
-+      case '0' ... '9':
-+      case 'a' ... 'z':
-+              if (choice && menu) {
-+                      *choice = find_choice(ichar);
-+                      if ((*choice >= 0 && *choice < menu->count - 1)) {
++      int choice;
+       while (menu->delay > 0) {
+               if (ansi)
+@@ -458,6 +487,18 @@ enum bootmenu_key bootmenu_autoboot_loop
+                       menu->delay = -1;
+                       c = getchar();
++                      choice = find_choice(c);
++                      if ((choice >= 0 &&
++                           choice < menu->count - 1)) {
++                              cch->choice = choice;
 +                              key = BKEY_CHOICE;
 +                              break;
-+                      } else if (ichar == '0') {
-+                              *choice = menu->count - 1;
++                      } else if (c == '0') {
++                              cch->choice = menu->count - 1;
 +                              key = BKEY_CHOICE;
 +                              break;
 +                      }
-+              }
-+              fallthrough;
-       default:
-               key = BKEY_NONE;
-               break;
-@@ -533,11 +588,17 @@ enum bootmenu_key bootmenu_conv_key(int
- }
++
+                       ichar = cli_ch_process(cch, c);
  
- enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
--                              struct cli_ch_state *cch)
-+                              struct cli_ch_state *cch,
-+                              int *choice)
+                       switch (ichar) {
+@@ -537,6 +578,7 @@ enum bootmenu_key bootmenu_loop(struct b
  {
        enum bootmenu_key key;
        int c, errchar = 0;
++      int choice;
  
-+      if (menu->last_choiced) {
-+              menu->last_choiced = false;
-+              return BKEY_SELECT;
-+      }
-+
        c = cli_ch_process(cch, 0);
        if (!c) {
-               while (!c && !tstc()) {
-@@ -552,7 +613,7 @@ enum bootmenu_key bootmenu_loop(struct b
+@@ -548,6 +590,18 @@ enum bootmenu_key bootmenu_loop(struct b
+               }
+               if (!c) {
+                       c = getchar();
++
++                      choice = find_choice(c);
++                      if ((choice >= 0 &&
++                           choice < menu->count - 1)) {
++                              cch->choice = choice;
++                              return BKEY_CHOICE;
++
++                      } else if (c == '0') {
++                              cch->choice = menu->count - 1;
++                              return BKEY_CHOICE;
++                      }
++
+                       c = cli_ch_process(cch, c);
                }
        }
+--- a/include/cli.h
++++ b/include/cli.h
+@@ -23,6 +23,8 @@ struct cli_ch_state {
+       char esc_save[8];
+       int emit_upto;
+       bool emitting;
++      /* mediatek bootmenu choice feature */
++      char choice;
+ };
  
--      key = bootmenu_conv_key(c);
-+      key = bootmenu_conv_key(menu, c, choice);
-       return key;
- }
+ /**
 --- a/include/menu.h
 +++ b/include/menu.h
-@@ -6,6 +6,8 @@
- #ifndef __MENU_H__
- #define __MENU_H__
-+#include <linux/ctype.h>
-+
- struct cli_ch_state;
- struct menu;
+@@ -37,6 +37,8 @@ int menu_default_choice(struct menu *m,
+  */
+ int menu_show(int bootdelay);
  
-@@ -20,6 +22,8 @@ int menu_get_choice(struct menu *m, void
- int menu_item_add(struct menu *m, char *item_key, void *item_data);
- int menu_destroy(struct menu *m);
- int menu_default_choice(struct menu *m, void **choice);
-+/* Add KEY_CHOICE support */
 +int get_choice_char(int index, char *result);
- /**
-  * menu_show() Show a boot menu
-@@ -43,6 +47,7 @@ struct bootmenu_data {
-       int last_active;                /* last active menu entry */
-       int count;                      /* total count of menu entries */
-       struct bootmenu_entry *first;   /* first menu entry */
-+      bool last_choiced;
- };
- /** enum bootmenu_key - keys that can be returned by the bootmenu */
-@@ -53,6 +58,7 @@ enum bootmenu_key {
++
+ struct bootmenu_data {
+       int delay;                      /* delay for autoboot */
+       int active;                     /* active menu entry */
+@@ -51,6 +53,7 @@ enum bootmenu_key {
+       BKEY_UP,
+       BKEY_DOWN,
        BKEY_SELECT,
++      BKEY_CHOICE,
        BKEY_QUIT,
        BKEY_SAVE,
-+      BKEY_CHOICE,
-       /* 'extra' keys, which are used by menus but not cedit */
-       BKEY_PLUS,
-@@ -83,7 +89,7 @@ enum bootmenu_key {
-  *    anything else: KEY_NONE
-  */
- enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
--                                       struct cli_ch_state *cch);
-+                                       struct cli_ch_state *cch, int *choice);
- /**
-  * bootmenu_loop() - handle waiting for a keypress when autoboot is disabled
-@@ -109,7 +115,7 @@ enum bootmenu_key bootmenu_autoboot_loop
-  *    Space: BKEY_SPACE
-  */
- enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
--                              struct cli_ch_state *cch);
-+                              struct cli_ch_state *cch, int *choice);
- /**
-  * bootmenu_conv_key() - Convert a U-Boot keypress into a menu key
-@@ -117,6 +123,7 @@ enum bootmenu_key bootmenu_loop(struct b
-  * @ichar: Keypress to convert (ASCII, including control characters)
-  * Returns: Menu key that corresponds to @ichar, or BKEY_NONE if none
-  */
--enum bootmenu_key bootmenu_conv_key(int ichar);
-+enum bootmenu_key bootmenu_conv_key(struct bootmenu_data *menu, int ichar,
-+                                  int *choice);
  
- #endif /* __MENU_H__ */
---- a/cmd/eficonfig.c
-+++ b/cmd/eficonfig.c
-@@ -239,7 +239,7 @@ char *eficonfig_choice_entry(void *data)
-       cli_ch_init(cch);
-       while (1) {
--              key = bootmenu_loop((struct bootmenu_data *)efi_menu, cch);
-+              key = bootmenu_loop((struct bootmenu_data *)efi_menu, cch, NULL);
-               switch (key) {
-               case BKEY_UP:
-@@ -1881,7 +1881,7 @@ char *eficonfig_choice_change_boot_order
-       cli_ch_init(cch);
-       while (1) {
--              key = bootmenu_loop(NULL, cch);
-+              key = bootmenu_loop(NULL, cch, NULL);
-               switch (key) {
-               case BKEY_PLUS:
---- a/boot/bootflow_menu.c
-+++ b/boot/bootflow_menu.c
-@@ -240,7 +240,7 @@ int bootflow_menu_run(struct bootstd_pri
-               key = 0;
-               if (ichar) {
--                      key = bootmenu_conv_key(ichar);
-+                      key = bootmenu_conv_key(NULL, ichar, NULL);
-                       if (key == BKEY_NONE)
-                               key = ichar;
-               }
index f373e2a38c27861f51e2b934551f542059bae64b..39b254133eb64373ba6946868161508ff6ccddcd 100644 (file)
@@ -23,17 +23,18 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
  
 --- a/drivers/mtd/spi/spi-nor-ids.c
 +++ b/drivers/mtd/spi/spi-nor-ids.c
-@@ -83,7 +83,8 @@ const struct flash_info spi_nor_ids[] =
+@@ -83,7 +83,9 @@ const struct flash_info spi_nor_ids[] =
        { INFO("en25q32b",   0x1c3016, 0, 64 * 1024,   64, 0) },
        { INFO("en25q64",    0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
        { INFO("en25q128b",  0x1c3018, 0, 64 * 1024,  256, 0) },
 -      { INFO("en25qh128",  0x1c7018, 0, 64 * 1024,  256, 0) },
 +      { INFO("en25qh128",  0x1c7018, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
++      { INFO("en25qx128",  0x1c7118, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 +      { INFO("en25qh256",  0x1c7019, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
        { INFO("en25s64",    0x1c3817, 0, 64 * 1024,  128, SECT_4K) },
  #endif
  #ifdef CONFIG_SPI_FLASH_GIGADEVICE    /* GIGADEVICE */
-@@ -149,6 +150,11 @@ const struct flash_info spi_nor_ids[] =
+@@ -149,6 +151,11 @@ const struct flash_info spi_nor_ids[] =
        {INFO("gd55x02g", 0xc8481C, 0, 64 * 1024, 4096, SECT_4K |
        SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES)},
        {
@@ -45,7 +46,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
                INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256,
                        SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
                        SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-@@ -520,6 +526,16 @@ const struct flash_info spi_nor_ids[] =
+@@ -520,6 +527,16 @@ const struct flash_info spi_nor_ids[] =
                        SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
        },
        {
@@ -62,7 +63,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
                INFO("w25q128jw", 0xef8018, 0, 64 * 1024, 256,
                        SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
                        SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-@@ -583,6 +599,11 @@ const struct flash_info spi_nor_ids[] =
+@@ -583,6 +600,11 @@ const struct flash_info spi_nor_ids[] =
                        SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
        },
        { INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
index afc586ff1c0f631ec08d02d9433f77349bcf5b7c..6eac7e11ad5eed87e59c63e0566ef9b68da43ad5 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
 
 --- a/env/Kconfig
 +++ b/env/Kconfig
-@@ -689,6 +689,12 @@ config ENV_UBI_VOLUME_REDUND
+@@ -688,6 +688,12 @@ config ENV_UBI_VOLUME_REDUND
        help
          Name of the redundant volume that you want to store the environment in.
  
index be06832ea1ea3200ab518c1557a41c577fc17cad..1c1071bafc25ae91022d494e52007954ae04cc7e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/cmd/bootmenu.c
 +++ b/cmd/bootmenu.c
-@@ -465,7 +465,11 @@ static void menu_display_statusline(stru
+@@ -463,7 +463,11 @@ static void menu_display_statusline(stru
        printf(ANSI_CURSOR_POSITION, 1, 1);
        puts(ANSI_CLEAR_LINE);
        printf(ANSI_CURSOR_POSITION, 2, 3);
@@ -13,7 +13,7 @@
        puts(ANSI_CLEAR_LINE_TO_END);
        printf(ANSI_CURSOR_POSITION, 3, 1);
        puts(ANSI_CLEAR_LINE);
-@@ -550,6 +554,7 @@ static enum bootmenu_ret bootmenu_show(i
+@@ -548,6 +552,7 @@ static enum bootmenu_ret bootmenu_show(i
                return BOOTMENU_RET_FAIL;
        }
  
                        goto cleanup;
 --- a/include/menu.h
 +++ b/include/menu.h
-@@ -47,6 +47,7 @@ struct bootmenu_data {
+@@ -45,6 +45,7 @@ struct bootmenu_data {
        int last_active;                /* last active menu entry */
        int count;                      /* total count of menu entries */
        struct bootmenu_entry *first;   /* first menu entry */
 +      char *mtitle;                   /* custom menu title */
-       bool last_choiced;
  };
  
+ /** enum bootmenu_key - keys that can be returned by the bootmenu */