1 From 240d98e6ad0aed3c11236aa40a60bbd6fe01fae5 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Mon, 25 Jul 2022 10:50:46 +0800
4 Subject: [PATCH 45/71] env: add support for NMBM upper MTD layer
6 Add an env driver for NMBM upper MTD layer
8 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
11 env/Kconfig | 19 ++++-
14 env/nmbm.c | 155 +++++++++++++++++++++++++++++++++++++++++
15 include/env_internal.h | 1 +
17 7 files changed, 180 insertions(+), 3 deletions(-)
18 create mode 100644 env/nmbm.c
22 @@ -50,6 +50,7 @@ DECLARE_GLOBAL_DATA_PTR;
23 defined(CONFIG_ENV_IS_IN_EXT4) || \
24 defined(CONFIG_ENV_IS_IN_MTD) || \
25 defined(CONFIG_ENV_IS_IN_NAND) || \
26 + defined(CONFIG_ENV_IS_IN_NMBM) || \
27 defined(CONFIG_ENV_IS_IN_NVRAM) || \
28 defined(CONFIG_ENV_IS_IN_ONENAND) || \
29 defined(CONFIG_ENV_IS_IN_SPI_FLASH) || \
30 @@ -63,7 +64,7 @@ DECLARE_GLOBAL_DATA_PTR;
31 #if !defined(ENV_IS_IN_DEVICE) && \
32 !defined(CONFIG_ENV_IS_NOWHERE)
33 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|MTD|\
34 -NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
35 +NAND|NMBM|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
41 @@ -62,7 +62,7 @@ config ENV_IS_NOWHERE
42 !ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \
43 !ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \
44 !ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \
45 - !ENV_IS_IN_UBI && !ENV_IS_IN_MTD
46 + !ENV_IS_IN_UBI && !ENV_IS_IN_NMBM && !ENV_IS_IN_MTD
48 Define this if you don't want to or can't have an environment stored
49 on a storage medium. In this case the environment will still exist
50 @@ -312,6 +312,21 @@ config ENV_RANGE
51 Specifying a range with more erase blocks than are needed to hold
52 CONFIG_ENV_SIZE allows bad blocks within the range to be avoided.
54 +config ENV_IS_IN_NMBM
55 + bool "Environment in a NMBM upper MTD layer"
56 + depends on !CHAIN_OF_TRUST
59 + Define this if you have a NMBM upper MTD which you want to use for
62 + - CONFIG_ENV_OFFSET:
65 + These two #defines specify the offset and size of the environment
66 + area within the first NAND device. CONFIG_ENV_OFFSET must be
67 + aligned to an erase block boundary.
69 config ENV_IS_IN_NVRAM
70 bool "Environment in a non-volatile RAM"
71 depends on !CHAIN_OF_TRUST
72 @@ -588,7 +603,7 @@ config ENV_MTD_NAME
74 hex "Environment offset"
75 depends on ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
76 - ENV_IS_IN_SPI_FLASH || ENV_IS_IN_MTD
77 + ENV_IS_IN_SPI_FLASH || ENV_IS_IN_NMBM || ENV_IS_IN_MTD
78 default 0x3f8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
79 default 0x140000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
80 default 0xF0000 if ARCH_SUNXI
83 @@ -26,6 +26,7 @@ obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_FAT) +
84 obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_EXT4) += ext4.o
85 obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_MTD) += mtd.o
86 obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_NAND) += nand.o
87 +obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_NMBM) += nmbm.o
88 obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_SPI_FLASH) += sf.o
89 obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_FLASH) += flash.o
93 @@ -75,6 +75,9 @@ static enum env_location env_locations[]
94 #ifdef CONFIG_ENV_IS_IN_NAND
97 +#ifdef CONFIG_ENV_IS_IN_NMBM
100 #ifdef CONFIG_ENV_IS_IN_NVRAM
106 +/* SPDX-License-Identifier: GPL-2.0 */
108 + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
110 + * Author: Weijie Gao <weijie.gao@mediatek.com>
113 +#include <command.h>
115 +#include <env_internal.h>
117 +#include <linux/kernel.h>
118 +#include <linux/stddef.h>
119 +#include <linux/types.h>
121 +#include <memalign.h>
124 +#include <nmbm/nmbm-mtd.h>
126 +#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_NMBM_MTD)
130 +#if defined(ENV_IS_EMBEDDED)
131 +env_t *env_ptr = &environment;
132 +#else /* ! ENV_IS_EMBEDDED */
134 +#endif /* ENV_IS_EMBEDDED */
136 +DECLARE_GLOBAL_DATA_PTR;
138 +static int env_nmbm_init(void)
140 +#if defined(ENV_IS_EMBEDDED)
141 + int crc1_ok = 0, crc2_ok = 0;
144 + tmp_env1 = env_ptr;
145 + crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
147 + if (!crc1_ok && !crc2_ok) {
149 + gd->env_valid = ENV_INVALID;
152 + } else if (crc1_ok && !crc2_ok) {
153 + gd->env_valid = ENV_VALID;
156 + if (gd->env_valid == ENV_VALID)
157 + env_ptr = tmp_env1;
159 + gd->env_addr = (ulong)env_ptr->data;
161 +#else /* ENV_IS_EMBEDDED */
162 + gd->env_addr = (ulong)&default_environment[0];
163 + gd->env_valid = ENV_VALID;
164 +#endif /* ENV_IS_EMBEDDED */
170 +static int env_nmbm_save(void)
172 + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
173 + struct mtd_info *mtd;
174 + struct erase_info ei;
177 + ret = env_export(env_new);
181 + mtd = nmbm_mtd_get_upper_by_index(0);
185 + printf("Erasing on NMBM...\n");
186 + memset(&ei, 0, sizeof(ei));
189 + ei.addr = CONFIG_ENV_OFFSET;
190 + ei.len = CONFIG_ENV_SIZE;
192 + if (mtd_erase(mtd, &ei))
195 + printf("Writing on NMBM... ");
196 + ret = mtd_write(mtd, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, NULL,
197 + (u_char *)env_new);
198 + puts(ret ? "FAILED!\n" : "OK\n");
202 +#endif /* CMD_SAVEENV */
204 +static int readenv(size_t offset, u_char *buf)
206 + struct mtd_info *mtd;
207 + struct mtd_oob_ops ops;
209 + size_t len = CONFIG_ENV_SIZE;
211 + mtd = nmbm_mtd_get_upper_by_index(0);
215 + ops.mode = MTD_OPS_AUTO_OOB;
219 + ops.len = min(len, (size_t)mtd->writesize);
222 + ret = mtd_read_oob(mtd, offset, &ops);
226 + buf += mtd->writesize;
227 + len -= mtd->writesize;
228 + offset += mtd->writesize;
234 +static int env_nmbm_load(void)
236 +#if !defined(ENV_IS_EMBEDDED)
237 + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
240 + ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
242 + env_set_default("readenv() failed", 0);
246 + return env_import(buf, 1, H_EXTERNAL);
247 +#endif /* ! ENV_IS_EMBEDDED */
252 +U_BOOT_ENV_LOCATION(nmbm) = {
253 + .location = ENVL_NMBM,
255 + .load = env_nmbm_load,
256 +#if defined(CMD_SAVEENV)
257 + .save = env_save_ptr(env_nmbm_save),
259 + .init = env_nmbm_init,
261 --- a/include/env_internal.h
262 +++ b/include/env_internal.h
263 @@ -111,6 +111,7 @@ enum env_location {
273 @@ -39,6 +39,7 @@ ENVCRC-$(CONFIG_ENV_IS_IN_FLASH) = y
274 ENVCRC-$(CONFIG_ENV_IS_IN_ONENAND) = y
275 ENVCRC-$(CONFIG_ENV_IS_IN_MTD) = y
276 ENVCRC-$(CONFIG_ENV_IS_IN_NAND) = y
277 +ENVCRC-$(CONFIG_ENV_IS_IN_NMBM) = y
278 ENVCRC-$(CONFIG_ENV_IS_IN_NVRAM) = y
279 ENVCRC-$(CONFIG_ENV_IS_IN_SPI_FLASH) = y
280 BUILD_ENVCRC ?= $(ENVCRC-y)