All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Add support for the GST ESPRESSOBin-Ultra board
@ 2021-08-11  8:35 Gerald Kerma
  2021-08-11  8:35 ` [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command Gerald Kerma
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Gerald Kerma @ 2021-08-11  8:35 UTC (permalink / raw)
  To: U-Boot; +Cc: Kerma Gérald

From: Kerma Gérald <gandalf@gk2.net>

Add support for the GST ESPRESSOBin-Ultra board

Kerma Gérald (3):
  cmd: mvebu: Implement the Marvell hw_info command
  arm: mvebu: mvebu_armada-37xx: Define the loadaddr environment
    variable
  arm: mvebu: Initial ESPRESSOBin-Ultra board support

 arch/arm/dts/Makefile                         |   1 +
 .../arm/dts/armada-3720-espressobin-ultra.dts | 202 ++++++++++++
 board/Marvell/mvebu_armada-37xx/MAINTAINERS   |   9 +
 board/Marvell/mvebu_armada-37xx/board.c       |  92 +++++-
 cmd/mvebu/Kconfig                             |  23 ++
 cmd/mvebu/Makefile                            |   2 +
 cmd/mvebu/hw_info.c                           | 312 ++++++++++++++++++
 .../mvebu_espressobin-ultra-88f3720_defconfig |  92 ++++++
 include/configs/mvebu_armada-37xx.h           |   1 +
 lib/hashtable.c                               |   2 +-
 10 files changed, 729 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/dts/armada-3720-espressobin-ultra.dts
 create mode 100644 cmd/mvebu/hw_info.c
 create mode 100644 configs/mvebu_espressobin-ultra-88f3720_defconfig

-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command
  2021-08-11  8:35 [PATCH 0/3] Add support for the GST ESPRESSOBin-Ultra board Gerald Kerma
@ 2021-08-11  8:35 ` Gerald Kerma
  2021-08-11 10:15   ` Luka Kovacic
  2021-08-11  8:35 ` [PATCH 2/3] arm: mvebu: mvebu_armada-37xx: Define the loadaddr environment variable Gerald Kerma
  2021-08-11  8:35 ` [PATCH 3/3] arm: mvebu: Initial ESPRESSOBin-Ultra board support Gerald Kerma
  2 siblings, 1 reply; 6+ messages in thread
From: Gerald Kerma @ 2021-08-11  8:35 UTC (permalink / raw)
  To: U-Boot; +Cc: Kerma Gérald, Luka Kovacic, Luka Perkov, Robert Marko

From: Kerma Gérald <gandalf@gk2.net>

The hw_info command is implemented to enable parsing Marvell hw_info
formatted environments. This format is often used on Marvell Armada A37XX
based devices to store parameters like the board serial number, factory
MAC addresses and some other information.
These parameters are usually written to the flash in the factory.

Currently the command supports reading/writing parameters and dumping the
current hw_info parameters.
EEPROM config pattern and checksum aren't supported.

This functionality has been tested on the GST ESPRESSOBin-Ultra board
successfully, both reading the stock U-Boot parameters in mainline U-Boot
and reading the parameters written by this command in the stock U-Boot.

Usage example:
 => hw_info load
 => saveenv

Signed-off-by: Kerma Gérald <gandalf@gk2.net>
Cc: Luka Kovacic <luka.kovacic@sartura.hr>
Cc: Luka Perkov <luka.perkov@sartura.hr>
Cc: Robert Marko <robert.marko@sartura.hr>
---
 cmd/mvebu/Kconfig   |  23 ++++
 cmd/mvebu/Makefile  |   2 +
 cmd/mvebu/hw_info.c | 312 ++++++++++++++++++++++++++++++++++++++++++++
 lib/hashtable.c     |   2 +-
 4 files changed, 338 insertions(+), 1 deletion(-)
 create mode 100644 cmd/mvebu/hw_info.c

diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig
index 7c42c75afb..d87220d44c 100644
--- a/cmd/mvebu/Kconfig
+++ b/cmd/mvebu/Kconfig
@@ -9,6 +9,29 @@ config CMD_MVEBU_BUBT
 	  For details about bubt command please see the documentation
 	  in doc/mvebu/cmd/bubt.txt
 
+config CMD_MVEBU_HW_INFO
+	bool "hw_info"
+	depends on SPI_FLASH && ENV_IS_IN_SPI_FLASH && ARCH_MVEBU
+	default n
+	help
+	  Enable loading of the Marvell hw_info parameters from the
+	  SPI flash hw_info area. Parameters (usually the board serial
+	  number and MAC addresses) are then imported into the
+	  existing U-Boot environment.
+	  Implementation of this command is compatible with the
+	  original Marvell U-Boot command. Reading and writing is
+	  supported.
+	  EEPROM config pattern and checksum aren't supported.
+
+config CMD_MVEBU_HW_INFO_OFFSET
+	hex "Marvell hw_info SPI flash offset"
+	depends on CMD_MVEBU_HW_INFO
+	default 0x3E0000
+	help
+	  This option defines the SPI flash offset of the Marvell
+	  hw_info area. This defaults to 0x3E0000 on most Armada
+	  A3720 platforms.
+
 choice
 	prompt "Flash for image"
 	default MVEBU_SPI_BOOT
diff --git a/cmd/mvebu/Makefile b/cmd/mvebu/Makefile
index ca96ad01d9..c988dca38c 100644
--- a/cmd/mvebu/Makefile
+++ b/cmd/mvebu/Makefile
@@ -6,3 +6,5 @@
 
 obj-$(CONFIG_CMD_MVEBU_BUBT) += bubt.o
 obj-$(CONFIG_CMD_MVEBU_COMPHY_RX_TRAINING) += comphy_rx_training.o
+obj-$(CONFIG_CMD_MVEBU_HW_INFO) += hw_info.o
+
diff --git a/cmd/mvebu/hw_info.c b/cmd/mvebu/hw_info.c
new file mode 100644
index 0000000000..1ef49d78d4
--- /dev/null
+++ b/cmd/mvebu/hw_info.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell hw_info command
+ * Helper command for interfacing with the Marvell hw_info parameters
+ *
+ * Copyright (c) 2021 Sartura Ltd.
+ * Copyright (c) 2018 Marvell International Ltd.
+ *
+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
+ */
+
+#include <command.h>
+#include <common.h>
+#include <env.h>
+#include <env_internal.h>
+#include <spi.h>
+#include <spi_flash.h>
+
+#define HW_INFO_SPI_FLASH_OFFSET	CONFIG_CMD_MVEBU_HW_INFO_OFFSET
+
+#define HW_INFO_MAX_ENV_SIZE		0x1F0
+#define HW_INFO_ENV_OFFSET		0xA
+#define HW_INFO_ENV_SEP			0x20
+
+#define HW_INFO_MAX_NAME_LEN		32
+
+static char hw_info_allowed_parameters[][HW_INFO_MAX_NAME_LEN] = {
+	"pcb_slm",
+	"pcb_rev",
+	"eco_rev",
+	"pcb_sn",
+	"ethaddr",
+	"eth1addr",
+	"eth2addr",
+	"eth3addr",
+	"eth4addr",
+	"eth5addr",
+	"eth6addr",
+	"eth7addr",
+	"eth8addr",
+	"eth9addr",
+};
+
+static int hw_info_allowed_param_count = (sizeof(hw_info_allowed_parameters) /
+					sizeof(hw_info_allowed_parameters[0]));
+
+static int hw_info_check_parameter(char *name)
+{
+	int idx;
+
+	for (idx = 0; idx < hw_info_allowed_param_count; idx++) {
+		if (strcmp(name, hw_info_allowed_parameters[idx]) == 0)
+			return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int read_spi_flash_offset(char *buf, int offset)
+{
+	struct spi_flash *flash;
+	int ret;
+
+	flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+				CONFIG_SF_DEFAULT_CS,
+				CONFIG_SF_DEFAULT_SPEED,
+				CONFIG_SF_DEFAULT_MODE);
+
+	if (!flash) {
+		printf("Error - unable to probe SPI flash.\n");
+		return -EIO;
+	}
+
+	ret = spi_flash_read(flash, offset, HW_INFO_MAX_ENV_SIZE, buf);
+	if (ret) {
+		printf("Error - unable to read hw_info environment from SPI flash.\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int write_spi_flash_offset(char *buf, int offset, ssize_t size)
+{
+	ssize_t safe_size, erase_size;
+	struct spi_flash *flash;
+	int ret;
+
+	flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+				CONFIG_SF_DEFAULT_CS,
+				CONFIG_SF_DEFAULT_SPEED,
+				CONFIG_SF_DEFAULT_MODE);
+
+	if (!flash) {
+		printf("Error - unable to probe SPI flash.\n");
+		return -EIO;
+	}
+
+	safe_size = size > HW_INFO_MAX_ENV_SIZE ? HW_INFO_MAX_ENV_SIZE : size;
+	erase_size = safe_size +
+		     (flash->erase_size - safe_size % flash->erase_size);
+	ret = spi_flash_erase(flash, HW_INFO_SPI_FLASH_OFFSET, erase_size);
+	if (ret) {
+		printf("Error - unable to erase the hw_info area on SPI flash.\n");
+		return ret;
+	}
+	ret = spi_flash_write(flash, offset, safe_size, buf);
+	if (ret) {
+		printf("Error - unable to write hw_info parameters to SPI flash.\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int cmd_hw_info_dump(void)
+{
+	char buffer[HW_INFO_MAX_ENV_SIZE];
+	struct hsearch_data htab;
+	char *res = NULL;
+	ssize_t len;
+	int ret = 0;
+
+	ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
+				    HW_INFO_ENV_OFFSET);
+	if (ret)
+		goto err;
+	memset(&htab, 0, sizeof(htab));
+	if (!hcreate_r(HW_INFO_MAX_ENV_SIZE, &htab)) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	if (!himport_r(&htab, buffer, HW_INFO_MAX_ENV_SIZE,
+		       HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
+		ret = -EFAULT;
+		goto err_htab;
+	}
+
+	len = hexport_r(&htab, '\n', H_HIDE_DOT, &res, 0, 0, NULL);
+	if (len > 0) {
+		printf("Parameters (hw_info):\n");
+		puts(res);
+		free(res);
+		ret = 0;
+		goto ret_htab;
+	}
+ret_htab:
+	hdestroy_r(&htab);
+	return ret;
+err_htab:
+	hdestroy_r(&htab);
+err:
+	printf("## Error: cannot store hw_info parameters to SPI flash\n");
+	return ret;
+}
+
+static int cmd_hw_info_load(bool print_env)
+{
+	char buffer[HW_INFO_MAX_ENV_SIZE];
+	char *res = NULL;
+	ssize_t len;
+	int ret = 0;
+
+	ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
+				    HW_INFO_ENV_OFFSET);
+	if (ret)
+		goto err;
+	if (!himport_r(&env_htab, buffer, HW_INFO_MAX_ENV_SIZE,
+		       HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
+		ret = -EFAULT;
+		goto err;
+	}
+
+	printf("Successfully imported the Marvell hw_info parameters.\n");
+	if (!print_env)
+		return 0;
+
+	len = hexport_r(&env_htab, '\n', H_HIDE_DOT, &res, 0, 0, NULL);
+	if (len > 0) {
+		printf("Updated environment:\n");
+		puts(res);
+		free(res);
+		return 0;
+	}
+err:
+	printf("## Error: cannot import hw_info parameters\n");
+	return ret;
+}
+
+static int cmd_hw_info_store(char *name)
+{
+	char buffer[HW_INFO_MAX_ENV_SIZE];
+	struct env_entry e, *ep, *rv;
+	struct hsearch_data htab;
+	char *res = NULL;
+	ssize_t len;
+	int ret = 0;
+
+	ret = hw_info_check_parameter(name);
+	if (ret) {
+		printf("Invalid parameter %s, stopping.\n", name);
+		goto err;
+	}
+
+	ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
+				    HW_INFO_ENV_OFFSET);
+	if (ret)
+		goto err;
+	memset(&htab, 0, sizeof(htab));
+	if (!hcreate_r(HW_INFO_MAX_ENV_SIZE, &htab)) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	if (!himport_r(&htab, buffer, HW_INFO_MAX_ENV_SIZE,
+		       HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
+		ret = -EFAULT;
+		goto err_htab;
+	}
+
+	e.key = name;
+	e.data = NULL;
+	if (!hsearch_r(e, ENV_FIND, &ep, &env_htab, H_HIDE_DOT)) {
+		ret = -ENOENT;
+		goto err_htab;
+	}
+	if (!ep) {
+		ret = -ENOENT;
+		goto err_htab;
+	}
+
+	printf("Storing %s=%s to hw_info...\n", ep->key, ep->data);
+
+	e.key = ep->key;
+	e.data = ep->data;
+	if (!hsearch_r(e, ENV_ENTER, &rv, &htab, H_HIDE_DOT)) {
+		ret = -EINVAL;
+		goto err_htab;
+	}
+	if (!rv) {
+		ret = -EINVAL;
+		goto err_htab;
+	}
+	len = hexport_r(&htab, HW_INFO_ENV_SEP, H_MATCH_KEY | H_MATCH_IDENT,
+			&res, 0, 0, NULL);
+	if (len <= 0) {
+		free(res);
+		goto ret_htab;
+	}
+	ret = write_spi_flash_offset(res, HW_INFO_SPI_FLASH_OFFSET +
+				     HW_INFO_ENV_OFFSET, len);
+	free(res);
+	if (ret)
+		goto err_htab;
+
+	printf("Successfully stored the Marvell hw_info parameters.\n");
+	return 0;
+ret_htab:
+	hdestroy_r(&htab);
+	return ret;
+err_htab:
+	hdestroy_r(&htab);
+err:
+	printf("## Error: cannot store hw_info parameters to SPI flash\n");
+	return ret;
+}
+
+static int do_hw_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+	const char *cmd = argv[1];
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	if (!strcmp(cmd, "dump")) {
+		if (cmd_hw_info_dump())
+			return -EINVAL;
+	} else if (!strcmp(cmd, "load")) {
+		if (cmd_hw_info_load(true))
+			return -EINVAL;
+	} else if (!strcmp(cmd, "store")) {
+		if (cmd_hw_info_store(argv[2]))
+			return -EINVAL;
+	} else {
+		return CMD_RET_USAGE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+	hw_info, 3, 0, do_hw_info,
+	"Marvell hw_info utility",
+	"hw_info\n"
+	"\tdump                        - Dump all hw_info parameters from SPI flash\n"
+	"\tload                        - Load all hw_info parameters from hw_info to environment variables\n"
+	"\tstore <env_name>            - Store specific hw_info parameter from envirnoment variable to SPI flash\n"
+	"\nSupported hw_info parameters:\n"
+	"\tpcb_slm       PCB SLM number\n"
+	"\tpcb_rev       PCB revision number\n"
+	"\teco_rev       ECO revision number\n"
+	"\tpcb_sn        PCB SN\n"
+	"\tethaddr       first MAC address\n"
+	"\teth1addr      second MAC address\n"
+	"\teth2addr      third MAC address\n"
+	"\teth3addr      fourth MAC address\n"
+	"\teth4addr      fifth MAC address\n"
+	"\teth5addr      sixth MAC address\n"
+	"\teth6addr      seventh MAC address\n"
+	"\teth7addr      eighth MAC address\n"
+	"\teth8addr      ninth MAC address\n"
+	"\teth9addr      tenth MAC address\n"
+);
diff --git a/lib/hashtable.c b/lib/hashtable.c
index ff5ff72639..06322e3304 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -794,7 +794,7 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[])
  * multi-line values.
  *
  * In theory, arbitrary separator characters can be used, but only
- * '\0' and '\n' have really been tested.
+ * '\0', '\n' and 0x20 have been tested.
  */
 
 int himport_r(struct hsearch_data *htab,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] arm: mvebu: mvebu_armada-37xx: Define the loadaddr environment variable
  2021-08-11  8:35 [PATCH 0/3] Add support for the GST ESPRESSOBin-Ultra board Gerald Kerma
  2021-08-11  8:35 ` [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command Gerald Kerma
@ 2021-08-11  8:35 ` Gerald Kerma
  2021-08-11  8:35 ` [PATCH 3/3] arm: mvebu: Initial ESPRESSOBin-Ultra board support Gerald Kerma
  2 siblings, 0 replies; 6+ messages in thread
From: Gerald Kerma @ 2021-08-11  8:35 UTC (permalink / raw)
  To: U-Boot; +Cc: Kerma Gérald, Luka Kovacic, Luka Perkov, Robert Marko

From: Kerma Gérald <gandalf@gk2.net>

Add the loadaddr U-Boot environment variable, as this is available in
the stock Marvell U-Boot by default on Marvell Armada A37XX platforms.

Signed-off-by: Kerma Gérald <gandalf@gk2.net>
Cc: Luka Kovacic <luka.kovacic@sartura.hr>
Cc: Luka Perkov <luka.perkov@sartura.hr>
Cc: Robert Marko <robert.marko@sartura.hr>
---
 include/configs/mvebu_armada-37xx.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/configs/mvebu_armada-37xx.h b/include/configs/mvebu_armada-37xx.h
index c8c34d7d92..83f710efd4 100644
--- a/include/configs/mvebu_armada-37xx.h
+++ b/include/configs/mvebu_armada-37xx.h
@@ -103,6 +103,7 @@
 
 /* fdt_addr and kernel_addr are needed for existing distribution boot scripts */
 #define CONFIG_EXTRA_ENV_SETTINGS	\
+	"loadaddr=0x6000000\0"		\
 	"scriptaddr=0x6d00000\0"	\
 	"pxefile_addr_r=0x6e00000\0"	\
 	"fdt_addr=0x6f00000\0"		\
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] arm: mvebu: Initial ESPRESSOBin-Ultra board support
  2021-08-11  8:35 [PATCH 0/3] Add support for the GST ESPRESSOBin-Ultra board Gerald Kerma
  2021-08-11  8:35 ` [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command Gerald Kerma
  2021-08-11  8:35 ` [PATCH 2/3] arm: mvebu: mvebu_armada-37xx: Define the loadaddr environment variable Gerald Kerma
@ 2021-08-11  8:35 ` Gerald Kerma
  2 siblings, 0 replies; 6+ messages in thread
From: Gerald Kerma @ 2021-08-11  8:35 UTC (permalink / raw)
  To: U-Boot; +Cc: Kerma Gérald, Luka Kovacic, Luka Perkov, Robert Marko

From: Kerma Gérald <gandalf@gk2.net>

Add initial support for the ESPRESSOBin-Ultra board from Globalscale
Technologies, Inc.

The board is based on the 64-bit dual-core Marvell Armada 3720 SoC.
Peripherals:
 - 5 Gigabit Ethernet ports (WAN has PoE, up to 30W, Topaz 6341 switch)
 - RTC clock (PCF8563)
 - USB 3.0 port
 - USB 2.0 port
 - 4x LED
 - UART over Micro-USB
 - M.2 slot (2280)
 - Mini PCI-E slot

Additionally, automatic import of the Marvell hw_info parameters is
enabled via the recently added hw_info command.
The parameters stored in Marvell hw_info are usually the board serial
number and MAC addresses.

Signed-off-by: Kerma Gérald <gandalf@gk2.net>
Cc: Luka Kovacic <luka.kovacic@sartura.hr>
Cc: Luka Perkov <luka.perkov@sartura.hr>
Cc: Robert Marko <robert.marko@sartura.hr>
Signed-off-by: Kerma Gérald <gandalf@gk2.net>
---
 arch/arm/dts/Makefile                         |   1 +
 .../arm/dts/armada-3720-espressobin-ultra.dts | 202 ++++++++++++++++++
 board/Marvell/mvebu_armada-37xx/MAINTAINERS   |   9 +
 board/Marvell/mvebu_armada-37xx/board.c       |  92 +++++++-
 .../mvebu_espressobin-ultra-88f3720_defconfig |  92 ++++++++
 5 files changed, 390 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/dts/armada-3720-espressobin-ultra.dts
 create mode 100644 configs/mvebu_espressobin-ultra-88f3720_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index c42715ead4..f21c9c94d3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -213,6 +213,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
 dtb-$(CONFIG_ARCH_MVEBU) +=			\
 	armada-3720-db.dtb			\
 	armada-3720-espressobin.dtb		\
+	armada-3720-espressobin-ultra.dtb	\
 	armada-3720-turris-mox.dtb		\
 	armada-3720-uDPU.dtb			\
 	armada-375-db.dtb			\
diff --git a/arch/arm/dts/armada-3720-espressobin-ultra.dts b/arch/arm/dts/armada-3720-espressobin-ultra.dts
new file mode 100644
index 0000000000..66ceee60c8
--- /dev/null
+++ b/arch/arm/dts/armada-3720-espressobin-ultra.dts
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for ESPRESSObin-Ultra board
+ * Copyright (C) 2016 Marvell
+ * Copyright (C) 2019 Globalscale technologies, Inc.
+ * Copyright (C) 2020 Sartura Ltd.
+ *
+ * Author: Jason Hung <jhung@globalscaletechnologies.com>
+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
+ * Author: Vladimir Vid <vladimir.vid@sartura.hr>
+ */
+
+/dts-v1/;
+
+#include "armada-372x.dtsi"
+
+/ {
+	model = "Globalscale Marvell ESPRESSOBin Ultra Board";
+	compatible = "globalscale,espressobin-ultra", "marvell,armada3720", "marvell,armada3710";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		ethernet0 = &eth0;
+		i2c0 = &i2c0;
+		spi0 = &spi0;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
+	};
+
+	vcc_sd_reg0: regulator@0 {
+		compatible = "regulator-gpio";
+		regulator-name = "vcc_sd0";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-type = "voltage";
+		states = <1800000 0x1
+			  3300000 0x0>;
+		gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>;
+	};
+
+	gpio-leds {
+		pinctrl-names = "default";
+		pinctrl-0 = <&led1_pins>, <&led2_pins>, <&led3_pins>, <&led4_pins>;
+		compatible = "gpio-leds";
+
+		led1 {
+			label = "led1";
+			gpios = <&gpionb 11 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+		led2 {
+			label = "led2";
+			gpios = <&gpionb 12 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+		led3 {
+			label = "led3";
+			gpios = <&gpionb 13 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+		led4 {
+			label = "led4";
+			gpios = <&gpionb 14 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+	};
+};
+
+&pinctrl_nb {
+	led1_pins: led1-pins {
+		groups = "pwm0";
+		function = "gpio";
+	};
+	led2_pins: led2-pins {
+		groups = "pwm1";
+		function = "gpio";
+	};
+	led3_pins: led3-pins {
+		groups = "pwm2";
+		function = "gpio";
+	};
+	led4_pins: led4-pins {
+		groups = "pwm3";
+		function = "gpio";
+	};
+};
+
+&comphy {
+	max-lanes = <3>;
+	phy0 {
+		phy-type = <COMPHY_TYPE_USB3_HOST0>;
+		phy-speed = <COMPHY_SPEED_5G>;
+	};
+
+	phy1 {
+		phy-type = <COMPHY_TYPE_PEX0>;
+		phy-speed = <COMPHY_SPEED_2_5G>;
+	};
+
+	phy2 {
+		phy-type = <COMPHY_TYPE_SATA0>;
+		phy-speed = <COMPHY_SPEED_5G>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>, <&smi_pins>;
+	phy-mode = "rgmii";
+	phy_addr = <0x3>;
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	rtc@51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&sata {
+	status = "okay";
+};
+
+&sdhci0 {
+	status = "disabled";
+};
+
+/* U11 */
+&sdhci1 {
+	non-removable;
+	bus-width = <8>;
+	mmc-ddr-1_8v;
+	mmc-hs400-1_8v;
+	marvell,xenon-emmc;
+	marvell,xenon-tun-count = <9>;
+	marvell,pad-type = "fixed-1-8v";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc_pins>;
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	mmccard: mmccard@0 {
+		compatible = "mmc-card";
+		reg = <0>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_quad_pins>;
+
+	spi-flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "st,m25p128", "jedec,spi-nor";
+		reg = <0>; /* Chip select 0 */
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+	};
+};
+
+/* Exported on the micro USB connector through an FTDI */
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "okay";
+};
+
+&usb2 {
+	status = "okay";
+};
+
+&usb3 {
+	status = "okay";
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_pins>;
+	reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
diff --git a/board/Marvell/mvebu_armada-37xx/MAINTAINERS b/board/Marvell/mvebu_armada-37xx/MAINTAINERS
index f2c0a582d7..6b1697b942 100644
--- a/board/Marvell/mvebu_armada-37xx/MAINTAINERS
+++ b/board/Marvell/mvebu_armada-37xx/MAINTAINERS
@@ -10,6 +10,15 @@ M:	Konstantin Porotchkin <kostap@marvell.com>
 S:	Maintained
 F:	configs/mvebu_espressobin-88f3720_defconfig
 
+ESPRESSOBin-Ultra BOARD
+M:	Kerma Gerald <gandalf@gk2.net>
+M:	Luka Kovacic <luka.kovacic@sartura.hr>
+M:	Robert Marko <robert.marko@sartura.hr>
+M:	Luka Perkov <luka.perkov@sartura.hr>
+S:	Maintained
+F:	arch/arm/dts/armada-3720-espressobin-ultra.dts
+F:	configs/mvebu_espressobin-ultra-88f3720_defconfig
+
 uDPU BOARD
 M:	Vladimir Vid <vladimir.vid@sartura.hr>
 S:	Maintained
diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c
index 2de9c2ac17..21c1eb7b22 100644
--- a/board/Marvell/mvebu_armada-37xx/board.c
+++ b/board/Marvell/mvebu_armada-37xx/board.c
@@ -11,6 +11,7 @@
 #include <i2c.h>
 #include <init.h>
 #include <mmc.h>
+#include <miiphy.h>
 #include <phy.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
@@ -55,6 +56,15 @@ DECLARE_GLOBAL_DATA_PTR;
 #define MVEBU_G2_SMI_PHY_CMD_REG	(24)
 #define MVEBU_G2_SMI_PHY_DATA_REG	(25)
 
+/* Marvell 88E1512 */
+#define MII_MARVELL_PHY_PAGE		22
+
+#define MV88E1512_GENERAL_CTRL		20
+#define MV88E1512_MODE_SGMII		1
+#define MV88E1512_RESET_OFFS		15
+
+#define ULTRA_MV88E1512_PHYADDR		0x1
+
 /*
  * Memory Controller Registers
  *
@@ -282,12 +292,68 @@ static int mii_multi_chip_mode_write(struct mii_dev *bus, int dev_smi_addr,
 	return 0;
 }
 
-/* Bring-up board-specific network stuff */
-int board_network_enable(struct mii_dev *bus)
+void force_phy_88e1512_sgmii_to_copper(u16 devaddr)
 {
-	if (!of_machine_is_compatible("globalscale,espressobin"))
-		return 0;
+	const char *name;
+	u16 reg;
+
+	name = miiphy_get_current_dev();
+	if (name) {
+		/* SGMII-to-Copper mode initialization */
+
+		/* Select page 18 */
+		miiphy_write(name, devaddr, MII_MARVELL_PHY_PAGE, 0x12);
+		/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
+		miiphy_read(name, devaddr, MV88E1512_GENERAL_CTRL, &reg);
+		reg &= ~0x7;
+		reg |= MV88E1512_MODE_SGMII;
+		miiphy_write(name, devaddr, MV88E1512_GENERAL_CTRL, reg);
+		/* PHY reset is necessary after changing MODE[2:0] */
+		miiphy_read(name, devaddr, MV88E1512_GENERAL_CTRL, &reg);
+		reg |= 1 << MV88E1512_RESET_OFFS;
+		miiphy_write(name, devaddr, MV88E1512_GENERAL_CTRL, reg);
+		/* Reset page selection */
+		miiphy_write(name, devaddr, MII_MARVELL_PHY_PAGE, 0);
+		udelay(100);
+	}
+}
+
+int board_network_enable_espressobin_ultra(struct mii_dev *bus)
+{
+	int i;
+	/* Setup 88E1512 SGMII-to-Copper mode */
+	force_phy_88e1512_sgmii_to_copper(ULTRA_MV88E1512_PHYADDR);
 
+	/*
+	 * FIXME: remove this code once Topaz driver gets available
+	 * A3720 ESPRESSObin Ultra Board Only
+	 * Configure Topaz switch (88E6341)
+	 * Set port 1,2,3,4,5 to forwarding Mode (through Switch Port registers)
+	 */
+	for (i = 0; i <= 5; i++) {
+		mii_multi_chip_mode_write(bus, 3, MVEBU_PORT_CTRL_SMI_ADDR(i),
+					  MVEBU_SW_PORT_CTRL_REG,
+					  i == 5 ? 0x7c : 0x7f);
+	}
+
+	/* RGMII Delay on Port 0 (CPU port), force link to 1000Mbps */
+	mii_multi_chip_mode_write(bus, 3, MVEBU_PORT_CTRL_SMI_ADDR(0),
+				  MVEBU_SW_LINK_CTRL_REG, 0xe002);
+
+	/* Power up PHY 1, 2, 3, 4, 5 (through Global 2 registers) */
+	mii_multi_chip_mode_write(bus, 3, MVEBU_SW_G2_SMI_ADDR,
+				  MVEBU_G2_SMI_PHY_DATA_REG, 0x1140);
+	for (i = 1; i <= 5; i++) {
+		mii_multi_chip_mode_write(bus, 3, MVEBU_SW_G2_SMI_ADDR,
+					  MVEBU_G2_SMI_PHY_CMD_REG, 0x9400 +
+					  (MVEBU_PORT_CTRL_SMI_ADDR(i) << 5));
+	}
+
+	return 0;
+}
+
+int board_network_enable_espressobin(struct mii_dev *bus)
+{
 	/*
 	 * FIXME: remove this code once Topaz driver gets available
 	 * A3720 Community Board Only
@@ -328,6 +394,16 @@ int board_network_enable(struct mii_dev *bus)
 	return 0;
 }
 
+/* Bring-up the board-specific networking */
+int board_network_enable(struct mii_dev *bus)
+{
+	if (of_machine_is_compatible("globalscale,espressobin"))
+		return board_network_enable_espressobin(bus);
+	if (of_machine_is_compatible("globalscale,espressobin-ultra"))
+		return board_network_enable_espressobin_ultra(bus);
+	return 0;
+}
+
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_ENV_IS_IN_SPI_FLASH)
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
@@ -336,8 +412,12 @@ int ft_board_setup(void *blob, struct bd_info *bd)
 	int parts_off;
 	int part_off;
 
-	/* Fill SPI MTD partitions for Linux kernel on Espressobin */
-	if (!of_machine_is_compatible("globalscale,espressobin"))
+	/*
+	 * Fill SPI MTD partitions for the Linux kernel on ESPRESSOBin and
+	 * ESPRESSOBin Ultra boards.
+	 */
+	if (!of_machine_is_compatible("globalscale,espressobin") &&
+	    !of_machine_is_compatible("globalscale,espressobin-ultra"))
 		return 0;
 
 	spi_off = fdt_node_offset_by_compatible(blob, -1, "jedec,spi-nor");
diff --git a/configs/mvebu_espressobin-ultra-88f3720_defconfig b/configs/mvebu_espressobin-ultra-88f3720_defconfig
new file mode 100644
index 0000000000..207f38d300
--- /dev/null
+++ b/configs/mvebu_espressobin-ultra-88f3720_defconfig
@@ -0,0 +1,92 @@
+CONFIG_ARM=y
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_TARGET_MVEBU_ARMADA_37XX=y
+CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_OFFSET=0x3F0000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_DM_GPIO=y
+CONFIG_DEBUG_UART_BASE=0xd0012000
+CONFIG_DEBUG_UART_CLOCK=25804800
+CONFIG_DEFAULT_DEVICE_TREE="armada-3720-espressobin-ultra"
+CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Autoboot in %d seconds, to stop use 's' key\n"
+CONFIG_AUTOBOOT_STOP_STR="s"
+CONFIG_AUTOBOOT_KEYED_CTRLC=y
+CONFIG_HUSH_PARSER=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="if printenv read_board_hw_info; then echo \"Marvell hw_info already imported...\" ; else setenv read_board_hw_info 1; hw_info load; fi"
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_ARCH_EARLY_INIT_R=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_BOARD_LATE_INIT=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_MVEBU_BUBT=y
+CONFIG_CMD_MVEBU_HW_INFO=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_MAC_PARTITION=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_AHCI_MVEBU=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_DM_I2C=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_XENON=y
+CONFIG_MTD=y
+CONFIG_SF_DEFAULT_MODE=0
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_PHY_MARVELL=y
+CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_AARDVARK=y
+CONFIG_MVEBU_COMPHY_SUPPORT=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ARMADA_37XX=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_MVEBU_A3700_UART=y
+CONFIG_MVEBU_A3700_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_SHA1=y
+CONFIG_SHA256=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_PCF8563=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command
  2021-08-11  8:35 ` [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command Gerald Kerma
@ 2021-08-11 10:15   ` Luka Kovacic
  2021-08-11 10:54     ` Gérald Kerma
  0 siblings, 1 reply; 6+ messages in thread
From: Luka Kovacic @ 2021-08-11 10:15 UTC (permalink / raw)
  To: Gerald Kerma, U-Boot; +Cc: Luka Perkov, Robert Marko

Hi Gerald,

On Wed, Aug 11, 2021 at 10:35 AM Gerald Kerma <Gandalf@gk2.net> wrote:
>
> From: Kerma Gérald <gandalf@gk2.net>
>
> The hw_info command is implemented to enable parsing Marvell hw_info
> formatted environments. This format is often used on Marvell Armada A37XX
> based devices to store parameters like the board serial number, factory
> MAC addresses and some other information.
> These parameters are usually written to the flash in the factory.
>
> Currently the command supports reading/writing parameters and dumping the
> current hw_info parameters.
> EEPROM config pattern and checksum aren't supported.
>
> This functionality has been tested on the GST ESPRESSOBin-Ultra board
> successfully, both reading the stock U-Boot parameters in mainline U-Boot
> and reading the parameters written by this command in the stock U-Boot.
>
> Usage example:
>  => hw_info load
>  => saveenv
>
> Signed-off-by: Kerma Gérald <gandalf@gk2.net>

This patch series has been resent and you have with an exception of a small
PHY -> COMPHY change just "rebranded" the patches and used your SoB, without
acknowledging the previous work.

Link to the original patchset:
https://patchwork.ozlabs.org/project/uboot/list/?series=229617

A new patchset will be sent today, which refactors the original patches.

> Cc: Luka Kovacic <luka.kovacic@sartura.hr>
> Cc: Luka Perkov <luka.perkov@sartura.hr>
> Cc: Robert Marko <robert.marko@sartura.hr>
> ---
>  cmd/mvebu/Kconfig   |  23 ++++
>  cmd/mvebu/Makefile  |   2 +
>  cmd/mvebu/hw_info.c | 312 ++++++++++++++++++++++++++++++++++++++++++++
>  lib/hashtable.c     |   2 +-
>  4 files changed, 338 insertions(+), 1 deletion(-)
>  create mode 100644 cmd/mvebu/hw_info.c
>
> diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig
> index 7c42c75afb..d87220d44c 100644
> --- a/cmd/mvebu/Kconfig
> +++ b/cmd/mvebu/Kconfig
> @@ -9,6 +9,29 @@ config CMD_MVEBU_BUBT
>           For details about bubt command please see the documentation
>           in doc/mvebu/cmd/bubt.txt
>
> +config CMD_MVEBU_HW_INFO
> +       bool "hw_info"
> +       depends on SPI_FLASH && ENV_IS_IN_SPI_FLASH && ARCH_MVEBU
> +       default n
> +       help
> +         Enable loading of the Marvell hw_info parameters from the
> +         SPI flash hw_info area. Parameters (usually the board serial
> +         number and MAC addresses) are then imported into the
> +         existing U-Boot environment.
> +         Implementation of this command is compatible with the
> +         original Marvell U-Boot command. Reading and writing is
> +         supported.
> +         EEPROM config pattern and checksum aren't supported.
> +
> +config CMD_MVEBU_HW_INFO_OFFSET
> +       hex "Marvell hw_info SPI flash offset"
> +       depends on CMD_MVEBU_HW_INFO
> +       default 0x3E0000
> +       help
> +         This option defines the SPI flash offset of the Marvell
> +         hw_info area. This defaults to 0x3E0000 on most Armada
> +         A3720 platforms.
> +
>  choice
>         prompt "Flash for image"
>         default MVEBU_SPI_BOOT
> diff --git a/cmd/mvebu/Makefile b/cmd/mvebu/Makefile
> index ca96ad01d9..c988dca38c 100644
> --- a/cmd/mvebu/Makefile
> +++ b/cmd/mvebu/Makefile
> @@ -6,3 +6,5 @@
>
>  obj-$(CONFIG_CMD_MVEBU_BUBT) += bubt.o
>  obj-$(CONFIG_CMD_MVEBU_COMPHY_RX_TRAINING) += comphy_rx_training.o
> +obj-$(CONFIG_CMD_MVEBU_HW_INFO) += hw_info.o
> +
> diff --git a/cmd/mvebu/hw_info.c b/cmd/mvebu/hw_info.c
> new file mode 100644
> index 0000000000..1ef49d78d4
> --- /dev/null
> +++ b/cmd/mvebu/hw_info.c
> @@ -0,0 +1,312 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Marvell hw_info command
> + * Helper command for interfacing with the Marvell hw_info parameters
> + *
> + * Copyright (c) 2021 Sartura Ltd.
> + * Copyright (c) 2018 Marvell International Ltd.
> + *
> + * Author: Luka Kovacic <luka.kovacic@sartura.hr>
> + */
> +
> +#include <command.h>
> +#include <common.h>
> +#include <env.h>
> +#include <env_internal.h>
> +#include <spi.h>
> +#include <spi_flash.h>
> +
> +#define HW_INFO_SPI_FLASH_OFFSET       CONFIG_CMD_MVEBU_HW_INFO_OFFSET
> +
> +#define HW_INFO_MAX_ENV_SIZE           0x1F0
> +#define HW_INFO_ENV_OFFSET             0xA
> +#define HW_INFO_ENV_SEP                        0x20
> +
> +#define HW_INFO_MAX_NAME_LEN           32
> +
> +static char hw_info_allowed_parameters[][HW_INFO_MAX_NAME_LEN] = {
> +       "pcb_slm",
> +       "pcb_rev",
> +       "eco_rev",
> +       "pcb_sn",
> +       "ethaddr",
> +       "eth1addr",
> +       "eth2addr",
> +       "eth3addr",
> +       "eth4addr",
> +       "eth5addr",
> +       "eth6addr",
> +       "eth7addr",
> +       "eth8addr",
> +       "eth9addr",
> +};
> +
> +static int hw_info_allowed_param_count = (sizeof(hw_info_allowed_parameters) /
> +                                       sizeof(hw_info_allowed_parameters[0]));
> +
> +static int hw_info_check_parameter(char *name)
> +{
> +       int idx;
> +
> +       for (idx = 0; idx < hw_info_allowed_param_count; idx++) {
> +               if (strcmp(name, hw_info_allowed_parameters[idx]) == 0)
> +                       return 0;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int read_spi_flash_offset(char *buf, int offset)
> +{
> +       struct spi_flash *flash;
> +       int ret;
> +
> +       flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
> +                               CONFIG_SF_DEFAULT_CS,
> +                               CONFIG_SF_DEFAULT_SPEED,
> +                               CONFIG_SF_DEFAULT_MODE);
> +
> +       if (!flash) {
> +               printf("Error - unable to probe SPI flash.\n");
> +               return -EIO;
> +       }
> +
> +       ret = spi_flash_read(flash, offset, HW_INFO_MAX_ENV_SIZE, buf);
> +       if (ret) {
> +               printf("Error - unable to read hw_info environment from SPI flash.\n");
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static int write_spi_flash_offset(char *buf, int offset, ssize_t size)
> +{
> +       ssize_t safe_size, erase_size;
> +       struct spi_flash *flash;
> +       int ret;
> +
> +       flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
> +                               CONFIG_SF_DEFAULT_CS,
> +                               CONFIG_SF_DEFAULT_SPEED,
> +                               CONFIG_SF_DEFAULT_MODE);
> +
> +       if (!flash) {
> +               printf("Error - unable to probe SPI flash.\n");
> +               return -EIO;
> +       }
> +
> +       safe_size = size > HW_INFO_MAX_ENV_SIZE ? HW_INFO_MAX_ENV_SIZE : size;
> +       erase_size = safe_size +
> +                    (flash->erase_size - safe_size % flash->erase_size);
> +       ret = spi_flash_erase(flash, HW_INFO_SPI_FLASH_OFFSET, erase_size);
> +       if (ret) {
> +               printf("Error - unable to erase the hw_info area on SPI flash.\n");
> +               return ret;
> +       }
> +       ret = spi_flash_write(flash, offset, safe_size, buf);
> +       if (ret) {
> +               printf("Error - unable to write hw_info parameters to SPI flash.\n");
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static int cmd_hw_info_dump(void)
> +{
> +       char buffer[HW_INFO_MAX_ENV_SIZE];
> +       struct hsearch_data htab;
> +       char *res = NULL;
> +       ssize_t len;
> +       int ret = 0;
> +
> +       ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
> +                                   HW_INFO_ENV_OFFSET);
> +       if (ret)
> +               goto err;
> +       memset(&htab, 0, sizeof(htab));
> +       if (!hcreate_r(HW_INFO_MAX_ENV_SIZE, &htab)) {
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +       if (!himport_r(&htab, buffer, HW_INFO_MAX_ENV_SIZE,
> +                      HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
> +               ret = -EFAULT;
> +               goto err_htab;
> +       }
> +
> +       len = hexport_r(&htab, '\n', H_HIDE_DOT, &res, 0, 0, NULL);
> +       if (len > 0) {
> +               printf("Parameters (hw_info):\n");
> +               puts(res);
> +               free(res);
> +               ret = 0;
> +               goto ret_htab;
> +       }
> +ret_htab:
> +       hdestroy_r(&htab);
> +       return ret;
> +err_htab:
> +       hdestroy_r(&htab);
> +err:
> +       printf("## Error: cannot store hw_info parameters to SPI flash\n");
> +       return ret;
> +}
> +
> +static int cmd_hw_info_load(bool print_env)
> +{
> +       char buffer[HW_INFO_MAX_ENV_SIZE];
> +       char *res = NULL;
> +       ssize_t len;
> +       int ret = 0;
> +
> +       ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
> +                                   HW_INFO_ENV_OFFSET);
> +       if (ret)
> +               goto err;
> +       if (!himport_r(&env_htab, buffer, HW_INFO_MAX_ENV_SIZE,
> +                      HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
> +               ret = -EFAULT;
> +               goto err;
> +       }
> +
> +       printf("Successfully imported the Marvell hw_info parameters.\n");
> +       if (!print_env)
> +               return 0;
> +
> +       len = hexport_r(&env_htab, '\n', H_HIDE_DOT, &res, 0, 0, NULL);
> +       if (len > 0) {
> +               printf("Updated environment:\n");
> +               puts(res);
> +               free(res);
> +               return 0;
> +       }
> +err:
> +       printf("## Error: cannot import hw_info parameters\n");
> +       return ret;
> +}
> +
> +static int cmd_hw_info_store(char *name)
> +{
> +       char buffer[HW_INFO_MAX_ENV_SIZE];
> +       struct env_entry e, *ep, *rv;
> +       struct hsearch_data htab;
> +       char *res = NULL;
> +       ssize_t len;
> +       int ret = 0;
> +
> +       ret = hw_info_check_parameter(name);
> +       if (ret) {
> +               printf("Invalid parameter %s, stopping.\n", name);
> +               goto err;
> +       }
> +
> +       ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
> +                                   HW_INFO_ENV_OFFSET);
> +       if (ret)
> +               goto err;
> +       memset(&htab, 0, sizeof(htab));
> +       if (!hcreate_r(HW_INFO_MAX_ENV_SIZE, &htab)) {
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +       if (!himport_r(&htab, buffer, HW_INFO_MAX_ENV_SIZE,
> +                      HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
> +               ret = -EFAULT;
> +               goto err_htab;
> +       }
> +
> +       e.key = name;
> +       e.data = NULL;
> +       if (!hsearch_r(e, ENV_FIND, &ep, &env_htab, H_HIDE_DOT)) {
> +               ret = -ENOENT;
> +               goto err_htab;
> +       }
> +       if (!ep) {
> +               ret = -ENOENT;
> +               goto err_htab;
> +       }
> +
> +       printf("Storing %s=%s to hw_info...\n", ep->key, ep->data);
> +
> +       e.key = ep->key;
> +       e.data = ep->data;
> +       if (!hsearch_r(e, ENV_ENTER, &rv, &htab, H_HIDE_DOT)) {
> +               ret = -EINVAL;
> +               goto err_htab;
> +       }
> +       if (!rv) {
> +               ret = -EINVAL;
> +               goto err_htab;
> +       }
> +       len = hexport_r(&htab, HW_INFO_ENV_SEP, H_MATCH_KEY | H_MATCH_IDENT,
> +                       &res, 0, 0, NULL);
> +       if (len <= 0) {
> +               free(res);
> +               goto ret_htab;
> +       }
> +       ret = write_spi_flash_offset(res, HW_INFO_SPI_FLASH_OFFSET +
> +                                    HW_INFO_ENV_OFFSET, len);
> +       free(res);
> +       if (ret)
> +               goto err_htab;
> +
> +       printf("Successfully stored the Marvell hw_info parameters.\n");
> +       return 0;
> +ret_htab:
> +       hdestroy_r(&htab);
> +       return ret;
> +err_htab:
> +       hdestroy_r(&htab);
> +err:
> +       printf("## Error: cannot store hw_info parameters to SPI flash\n");
> +       return ret;
> +}
> +
> +static int do_hw_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> +{
> +       const char *cmd = argv[1];
> +
> +       if (argc < 2)
> +               return CMD_RET_USAGE;
> +
> +       if (!strcmp(cmd, "dump")) {
> +               if (cmd_hw_info_dump())
> +                       return -EINVAL;
> +       } else if (!strcmp(cmd, "load")) {
> +               if (cmd_hw_info_load(true))
> +                       return -EINVAL;
> +       } else if (!strcmp(cmd, "store")) {
> +               if (cmd_hw_info_store(argv[2]))
> +                       return -EINVAL;
> +       } else {
> +               return CMD_RET_USAGE;
> +       }
> +
> +       return CMD_RET_SUCCESS;
> +}
> +
> +U_BOOT_CMD(
> +       hw_info, 3, 0, do_hw_info,
> +       "Marvell hw_info utility",
> +       "hw_info\n"
> +       "\tdump                        - Dump all hw_info parameters from SPI flash\n"
> +       "\tload                        - Load all hw_info parameters from hw_info to environment variables\n"
> +       "\tstore <env_name>            - Store specific hw_info parameter from envirnoment variable to SPI flash\n"
> +       "\nSupported hw_info parameters:\n"
> +       "\tpcb_slm       PCB SLM number\n"
> +       "\tpcb_rev       PCB revision number\n"
> +       "\teco_rev       ECO revision number\n"
> +       "\tpcb_sn        PCB SN\n"
> +       "\tethaddr       first MAC address\n"
> +       "\teth1addr      second MAC address\n"
> +       "\teth2addr      third MAC address\n"
> +       "\teth3addr      fourth MAC address\n"
> +       "\teth4addr      fifth MAC address\n"
> +       "\teth5addr      sixth MAC address\n"
> +       "\teth6addr      seventh MAC address\n"
> +       "\teth7addr      eighth MAC address\n"
> +       "\teth8addr      ninth MAC address\n"
> +       "\teth9addr      tenth MAC address\n"
> +);
> diff --git a/lib/hashtable.c b/lib/hashtable.c
> index ff5ff72639..06322e3304 100644
> --- a/lib/hashtable.c
> +++ b/lib/hashtable.c
> @@ -794,7 +794,7 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[])
>   * multi-line values.
>   *
>   * In theory, arbitrary separator characters can be used, but only
> - * '\0' and '\n' have really been tested.
> + * '\0', '\n' and 0x20 have been tested.
>   */
>
>  int himport_r(struct hsearch_data *htab,
> --
> 2.30.2
>

Kind regards,
Luka Kovacic

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command
  2021-08-11 10:15   ` Luka Kovacic
@ 2021-08-11 10:54     ` Gérald Kerma
  0 siblings, 0 replies; 6+ messages in thread
From: Gérald Kerma @ 2021-08-11 10:54 UTC (permalink / raw)
  To: Luka Kovacic, U-Boot; +Cc: Luka Perkov, Robert Marko

Héllo Luka,

Le 11/08/2021 à 12:15, Luka Kovacic a écrit :
> Hi Gerald,
>
> On Wed, Aug 11, 2021 at 10:35 AM Gerald Kerma <Gandalf@gk2.net> wrote:
>> From: Kerma Gérald <gandalf@gk2.net>
>>
>> The hw_info command is implemented to enable parsing Marvell hw_info
>> formatted environments. This format is often used on Marvell Armada A37XX
>> based devices to store parameters like the board serial number, factory
>> MAC addresses and some other information.
>> These parameters are usually written to the flash in the factory.
>>
>> Currently the command supports reading/writing parameters and dumping the
>> current hw_info parameters.
>> EEPROM config pattern and checksum aren't supported.
>>
>> This functionality has been tested on the GST ESPRESSOBin-Ultra board
>> successfully, both reading the stock U-Boot parameters in mainline U-Boot
>> and reading the parameters written by this command in the stock U-Boot.
>>
>> Usage example:
>>   => hw_info load
>>   => saveenv
>>
>> Signed-off-by: Kerma Gérald <gandalf@gk2.net>
> This patch series has been resent and you have with an exception of a small
> PHY -> COMPHY change just "rebranded" the patches and used your SoB, without
> acknowledging the previous work.


Yes, it was just a "refresh"...

> Link to the original patchset:
> https://patchwork.ozlabs.org/project/uboot/list/?series=229617
>
> A new patchset will be sent today, which refactors the original patches.


Great !

Good news if you can take back again on this job...

Thanks for this.


Do not hesitate if you need testing...


>> Cc: Luka Kovacic <luka.kovacic@sartura.hr>
>> Cc: Luka Perkov <luka.perkov@sartura.hr>
>> Cc: Robert Marko <robert.marko@sartura.hr>
>> ---
>>   cmd/mvebu/Kconfig   |  23 ++++
>>   cmd/mvebu/Makefile  |   2 +
>>   cmd/mvebu/hw_info.c | 312 ++++++++++++++++++++++++++++++++++++++++++++
>>   lib/hashtable.c     |   2 +-
>>   4 files changed, 338 insertions(+), 1 deletion(-)
>>   create mode 100644 cmd/mvebu/hw_info.c
>>
>> diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig
>> index 7c42c75afb..d87220d44c 100644
>> --- a/cmd/mvebu/Kconfig
>> +++ b/cmd/mvebu/Kconfig
>> @@ -9,6 +9,29 @@ config CMD_MVEBU_BUBT
>>            For details about bubt command please see the documentation
>>            in doc/mvebu/cmd/bubt.txt
>>
>> +config CMD_MVEBU_HW_INFO
>> +       bool "hw_info"
>> +       depends on SPI_FLASH && ENV_IS_IN_SPI_FLASH && ARCH_MVEBU
>> +       default n
>> +       help
>> +         Enable loading of the Marvell hw_info parameters from the
>> +         SPI flash hw_info area. Parameters (usually the board serial
>> +         number and MAC addresses) are then imported into the
>> +         existing U-Boot environment.
>> +         Implementation of this command is compatible with the
>> +         original Marvell U-Boot command. Reading and writing is
>> +         supported.
>> +         EEPROM config pattern and checksum aren't supported.
>> +
>> +config CMD_MVEBU_HW_INFO_OFFSET
>> +       hex "Marvell hw_info SPI flash offset"
>> +       depends on CMD_MVEBU_HW_INFO
>> +       default 0x3E0000
>> +       help
>> +         This option defines the SPI flash offset of the Marvell
>> +         hw_info area. This defaults to 0x3E0000 on most Armada
>> +         A3720 platforms.
>> +
>>   choice
>>          prompt "Flash for image"
>>          default MVEBU_SPI_BOOT
>> diff --git a/cmd/mvebu/Makefile b/cmd/mvebu/Makefile
>> index ca96ad01d9..c988dca38c 100644
>> --- a/cmd/mvebu/Makefile
>> +++ b/cmd/mvebu/Makefile
>> @@ -6,3 +6,5 @@
>>
>>   obj-$(CONFIG_CMD_MVEBU_BUBT) += bubt.o
>>   obj-$(CONFIG_CMD_MVEBU_COMPHY_RX_TRAINING) += comphy_rx_training.o
>> +obj-$(CONFIG_CMD_MVEBU_HW_INFO) += hw_info.o
>> +
>> diff --git a/cmd/mvebu/hw_info.c b/cmd/mvebu/hw_info.c
>> new file mode 100644
>> index 0000000000..1ef49d78d4
>> --- /dev/null
>> +++ b/cmd/mvebu/hw_info.c
>> @@ -0,0 +1,312 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Marvell hw_info command
>> + * Helper command for interfacing with the Marvell hw_info parameters
>> + *
>> + * Copyright (c) 2021 Sartura Ltd.
>> + * Copyright (c) 2018 Marvell International Ltd.
>> + *
>> + * Author: Luka Kovacic <luka.kovacic@sartura.hr>
>> + */
>> +
>> +#include <command.h>
>> +#include <common.h>
>> +#include <env.h>
>> +#include <env_internal.h>
>> +#include <spi.h>
>> +#include <spi_flash.h>
>> +
>> +#define HW_INFO_SPI_FLASH_OFFSET       CONFIG_CMD_MVEBU_HW_INFO_OFFSET
>> +
>> +#define HW_INFO_MAX_ENV_SIZE           0x1F0
>> +#define HW_INFO_ENV_OFFSET             0xA
>> +#define HW_INFO_ENV_SEP                        0x20
>> +
>> +#define HW_INFO_MAX_NAME_LEN           32
>> +
>> +static char hw_info_allowed_parameters[][HW_INFO_MAX_NAME_LEN] = {
>> +       "pcb_slm",
>> +       "pcb_rev",
>> +       "eco_rev",
>> +       "pcb_sn",
>> +       "ethaddr",
>> +       "eth1addr",
>> +       "eth2addr",
>> +       "eth3addr",
>> +       "eth4addr",
>> +       "eth5addr",
>> +       "eth6addr",
>> +       "eth7addr",
>> +       "eth8addr",
>> +       "eth9addr",
>> +};
>> +
>> +static int hw_info_allowed_param_count = (sizeof(hw_info_allowed_parameters) /
>> +                                       sizeof(hw_info_allowed_parameters[0]));
>> +
>> +static int hw_info_check_parameter(char *name)
>> +{
>> +       int idx;
>> +
>> +       for (idx = 0; idx < hw_info_allowed_param_count; idx++) {
>> +               if (strcmp(name, hw_info_allowed_parameters[idx]) == 0)
>> +                       return 0;
>> +       }
>> +
>> +       return -EINVAL;
>> +}
>> +
>> +static int read_spi_flash_offset(char *buf, int offset)
>> +{
>> +       struct spi_flash *flash;
>> +       int ret;
>> +
>> +       flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
>> +                               CONFIG_SF_DEFAULT_CS,
>> +                               CONFIG_SF_DEFAULT_SPEED,
>> +                               CONFIG_SF_DEFAULT_MODE);
>> +
>> +       if (!flash) {
>> +               printf("Error - unable to probe SPI flash.\n");
>> +               return -EIO;
>> +       }
>> +
>> +       ret = spi_flash_read(flash, offset, HW_INFO_MAX_ENV_SIZE, buf);
>> +       if (ret) {
>> +               printf("Error - unable to read hw_info environment from SPI flash.\n");
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static int write_spi_flash_offset(char *buf, int offset, ssize_t size)
>> +{
>> +       ssize_t safe_size, erase_size;
>> +       struct spi_flash *flash;
>> +       int ret;
>> +
>> +       flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
>> +                               CONFIG_SF_DEFAULT_CS,
>> +                               CONFIG_SF_DEFAULT_SPEED,
>> +                               CONFIG_SF_DEFAULT_MODE);
>> +
>> +       if (!flash) {
>> +               printf("Error - unable to probe SPI flash.\n");
>> +               return -EIO;
>> +       }
>> +
>> +       safe_size = size > HW_INFO_MAX_ENV_SIZE ? HW_INFO_MAX_ENV_SIZE : size;
>> +       erase_size = safe_size +
>> +                    (flash->erase_size - safe_size % flash->erase_size);
>> +       ret = spi_flash_erase(flash, HW_INFO_SPI_FLASH_OFFSET, erase_size);
>> +       if (ret) {
>> +               printf("Error - unable to erase the hw_info area on SPI flash.\n");
>> +               return ret;
>> +       }
>> +       ret = spi_flash_write(flash, offset, safe_size, buf);
>> +       if (ret) {
>> +               printf("Error - unable to write hw_info parameters to SPI flash.\n");
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static int cmd_hw_info_dump(void)
>> +{
>> +       char buffer[HW_INFO_MAX_ENV_SIZE];
>> +       struct hsearch_data htab;
>> +       char *res = NULL;
>> +       ssize_t len;
>> +       int ret = 0;
>> +
>> +       ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
>> +                                   HW_INFO_ENV_OFFSET);
>> +       if (ret)
>> +               goto err;
>> +       memset(&htab, 0, sizeof(htab));
>> +       if (!hcreate_r(HW_INFO_MAX_ENV_SIZE, &htab)) {
>> +               ret = -ENOMEM;
>> +               goto err;
>> +       }
>> +       if (!himport_r(&htab, buffer, HW_INFO_MAX_ENV_SIZE,
>> +                      HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
>> +               ret = -EFAULT;
>> +               goto err_htab;
>> +       }
>> +
>> +       len = hexport_r(&htab, '\n', H_HIDE_DOT, &res, 0, 0, NULL);
>> +       if (len > 0) {
>> +               printf("Parameters (hw_info):\n");
>> +               puts(res);
>> +               free(res);
>> +               ret = 0;
>> +               goto ret_htab;
>> +       }
>> +ret_htab:
>> +       hdestroy_r(&htab);
>> +       return ret;
>> +err_htab:
>> +       hdestroy_r(&htab);
>> +err:
>> +       printf("## Error: cannot store hw_info parameters to SPI flash\n");
>> +       return ret;
>> +}
>> +
>> +static int cmd_hw_info_load(bool print_env)
>> +{
>> +       char buffer[HW_INFO_MAX_ENV_SIZE];
>> +       char *res = NULL;
>> +       ssize_t len;
>> +       int ret = 0;
>> +
>> +       ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
>> +                                   HW_INFO_ENV_OFFSET);
>> +       if (ret)
>> +               goto err;
>> +       if (!himport_r(&env_htab, buffer, HW_INFO_MAX_ENV_SIZE,
>> +                      HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
>> +               ret = -EFAULT;
>> +               goto err;
>> +       }
>> +
>> +       printf("Successfully imported the Marvell hw_info parameters.\n");
>> +       if (!print_env)
>> +               return 0;
>> +
>> +       len = hexport_r(&env_htab, '\n', H_HIDE_DOT, &res, 0, 0, NULL);
>> +       if (len > 0) {
>> +               printf("Updated environment:\n");
>> +               puts(res);
>> +               free(res);
>> +               return 0;
>> +       }
>> +err:
>> +       printf("## Error: cannot import hw_info parameters\n");
>> +       return ret;
>> +}
>> +
>> +static int cmd_hw_info_store(char *name)
>> +{
>> +       char buffer[HW_INFO_MAX_ENV_SIZE];
>> +       struct env_entry e, *ep, *rv;
>> +       struct hsearch_data htab;
>> +       char *res = NULL;
>> +       ssize_t len;
>> +       int ret = 0;
>> +
>> +       ret = hw_info_check_parameter(name);
>> +       if (ret) {
>> +               printf("Invalid parameter %s, stopping.\n", name);
>> +               goto err;
>> +       }
>> +
>> +       ret = read_spi_flash_offset(buffer, HW_INFO_SPI_FLASH_OFFSET +
>> +                                   HW_INFO_ENV_OFFSET);
>> +       if (ret)
>> +               goto err;
>> +       memset(&htab, 0, sizeof(htab));
>> +       if (!hcreate_r(HW_INFO_MAX_ENV_SIZE, &htab)) {
>> +               ret = -ENOMEM;
>> +               goto err;
>> +       }
>> +       if (!himport_r(&htab, buffer, HW_INFO_MAX_ENV_SIZE,
>> +                      HW_INFO_ENV_SEP, H_NOCLEAR, 0, 0, NULL)) {
>> +               ret = -EFAULT;
>> +               goto err_htab;
>> +       }
>> +
>> +       e.key = name;
>> +       e.data = NULL;
>> +       if (!hsearch_r(e, ENV_FIND, &ep, &env_htab, H_HIDE_DOT)) {
>> +               ret = -ENOENT;
>> +               goto err_htab;
>> +       }
>> +       if (!ep) {
>> +               ret = -ENOENT;
>> +               goto err_htab;
>> +       }
>> +
>> +       printf("Storing %s=%s to hw_info...\n", ep->key, ep->data);
>> +
>> +       e.key = ep->key;
>> +       e.data = ep->data;
>> +       if (!hsearch_r(e, ENV_ENTER, &rv, &htab, H_HIDE_DOT)) {
>> +               ret = -EINVAL;
>> +               goto err_htab;
>> +       }
>> +       if (!rv) {
>> +               ret = -EINVAL;
>> +               goto err_htab;
>> +       }
>> +       len = hexport_r(&htab, HW_INFO_ENV_SEP, H_MATCH_KEY | H_MATCH_IDENT,
>> +                       &res, 0, 0, NULL);
>> +       if (len <= 0) {
>> +               free(res);
>> +               goto ret_htab;
>> +       }
>> +       ret = write_spi_flash_offset(res, HW_INFO_SPI_FLASH_OFFSET +
>> +                                    HW_INFO_ENV_OFFSET, len);
>> +       free(res);
>> +       if (ret)
>> +               goto err_htab;
>> +
>> +       printf("Successfully stored the Marvell hw_info parameters.\n");
>> +       return 0;
>> +ret_htab:
>> +       hdestroy_r(&htab);
>> +       return ret;
>> +err_htab:
>> +       hdestroy_r(&htab);
>> +err:
>> +       printf("## Error: cannot store hw_info parameters to SPI flash\n");
>> +       return ret;
>> +}
>> +
>> +static int do_hw_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>> +{
>> +       const char *cmd = argv[1];
>> +
>> +       if (argc < 2)
>> +               return CMD_RET_USAGE;
>> +
>> +       if (!strcmp(cmd, "dump")) {
>> +               if (cmd_hw_info_dump())
>> +                       return -EINVAL;
>> +       } else if (!strcmp(cmd, "load")) {
>> +               if (cmd_hw_info_load(true))
>> +                       return -EINVAL;
>> +       } else if (!strcmp(cmd, "store")) {
>> +               if (cmd_hw_info_store(argv[2]))
>> +                       return -EINVAL;
>> +       } else {
>> +               return CMD_RET_USAGE;
>> +       }
>> +
>> +       return CMD_RET_SUCCESS;
>> +}
>> +
>> +U_BOOT_CMD(
>> +       hw_info, 3, 0, do_hw_info,
>> +       "Marvell hw_info utility",
>> +       "hw_info\n"
>> +       "\tdump                        - Dump all hw_info parameters from SPI flash\n"
>> +       "\tload                        - Load all hw_info parameters from hw_info to environment variables\n"
>> +       "\tstore <env_name>            - Store specific hw_info parameter from envirnoment variable to SPI flash\n"
>> +       "\nSupported hw_info parameters:\n"
>> +       "\tpcb_slm       PCB SLM number\n"
>> +       "\tpcb_rev       PCB revision number\n"
>> +       "\teco_rev       ECO revision number\n"
>> +       "\tpcb_sn        PCB SN\n"
>> +       "\tethaddr       first MAC address\n"
>> +       "\teth1addr      second MAC address\n"
>> +       "\teth2addr      third MAC address\n"
>> +       "\teth3addr      fourth MAC address\n"
>> +       "\teth4addr      fifth MAC address\n"
>> +       "\teth5addr      sixth MAC address\n"
>> +       "\teth6addr      seventh MAC address\n"
>> +       "\teth7addr      eighth MAC address\n"
>> +       "\teth8addr      ninth MAC address\n"
>> +       "\teth9addr      tenth MAC address\n"
>> +);
>> diff --git a/lib/hashtable.c b/lib/hashtable.c
>> index ff5ff72639..06322e3304 100644
>> --- a/lib/hashtable.c
>> +++ b/lib/hashtable.c
>> @@ -794,7 +794,7 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[])
>>    * multi-line values.
>>    *
>>    * In theory, arbitrary separator characters can be used, but only
>> - * '\0' and '\n' have really been tested.
>> + * '\0', '\n' and 0x20 have been tested.
>>    */
>>
>>   int himport_r(struct hsearch_data *htab,
>> --
>> 2.30.2
>>
> Kind regards,
> Luka Kovacic

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-08-11 12:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-11  8:35 [PATCH 0/3] Add support for the GST ESPRESSOBin-Ultra board Gerald Kerma
2021-08-11  8:35 ` [PATCH 1/3] cmd: mvebu: Implement the Marvell hw_info command Gerald Kerma
2021-08-11 10:15   ` Luka Kovacic
2021-08-11 10:54     ` Gérald Kerma
2021-08-11  8:35 ` [PATCH 2/3] arm: mvebu: mvebu_armada-37xx: Define the loadaddr environment variable Gerald Kerma
2021-08-11  8:35 ` [PATCH 3/3] arm: mvebu: Initial ESPRESSOBin-Ultra board support Gerald Kerma

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.