uboot-mediatek: sync mtk-openwrt open source u-boot patches

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>
This commit is contained in:
Shiji Yang 2025-01-11 21:09:20 +08:00 committed by Daniel Golle
parent 24ade65ab5
commit 2266d8c077
6 changed files with 248 additions and 256 deletions

View File

@ -13,13 +13,13 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/mtd/Makefile | 1 + drivers/mtd/Makefile | 1 +
drivers/mtd/nmbm/Kconfig | 29 + drivers/mtd/nmbm/Kconfig | 29 +
drivers/mtd/nmbm/Makefile | 5 + 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.h | 37 +
drivers/mtd/nmbm/nmbm-debug.inl | 39 + drivers/mtd/nmbm/nmbm-debug.inl | 39 +
drivers/mtd/nmbm/nmbm-private.h | 137 ++ drivers/mtd/nmbm/nmbm-private.h | 137 ++
include/nmbm/nmbm-os.h | 66 + include/nmbm/nmbm-os.h | 68 +
include/nmbm/nmbm.h | 102 ++ include/nmbm/nmbm.h | 105 ++
10 files changed, 3354 insertions(+) 10 files changed, 3463 insertions(+)
create mode 100644 drivers/mtd/nmbm/Kconfig create mode 100644 drivers/mtd/nmbm/Kconfig
create mode 100644 drivers/mtd/nmbm/Makefile create mode 100644 drivers/mtd/nmbm/Makefile
create mode 100644 drivers/mtd/nmbm/nmbm-core.c 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 --- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig
@@ -282,6 +282,8 @@ source "drivers/mtd/ubi/Kconfig" @@ -276,6 +276,8 @@ config SYS_NAND_MAX_CHIPS
help
source "drivers/mtd/nvmxip/Kconfig" The maximum number of NAND chips per device to be supported.
+source "drivers/mtd/nmbm/Kconfig" +source "drivers/mtd/nmbm/Kconfig"
+ +
endif source "drivers/mtd/spi/Kconfig"
endmenu source "drivers/mtd/ubi/Kconfig"
--- a/drivers/mtd/Makefile --- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_SPL_UBI) += ubispl/ @@ -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 +obj-$(CONFIG_NMBM) += nmbm-core.o
--- /dev/null --- /dev/null
+++ b/drivers/mtd/nmbm/nmbm-core.c +++ 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 +// 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> + * 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 + * nmbm_erase_phys_block - Erase a block with retry
+ * @ni: NMBM instance structure + * @ni: NMBM instance structure
+ * @addr: Linear address + * @addr: Linear address
@ -752,7 +783,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ addr = ba2addr(ni, ba); + addr = ba2addr(ni, ba);
+ +
+ for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) { + 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, + ret = nmbm_read_phys_page(ni, addr + off, ni->page_cache, NULL,
+ NMBM_MODE_PLACE_OOB); + NMBM_MODE_PLACE_OOB);
@ -791,7 +822,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ bool success; + bool success;
+ +
+ while (ba < limit) { + while (ba < limit) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) + if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+ goto next_block; + goto next_block;
@ -842,7 +873,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ addr = ba2addr(ni, ba); + addr = ba2addr(ni, ba);
+ +
+ for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) { + for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ /* Prepare page data. fill 0xff to unused region */ + /* Prepare page data. fill 0xff to unused region */
+ memcpy(ni->page_cache, data, size); + memcpy(ni->page_cache, data, size);
@ -886,7 +917,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ bool success; + bool success;
+ +
+ while (ba > limit) { + while (ba > limit) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) + if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+ goto next_block; + goto next_block;
@ -941,7 +972,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ int ret; + int ret;
+ +
+ while (sizeremain) { + while (sizeremain) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ leading = off & ni->writesize_mask; + leading = off & ni->writesize_mask;
+ chunksize = ni->lower.writesize - leading; + chunksize = ni->lower.writesize - leading;
@ -991,7 +1022,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ int ret; + int ret;
+ +
+ while (sizeremain) { + while (sizeremain) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ leading = off & ni->writesize_mask; + leading = off & ni->writesize_mask;
+ chunksize = ni->lower.writesize - leading; + chunksize = ni->lower.writesize - leading;
@ -1047,7 +1078,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ bool success; + bool success;
+ +
+ while (sizeremain && ba < limit) { + while (sizeremain && ba < limit) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ chunksize = sizeremain; + chunksize = sizeremain;
+ if (chunksize > ni->lower.erasesize) + 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 */ + /* Try to write new info table next to the existing table */
+ while (write_ba >= ni->mapping_blocks_ba) { + while (write_ba >= ni->mapping_blocks_ba) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ success = nmbm_write_info_table(ni, write_ba, + success = nmbm_write_info_table(ni, write_ba,
+ ni->mapping_blocks_top_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 */ + /* Try to write temporary info table into spare unmapped blocks */
+ while (write_ba >= ni->mapping_blocks_ba) { + while (write_ba >= ni->mapping_blocks_ba) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ success = nmbm_write_info_table(ni, write_ba, + success = nmbm_write_info_table(ni, write_ba,
+ ni->mapping_blocks_top_ba, + ni->mapping_blocks_top_ba,
@ -1514,7 +1545,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ +
+ /* Write new backup info table. */ + /* Write new backup info table. */
+ while (write_ba >= main_table_end_ba) { + while (write_ba >= main_table_end_ba) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ success = nmbm_write_info_table(ni, write_ba, + success = nmbm_write_info_table(ni, write_ba,
+ ni->mapping_blocks_top_ba, + ni->mapping_blocks_top_ba,
@ -1903,7 +1934,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ int ret; + int ret;
+ +
+ while (sizeremain && ba < limit) { + while (sizeremain && ba < limit) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) + if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+ goto next_block; + goto next_block;
@ -1996,7 +2027,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ bool success; + bool success;
+ +
+ while (ba < limit - size2blk(ni, ni->info_table_size)) { + while (ba < limit - size2blk(ni, ni->info_table_size)) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ success = nmbm_try_load_info_table(ni, ba, table_end_ba, + success = nmbm_try_load_info_table(ni, ba, table_end_ba,
+ write_count, + write_count,
@ -2208,7 +2239,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ limit = block_count - ni->lower.max_reserved_blocks; + limit = block_count - ni->lower.max_reserved_blocks;
+ +
+ while (ba >= limit) { + while (ba >= limit) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ ba--; + ba--;
+ addr = ba2addr(ni, 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; + for (off = 0; off < ni->lower.erasesize;
+ off += ni->lower.writesize) { + off += ni->lower.writesize) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ ret = nmbn_read_data(ni, addr + off, &sig, + ret = nmbn_read_data(ni, addr + off, &sig,
+ sizeof(sig)); + sizeof(sig));
@ -2281,7 +2312,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ return false; + return false;
+ } + }
+ +
+ if (!nld->oobsize || !is_power_of_2(nld->oobsize)) { + if (!nld->oobsize) {
+ nmbm_log_lower(nld, NMBM_LOG_ERR, + nmbm_log_lower(nld, NMBM_LOG_ERR,
+ "Page spare size %u is not valid\n", nld->oobsize); + "Page spare size %u is not valid\n", nld->oobsize);
+ return false; + return false;
@ -2594,7 +2625,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ end_ba = addr2ba(ni, addr + size - 1); + end_ba = addr2ba(ni, addr + size - 1);
+ +
+ while (start_ba <= end_ba) { + while (start_ba <= end_ba) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ ret = nmbm_erase_logic_block(ni, start_ba); + ret = nmbm_erase_logic_block(ni, start_ba);
+ if (ret) { + if (ret) {
@ -2726,7 +2757,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ } + }
+ +
+ while (sizeremain) { + while (sizeremain) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ leading = off & ni->writesize_mask; + leading = off & ni->writesize_mask;
+ chunksize = ni->lower.writesize - leading; + 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 + * nmbm_write_single_page - Write one page based on logic address
+ * @ni: NMBM instance structure + * @ni: NMBM instance structure
+ * @addr: logic linear address + * @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 + * nmbm_write_range - Write data without oob
+ * @ni: NMBM instance structure + * @ni: NMBM instance structure
+ * @addr: logic linear address + * @addr: logic linear address
@ -2893,7 +2997,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ } + }
+ +
+ while (sizeremain) { + while (sizeremain) {
+ schedule(); + WATCHDOG_RESET();
+ +
+ leading = off & ni->writesize_mask; + leading = off & ni->writesize_mask;
+ chunksize = ni->lower.writesize - leading; + chunksize = ni->lower.writesize - leading;
@ -3250,7 +3354,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#endif /* _NMBM_PRIVATE_H_ */ +#endif /* _NMBM_PRIVATE_H_ */
--- /dev/null --- /dev/null
+++ b/include/nmbm/nmbm-os.h +++ b/include/nmbm/nmbm-os.h
@@ -0,0 +1,66 @@ @@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 */
+/* +/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * 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 <div64.h>
+#include <stdbool.h> +#include <stdbool.h>
+#include <watchdog.h> +#include <cyclic.h>
+#include <u-boot/crc.h> +#include <u-boot/crc.h>
+#include <linux/errno.h> +#include <linux/errno.h>
+#include <linux/log2.h> +#include <linux/log2.h>
@ -3316,10 +3420,12 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#define NMBM_DEFAULT_LOG_LEVEL 1 +#define NMBM_DEFAULT_LOG_LEVEL 1
+#endif +#endif
+ +
+#define WATCHDOG_RESET schedule
+
+#endif /* _NMBM_OS_H_ */ +#endif /* _NMBM_OS_H_ */
--- /dev/null --- /dev/null
+++ b/include/nmbm/nmbm.h +++ b/include/nmbm/nmbm.h
@@ -0,0 +1,102 @@ @@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* +/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * 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 (*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 (*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 (*erase_block)(void *arg, uint64_t addr);
+ +
+ int (*is_bad_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, +int nmbm_write_single_page(struct nmbm_instance *ni, uint64_t addr,
+ const void *data, const void *oob, + const void *data, const void *oob,
+ enum nmbm_oob_mode mode); + 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, +int nmbm_write_range(struct nmbm_instance *ni, uint64_t addr, size_t size,
+ const void *data, enum nmbm_oob_mode mode, + const void *data, enum nmbm_oob_mode mode,
+ size_t *retlen); + size_t *retlen);

View File

@ -7,29 +7,29 @@ Add an env driver for NMBM upper MTD layer
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- ---
cmd/nvedit.c | 3 +-
env/Kconfig | 19 ++++- env/Kconfig | 19 ++++-
env/Makefile | 1 + env/Makefile | 1 +
env/env.c | 3 + env/env.c | 3 +
env/nmbm.c | 155 +++++++++++++++++++++++++++++++++++++++++ env/nmbm.c | 155 +++++++++++++++++++++++++++++++++++++++++
include/env_internal.h | 1 + include/env_internal.h | 1 +
tools/Makefile | 1 + tools/Makefile | 1 +
7 files changed, 180 insertions(+), 3 deletions(-) 6 files changed, 178 insertions(+), 2 deletions(-)
create mode 100644 env/nmbm.c create mode 100644 env/nmbm.c
--- a/env/Kconfig --- a/env/Kconfig
+++ b/env/Kconfig +++ b/env/Kconfig
@@ -59,6 +59,7 @@ config ENV_IS_DEFAULT @@ -61,7 +61,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 && \
!ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \ !ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \
+ !ENV_IS_IN_NMBM && \
!ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \ !ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \
!ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \ !ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \
!ENV_IS_IN_UBI && !ENV_IS_IN_MTD - !ENV_IS_IN_UBI && !ENV_IS_IN_MTD
@@ -315,6 +316,21 @@ config ENV_RANGE + !ENV_IS_IN_UBI && !ENV_IS_IN_NMBM && !ENV_IS_IN_MTD
Specifying a range with more erase blocks than are needed to hold select ENV_IS_NOWHERE
CONFIG_ENV_SIZE allows bad blocks within the range to be avoided.
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 +config ENV_IS_IN_NMBM
+ bool "Environment in a NMBM upper MTD layer" + 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 + area within the first NAND device. CONFIG_ENV_OFFSET must be
+ aligned to an erase block boundary. + aligned to an erase block boundary.
+ +
config ENV_IS_IN_NVRAM config ENV_RANGE
bool "Environment in a non-volatile RAM" hex "Length of the region in which the environment can be written"
depends on !CHAIN_OF_TRUST depends on ENV_IS_IN_NAND
@@ -591,7 +607,7 @@ config ENV_MTD_NAME @@ -591,7 +606,7 @@ config ENV_MTD_NAME
config ENV_OFFSET config ENV_OFFSET
hex "Environment offset" hex "Environment offset"
depends on ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \ depends on ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \

View 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> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- ---
cmd/bootmenu.c | 34 ++++++++++++++++++++++++----- cmd/bootmenu.c | 28 +++++++++++++++++++++++---
common/menu.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-- common/menu.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/menu.h | 12 +++++++---- include/cli.h | 2 ++
3 files changed, 93 insertions(+), 11 deletions(-) include/menu.h | 3 +++
4 files changed, 84 insertions(+), 3 deletions(-)
--- a/cmd/bootmenu.c --- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c +++ b/cmd/bootmenu.c
@@ -88,6 +88,7 @@ static char *bootmenu_choice_entry(void @@ -114,6 +114,8 @@ 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
++menu->active; ++menu->active;
/* no menu key selected, regenerate menu */ /* no menu key selected, regenerate menu */
return NULL; return NULL;
+ case BKEY_CHOICE: + case BKEY_CHOICE:
+ menu->active = choice; + menu->active = cch->choice;
+ if (!menu->last_choiced) {
+ menu->last_choiced = true;
+ return NULL;
+ }
case BKEY_SELECT: case BKEY_SELECT:
iter = menu->first; iter = menu->first;
for (i = 0; i < menu->active; ++i) 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; unsigned short int i = *index;
struct bootmenu_entry *entry = NULL; struct bootmenu_entry *entry = NULL;
struct bootmenu_entry *iter = *current; struct bootmenu_entry *iter = *current;
@ -58,24 +34,28 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
while ((option = bootmenu_getoption(i))) { 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) if (!entry)
return -ENOMEM; return -ENOMEM;
- entry->title = strndup(option, sep - option); - 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; + len = sep - option + 4;
+
+ choice_option = malloc(len); + choice_option = malloc(len);
+ if (!choice_option) { + if (!choice_option) {
+ free(entry->title); + free(entry->title);
+ free(entry); + free(entry);
+ return -ENOMEM; + return -ENOMEM;
+ } + }
+
+ if (!get_choice_char(i, &choice_char)) + if (!get_choice_char(i, &choice_char))
+ len = snprintf(choice_option, len, "%c. %s", choice_char, option); + len = snprintf(choice_option, len, "%c. %s", choice_char, option);
+ else + else
+ len = snprintf(choice_option, len, " %s", option); + len = snprintf(choice_option, len, " %s", option);
+
+ entry->title = strndup(choice_option, len); + entry->title = strndup(choice_option, len);
+
if (!entry->title) { if (!entry->title) {
free(entry); free(entry);
return -ENOMEM; return -ENOMEM;
@ -84,15 +64,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
entry->command = strdup(sep + 1); entry->command = strdup(sep + 1);
if (!entry->command) { if (!entry->command) {
@@ -347,6 +370,7 @@ static struct bootmenu_data *bootmenu_cr @@ -382,9 +404,9 @@ 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
/* Add Quit entry if exiting bootmenu is disabled */ /* Add Quit entry if exiting bootmenu is disabled */
if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE)) if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
@ -106,7 +78,15 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
free(entry); free(entry);
--- a/common/menu.c --- a/common/menu.c
+++ b/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; 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 * 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 * 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) @@ -441,6 +469,7 @@ enum bootmenu_key bootmenu_autoboot_loop
}
enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
- struct cli_ch_state *cch)
+ struct cli_ch_state *cch, int *choice)
{ {
enum bootmenu_key key = BKEY_NONE; enum bootmenu_key key = BKEY_NONE;
int i, c; int i, c;
@@ -472,6 +499,19 @@ enum bootmenu_key bootmenu_autoboot_loop + int choice;
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) while (menu->delay > 0) {
+enum bootmenu_key bootmenu_conv_key(struct bootmenu_data *menu, int ichar, if (ansi)
+ int *choice) @@ -458,6 +487,18 @@ enum bootmenu_key bootmenu_autoboot_loop
{ menu->delay = -1;
enum bootmenu_key key; c = getchar();
@@ -524,6 +565,20 @@ enum bootmenu_key bootmenu_conv_key(int + choice = find_choice(c);
case ' ': + if ((choice >= 0 &&
key = BKEY_SPACE; + choice < menu->count - 1)) {
break; + cch->choice = choice;
+ case '0' ... '9':
+ case 'a' ... 'z':
+ if (choice && menu) {
+ *choice = find_choice(ichar);
+ if ((*choice >= 0 && *choice < menu->count - 1)) {
+ key = BKEY_CHOICE; + key = BKEY_CHOICE;
+ break; + break;
+ } else if (ichar == '0') { + } else if (c == '0') {
+ *choice = menu->count - 1; + cch->choice = menu->count - 1;
+ key = BKEY_CHOICE; + key = BKEY_CHOICE;
+ break; + break;
+ } + }
+ } +
+ fallthrough; ichar = cli_ch_process(cch, c);
default:
key = BKEY_NONE;
break;
@@ -533,11 +588,17 @@ enum bootmenu_key bootmenu_conv_key(int
}
enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, switch (ichar) {
- struct cli_ch_state *cch) @@ -537,6 +578,7 @@ enum bootmenu_key bootmenu_loop(struct b
+ struct cli_ch_state *cch,
+ int *choice)
{ {
enum bootmenu_key key; enum bootmenu_key key;
int c, errchar = 0; int c, errchar = 0;
+ int choice;
+ if (menu->last_choiced) {
+ menu->last_choiced = false;
+ return BKEY_SELECT;
+ }
+
c = cli_ch_process(cch, 0); c = cli_ch_process(cch, 0);
if (!c) { if (!c) {
while (!c && !tstc()) { @@ -548,6 +590,18 @@ enum bootmenu_key bootmenu_loop(struct b
@@ -552,7 +613,7 @@ 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
- key = bootmenu_conv_key(c); +++ b/include/cli.h
+ key = bootmenu_conv_key(menu, c, choice); @@ -23,6 +23,8 @@ struct cli_ch_state {
char esc_save[8];
return key; int emit_upto;
} bool emitting;
--- a/include/menu.h + /* mediatek bootmenu choice feature */
+++ b/include/menu.h + char choice;
@@ -6,6 +6,8 @@
#ifndef __MENU_H__
#define __MENU_H__
+#include <linux/ctype.h>
+
struct cli_ch_state;
struct menu;
@@ -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 { --- a/include/menu.h
+++ b/include/menu.h
@@ -37,6 +37,8 @@ int menu_default_choice(struct menu *m,
*/
int menu_show(int bootdelay);
+int get_choice_char(int index, char *result);
+
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_SELECT,
+ BKEY_CHOICE,
BKEY_QUIT, BKEY_QUIT,
BKEY_SAVE, 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;
}

View File

@ -23,17 +23,18 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/drivers/mtd/spi/spi-nor-ids.c --- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/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("en25q32b", 0x1c3016, 0, 64 * 1024, 64, 0) },
{ INFO("en25q64", 0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, { INFO("en25q64", 0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("en25q128b", 0x1c3018, 0, 64 * 1024, 256, 0) }, { INFO("en25q128b", 0x1c3018, 0, 64 * 1024, 256, 0) },
- { INFO("en25qh128", 0x1c7018, 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("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("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) }, { INFO("en25s64", 0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
#endif #endif
#ifdef CONFIG_SPI_FLASH_GIGADEVICE /* GIGADEVICE */ #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 | {INFO("gd55x02g", 0xc8481C, 0, 64 * 1024, 4096, SECT_4K |
SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES)}, 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, INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) 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) 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, INFO("w25q128jw", 0xef8018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) 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) 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) }, { INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },

View File

@ -14,7 +14,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/env/Kconfig --- a/env/Kconfig
+++ b/env/Kconfig +++ b/env/Kconfig
@@ -689,6 +689,12 @@ config ENV_UBI_VOLUME_REDUND @@ -688,6 +688,12 @@ config ENV_UBI_VOLUME_REDUND
help help
Name of the redundant volume that you want to store the environment in. Name of the redundant volume that you want to store the environment in.

View File

@ -1,6 +1,6 @@
--- a/cmd/bootmenu.c --- a/cmd/bootmenu.c
+++ b/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); printf(ANSI_CURSOR_POSITION, 1, 1);
puts(ANSI_CLEAR_LINE); puts(ANSI_CLEAR_LINE);
printf(ANSI_CURSOR_POSITION, 2, 3); printf(ANSI_CURSOR_POSITION, 2, 3);
@ -13,7 +13,7 @@
puts(ANSI_CLEAR_LINE_TO_END); puts(ANSI_CLEAR_LINE_TO_END);
printf(ANSI_CURSOR_POSITION, 3, 1); printf(ANSI_CURSOR_POSITION, 3, 1);
puts(ANSI_CLEAR_LINE); 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; return BOOTMENU_RET_FAIL;
} }
@ -23,11 +23,11 @@
goto cleanup; goto cleanup;
--- a/include/menu.h --- a/include/menu.h
+++ b/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 last_active; /* last active menu entry */
int count; /* total count of menu entries */ int count; /* total count of menu entries */
struct bootmenu_entry *first; /* first menu entry */ struct bootmenu_entry *first; /* first menu entry */
+ char *mtitle; /* custom menu title */ + char *mtitle; /* custom menu title */
bool last_choiced;
}; };
/** enum bootmenu_key - keys that can be returned by the bootmenu */