[U-Boot] [PATCH v10 24/27] env: add spi-nor environment

Jagan Teki jagan at amarulasolutions.com
Thu Dec 28 06:12:30 UTC 2017


Now spi-nor framework is up so access the environment
through en/spinor.c

Signed-off-by: Suneel Garapati <suneelglinux at gmail.com>
Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
---
 cmd/nvedit.c          |   1 +
 env/Kconfig           |  27 ++++++++++++
 env/Makefile          |   1 +
 env/env.c             |   2 +
 env/spinor.c          | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/environment.h |   1 +
 6 files changed, 145 insertions(+)
 create mode 100644 env/spinor.c

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 4e79d03..2e5e88d 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -50,6 +50,7 @@ DECLARE_GLOBAL_DATA_PTR;
 	!defined(CONFIG_ENV_IS_IN_ONENAND)	&& \
 	!defined(CONFIG_ENV_IS_IN_SATA)		&& \
 	!defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \
+	!defined(CONFIG_ENV_IS_IN_SPI_NOR)	&& \
 	!defined(CONFIG_ENV_IS_IN_REMOTE)	&& \
 	!defined(CONFIG_ENV_IS_IN_UBI)		&& \
 	!defined(CONFIG_ENV_IS_NOWHERE)
diff --git a/env/Kconfig b/env/Kconfig
index 2477bf8..1b694d5 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -329,6 +329,22 @@ config ENV_IS_IN_SPI_FLASH
 
 	  Define the SPI work mode. If not defined then use SPI_MODE_3.
 
+config ENV_IS_IN_SPI_NOR
+	bool "Environment is in SPI-NOR flash"
+	depends on !CHAIN_OF_TRUST
+	help
+	  Define this if you have a SPI NOR Flash memory device which you
+	  want to use for the environment.
+
+	  - CONFIG_ENV_OFFSET:
+	  - CONFIG_ENV_SIZE:
+
+	  These two #defines specify the offset and size of the
+	  environment area within the SPI NOR Flash. CONFIG_ENV_OFFSET must be
+	  aligned to an erase sector boundary.
+
+	  - CONFIG_ENV_SECT_SIZE:
+
 config ENV_IS_IN_UBI
 	bool "Environment in a UBI volume"
 	depends on !CHAIN_OF_TRUST
@@ -396,6 +412,17 @@ config ENV_FAT_FILE
 	  It's a string of the FAT file name. This file use to store the
 	  environment.
 
+config ENV_SPI_NOR_DEVNUM
+	int "SPI-NOR device number for the environment"
+	depends on ENV_IS_IN_SPI_NOR
+	default 0
+	help
+	  Define this an integer of spi nor device number for the environment.
+	  Since spi nor framework assign device numbers automatically by devicetree
+	  node definition which start from 0, so assign 0 as default.
+
+	  If board need different devnum then, this can be change.
+
 if ARCH_SUNXI
 
 config ENV_OFFSET
diff --git a/env/Makefile b/env/Makefile
index 7ce8231..21fe9a4 100644
--- a/env/Makefile
+++ b/env/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_ENV_IS_IN_NVRAM) += nvram.o
 obj-$(CONFIG_ENV_IS_IN_ONENAND) += onenand.o
 obj-$(CONFIG_ENV_IS_IN_SATA) += sata.o
 obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += sf.o
+obj-$(CONFIG_ENV_IS_IN_SPI_NOR) += spinor.o
 obj-$(CONFIG_ENV_IS_IN_REMOTE) += remote.o
 obj-$(CONFIG_ENV_IS_IN_UBI) += ubi.o
 obj-$(CONFIG_ENV_IS_NOWHERE) += nowhere.o
diff --git a/env/env.c b/env/env.c
index 76a5608..be1672c 100644
--- a/env/env.c
+++ b/env/env.c
@@ -44,6 +44,8 @@ static enum env_location env_get_default_location(void)
 		return ENVL_REMOTE;
 	else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)
 		return ENVL_SPI_FLASH;
+	else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_NOR)
+		return ENVL_SPI_NOR;
 	else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI)
 		return ENVL_UBI;
 	else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
diff --git a/env/spinor.c b/env/spinor.c
new file mode 100644
index 0000000..bc6fdfa
--- /dev/null
+++ b/env/spinor.c
@@ -0,0 +1,113 @@
+/*
+ * SPI-NOR Environment.
+ *
+ * Copyright (C) 2017 Jagan Teki <jagan at openedev.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <environment.h>
+#include <memalign.h>
+#include <mtd.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/spi-nor.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct spi_nor *env_init_spinor(void)
+{
+	struct spi_nor *nor;
+	int devnum = CONFIG_ENV_SPI_NOR_DEVNUM;
+
+	nor = find_spi_nor_device(devnum);
+	if (!nor)
+		return NULL;
+
+	if (spi_nor_scan(nor))
+		return NULL;
+
+	return nor;
+}
+
+static int env_spinor_save(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+	struct spi_nor *nor;
+	struct mtd_info *mtd;
+	struct erase_info instr;
+	loff_t len, sector;
+	int ret;
+
+	nor = env_init_spinor();
+	if (!nor)
+		return -EIO;
+
+	ret = env_export(env_new);
+	if (ret)
+		return -EINVAL;
+
+	mtd = spi_nor_get_mtd_info(nor);
+	if (!mtd)
+		return -EIO;
+
+	sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE);
+	len = sector * CONFIG_ENV_SECT_SIZE;
+	instr.mtd = mtd;
+        instr.addr = CONFIG_ENV_OFFSET;
+        instr.len = len;
+        instr.callback = 0;
+
+	puts("erasing spinor flash...\n");
+        ret = mtd_derase(mtd, &instr);
+	if (ret)
+		return -EIO;
+
+	len = CONFIG_ENV_SIZE;
+	puts("writing spinor flash...\n");
+	ret = mtd_dwrite(mtd, CONFIG_ENV_OFFSET, len,
+			 (size_t *)&len, (u_char *)env_new);
+	if (ret)
+		return -EIO;
+
+	puts("done\n");
+	return ret;
+}
+
+static int env_spinor_load(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+	struct spi_nor *nor;
+	struct mtd_info *mtd;
+	loff_t offset, len;
+	int ret;
+
+	nor = env_init_spinor();
+	if (!nor)
+		return -EIO;
+
+	offset = CONFIG_ENV_OFFSET;
+	len = CONFIG_ENV_SIZE;
+
+	mtd = spi_nor_get_mtd_info(nor);
+	if (!mtd)
+		return -EIO;
+
+	ret = mtd_dread(mtd, offset, len, (size_t *)&len, (uchar *)buf);
+	if (ret)
+		return -EIO;
+
+	ret = env_import(buf, 1);
+	if (ret)
+		gd->env_valid = ENV_VALID;
+
+	return ret;
+}
+
+U_BOOT_ENV_LOCATION(spinor) = {
+	.location	= ENVL_SPI_NOR,
+	ENV_NAME("SPI-NOR Flash")
+	.load		= env_spinor_load,
+	.save		= env_save_ptr(env_spinor_save),
+};
diff --git a/include/environment.h b/include/environment.h
index d29f82c..8e8be26 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -198,6 +198,7 @@ enum env_location {
 	ENVL_ONENAND,
 	ENVL_REMOTE,
 	ENVL_SPI_FLASH,
+	ENVL_SPI_NOR,
 	ENVL_UBI,
 	ENVL_NOWHERE,
 
-- 
2.7.4



More information about the U-Boot mailing list