[PATCH u-boot-marvell v3 35/39] tools: kwboot: Avoid code repetition in kwboot_img_patch()

2021-09-24 Thread Marek Behún
From: Marek Behún 

Change kwboot_img_patch() to avoid code repetition of setting errno to
EINVAL.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 55 ++
 1 file changed, 20 insertions(+), 35 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 9eb007f1bb..9da5b42ebf 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -1386,7 +1386,6 @@ _copy_baudrate_change_code(struct main_hdr_v1 *hdr, void 
*dst, int pre,
 static int
 kwboot_img_patch(void *img, size_t *size, int baudrate)
 {
-   int rc;
struct main_hdr_v1 *hdr;
uint32_t srcaddr;
uint8_t csum;
@@ -1394,33 +1393,25 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
int image_ver;
int is_secure;
 
-   rc = -1;
hdr = img;
 
-   if (*size < sizeof(struct main_hdr_v1)) {
-   errno = EINVAL;
-   goto out;
-   }
+   if (*size < sizeof(struct main_hdr_v1))
+   goto err;
 
image_ver = kwbimage_version(img);
if (image_ver != 0 && image_ver != 1) {
fprintf(stderr, "Invalid image header version\n");
-   errno = EINVAL;
-   goto out;
+   goto err;
}
 
hdrsz = kwbheader_size(hdr);
 
-   if (*size < hdrsz) {
-   errno = EINVAL;
-   goto out;
-   }
+   if (*size < hdrsz)
+   goto err;
 
csum = kwboot_hdr_csum8(hdr) - hdr->checksum;
-   if (csum != hdr->checksum) {
-   errno = EINVAL;
-   goto out;
-   }
+   if (csum != hdr->checksum)
+   goto err;
 
if (image_ver == 0) {
struct main_hdr_v0 *hdr_v0 = img;
@@ -1433,10 +1424,9 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
 
switch (hdr->blockid) {
case IBR_HDR_SATA_ID:
-   if (srcaddr < 1) {
-   errno = EINVAL;
-   goto out;
-   }
+   if (srcaddr < 1)
+   goto err;
+
hdr->srcaddr = cpu_to_le32((srcaddr - 1) * 512);
break;
 
@@ -1459,10 +1449,8 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
}
 
if (hdrsz > le32_to_cpu(hdr->srcaddr) ||
-   *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize)) {
-   errno = EINVAL;
-   goto out;
-   }
+   *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize))
+   goto err;
 
is_secure = kwboot_img_is_secure(img);
 
@@ -1470,8 +1458,7 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
if (is_secure) {
fprintf(stderr,
"Image has secure header with signature for 
non-UART booting\n");
-   errno = EINVAL;
-   goto out;
+   goto err;
}
 
kwboot_printv("Patching image boot signature to UART\n");
@@ -1485,15 +1472,13 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
if (image_ver == 0) {
fprintf(stderr,
"Cannot inject code for changing baudrate into 
v0 image header\n");
-   errno = EINVAL;
-   goto out;
+   goto err;
}
 
if (is_secure) {
fprintf(stderr,
"Cannot inject code for changing baudrate into 
image with secure header\n");
-   errno = EINVAL;
-   goto out;
+   goto err;
}
 
/*
@@ -1529,8 +1514,7 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
 
if (is_secure) {
fprintf(stderr, "Cannot align image with secure 
header\n");
-   errno = EINVAL;
-   goto out;
+   goto err;
}
 
kwboot_printv("Aligning image header to Xmodem block size\n");
@@ -1540,9 +1524,10 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
hdr->checksum = kwboot_hdr_csum8(hdr) - csum;
 
*size = le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize);
-   rc = 0;
-out:
-   return rc;
+   return 0;
+err:
+   errno = EINVAL;
+   return -1;
 }
 
 static void
-- 
2.32.0



[PATCH u-boot-marvell v3 31/39] tools: kwboot: Fix initializing tty device

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Retrieve current terminal settings via tcgetattr(), set to raw mode with
cfmakeraw(), enable receiver via CREAD and ignore modem control lines
via CLOCAL.

Signed-off-by: Pali Rohár 
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index d8b950787b..fc83161d70 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -648,11 +648,12 @@ kwboot_open_tty(const char *path, int baudrate)
if (fd < 0)
goto out;
 
-   memset(, 0, sizeof(tio));
-
-   tio.c_iflag = 0;
-   tio.c_cflag = CREAD|CLOCAL|CS8;
+   rc = tcgetattr(fd, );
+   if (rc)
+   goto out;
 
+   cfmakeraw();
+   tio.c_cflag |= CREAD|CLOCAL;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 10;
 
-- 
2.32.0



[PATCH u-boot-marvell v3 32/39] tools: kwboot: Disable tty interbyte timeout

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Function kwboot_tty_recv() has its own handling of read timeout, we
don't need to do set it in tty settings.

Signed-off-by: Pali Rohár 
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index fc83161d70..a527c79cf3 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -655,7 +655,7 @@ kwboot_open_tty(const char *path, int baudrate)
cfmakeraw();
tio.c_cflag |= CREAD|CLOCAL;
tio.c_cc[VMIN] = 1;
-   tio.c_cc[VTIME] = 10;
+   tio.c_cc[VTIME] = 0;
 
rc = tcsetattr(fd, TCSANOW, );
if (rc)
-- 
2.32.0



[PATCH u-boot-marvell v3 36/39] tools: kwboot: Update file header

2021-09-24 Thread Marek Behún
From: Marek Behún 

Mention all supported platforms in file header.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 9da5b42ebf..6fa6dff04d 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -1,6 +1,7 @@
 /*
  * Boot a Marvell SoC, with Xmodem over UART0.
- *  supports Kirkwood, Dove, Armada 370, Armada XP
+ *  supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
+ *   Armada 39x
  *
  * (c) 2012 Daniel Stodden 
  *
-- 
2.32.0



[PATCH u-boot-marvell v3 39/39] MAINTAINERS: Add entry for kwbimage / kwboot tools

2021-09-24 Thread Marek Behún
From: Marek Behún 

Add entry for these tools with Marek, Pali and Stefan as maintainers.

Signed-off-by: Marek Behún 
---
 MAINTAINERS | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 67c96a6045..6f103230da 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -776,6 +776,16 @@ S: Maintained
 T: git https://source.denx.de/u-boot/custodians/u-boot-i2c.git
 F: drivers/i2c/
 
+KWBIMAGE / KWBOOT TOOLS
+M: Pali Rohár 
+M: Marek Behún 
+M: Stefan Roese 
+S: Maintained
+T: git https://source.denx.de/u-boot/custodians/u-boot-marvell.git
+F: doc/README.kwbimage
+F: doc/kwboot.1
+F: tools/kwb*
+
 LOGGING
 M: Simon Glass 
 S: Maintained
-- 
2.32.0



Re: [PATCH v4 0/2] mtd: spi: nor: force mtd name to "nor%d"

2021-09-24 Thread Marek Behún
On Fri, 24 Sep 2021 22:09:15 +0200
Marek Vasut  wrote:

> I have a feeling the discussion is again banking toward "mtdparts" and 
> "DT", which really is a solved problem, or at least we agreed upon the 
> solution.

I was trying to explain to Patrick how he can convert the ST board so
that the mtd partitions will be defined in DT and board code won't need
mtdids if he also converts to distro boot correctly.

> The patch is trying to fix MTDIDS and their look up in 
> get_mtd_device_nm(). This is all U-Boot stuff, it has nothing to do with 
> passing mtd partitions to Linux at all.

The solution here is to get rid of MTDIDS also. But I guess this will
take some time, so it does make sense for get_mtd_device_nm() to
return the same device as previously when given argument "norN".

The reason why I put SPI NOR name into mtd->name was because otherwise
the `mtd list` command did not print that name anywhere (since it
doesn't know how, because that SPI-NOR data are private for the
jedec_spi_nor driver).

Since
- every mtd device has mtd->type, for NOR flash this is MTD_NORFLASH
- we can iterate mtd devices in order they were registered
  (mtd_for_each_device does this)
we can easily implement a function
  get_mtd_device_by_type_and_id()
that, when given string "norN" will find the N-th mtd device of type
MTD_NORFLASH.

This function could than be called from get_mtd_device_nm() if
everything failed, or in some other way.

Tom, Marek, Patrick, what do you think?

Marek


Re: about mtd erase fix series

2021-09-24 Thread Marek Behún
On Fri, 24 Sep 2021 20:00:31 -0400
Tom Rini  wrote:

> On Sat, Sep 25, 2021 at 01:49:26AM +0200, Marek Behún wrote:
> 
> > Hi Tom, Jagan,
> > 
> > in July I resent the series
> >   Fix `mtd erase` when used with mtdpart
> > https://patchwork.ozlabs.org/project/uboot/list/?series=253565=*
> > 
> > There was a build error in CI, more info at 
> >   https://lists.denx.de/pipermail/u-boot/2021-July/455851.html
> > 
> > The CI link mentioned
> >   https://source.denx.de/u-boot/custodians/u-boot-spi/-/pipelines/8345
> > gives 404 now.
> > 
> > Jagan, could you please retrigger CI for this, and send me results?
> > The series still applied cleanly on master branch and compiled for my
> > config.
> > 
> > The fix is needed for `mtd erase`.  
> 
> Note that you can trigger a CI run yourself via github, to run on Azure.
> See doc/develop/ci_testing.rst in tree for more details.
> 

Hm, and it seems I was already working on this, since I put another
commit there that is not on mailing list. Ok, I will try to fix this
and resend.

Marek


[PATCH u-boot-marvell 8/9] arm: mvebu: a38x: serdes: Remove unused PCIe macros and functions

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Remove unused PCIe functions from SerDes code. They are unused and are
duplicated either from generic PCIe code or from pci_mvebu.c.

Remove also unused PCIe macros from SerDes code. They are just obfuscated
variants of standards macros in include/pci.h or in pci_mvebu.c.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c | 128 -
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h |  60 --
 2 files changed, 188 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
index 0445b43def..55c3f9ca39 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
@@ -62,131 +62,3 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 
count)
 
return MV_OK;
 }
-
-int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
-{
-   u32 pex_status;
-
-   DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
-
-   if (bus_num >= MAX_PEX_BUSSES) {
-   DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
-bus_num, 4);
-   return MV_BAD_PARAM;
-   }
-
-   pex_status = reg_read(PEX_STATUS_REG(pex_if));
-   pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
-   pex_status |=
-   (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
-   reg_write(PEX_STATUS_REG(pex_if), pex_status);
-
-   return MV_OK;
-}
-
-int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
-{
-   u32 pex_status;
-
-   DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
-
-   pex_status = reg_read(PEX_STATUS_REG(pex_if));
-   pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
-   pex_status |=
-   (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
-   reg_write(PEX_STATUS_REG(pex_if), pex_status);
-
-   return MV_OK;
-}
-
-/*
- * pex_config_read - Read from configuration space
- *
- * DESCRIPTION:
- *   This function performs a 32 bit read from PEX configuration space.
- *   It supports both type 0 and type 1 of Configuration Transactions
- *   (local and over bridge). In order to read from local bus segment, use
- *   bus number retrieved from pex_local_bus_num_get(). Other bus numbers
- *   will result configuration transaction of type 1 (over bridge).
- *
- * INPUT:
- *   pex_if   - PEX interface number.
- *   bus  - PEX segment bus number.
- *   dev  - PEX device number.
- *   func - Function number.
- *   reg_offs - Register offset.
- *
- * OUTPUT:
- *   None.
- *
- * RETURN:
- *   32bit register data, 0x on error
- */
-u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
-{
-   u32 pex_data = 0;
-   u32 local_dev, local_bus;
-   u32 pex_status;
-
-   pex_status = reg_read(PEX_STATUS_REG(pex_if));
-   local_dev =
-   ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
-   local_bus =
-   ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
-
-   /*
-* In PCI Express we have only one device number
-* and this number is the first number we encounter
-* else that the local_dev
-* spec pex define return on config read/write on any device
-*/
-   if (bus == local_bus) {
-   if (local_dev == 0) {
-   /*
-* if local dev is 0 then the first number we encounter
-* after 0 is 1
-*/
-   if ((dev != 1) && (dev != local_dev))
-   return MV_ERROR;
-   } else {
-   /*
-* if local dev is not 0 then the first number we
-* encounter is 0
-*/
-   if ((dev != 0) && (dev != local_dev))
-   return MV_ERROR;
-   }
-   }
-
-   /* Creating PEX address to be passed */
-   pex_data = (bus << PXCAR_BUS_NUM_OFFS);
-   pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
-   pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
-   /* Legacy register space */
-   pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
-   /* Extended register space */
-   pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
- PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
-   pex_data |= PXCAR_CONFIG_EN;
-
-   /* Write the address to the PEX configuration address register */
-   reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
-
-   /*
-* In order to let the PEX controller absorbed the address
-* of the read transaction we perform a validity check that
-  

[PATCH u-boot-marvell 7/9] arm: mvebu: a38x: serdes: Don't configure PCIe cards in SerDes init code

2021-09-24 Thread Marek Behún
From: Pali Rohár 

This code is trying to parse PCIe config space of PCIe card connected on
the other end of link and then is trying to force 5.0 GT/s speed via Target
Link Speed bits in PCIe Root Port Link Control 2 Register on the local part
of link if it sees that card supports 5.0 GT/s via Max Link Speed bits in
Link Capabilities Register.

The code is incorrect for more reasons:
- Accessing config space of an endpoint card cannot be done immediately.
  If the PCIe link is not up, reading vendor/device ID registers will
  return all ones.
- Parsing is incomplete, so it can cause issues even for working cards.

Moreover there is no need to force speed to 5.0 GT/s via Target Link Speed
bits on PCIe Root Port Link Control 2 Register. Hardware changes speed from
2.5 GT/s to 5.0 GT/s autonomously when it is supported.

Most importantly, this code does not change link speed at all, since
because after updating Target Link Speed bits on PCIe Root Port Link
Control 2 Register, it is required to retrain the link, and the code for
that is completely missing.

The code was probably needed for making buggy endpoint cards work. Such a
workaround, though, should be implemented via PCIe subsystem (via quirks,
for example), as buggy cards could also affect other PCIe controllers.

Note that this code is fully unrelated to a38x SerDes code and really
should not have been included in SerDes initialization. Usage of magic
constants without names and comments made this SerDes code hard to read and
understand.

Remove this PCIe application code from low level SerDes code. As this code
is configuring only 5.0 GT/s part, in the worst case, it could leave buggy
cards at the initial speed of 2.5 GT/s (if somehow before this change they
could have been "upgraded" to 5.0 GT/s speed even with missing link
retraining). Compliant cards which just need longer initialization should
work better after this change.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c | 128 +
 1 file changed, 1 insertion(+), 127 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
index a7e45a5550..0445b43def 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
@@ -21,10 +21,8 @@ __weak void board_pex_config(void)
 
 int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
 {
-   u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
-   temp_reg, addr, dev_id, ctrl_mode;
enum serdes_type serdes_type;
-   u32 idx;
+   u32 idx, tmp;
 
DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
 
@@ -60,132 +58,8 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 
count)
 
reg_write(SOC_CONTROL_REG1, tmp);
 
-   /* Support gen1/gen2 */
-   DEBUG_INIT_FULL_S("Support gen1/gen2\n");
-
board_pex_config();
 
-   next_busno = 0;
-   mdelay(150);
-
-   for (idx = 0; idx < count; idx++) {
-   serdes_type = serdes_map[idx].serdes_type;
-   DEBUG_INIT_FULL_S(" serdes_type=0x");
-   DEBUG_INIT_FULL_D(serdes_type, 8);
-   DEBUG_INIT_FULL_S("\n");
-   DEBUG_INIT_FULL_S(" idx=0x");
-   DEBUG_INIT_FULL_D(idx, 8);
-   DEBUG_INIT_FULL_S("\n");
-
-   /* Configuration for PEX only */
-   if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
-   (serdes_type != PEX2) && (serdes_type != PEX3))
-   continue;
-
-   if ((serdes_type != PEX0) &&
-   ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
-(serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
-   /* for PEX by4 - relevant for the first port only */
-   continue;
-   }
-
-   pex_idx = serdes_type - PEX0;
-   tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
-
-   first_busno = next_busno;
-   if ((tmp & 0x7f) != 0x7e) {
-   DEBUG_INIT_S("PCIe, Idx ");
-   DEBUG_INIT_D(pex_idx, 1);
-   DEBUG_INIT_S(": detected no link\n");
-   continue;
-   }
-
-   next_busno++;
-
-   /*
-* Read maximum link speed. It must be 0x2 (5.0 GT/s) as this
-* value was set in serdes_power_up_ctrl() function.
-*/
-   temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
-(pex_idx, PEX_LINK_CAPABILITY_REG)));
-   temp_pex_reg &= 0xf;
-   if (temp_pex_reg != 0x2)
-   continue;
-
-   /* Read nego

[PATCH u-boot-marvell v3 22/39] tools: kwboot: Patch destination address to DDR area for SPI image

2021-09-24 Thread Marek Behún
From: Pali Rohár 

SPI/NOR kwbimage may have destination address set to 0x, which
means that the image is not downloaded to DDR but rather it is executed
directly from SPI/NOR. In this case execution address is set to SPI/NOR
area.

When patching image to UART type, change destination and execution
addresses from SPI/NOR XIP area to DDR area 0x0080 (which is default
for A38x).

Signed-off-by: Pali Rohár 
[ refactored ]
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 907a574bfc..b1dcd3796c 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -836,6 +836,14 @@ kwboot_img_patch_hdr(void *img, size_t size)
if (srcaddr == 0x)
hdr->srcaddr = cpu_to_le32(hdrsz);
break;
+
+   case IBR_HDR_SPI_ID:
+   if (hdr->destaddr == cpu_to_le32(0x)) {
+   kwboot_printv("Patching destination and execution 
addresses from SPI/NOR XIP area to DDR area 0x0080\n");
+   hdr->destaddr = cpu_to_le32(0x0080);
+   hdr->execaddr = cpu_to_le32(0x0080);
+   }
+   break;
}
 
is_secure = kwboot_img_is_secure(img);
-- 
2.32.0



[PATCH u-boot-marvell v3 21/39] tools: kwboot: Patch source address in image header

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Some image types have source address in non-bytes unit; for example for
SATA images, it is in 512 B units.

We need to multiply by unit size when patching image type to UART.

Signed-off-by: Pali Rohár 
[ refactored ]
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 40 +---
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 2446d0a7b5..907a574bfc 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -773,6 +773,7 @@ kwboot_img_patch_hdr(void *img, size_t size)
 {
int rc;
struct main_hdr_v1 *hdr;
+   uint32_t srcaddr;
uint8_t csum;
size_t hdrsz = sizeof(*hdr);
int image_ver;
@@ -809,6 +810,34 @@ kwboot_img_patch_hdr(void *img, size_t size)
goto out;
}
 
+   if (image_ver == 0) {
+   struct main_hdr_v0 *hdr_v0 = img;
+
+   hdr_v0->nandeccmode = IBR_HDR_ECC_DISABLED;
+   hdr_v0->nandpagesize = 0;
+   }
+
+   srcaddr = le32_to_cpu(hdr->srcaddr);
+
+   switch (hdr->blockid) {
+   case IBR_HDR_SATA_ID:
+   if (srcaddr < 1) {
+   errno = EINVAL;
+   goto out;
+   }
+   hdr->srcaddr = cpu_to_le32((srcaddr - 1) * 512);
+   break;
+
+   case IBR_HDR_SDIO_ID:
+   hdr->srcaddr = cpu_to_le32(srcaddr * 512);
+   break;
+
+   case IBR_HDR_PEX_ID:
+   if (srcaddr == 0x)
+   hdr->srcaddr = cpu_to_le32(hdrsz);
+   break;
+   }
+
is_secure = kwboot_img_is_secure(img);
 
if (hdr->blockid != IBR_HDR_UART_ID) {
@@ -823,17 +852,6 @@ kwboot_img_patch_hdr(void *img, size_t size)
hdr->blockid = IBR_HDR_UART_ID;
}
 
-   if (image_ver == 0) {
-   struct main_hdr_v0 *hdr_v0 = img;
-
-   hdr_v0->nandeccmode = IBR_HDR_ECC_DISABLED;
-   hdr_v0->nandpagesize = 0;
-
-   hdr_v0->srcaddr = hdr_v0->ext
-   ? sizeof(struct kwb_header)
-   : sizeof(*hdr_v0);
-   }
-
hdr->checksum = kwboot_img_csum8(hdr, hdrsz) - csum;
 
rc = 0;
-- 
2.32.0



[PATCH u-boot-marvell v3 20/39] tools: kwboot: Don't patch image header if signed

2021-09-24 Thread Marek Behún
From: Pali Rohár 

It is not possible to modify image with secure header due to
cryptographic signature.

Signed-off-by: Pali Rohár 
[ refactored ]
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 30 +-
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 9394a51380..2446d0a7b5 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -756,6 +756,18 @@ kwboot_img_csum8(void *_data, size_t size)
return csum;
 }
 
+static int
+kwboot_img_is_secure(void *img)
+{
+   struct opt_hdr_v1 *ohdr;
+
+   for_each_opt_hdr_v1 (ohdr, img)
+   if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE)
+   return 1;
+
+   return 0;
+}
+
 static int
 kwboot_img_patch_hdr(void *img, size_t size)
 {
@@ -764,6 +776,7 @@ kwboot_img_patch_hdr(void *img, size_t size)
uint8_t csum;
size_t hdrsz = sizeof(*hdr);
int image_ver;
+   int is_secure;
 
rc = -1;
hdr = img;
@@ -796,12 +809,19 @@ kwboot_img_patch_hdr(void *img, size_t size)
goto out;
}
 
-   if (hdr->blockid == IBR_HDR_UART_ID) {
-   rc = 0;
-   goto out;
-   }
+   is_secure = kwboot_img_is_secure(img);
 
-   hdr->blockid = IBR_HDR_UART_ID;
+   if (hdr->blockid != IBR_HDR_UART_ID) {
+   if (is_secure) {
+   fprintf(stderr,
+   "Image has secure header with signature for 
non-UART booting\n");
+   errno = EINVAL;
+   goto out;
+   }
+
+   kwboot_printv("Patching image boot signature to UART\n");
+   hdr->blockid = IBR_HDR_UART_ID;
+   }
 
if (image_ver == 0) {
struct main_hdr_v0 *hdr_v0 = img;
-- 
2.32.0



[PATCH u-boot-marvell v3 34/39] tools: kwboot: Cosmetic fix

2021-09-24 Thread Marek Behún
From: Marek Behún 

Add spaces around the | operator.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 5e491f31a4..9eb007f1bb 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -644,7 +644,7 @@ kwboot_open_tty(const char *path, int baudrate)
 
rc = -1;
 
-   fd = open(path, O_RDWR|O_NOCTTY|O_NDELAY);
+   fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0)
goto out;
 
@@ -653,7 +653,7 @@ kwboot_open_tty(const char *path, int baudrate)
goto out;
 
cfmakeraw();
-   tio.c_cflag |= CREAD|CLOCAL;
+   tio.c_cflag |= CREAD | CLOCAL;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
 
@@ -1137,7 +1137,7 @@ kwboot_terminal(int tty)
}
 
kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
- quit[0]|0100, quit[1]);
+ quit[0] | 0100, quit[1]);
} else
in = -1;
 
-- 
2.32.0



[PATCH u-boot-marvell v3 25/39] tools: kwbimage: Update comments describing kwbimage v1 structures

2021-09-24 Thread Marek Behún
From: Pali Rohár 

These structures are relevant for several other platforms, mention them
all.

Signed-off-by: Pali Rohár 
Signed-off-by: Marek Behún 
---
 tools/kwbimage.c | 3 ++-
 tools/kwbimage.h | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index d1f4f93e0f..77bf4dd886 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Image manipulator for Marvell SoCs
- *  supports Kirkwood, Dove, Armada 370, Armada XP, and Armada 38x
+ *  supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
+ *  Armada 39x
  *
  * (C) Copyright 2013 Thomas Petazzoni
  * 
diff --git a/tools/kwbimage.h b/tools/kwbimage.h
index 56a748d4cf..679c454367 100644
--- a/tools/kwbimage.h
+++ b/tools/kwbimage.h
@@ -69,7 +69,7 @@ struct ext_hdr_v0 {
uint8_t   checksum;
 } __packed;
 
-/* Structure of the main header, version 1 (Armada 370/38x/XP) */
+/* Structure of the main header, version 1 (Armada 370/XP/375/38x/39x) */
 struct main_hdr_v1 {
uint8_t  blockid;   /* 0x0   */
uint8_t  flags; /* 0x1   */
@@ -103,7 +103,7 @@ struct main_hdr_v1 {
 #define MAIN_HDR_V1_OPT_BAUD_1152000x7
 
 /*
- * Header for the optional headers, version 1 (Armada 370, Armada XP)
+ * Header for the optional headers, version 1 (Armada 370/XP/375/38x/39x)
  */
 struct opt_hdr_v1 {
uint8_t  headertype;
@@ -127,7 +127,7 @@ struct sig_v1 {
 } __packed;
 
 /*
- * Structure of secure header (Armada 38x)
+ * Structure of secure header (Armada XP/375/38x/39x)
  */
 struct secure_hdr_v1 {
uint8_t  headertype;/* 0x0 */
-- 
2.32.0



[PATCH u-boot-marvell v3 37/39] tools: kwboot: Add Pali and Marek as authors

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Add Pali and Marek as another authors of the kwboot utility.

Signed-off-by: Pali Rohár 
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 6fa6dff04d..6a1a030308 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -4,6 +4,8 @@
  *   Armada 39x
  *
  * (c) 2012 Daniel Stodden 
+ * (c) 2021 Pali Rohár 
+ * (c) 2021 Marek Behún 
  *
  * References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
  *   Integrated Controller: Functional Specifications" December 2,
-- 
2.32.0



[PATCH u-boot-marvell 9/9] arm: mvebu: a38x: serdes: Update comment about PCIE*_ENABLE_* defines

2021-09-24 Thread Marek Behún
From: Pali Rohár 

These are part of SOC_CONTROL_REG1 register, not PEX_CAPABILITIES_REG.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
index 55a4c267c4..64193d5288 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
@@ -12,7 +12,7 @@
 /* Direct access to PEX0 Root Port's PCIe Capability structure */
 #define PEX0_RP_PCIE_CFG_OFFSET(0x0008 + 0x60)
 
-/* PEX_CAPABILITIES_REG fields */
+/* SOC_CONTROL_REG1 fields */
 #define PCIE0_ENABLE_OFFS  0
 #define PCIE0_ENABLE_MASK  (0x1 << PCIE0_ENABLE_OFFS)
 #define PCIE1_ENABLE_OFFS  1
-- 
2.32.0



[PATCH u-boot-marvell 4/9] arm: mvebu: a38x: serdes: Don't overwrite read-only SAR PCIe registers

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Device/Port Type bits of PCIe Root Port PCI Express Capabilities Register
are read-only SAR registers and are initialized according to current mode
configured by PCIe controller. Changing PCIe controller mode (from Root
Complex mode to Endpoint mode or the other way) is possible via PCI
Express Control Register (offset 0x41A00), bit 1 (ConfRoot Complex). This
has to be done in PCIe controller driver (in our case pci_mvebu.c). Note
that default mode is Root Complex.

Maximum Link Speed bits of PCIe Root Port Link Capabilities Register are
platform specific and overwriting them does not make sense. They are set by
PCIe controller according to current SerDes configuration. For A38x it is
5.0 GT/s if SerDes supports appropriate speed.

Maximum Link Width bits of PCIe Root Port Link Capabilities Register are
read-only SAR registers, but unfortunately if this is not set correctly
here, then access PCI config space of the endpoint card behind this Root
Port does not work.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c| 22 --
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h|  4 ++
 .../serdes/a38x/high_speed_env_spec.c | 40 +++
 3 files changed, 19 insertions(+), 47 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
index 0eb31d589c..7c18df8113 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
@@ -28,28 +28,6 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 
count)
 
DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
 
-   for (idx = 0; idx < count; idx++) {
-   serdes_type = serdes_map[idx].serdes_type;
-   /* configuration for PEX only */
-   if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
-   (serdes_type != PEX2) && (serdes_type != PEX3))
-   continue;
-
-   if ((serdes_type != PEX0) &&
-   ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
-(serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
-   /* for PEX by4 - relevant for the first port only */
-   continue;
-   }
-
-   /* Set Device/Port Type to RootComplex */
-   pex_idx = serdes_type - PEX0;
-   tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
-   tmp &= ~(0xf << 20);
-   tmp |= (0x4 << 20);
-   reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
-   }
-
tmp = reg_read(SOC_CONTROL_REG1);
tmp &= ~0x03;
 
diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
index a882d24208..5d70166fc5 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
@@ -6,8 +6,12 @@
 #ifndef _CTRL_PEX_H
 #define _CTRL_PEX_H
 
+#include 
 #include "high_speed_env_spec.h"
 
+/* Direct access to PEX0 Root Port's PCIe Capability structure */
+#define PEX0_RP_PCIE_CFG_OFFSET(0x0008 + 0x60)
+
 /* Sample at Reset */
 #define MPP_SAMPLE_AT_RESET(id)(0xe4200 + (id * 4))
 
diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c 
b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
index 09192acef2..a712fa8994 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
@@ -1714,7 +1714,7 @@ int serdes_power_up_ctrl(u32 serdes_num, int 
serdes_power_up,
(serdes_mode == PEX_END_POINT_X1);
pex_idx = serdes_type - PEX0;
 
-   if ((is_pex_by1 == 1) || (serdes_type == PEX0)) {
+   if (serdes_type == PEX0) {
/* For PEX by 4, init only the PEX 0 */
reg_data = reg_read(SOC_CONTROL_REG1);
if (is_pex_by1 == 1)
@@ -1723,30 +1723,20 @@ int serdes_power_up_ctrl(u32 serdes_num, int 
serdes_power_up,
reg_data &= ~0x4000;
reg_write(SOC_CONTROL_REG1, reg_data);
 
-   /* Set Maximum Link Width to X1 or X4 */
-   reg_data = reg_read(PEX_CFG_DIRECT_ACCESS(
-pex_idx,
-PEX_LINK_CAPABILITY_REG));
-   reg_data &= ~0x3f0;
-   if (is_pex_by1 == 1)
-   reg_data |= 0x10;
-   else
-   reg_data |= 0x40;
-   

[PATCH u-boot-marvell 5/9] arm: mvebu: a38x: serdes: Don't set PCIe Common Clock Configuration

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Enabling Common Clock Configuration bit in PCIe Root Port Link Control
Register should not be done unconditionally. It is enabled by operating
system as part of ASPM. Also after enabling Common Clock Configuration it
is required to do more work, like retraining link. Some cards may be broken
due to this incomplete Common Clock Configuration and some cards are broken
and do not support ASPM at all.

Remove this incomplete code for Common Clock Configuration. It really
should not be done in SerDes code as it is not related to SerDes, but to
PCIe subsystem.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 .../mach-mvebu/serdes/a38x/high_speed_env_spec.c  | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c 
b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
index a712fa8994..824f4d3e3d 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
@@ -1737,21 +1737,6 @@ int serdes_power_up_ctrl(u32 serdes_num, int 
serdes_power_up,
reg_data |= (is_pex_by1 ? 1 : 4) << 4;
reg_write(PEX0_RP_PCIE_CFG_OFFSET +
  PCI_EXP_LNKCAP, reg_data);
-
-   /*
-* Set Common Clock Configuration to indicates
-* that both devices on the link use a
-* distributed common reference clock.
-*/
-   reg_data = reg_read(PEX_CFG_DIRECT_ACCESS(
-pex_idx,
-PEX_LINK_CTRL_STAT_REG));
-   reg_data &= ~0x40;
-   reg_data |= 0x40;
-   reg_write(PEX_CFG_DIRECT_ACCESS(
-  pex_idx,
-  PEX_LINK_CTRL_STAT_REG),
- reg_data);
}
 
CHECK_STATUS(mv_seq_exec(serdes_num, PEX_POWER_UP_SEQ));
-- 
2.32.0



[PATCH u-boot-marvell 6/9] arm: mvebu: a38x: serdes: Don't overwrite PCI device ID

2021-09-24 Thread Marek Behún
From: Pali Rohár 

PCI device ID is part of the PCIe controller SoC / revision. For Root
Complex mode (which is the default and the only mode supported currently
by U-Boot and Linux kernel), it is PCI device ID of PCIe Root Port device.

If there is some issue with this device ID, it should be set / updated by
PCIe controller driver (pci_mvebu.c), as this register resides in address
space of the controller. It shouldn't be done in SerDes initialization
code.

In the worst case (a specific board for example) it could be done via
U-Boot's weak function board_pex_config().

But it should not be overwritten globally for all A38x devices.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c | 27 --
 1 file changed, 27 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
index 7c18df8113..a7e45a5550 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
@@ -186,33 +186,6 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 
count)
(": Link upgraded to Gen2 based on client 
capabilities\n");
}
 
-   /* Update pex DEVICE ID */
-   ctrl_mode = sys_env_model_get();
-
-   for (idx = 0; idx < count; idx++) {
-   serdes_type = serdes_map[idx].serdes_type;
-   /* configuration for PEX only */
-   if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
-   (serdes_type != PEX2) && (serdes_type != PEX3))
-   continue;
-
-   if ((serdes_type != PEX0) &&
-   ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
-(serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
-   /* for PEX by4 - relevant for the first port only */
-   continue;
-   }
-
-   pex_idx = serdes_type - PEX0;
-   dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
- (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
-   dev_id &= 0x;
-   dev_id |= ((ctrl_mode << 16) & 0x);
-   reg_write(PEX_CFG_DIRECT_ACCESS
- (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
-   }
-   DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
-
return MV_OK;
 }
 
-- 
2.32.0



[PATCH u-boot-marvell 3/9] arm: mvebu: a38x: serdes: Add comments for hws_pex_config() code

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Add comments to understand what this magic code is doing.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c 
b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
index 717bcfb29c..0eb31d589c 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
@@ -42,6 +42,7 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 
count)
continue;
}
 
+   /* Set Device/Port Type to RootComplex */
pex_idx = serdes_type - PEX0;
tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
tmp &= ~(0xf << 20);
@@ -122,12 +123,18 @@ int hws_pex_config(const struct serdes_map *serdes_map, 
u8 count)
}
 
next_busno++;
+
+   /*
+* Read maximum link speed. It must be 0x2 (5.0 GT/s) as this
+* value was set in serdes_power_up_ctrl() function.
+*/
temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
 (pex_idx, PEX_LINK_CAPABILITY_REG)));
temp_pex_reg &= 0xf;
if (temp_pex_reg != 0x2)
continue;
 
+   /* Read negotiated link speed */
temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
 pex_idx,
 PEX_LINK_CTRL_STAT_REG)) &
@@ -155,6 +162,7 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 
count)
continue;
}
 
+   /* Find start of the PCI Express Capability registers */
while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
& 0xff) != 0x10) {
addr = (pex_config_read(pex_idx, first_busno, 0,
@@ -173,11 +181,15 @@ int hws_pex_config(const struct serdes_map *serdes_map, 
u8 count)
tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
tmp &= ~(BIT(0) | BIT(1));
-   tmp |= BIT(1);
+   tmp |= BIT(1);  /* Force Target Link Speed to 5.0 GT/s */
tmp |= BIT(6);  /* Select Deemphasize (-3.5d_b) */
reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
 
+   /*
+* Enable Auto Speed change. When set, link will issue link
+* speed change to max possible link speed.
+*/
tmp = reg_read(PEX_CTRL_REG(pex_idx));
DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
tmp |= BIT(10);
-- 
2.32.0



[PATCH u-boot-marvell v3 04/39] tools: kwboot: Refactor and fix writing buffer

2021-09-24 Thread Marek Behún
From: Marek Behún 

There are 3 instances in kwboot.c where we need to write() a given
buffer whole (iteratively writing until all data are written), and 2 of
those instances are wrong, for they do not increment the buffer pointer.

Refactor the code into a new function kwboot_write() where it is fixed.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 55 --
 1 file changed, 26 insertions(+), 29 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index f18f6d2134..22cdd137ad 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -72,6 +72,23 @@ static int msg_req_delay = KWBOOT_MSG_REQ_DELAY;
 static int msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO;
 static int blk_rsp_timeo = KWBOOT_BLK_RSP_TIMEO;
 
+static ssize_t
+kwboot_write(int fd, const char *buf, size_t len)
+{
+   size_t tot = 0;
+
+   while (tot < len) {
+   ssize_t wr = write(fd, buf + tot, len - tot);
+
+   if (wr < 0)
+   return -1;
+
+   tot += wr;
+   }
+
+   return tot;
+}
+
 static void
 kwboot_printv(const char *fmt, ...)
 {
@@ -191,26 +208,13 @@ out:
 static int
 kwboot_tty_send(int fd, const void *buf, size_t len)
 {
-   int rc;
-   ssize_t n;
-
if (!buf)
return 0;
 
-   rc = -1;
-
-   do {
-   n = write(fd, buf, len);
-   if (n < 0)
-   goto out;
-
-   buf = (char *)buf + n;
-   len -= n;
-   } while (len > 0);
+   if (kwboot_write(fd, buf, len) < 0)
+   return -1;
 
-   rc = tcdrain(fd);
-out:
-   return rc;
+   return tcdrain(fd);
 }
 
 static int
@@ -462,7 +466,7 @@ can:
 static int
 kwboot_term_pipe(int in, int out, const char *quit, int *s)
 {
-   ssize_t nin, nout;
+   ssize_t nin;
char _buf[128], *buf = _buf;
 
nin = read(in, buf, sizeof(_buf));
@@ -480,22 +484,15 @@ kwboot_term_pipe(int in, int out, const char *quit, int 
*s)
buf++;
nin--;
} else {
-   while (*s > 0) {
-   nout = write(out, quit, *s);
-   if (nout <= 0)
-   return -1;
-   (*s) -= nout;
-   }
+   if (kwboot_write(out, quit, *s) < 0)
+   return -1;
+   *s = 0;
}
}
}
 
-   while (nin > 0) {
-   nout = write(out, buf, nin);
-   if (nout <= 0)
-   return -1;
-   nin -= nout;
-   }
+   if (kwboot_write(out, buf, nin) < 0)
+   return -1;
 
return 0;
 }
-- 
2.32.0



[PATCH u-boot-marvell v3 08/39] tools: kwboot: Fix comparison of integers with different size

2021-09-24 Thread Marek Behún
From: Marek Behún 

The compiler complains that we are comparing int with size_t when
compiled with -W.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 88353d19c0..3d9f73e697 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -352,8 +352,7 @@ kwboot_xm_makeblock(struct kwboot_block *block, const void 
*data,
size_t size, int pnum)
 {
const size_t blksz = sizeof(block->data);
-   size_t n;
-   int i;
+   size_t i, n;
 
block->soh = SOH;
block->pnum = pnum;
-- 
2.32.0



[PATCH u-boot-marvell v3 03/39] tools: kwboot: Make the quit sequence buffer const

2021-09-24 Thread Marek Behún
From: Marek Behún 

This buffer is never written to. Make it const.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index e6e99849a7..f18f6d2134 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -460,7 +460,7 @@ can:
 }
 
 static int
-kwboot_term_pipe(int in, int out, char *quit, int *s)
+kwboot_term_pipe(int in, int out, const char *quit, int *s)
 {
ssize_t nin, nout;
char _buf[128], *buf = _buf;
@@ -504,7 +504,7 @@ static int
 kwboot_terminal(int tty)
 {
int rc, in, s;
-   char *quit = "\34c";
+   const char *quit = "\34c";
struct termios otio, tio;
 
rc = -1;
-- 
2.32.0



[PATCH u-boot-marvell v3 07/39] tools: kwboot: Fix return type of kwboot_xm_makeblock() function

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Function kwboot_xm_makeblock() always returns length of xmodem block. It
is always non-negative and calculated from variable with size_t type. Set
return type of this function to size_t and remove dead code which checks
for negative value.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 tools/kwboot.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index b9a402ca91..88353d19c0 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -347,7 +347,7 @@ kwboot_debugmsg(int tty, void *msg)
return rc;
 }
 
-static int
+static size_t
 kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
size_t size, int pnum)
 {
@@ -441,9 +441,6 @@ kwboot_xmodem(int tty, const void *_data, size_t size)
n = kwboot_xm_makeblock(,
data + N, size - N,
pnum++);
-   if (n < 0)
-   goto can;
-
if (!n)
break;
 
-- 
2.32.0



[PATCH u-boot-marvell v3 01/39] tools: kwbimage: Fix printf format warning

2021-09-24 Thread Marek Behún
From: Marek Behún 

On 32-bit ARM the compiler complains:
  tools/kwbimage.c:547: warning: format ‘%lu’ expects argument of type
 ‘long unsigned int’, but argument 4 has
 type ‘unsigned int’

Fix this by using %zu instead of %lu format specifier.

Signed-off-by: Marek Behún 
---
 tools/kwbimage.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index d200ff2425..e72555fe74 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -542,7 +542,7 @@ static int kwb_export_pubkey(RSA *key, struct pubkey_der_v1 
*dst, FILE *hashf,
}
 
if (4 + size_seq > sizeof(dst->key)) {
-   fprintf(stderr, "export pk failed: seq too large (%d, %lu)\n",
+   fprintf(stderr, "export pk failed: seq too large (%d, %zu)\n",
4 + size_seq, sizeof(dst->key));
fprintf(stderr, errmsg, keyname);
return -ENOBUFS;
-- 
2.32.0



[PATCH u-boot-marvell v3 23/39] tools: kwbimage: Refactor image_version()

2021-09-24 Thread Marek Behún
From: Marek Behún 

Rename this function to kwbimage_version() and don't cast argument if
not needed.

Signed-off-by: Marek Behún 
---
 tools/kwbimage.c | 8 
 tools/kwbimage.h | 4 ++--
 tools/kwboot.c   | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 16b082b35f..944a108cee 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -282,7 +282,7 @@ static uint8_t image_checksum8(void *start, uint32_t len)
 
 size_t kwbimage_header_size(unsigned char *ptr)
 {
-   if (image_version((void *)ptr) == 0)
+   if (kwbimage_version((void *)ptr) == 0)
return sizeof(struct main_hdr_v0);
else
return KWBHEADER_V1_SIZE((struct main_hdr_v1 *)ptr);
@@ -1622,7 +1622,7 @@ static void kwbimage_print_header(const void *ptr)
 
printf("Image Type:   MVEBU Boot from %s Image\n",
   image_boot_mode_name(mhdr->blockid));
-   printf("Image version:%d\n", image_version((void *)ptr));
+   printf("Image version:%d\n", kwbimage_version(ptr));
 
for_each_opt_hdr_v1 (ohdr, mhdr) {
if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
@@ -1659,7 +1659,7 @@ static int kwbimage_verify_header(unsigned char *ptr, int 
image_size,
return -FDT_ERR_BADSTRUCTURE;
 
/* Only version 0 extended header has checksum */
-   if (image_version((void *)ptr) == 0) {
+   if (kwbimage_version(ptr) == 0) {
struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
 
if (mhdr->ext & 0x1) {
@@ -1676,7 +1676,7 @@ static int kwbimage_verify_header(unsigned char *ptr, int 
image_size,
if (checksum != ext_hdr->checksum)
return -FDT_ERR_BADSTRUCTURE;
}
-   } else if (image_version((void *)ptr) == 1) {
+   } else if (kwbimage_version(ptr) == 1) {
struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
const uint8_t *mhdr_end;
struct opt_hdr_v1 *ohdr;
diff --git a/tools/kwbimage.h b/tools/kwbimage.h
index 9a949e03c0..738034beb1 100644
--- a/tools/kwbimage.h
+++ b/tools/kwbimage.h
@@ -229,7 +229,7 @@ void init_kwb_image_type (void);
  * header, byte 8 was reserved, and always set to 0. In the v1 header,
  * byte 8 has been changed to a proper field, set to 1.
  */
-static inline unsigned int image_version(const void *header)
+static inline unsigned int kwbimage_version(const void *header)
 {
const unsigned char *ptr = header;
return ptr[8];
@@ -258,7 +258,7 @@ static inline int opt_hdr_v1_valid_size(const struct 
opt_hdr_v1 *ohdr,
 static inline struct opt_hdr_v1 *opt_hdr_v1_first(void *img) {
struct main_hdr_v1 *mhdr;
 
-   if (image_version(img) != 1)
+   if (kwbimage_version(img) != 1)
return NULL;
 
mhdr = img;
diff --git a/tools/kwboot.c b/tools/kwboot.c
index b1dcd3796c..e47bf94e89 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -583,7 +583,7 @@ kwboot_xmodem(int tty, const void *_img, size_t size)
int rc, pnum;
size_t hdrsz;
 
-   if (image_version(img) == 0)
+   if (kwbimage_version(img) == 0)
hdrsz = KWBHEADER_V0_SIZE((struct main_hdr_v0 *)img);
else
hdrsz = KWBHEADER_V1_SIZE((struct main_hdr_v1 *)img);
@@ -787,7 +787,7 @@ kwboot_img_patch_hdr(void *img, size_t size)
goto out;
}
 
-   image_ver = image_version(img);
+   image_ver = kwbimage_version(img);
if (image_ver != 0 && image_ver != 1) {
fprintf(stderr, "Invalid image header version\n");
errno = EINVAL;
-- 
2.32.0



[PATCH u-boot-marvell v3 18/39] tools: kwboot: Always call kwboot_img_patch_hdr()

2021-09-24 Thread Marek Behún
From: Pali Rohár 

The kwboot_img_patch_hdr() function already decides if header patching
is needed. Always call this function and deprecate the unneeded command
line option `-p`.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 tools/kwboot.c | 23 ++-
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index ad91afd075..9394a51380 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -709,9 +709,9 @@ out:
 }
 
 static void *
-kwboot_mmap_image(const char *path, size_t *size, int prot)
+kwboot_mmap_image(const char *path, size_t *size)
 {
-   int rc, fd, flags;
+   int rc, fd;
struct stat st;
void *img;
 
@@ -726,9 +726,7 @@ kwboot_mmap_image(const char *path, size_t *size, int prot)
if (rc)
goto out;
 
-   flags = (prot & PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED;
-
-   img = mmap(NULL, st.st_size, prot, flags, fd, 0);
+   img = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 
0);
if (img == MAP_FAILED) {
img = NULL;
goto out;
@@ -833,7 +831,6 @@ kwboot_usage(FILE *stream, char *progname)
fprintf(stream, "\n");
fprintf(stream,
"  -b : boot  with preamble (Kirkwood, Armada 
370/XP)\n");
-   fprintf(stream, "  -p: patch  to type 0x69 (uart boot)\n");
fprintf(stream,
"  -D : boot  without preamble (Dove)\n");
fprintf(stream, "  -d: enter debug mode\n");
@@ -853,7 +850,7 @@ int
 main(int argc, char **argv)
 {
const char *ttypath, *imgpath;
-   int rv, rc, tty, term, prot, patch;
+   int rv, rc, tty, term;
void *bootmsg;
void *debugmsg;
void *img;
@@ -867,7 +864,6 @@ main(int argc, char **argv)
imgpath = NULL;
img = NULL;
term = 0;
-   patch = 0;
size = 0;
speed = B115200;
 
@@ -894,7 +890,7 @@ main(int argc, char **argv)
break;
 
case 'p':
-   patch = 1;
+   /* nop, for backward compatibility */
break;
 
case 't':
@@ -934,9 +930,6 @@ main(int argc, char **argv)
if (!bootmsg && !term && !debugmsg)
goto usage;
 
-   if (patch && !imgpath)
-   goto usage;
-
if (argc - optind < 1)
goto usage;
 
@@ -949,16 +942,12 @@ main(int argc, char **argv)
}
 
if (imgpath) {
-   prot = PROT_READ | (patch ? PROT_WRITE : 0);
-
-   img = kwboot_mmap_image(imgpath, , prot);
+   img = kwboot_mmap_image(imgpath, );
if (!img) {
perror(imgpath);
goto out;
}
-   }
 
-   if (patch) {
rc = kwboot_img_patch_hdr(img, size);
if (rc) {
fprintf(stderr, "%s: Invalid image.\n", imgpath);
-- 
2.32.0



[PATCH u-boot-marvell v3 16/39] tools: kwboot: Prevent waiting indefinitely if no xmodem reply is received

2021-09-24 Thread Marek Behún
From: Marek Behún 

Currently if BootROM fails to respond with ACK/NAK to a xmodem block, we
will be waiting indefinitely for such response.

Make sure that we only wait at most 1 second (blk_rsp_timeo) for ACK/NAK
for each block in case non-xmodem text output is not being expected.
Interpret this timeout expiration as NAK, to try to send the block
again.

On the other hand, if timeout expires without ACK while some non-xmodem
output was already received (DDR training output, for example), we know
that the block was received, since the code is being executed, so in
this case exit with ETIMEDOUT.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index cf6e32c6fa..8c11dca5ed 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -407,17 +407,18 @@ static int
 kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print)
 {
int timeout = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo;
-   uint64_t recv_until = 0;
+   uint64_t recv_until = _now() + timeout;
int rc;
 
-   *non_xm_print = 0;
+   if (non_xm_print)
+   *non_xm_print = 0;
 
while (1) {
rc = kwboot_tty_recv(fd, c, 1, timeout);
if (rc) {
if (errno != ETIMEDOUT)
return rc;
-   else if (recv_until && recv_until < _now())
+   else if (allow_non_xm && *non_xm_print)
return -1;
else
*c = NAK;
@@ -430,12 +431,19 @@ kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, 
int *non_xm_print)
/*
 * If printing non-xmodem text output is allowed and such a byte
 * was received, print it and increase receiving time.
+* Otherwise decrease timeout by time elapsed.
 */
if (allow_non_xm) {
recv_until = _now() + timeout;
putchar(*c);
fflush(stdout);
*non_xm_print = 1;
+   } else {
+   timeout = recv_until - _now();
+   if (timeout < 0) {
+   errno = ETIMEDOUT;
+   return -1;
+   }
}
}
 
-- 
2.32.0



[PATCH u-boot-marvell v3 33/39] tools: kwboot: Disable non-blocking mode

2021-09-24 Thread Marek Behún
From: Pali Rohár 

The kwboot utility does not handle EAGAIN / EBUSY errors, it expects
blocking mode on tty - it uses select() to check if data is available.

Disable non-blocking mode by clearing O_NDELAY flag which was set by
open().

We can't just take O_NDELAY from open(), because it is required there
until the CLOCAL flag is set on the tty.

Signed-off-by: Pali Rohár 
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index a527c79cf3..5e491f31a4 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -639,7 +639,7 @@ baud_fail:
 static int
 kwboot_open_tty(const char *path, int baudrate)
 {
-   int rc, fd;
+   int rc, fd, flags;
struct termios tio;
 
rc = -1;
@@ -661,6 +661,14 @@ kwboot_open_tty(const char *path, int baudrate)
if (rc)
goto out;
 
+   flags = fcntl(fd, F_GETFL);
+   if (flags < 0)
+   goto out;
+
+   rc = fcntl(fd, F_SETFL, flags & ~O_NDELAY);
+   if (rc)
+   goto out;
+
rc = kwboot_tty_change_baudrate(fd, baudrate);
if (rc)
goto out;
-- 
2.32.0



[PATCH u-boot-marvell v3 05/39] tools: kwboot: Print version information header

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Print kwboot's (U-Boot's) version when printing usage.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 tools/kwboot.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 22cdd137ad..454339db14 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -11,6 +11,7 @@
 
 #include "kwbimage.h"
 #include "mkimage.h"
+#include "version.h"
 
 #include 
 #include 
@@ -681,6 +682,7 @@ out:
 static void
 kwboot_usage(FILE *stream, char *progname)
 {
+   fprintf(stream, "kwboot version %s\n", PLAIN_VERSION);
fprintf(stream,
"Usage: %s [OPTIONS] [-b  | -D  ] [-B  ] 
\n",
progname);
-- 
2.32.0



[PATCH u-boot-marvell v3 06/39] tools: kwboot: Fix kwboot_xm_sendblock() function when kwboot_tty_recv() fails

2021-09-24 Thread Marek Behún
From: Pali Rohár 

When kwboot_tty_recv() fails or times out, it does not set the `c`
variable to NAK. The variable is then compared, while it holds either
an undefined value or a value from previous iteration. Set `c` to NAK so
that the other side will try to resend current block, and remove the
now unnecessary break.

In other failure cases return immediately.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 tools/kwboot.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 454339db14..b9a402ca91 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -380,12 +380,15 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block)
do {
rc = kwboot_tty_send(fd, block, sizeof(*block));
if (rc)
-   break;
+   return rc;
 
do {
rc = kwboot_tty_recv(fd, , 1, blk_rsp_timeo);
-   if (rc)
-   break;
+   if (rc) {
+   if (errno != ETIMEDOUT)
+   return rc;
+   c = NAK;
+   }
 
if (c != ACK && c != NAK && c != CAN)
printf("%c", c);
-- 
2.32.0



[PATCH u-boot-marvell v3 09/39] tools: kwboot: Fix printing progress

2021-09-24 Thread Marek Behún
From: Pali Rohár 

Ensure that `pos` is still in range up to the `width` so printing 100%
works also for bigger images. After printing 100% progress reset it to
zero, so that next progressbar can be started.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 tools/kwboot.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 3d9f73e697..eb4b3fe230 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -140,12 +140,14 @@ __progress(int pct, char c)
fputc(c, stdout);
 
nl = "]\n";
-   pos++;
+   pos = (pos + 1) % width;
 
if (pct == 100) {
-   while (pos++ < width)
+   while (pos && pos++ < width)
fputc(' ', stdout);
fputs(nl, stdout);
+   nl = "";
+   pos = 0;
}
 
fflush(stdout);
@@ -162,6 +164,9 @@ kwboot_progress(int _pct, char c)
 
if (kwboot_verbose)
__progress(pct, c);
+
+   if (pct == 100)
+   pct = 0;
 }
 
 static int
-- 
2.32.0



about mtd erase fix series

2021-09-24 Thread Marek Behún
Hi Tom, Jagan,

in July I resent the series
  Fix `mtd erase` when used with mtdpart
https://patchwork.ozlabs.org/project/uboot/list/?series=253565=*

There was a build error in CI, more info at 
  https://lists.denx.de/pipermail/u-boot/2021-July/455851.html

The CI link mentioned
  https://source.denx.de/u-boot/custodians/u-boot-spi/-/pipelines/8345
gives 404 now.

Jagan, could you please retrigger CI for this, and send me results?
The series still applied cleanly on master branch and compiled for my
config.

The fix is needed for `mtd erase`.

Marek


[PATCH u-boot-marvell] arm: mvebu: turris_omnia: fix leaked mtd device

2021-09-24 Thread Marek Behún
From: Marek Behún 

After getting MTD device via get_mtd_device_nm(), we need to put it with
put_mtd_device(), otherwise we get

  Removing MTD device #0 (mx25l6405d) with use count 1

before booting kernel.

Signed-off-by: Marek Behún 
---
 board/CZ.NIC/turris_omnia/turris_omnia.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c 
b/board/CZ.NIC/turris_omnia/turris_omnia.c
index bac78af04e..a48e1f5c30 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -647,10 +647,13 @@ int ft_board_setup(void *blob, struct bd_info *bd)
if (!fixup_mtd_partitions(blob, node, mtd))
goto fail;
 
+   put_mtd_device(mtd);
return 0;
 
 fail:
printf("Failed fixing SPI NOR partitions!\n");
+   if (!IS_ERR_OR_NULL(mtd))
+   put_mtd_device(mtd);
return 0;
 }
 #endif
-- 
2.32.0



[PATCH u-boot-marvell v3 12/39] tools: kwboot: Use a function to check whether received byte is a Xmodem reply

2021-09-24 Thread Marek Behún
From: Marek Behún 

This is a non-functional change that should make the code more readable.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 7f231c0823..2e5684b91c 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -375,6 +375,12 @@ kwboot_xm_makeblock(struct kwboot_block *block, const void 
*data,
return n;
 }
 
+static int
+_is_xm_reply(char c)
+{
+   return c == ACK || c == NAK || c == CAN;
+}
+
 static int
 kwboot_xm_sendblock(int fd, struct kwboot_block *block)
 {
@@ -395,10 +401,10 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block)
c = NAK;
}
 
-   if (c != ACK && c != NAK && c != CAN)
+   if (!_is_xm_reply(c))
printf("%c", c);
 
-   } while (c != ACK && c != NAK && c != CAN);
+   } while (!_is_xm_reply(c));
 
if (c != ACK)
kwboot_progress(-1, '+');
-- 
2.32.0



[PATCH u-boot-marvell v3 11/39] tools: kwboot: Split sending image into header and data stages

2021-09-24 Thread Marek Behún
From: Pali Rohár 

This change is required to implement other features in kwboot.

Split sending header and data parts of the image into two stages.

Signed-off-by: Pali Rohár 
[ refactored ]
Signed-off-by: Marek Behún 
---
 tools/kwbimage.h |  8 +++--
 tools/kwboot.c   | 84 +++-
 2 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/tools/kwbimage.h b/tools/kwbimage.h
index e063e3e41e..074bdfbe46 100644
--- a/tools/kwbimage.h
+++ b/tools/kwbimage.h
@@ -195,6 +195,10 @@ struct register_set_hdr_v1 {
 #define OPT_HDR_V1_BINARY_TYPE   0x2
 #define OPT_HDR_V1_REGISTER_TYPE 0x3
 
+#define KWBHEADER_V0_SIZE(hdr) \
+   (((hdr)->ext & 0x1) ? sizeof(struct kwb_header) : \
+ sizeof(struct main_hdr_v0))
+
 #define KWBHEADER_V1_SIZE(hdr) \
(((hdr)->headersz_msb << 16) | le16_to_cpu((hdr)->headersz_lsb))
 
@@ -225,9 +229,9 @@ void init_kwb_image_type (void);
  * header, byte 8 was reserved, and always set to 0. In the v1 header,
  * byte 8 has been changed to a proper field, set to 1.
  */
-static inline unsigned int image_version(void *header)
+static inline unsigned int image_version(const void *header)
 {
-   unsigned char *ptr = header;
+   const unsigned char *ptr = header;
return ptr[8];
 }
 
diff --git a/tools/kwboot.c b/tools/kwboot.c
index 0e533e3698..7f231c0823 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -57,11 +57,13 @@ static unsigned char kwboot_msg_debug[] = {
 #define NAK21  /* target block negative ack */
 #define CAN24  /* target/sender transfer cancellation */
 
+#define KWBOOT_XM_BLKSZ128 /* xmodem block size */
+
 struct kwboot_block {
uint8_t soh;
uint8_t pnum;
uint8_t _pnum;
-   uint8_t data[128];
+   uint8_t data[KWBOOT_XM_BLKSZ];
uint8_t csum;
 } __packed;
 
@@ -356,16 +358,15 @@ static size_t
 kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
size_t size, int pnum)
 {
-   const size_t blksz = sizeof(block->data);
size_t i, n;
 
block->soh = SOH;
block->pnum = pnum;
block->_pnum = ~block->pnum;
 
-   n = size < blksz ? size : blksz;
+   n = size < KWBOOT_XM_BLKSZ ? size : KWBOOT_XM_BLKSZ;
memcpy(>data[0], data, n);
-   memset(>data[n], 0, blksz - n);
+   memset(>data[n], 0, KWBOOT_XM_BLKSZ - n);
 
block->csum = 0;
for (i = 0; i < n; i++)
@@ -425,48 +426,73 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block)
 }
 
 static int
-kwboot_xmodem(int tty, const void *_data, size_t size)
+kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
+ size_t size)
 {
-   const uint8_t *data = _data;
-   int rc, pnum, N, err;
-
-   pnum = 1;
-   N = 0;
+   size_t sent, left;
+   int rc;
 
-   kwboot_printv("Sending boot image...\n");
+   kwboot_printv("Sending boot image %s (%zu bytes)...\n",
+ header ? "header" : "data", size);
 
-   sleep(2); /* flush isn't effective without it */
-   tcflush(tty, TCIOFLUSH);
+   left = size;
+   sent = 0;
 
-   do {
+   while (sent < size) {
struct kwboot_block block;
-   int n;
+   size_t blksz;
 
-   n = kwboot_xm_makeblock(,
-   data + N, size - N,
-   pnum++);
-   if (!n)
-   break;
+   blksz = kwboot_xm_makeblock(, data, left, (*pnum)++);
+   data += blksz;
 
rc = kwboot_xm_sendblock(tty, );
if (rc)
goto out;
 
-   N += n;
-   kwboot_progress(N * 100 / size, '.');
-   } while (1);
+   sent += blksz;
+   left -= blksz;
+
+   kwboot_progress(sent * 100 / size, '.');
+   }
 
-   rc = kwboot_tty_send_char(tty, EOT);
+   kwboot_printv("Done\n");
 
+   return 0;
 out:
kwboot_printv("\n");
return rc;
+}
 
-can:
-   err = errno;
-   kwboot_tty_send_char(tty, CAN);
-   errno = err;
-   goto out;
+static int
+kwboot_xmodem(int tty, const void *_img, size_t size)
+{
+   const uint8_t *img = _img;
+   int rc, pnum;
+   size_t hdrsz;
+
+   if (image_version(img) == 0)
+   hdrsz = KWBHEADER_V0_SIZE((struct main_hdr_v0 *)img);
+   else
+   hdrsz = KWBHEADER_V1_SIZE((struct main_hdr_v1 *)img);
+
+   kwboot_printv("Waiting 2s and flushing tty\n");
+   sleep(2); /* flush isn't effective without it */
+   tcflush(tty, TCIOFLUSH);
+
+   pnum = 1;
+
+   rc = kwboot_xmodem_one(tty, , 1, img, hdrsz);
+   if (rc)
+   return rc;
+
+   img +

[PATCH u-boot-marvell v3 15/39] tools: kwboot: Allow greater timeout when executing header code

2021-09-24 Thread Marek Behún
From: Marek Behún 

When executing header code (which contains U-Boot SPL in most cases),
wait 10s after every non-xmodem character received (i.e. printed by
U-Boot SPL) before timing out.

Sometimes DDR training, which runs in SPL, may be slow.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 34 +++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 2f4c61bed6..cf6e32c6fa 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -68,6 +69,7 @@ struct kwboot_block {
 } __packed;
 
 #define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
+#define KWBOOT_HDR_RSP_TIMEO 1 /* ms */
 
 static int kwboot_verbose;
 
@@ -375,6 +377,26 @@ kwboot_xm_makeblock(struct kwboot_block *block, const void 
*data,
return n;
 }
 
+static uint64_t
+_now(void)
+{
+   struct timespec ts;
+
+   if (clock_gettime(CLOCK_MONOTONIC, )) {
+   static int err_print;
+
+   if (!err_print) {
+   perror("clock_gettime() does not work");
+   err_print = 1;
+   }
+
+   /* this will just make the timeout not work */
+   return -1ULL;
+   }
+
+   return ts.tv_sec * 1000ULL + (ts.tv_nsec + 50) / 100;
+}
+
 static int
 _is_xm_reply(char c)
 {
@@ -384,16 +406,21 @@ _is_xm_reply(char c)
 static int
 kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print)
 {
+   int timeout = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo;
+   uint64_t recv_until = 0;
int rc;
 
*non_xm_print = 0;
 
while (1) {
-   rc = kwboot_tty_recv(fd, c, 1, blk_rsp_timeo);
+   rc = kwboot_tty_recv(fd, c, 1, timeout);
if (rc) {
if (errno != ETIMEDOUT)
return rc;
-   *c = NAK;
+   else if (recv_until && recv_until < _now())
+   return -1;
+   else
+   *c = NAK;
}
 
/* If received xmodem reply, end. */
@@ -402,9 +429,10 @@ kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, 
int *non_xm_print)
 
/*
 * If printing non-xmodem text output is allowed and such a byte
-* was received, print it.
+* was received, print it and increase receiving time.
 */
if (allow_non_xm) {
+   recv_until = _now() + timeout;
putchar(*c);
fflush(stdout);
*non_xm_print = 1;
-- 
2.32.0



[PATCH u-boot-marvell v3 13/39] tools: kwboot: Allow non-xmodem text output from BootROM only in a specific case

2021-09-24 Thread Marek Behún
From: Pali Rohár 

When sending image header / image data, BootROM does not send any
non-xmodem text output. We should therefore interpret unknown bytes in
the xmodem protocol as errors and resend current packet. This should
improve the transfer in case there are errors on the UART line.

Text output from BootROM may only happen after whole image header is
sent and before ACK for the last packet of image header is received.
In this case BootROM may execute code from the image, which may interact
with UART (U-Boot SPL, for example, prints stuff on UART).

Print received non-xmodem output from BootROM only in this case.

Signed-off-by: Pali Rohár 
[ refactored & simplified ]
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 70 ++
 1 file changed, 53 insertions(+), 17 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 2e5684b91c..4636622a6c 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -382,33 +382,62 @@ _is_xm_reply(char c)
 }
 
 static int
-kwboot_xm_sendblock(int fd, struct kwboot_block *block)
+kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm)
+{
+   int rc;
+
+   while (1) {
+   rc = kwboot_tty_recv(fd, c, 1, blk_rsp_timeo);
+   if (rc) {
+   if (errno != ETIMEDOUT)
+   return rc;
+   *c = NAK;
+   }
+
+   /* If received xmodem reply, end. */
+   if (_is_xm_reply(*c))
+   break;
+
+   /*
+* If printing non-xmodem text output is allowed and such a byte
+* was received, print it.
+*/
+   if (allow_non_xm) {
+   putchar(*c);
+   fflush(stdout);
+   }
+   }
+
+   return 0;
+}
+
+static int
+kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
+   int *done_print)
 {
int rc, retries;
char c;
 
+   *done_print = 0;
+
retries = 16;
do {
rc = kwboot_tty_send(fd, block, sizeof(*block));
if (rc)
return rc;
 
-   do {
-   rc = kwboot_tty_recv(fd, , 1, blk_rsp_timeo);
-   if (rc) {
-   if (errno != ETIMEDOUT)
-   return rc;
-   c = NAK;
-   }
-
-   if (!_is_xm_reply(c))
-   printf("%c", c);
+   if (allow_non_xm && !*done_print) {
+   kwboot_progress(100, '.');
+   kwboot_printv("Done\n");
+   *done_print = 1;
+   }
 
-   } while (!_is_xm_reply(c));
+   rc = kwboot_xm_recv_reply(fd, , allow_non_xm);
+   if (rc)
+   return rc;
 
-   if (c != ACK)
+   if (!allow_non_xm && c != ACK)
kwboot_progress(-1, '+');
-
} while (c == NAK && retries-- > 0);
 
rc = -1;
@@ -435,6 +464,7 @@ static int
 kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
  size_t size)
 {
+   int done_print = 0;
size_t sent, left;
int rc;
 
@@ -446,22 +476,28 @@ kwboot_xmodem_one(int tty, int *pnum, int header, const 
uint8_t *data,
 
while (sent < size) {
struct kwboot_block block;
+   int last_block;
size_t blksz;
 
blksz = kwboot_xm_makeblock(, data, left, (*pnum)++);
data += blksz;
 
-   rc = kwboot_xm_sendblock(tty, );
+   last_block = (left <= blksz);
+
+   rc = kwboot_xm_sendblock(tty, , header && last_block,
+_print);
if (rc)
goto out;
 
sent += blksz;
left -= blksz;
 
-   kwboot_progress(sent * 100 / size, '.');
+   if (!done_print)
+   kwboot_progress(sent * 100 / size, '.');
}
 
-   kwboot_printv("Done\n");
+   if (!done_print)
+   kwboot_printv("Done\n");
 
return 0;
 out:
-- 
2.32.0



[PATCH u-boot-marvell v3 17/39] tools: kwboot: Properly finish xmodem transfer

2021-09-24 Thread Marek Behún
From: Pali Rohár 

After kwboot sends EOT, BootROM sends back ACK. Add code for handling
this and retry sending EOT on error.

Signed-off-by: Pali Rohár 
[ refactored ]
Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 62 --
 1 file changed, 45 insertions(+), 17 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 8c11dca5ed..ad91afd075 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -403,6 +403,29 @@ _is_xm_reply(char c)
return c == ACK || c == NAK || c == CAN;
 }
 
+static int
+_xm_reply_to_error(int c)
+{
+   int rc = -1;
+
+   switch (c) {
+   case ACK:
+   rc = 0;
+   break;
+   case NAK:
+   errno = EBADMSG;
+   break;
+   case CAN:
+   errno = ECANCELED;
+   break;
+   default:
+   errno = EPROTO;
+   break;
+   }
+
+   return rc;
+}
+
 static int
 kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print)
 {
@@ -483,24 +506,29 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, 
int allow_non_xm,
if (non_xm_print)
kwboot_printv("\n");
 
-   rc = -1;
+   return _xm_reply_to_error(c);
+}
 
-   switch (c) {
-   case ACK:
-   rc = 0;
-   break;
-   case NAK:
-   errno = EBADMSG;
-   break;
-   case CAN:
-   errno = ECANCELED;
-   break;
-   default:
-   errno = EPROTO;
-   break;
-   }
+static int
+kwboot_xm_finish(int fd)
+{
+   int rc, retries;
+   char c;
 
-   return rc;
+   kwboot_printv("Finishing transfer\n");
+
+   retries = 16;
+   do {
+   rc = kwboot_tty_send_char(fd, EOT);
+   if (rc)
+   return rc;
+
+   rc = kwboot_xm_recv_reply(fd, , 0, NULL);
+   if (rc)
+   return rc;
+   } while (c == NAK && retries-- > 0);
+
+   return _xm_reply_to_error(c);
 }
 
 static int
@@ -577,7 +605,7 @@ kwboot_xmodem(int tty, const void *_img, size_t size)
if (rc)
return rc;
 
-   return kwboot_tty_send_char(tty, EOT);
+   return kwboot_xm_finish(tty);
 }
 
 static int
-- 
2.32.0



[PATCH u-boot-marvell v3 14/39] tools: kwboot: Print new line after SPL output

2021-09-24 Thread Marek Behún
From: Marek Behún 

There is no separation between output from the code from binary header
(U-Boot SPL in most cases) and subsequent kwboot output.

Print '\n' to make distinguishing these two easier.

Signed-off-by: Marek Behún 
---
 tools/kwboot.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 4636622a6c..2f4c61bed6 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -382,10 +382,12 @@ _is_xm_reply(char c)
 }
 
 static int
-kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm)
+kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print)
 {
int rc;
 
+   *non_xm_print = 0;
+
while (1) {
rc = kwboot_tty_recv(fd, c, 1, blk_rsp_timeo);
if (rc) {
@@ -405,6 +407,7 @@ kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm)
if (allow_non_xm) {
putchar(*c);
fflush(stdout);
+   *non_xm_print = 1;
}
}
 
@@ -415,6 +418,7 @@ static int
 kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
int *done_print)
 {
+   int non_xm_print;
int rc, retries;
char c;
 
@@ -432,7 +436,7 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, int 
allow_non_xm,
*done_print = 1;
}
 
-   rc = kwboot_xm_recv_reply(fd, , allow_non_xm);
+   rc = kwboot_xm_recv_reply(fd, , allow_non_xm, _xm_print);
if (rc)
return rc;
 
@@ -440,6 +444,9 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, int 
allow_non_xm,
kwboot_progress(-1, '+');
} while (c == NAK && retries-- > 0);
 
+   if (non_xm_print)
+   kwboot_printv("\n");
+
rc = -1;
 
switch (c) {
-- 
2.32.0



[PATCH u-boot-marvell v3 10/39] tools: kwboot: Print newline on error when progress was not completed

2021-09-24 Thread Marek Behún
From: Pali Rohár 

When progress was not completed, current terminal position is in progress
bar. So print newline before printing error message to make error message
more readable.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 tools/kwboot.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index eb4b3fe230..0e533e3698 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -459,6 +459,7 @@ kwboot_xmodem(int tty, const void *_data, size_t size)
rc = kwboot_tty_send_char(tty, EOT);
 
 out:
+   kwboot_printv("\n");
return rc;
 
 can:
-- 
2.32.0



[PATCH u-boot-marvell v3 38/39] doc/kwboot.1: Update man page

2021-09-24 Thread Marek Behún
From: Marek Behún 

Update man page for the kwboot utility.

Signed-off-by: Marek Behún 
---
 doc/kwboot.1 | 60 ++--
 1 file changed, 39 insertions(+), 21 deletions(-)

diff --git a/doc/kwboot.1 b/doc/kwboot.1
index 1e9ca268f7..acdea891d9 100644
--- a/doc/kwboot.1
+++ b/doc/kwboot.1
@@ -1,21 +1,22 @@
-.TH KWBOOT 1 "2012-05-19"
+.TH KWBOOT 1 "2021-08-25"
 
 .SH NAME
-kwboot \- Boot Marvell Kirkwood SoCs over a serial link.
+kwboot \- Boot Marvell Kirkwood (and others 32-bit) SoCs over a serial link.
 .SH SYNOPSIS
 .B kwboot
 .RB [ "-b \fIimage\fP" ]
-.RB [ "-p" ]
 .RB [ "-t" ]
 .RB [ "-B \fIbaudrate\fP" ]
 .RB \fITTY\fP
 .SH "DESCRIPTION"
 
-The \fBmkimage\fP program boots boards based on Marvell's Kirkwood
-platform over their integrated UART. Boot image files will typically
+The \fBkwboot\fP program boots boards based on Marvell's 32-bit
+platforms including Kirkwood, Dove, A370, AXP, A375, A38x
+and A39x over their integrated UART. Boot image files will typically
 contain a second stage boot loader, such as U-Boot. The image file
 must conform to Marvell's BootROM firmware image format
-(\fIkwbimage\fP), created using a tool such as \fBmkimage\fP.
+(\fIkwbimage v0\fP or \fIv1\fP), created using a tool such as
+\fBmkimage\fP.
 
 Following power-up or a system reset, system BootROM code polls the
 UART for a brief period of time, sensing a handshake message which
@@ -36,25 +37,23 @@ by the second-stage loader.
 Handshake; then upload file \fIimage\fP over \fITTY\fP.
 
 Note that for the encapsulated boot code to be executed, \fIimage\fP
-must be of type "UART boot" (0x69). Boot images of different types,
-such as backup images of vendor firmware downloaded from flash memory
-(type 0x8B), will not work (or not as expected). See \fB-p\fP for a
-workaround.
+must be of type "UART boot" (0x69). The \fBkwboot\fP program changes
+this type automatically, unless the \fIimage\fP is signed, in which
+case it cannot be changed.
 
 This mode writes handshake status and upload progress indication to
-stdout.
+stdout. It is possible that \fIimage\fP contains an optional binary
+code in it's header which may also print some output via UART (for
+example U-Boot SPL does this). In such a case, this output is also
+written to stdout after the header is sent.
 
 .TP
 .BI "\-p"
-In combination with \fB-b\fP, patches the header in \fIimage\fP prior
-to upload, to "UART boot" type.
+Obsolete. Does nothing.
 
-This option attempts on-the-fly conversion of some none-UART image
-types, such as images which were originally formatted to be stored in
-flash memory.
-
-Conversion is performed in memory. The contents of \fIimage\fP will
-not be altered.
+In the past, when this option was used, the program patched the header
+in the image prior upload, to "UART boot" type. This is now done by
+default.
 
 .TP
 .BI "\-t"
@@ -65,11 +64,26 @@ If used in combination with \fB-b\fP, terminal mode is 
entered
 immediately following a successful image upload.
 
 If standard I/O streams connect to a console, this mode will terminate
-after receiving 'ctrl-\\' followed by 'c' from console input.
+after receiving \fBctrl-\e\fP followed by \fBc\fP from console input.
 
 .TP
 .BI "\-B \fIbaudrate\fP"
-Adjust the baud rate on \fITTY\fP. Default rate is 115200.
+If used in combination with \fB-b\fP, inject into the image header
+code that changes baud rate to \fIbaudrate\fP after uploading image
+header, and code that changes the baud rate back to the default
+(115200 Bd) before executing payload, and also adjust the baud rate
+on \fITTY\fP correspondingly. This can make the upload significantly
+faster.
+
+If used in combination with \fB-t\fP, adjust the baud rate to
+\fIbaudrate\fP on \fITTY\fP before starting terminal.
+
+If both \fB-b\fP and \fB-t\fP are used, the baud rate is changed
+back to 115200 after the upload.
+
+Tested values for \fIbaudrate\fP for Armada 38x include: 115200,
+230400, 460800, 50, 576000, 921600, 100, 1152000, 150,
+200, 250, 3125000, 400 and 520.
 
 .SH "SEE ALSO"
 .PP
@@ -82,3 +96,7 @@ Daniel Stodden 
 Luka Perkov 
 .br
 David Purdy 
+.br
+Pali Rohár 
+.br
+Marek Behún 
-- 
2.32.0



[PATCH u-boot-marvell 2/6] arm: a37xx: pci: Add support for accessing PCI Bridge on root bus

2021-09-25 Thread Marek Behún
From: Pali Rohár 

Aardvark does not have a real PCIe Root Port device on the root bus.
Instead it has PCIe registers of PCIe Root Port device mapped in
internal Aardvark memory space starting at offset 0xc0.

The PCIe Root Port itself is normally available as a PCI Bridge device
on the root bus with bus number zero. Aardvark instead has the
configuration registers of this PCI Bridge at offset 0x00 of Aardvark's
memory space, but the class code of this device is Mass Storage
Controller (0x010400), instead of PCI Bridge (0x600400), which causes
U-Boot to fail to recognize it as a P2P Bridge

Add a hook into the pcie_advk_read_config() / pcie_advk_write_config()
functions to redirect access for root bus from PIO transfer to this
internal Aardvark memory space. This will allow U-Boot to access
configuration space of this PCI Bridge which represents PCIe Root Port.

Redirect access to PCI Bridge registers in range 0x10 - 0x34 to driver's
internal buffer (cfgcache[]). This is because at those addresses
Aardvark has different registers, incompatible with config space of a
PCI Bridge.

Redirect access to PCI Bridge register PCI_ROM_ADDRESS1 (0x38) to
Aardvark internal address for that register (0x30).

When reading PCI Bridge register PCI_HEADER_TYPE, set it explicitly to
value Type 1 (PCI_HEADER_TYPE_BRIDGE) as PCI Bridge must be of Type 1.

When writing to PCI_PRIMARY_BUS or PCI_SECONDARY_BUS registers on this
PCI Bridge, correctly update driver's first_busno and sec_busno
variables, so that pcie_advk_addr_valid() function can check if address
of any device behind the root bus is valid and that PIO transfers are
started with correct config type (1 vs 0), which is required for
accessing devices behind some PCI bridge after the root bus.

U-Boot's PCI_PNP code sets primary and secondary bus numbers as relative
to the configured bus number of the root bus. This is done so that
U-Boot can support multiple PCIe host bridges or multiple root port
buses, when internal bus numbers are different.

Now that root bus is available, update code in pcie_advk_read_config()
and pcie_advk_write_config() functions to correctly calculate real
Aardvark bus number of the target device from U-Boot's bus number as:
  busno = PCI_BUS(bdf) - dev_seq(bus)

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 drivers/pci/pci-aardvark.c | 143 -
 1 file changed, 124 insertions(+), 19 deletions(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index 741e0431e1..692210ded9 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -39,6 +39,8 @@
 #define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0)
 #define PCIE_CORE_CMD_MEM_ACCESS_ENBIT(1)
 #define PCIE_CORE_CMD_MEM_IO_REQ_ENBIT(2)
+#define PCIE_CORE_DEV_REV_REG  0x8
+#define PCIE_CORE_EXP_ROM_BAR_REG  0x30
 #define PCIE_CORE_DEV_CTRL_STATS_REG   0xc8
 #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE   (0 << 4)
 #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
@@ -163,7 +165,7 @@
 #define PCIE_CONFIG_WR_TYPE1   0xb
 
 /* PCI_BDF shifts 8bit, so we need extra 4bit shift */
-#define PCIE_BDF(dev)  (dev << 4)
+#define PCIE_BDF(b, d, f)  (PCI_BDF(b, d, f) << 4)
 #define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20)
 #define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15)
 #define PCIE_CONF_FUNC(fun)(((fun) & 0x7)  << 12)
@@ -188,13 +190,17 @@
  *   first_busno stores the bus number of the PCIe root-port
  *   number which may vary depending on the PCIe setup
  *   (PEX switches etc).
+ * @sec_busno:   sec_busno stores the bus number for the device behind
+ *   the PCIe root-port
  * @device:  The pointer to PCI uclass device.
  */
 struct pcie_advk {
void   *base;
intfirst_busno;
+   intsec_busno;
struct udevice *dev;
struct gpio_desc reset_gpio;
+   u32cfgcache[0x34 - 0x10];
 };
 
 static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
@@ -210,22 +216,30 @@ static inline uint advk_readl(struct pcie_advk *pcie, 
uint reg)
 /**
  * pcie_advk_addr_valid() - Check for valid bus address
  *
+ * @pcie: Pointer to the PCI bus
+ * @busno: Bus number of PCI device
+ * @dev: Device number of PCI device
+ * @func: Function number of PCI device
  * @bdf: The PCI device to access
- * @first_busno: Bus number of the PCIe controller root complex
  *
- * Return: 1 on valid, 0 on invalid
+ * Return: true on valid, false on invalid
  */
-static int pcie_advk_addr_valid(pci_dev_t bdf, int first_busno)
+s

[PATCH u-boot-marvell 3/6] arm: a37xx: pci: Do not automatically enable bus mastering on PCI Bridge

2021-09-25 Thread Marek Behún
From: Pali Rohár 

Now that PCI Bridge is working for the PCIe Root Port, U-Boot's PCI_PNP
code automatically enables memory access and bus mastering when needed.

We do not need to enable it when setting the HW up.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 drivers/pci/pci-aardvark.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index 692210ded9..8c025dc45d 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -910,12 +910,6 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie)
if (pcie_advk_wait_for_link(pcie))
return -ENXIO;
 
-   reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
-   reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
-   PCIE_CORE_CMD_IO_ACCESS_EN |
-   PCIE_CORE_CMD_MEM_IO_REQ_EN;
-   advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);
-
return 0;
 }
 
-- 
2.32.0



[PATCH u-boot-marvell 4/6] arm: a37xx: pci: Handle propagation of CRSSVE bit from PCIe Root Port

2021-09-25 Thread Marek Behún
From: Pali Rohár 

Now that PCI Bridge (PCIe Root Port) for Aardvark is emulated in U-Boot,
add support for handling and propagation of CRSSVE bit.

When CRSSVE bit is unset (default), driver has to reissue config
read/write request on CRS response.

CRSSVE bit is supported only when CRSVIS bit is provided in read-only
Root Capabilities register. So manually inject this CRSVIS bit into read
response for that register.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 drivers/pci/pci-aardvark.c | 26 ++
 include/pci.h  |  4 
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index 8c025dc45d..53e9e23d4a 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -41,6 +41,7 @@
 #define PCIE_CORE_CMD_MEM_IO_REQ_ENBIT(2)
 #define PCIE_CORE_DEV_REV_REG  0x8
 #define PCIE_CORE_EXP_ROM_BAR_REG  0x30
+#define PCIE_CORE_PCIEXP_CAP_OFF   0xc0
 #define PCIE_CORE_DEV_CTRL_STATS_REG   0xc8
 #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE   (0 << 4)
 #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
@@ -201,6 +202,7 @@ struct pcie_advk {
struct udevice *dev;
struct gpio_desc reset_gpio;
u32cfgcache[0x34 - 0x10];
+   bool   cfgcrssve;
 };
 
 static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
@@ -413,6 +415,18 @@ static int pcie_advk_read_config(const struct udevice 
*bus, pci_dev_t bdf,
data |= PCI_HEADER_TYPE_BRIDGE << 16;
}
 
+   if ((offset & ~3) == PCIE_CORE_PCIEXP_CAP_OFF + PCI_EXP_RTCTL) {
+   /* CRSSVE bit is stored only in cache */
+   if (pcie->cfgcrssve)
+   data |= PCI_EXP_RTCTL_CRSSVE;
+   }
+
+   if ((offset & ~3) == PCIE_CORE_PCIEXP_CAP_OFF +
+(PCI_EXP_RTCAP & ~3)) {
+   /* CRS is emulated below, so set CRSVIS capability */
+   data |= PCI_EXP_RTCAP_CRSVIS << 16;
+   }
+
*valuep = pci_conv_32_to_size(data, offset, size);
 
return 0;
@@ -423,13 +437,14 @@ static int pcie_advk_read_config(const struct udevice 
*bus, pci_dev_t bdf,
 * OS is allowed only for 4-byte PCI_VENDOR_ID config read request and
 * only when CRSSVE bit in Root Port PCIe device is enabled. In all
 * other error PCIe Root Complex must return all-ones.
-* Aardvark HW does not have Root Port PCIe device and U-Boot does not
-* implement emulation of this device.
+*
 * U-Boot currently does not support handling of CRS return value for
 * PCI_VENDOR_ID config read request and also does not set CRSSVE bit.
-* Therefore disable returning CRS response for now.
+* So it means that pcie->cfgcrssve is false. But the code is prepared
+* for returning CRS, so that if U-Boot does support CRS in the future,
+* it will work for Aardvark.
 */
-   allow_crs = false;
+   allow_crs = pcie->cfgcrssve;
 
if (advk_readl(pcie, PIO_START)) {
dev_err(pcie->dev,
@@ -583,6 +598,9 @@ static int pcie_advk_write_config(struct udevice *bus, 
pci_dev_t bdf,
(offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8))
pcie->sec_busno = (data >> 8) & 0xff;
 
+   if ((offset & ~3) == PCIE_CORE_PCIEXP_CAP_OFF + PCI_EXP_RTCTL)
+   pcie->cfgcrssve = data & PCI_EXP_RTCTL_CRSSVE;
+
return 0;
}
 
diff --git a/include/pci.h b/include/pci.h
index 0fc22adffd..69eafeb4b9 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -495,6 +495,10 @@
 #define  PCI_EXP_LNKSTA_DLLLA  0x2000  /* Data Link Layer Link Active */
 #define PCI_EXP_SLTCAP 20  /* Slot Capabilities */
 #define  PCI_EXP_SLTCAP_PSN0xfff8 /* Physical Slot Number */
+#define PCI_EXP_RTCTL  28  /* Root Control */
+#define  PCI_EXP_RTCTL_CRSSVE  0x0010  /* CRS Software Visibility Enable */
+#define PCI_EXP_RTCAP  30  /* Root Capabilities */
+#define  PCI_EXP_RTCAP_CRSVIS  0x0001  /* CRS Software Visibility capability */
 #define PCI_EXP_DEVCAP236  /* Device Capabilities 2 */
 #define  PCI_EXP_DEVCAP2_ARI   0x0020 /* ARI Forwarding Supported */
 #define PCI_EXP_DEVCTL240  /* Device Control 2 */
-- 
2.32.0



[PATCH u-boot-marvell 1/6] arm: a37xx: pci: Fix pcie_advk_link_up()

2021-09-25 Thread Marek Behún
From: Pali Rohár 

Aardvark reports Disabled and Hot Reset LTSSM states as values >= 0x20.
Link is not up in these states, so fix pcie_advk_link_up() function.

Signed-off-by: Pali Rohár 
Reviewed-by: Marek Behún 
---
 drivers/pci/pci-aardvark.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index cf6e30f936..741e0431e1 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -145,6 +145,7 @@
 #define LTSSM_SHIFT24
 #define LTSSM_MASK 0x3f
 #define LTSSM_L0   0x10
+#define LTSSM_DISABLED 0x20
 #define VENDOR_ID_REG  (LMI_BASE_ADDR + 0x44)
 
 /* PCIe core controller registers */
@@ -569,7 +570,7 @@ static int pcie_advk_link_up(struct pcie_advk *pcie)
 
val = advk_readl(pcie, CFG_REG);
ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK;
-   return ltssm_state >= LTSSM_L0;
+   return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED;
 }
 
 /**
-- 
2.32.0



[PATCH u-boot-marvell 0/6] A3720 PCIe enhancements

2021-09-25 Thread Marek Behún
From: Marek Behún 

Hello Stefan,

Pali has worked on some more enhancements for Armada 3720 PCIe driver
(Aardvark).

The main change is adding support for accessing configuration space of
the PCI Bridge on the PCIe Root Port. Linux does something similar with
pci-bridge-emul.

Marek

Marek Behún (2):
  arm: a37xx: pci: Cosmetic change
  arm: a37xx: pci: Update private structure documentation

Pali Rohár (4):
  arm: a37xx: pci: Fix pcie_advk_link_up()
  arm: a37xx: pci: Add support for accessing PCI Bridge on root bus
  arm: a37xx: pci: Do not automatically enable bus mastering on PCI
Bridge
  arm: a37xx: pci: Handle propagation of CRSSVE bit from PCIe Root Port

 drivers/pci/pci-aardvark.c | 199 +
 include/pci.h  |   4 +
 2 files changed, 163 insertions(+), 40 deletions(-)

-- 
2.32.0



[PATCH u-boot-marvell 5/6] arm: a37xx: pci: Cosmetic change

2021-09-25 Thread Marek Behún
From: Marek Behún 

Update indentation in driver's private structure.

Signed-off-by: Marek Behún 
---
 drivers/pci/pci-aardvark.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index 53e9e23d4a..b4f350ca2c 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -196,13 +196,13 @@
  * @device:  The pointer to PCI uclass device.
  */
 struct pcie_advk {
-   void   *base;
-   intfirst_busno;
-   intsec_busno;
-   struct udevice *dev;
-   struct gpio_desc reset_gpio;
-   u32cfgcache[0x34 - 0x10];
-   bool   cfgcrssve;
+   void*base;
+   int first_busno;
+   int sec_busno;
+   struct udevice  *dev;
+   struct gpio_descreset_gpio;
+   u32 cfgcache[0x34 - 0x10];
+   boolcfgcrssve;
 };
 
 static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
-- 
2.32.0



[PATCH u-boot-spi v2 2/9] mtd: spi-nor-core: Check return value of write_enable() in spi_nor_erase()

2021-09-25 Thread Marek Behún
From: Marek Behún 

The spi_nor_erase() function does not check return value of the
write_enable() call. Fix this.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Reviewed-by: Jagan Teki 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 529e7e9178..d2018ab702 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -929,7 +929,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
if (ret < 0)
goto erase_err;
 #endif
-   write_enable(nor);
+   ret = write_enable(nor);
+   if (ret < 0)
+   goto erase_err;
 
ret = spi_nor_erase_sector(nor, addr);
if (ret < 0)
-- 
2.32.0



[PATCH u-boot-spi v2 8/9] mtd: mtdpart: Make mtdpart's _erase method sane

2021-09-25 Thread Marek Behún
From: Marek Behún 

The _erase() method of the mtdpart driver, part_erase(), currently
implements offset shifting (for given mtdpart partition) in a weird way:
  1. part_erase() adds partition offset to block address
  2. parent driver's _erase() method is called
  3. parent driver's _erase() method calls mtd_erase_callback()
  4. mtd_erase_callback() subtracts partition offset from block address
 so that the callback function is given correct address
The problem here is that if the parent's driver does not call
mtd_erase_callback() in some scenario (this was recently a case for
spi_nor_erase(), which did not call mtd_erase_callback() at all), the
offset is not shifted back.

Moreover the code would be more readable if part_erase() not only added
partition offset before calling parent's _erase(), but also subtracted
it back afterwards. Currently the mtd_erase_callback() is expected to do
this subtracting since it does have to do it anyway.

Add the more steps to this procedure:
  5. mtd_erase_callback() adds partition offset to block address so that
 it returns the the erase_info structure members as it received them
  6. part_erase() subtracts partition offset from block address

This makes the code more logical and also prevents errors in case
parent's driver does not call mtd_erase_callback() for some reason.

(BTW, the purpose of mtd_erase_callback() in Linux is to inform the
 caller that it is done, since in Linux erasing is done asynchronously.
 We are abusing the purpose of mtd_erase_callback() in U-Boot for
 completely different purpose. The callback function itself has empty
 implementation in all cases in U-Boot.)

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/mtdpart.c | 26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index aa58f722da..6ab481a7b1 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -446,24 +446,34 @@ static int part_erase(struct mtd_info *mtd, struct 
erase_info *instr)
int ret;
 
instr->addr += mtd->offset;
+
ret = mtd->parent->_erase(mtd->parent, instr);
-   if (ret) {
-   if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
-   instr->fail_addr -= mtd->offset;
-   instr->addr -= mtd->offset;
-   }
+   if (ret && instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
+   instr->fail_addr -= mtd->offset;
+
+   instr->addr -= mtd->offset;
+
return ret;
 }
 
 void mtd_erase_callback(struct erase_info *instr)
 {
-   if (instr->mtd->_erase == part_erase) {
+   if (!instr->callback)
+   return;
+
+   if (instr->mtd->_erase == part_erase && instr->len) {
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr -= instr->mtd->offset;
instr->addr -= instr->mtd->offset;
}
-   if (instr->callback)
-   instr->callback(instr);
+
+   instr->callback(instr);
+
+   if (instr->mtd->_erase == part_erase && instr->len) {
+   if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
+   instr->fail_addr += instr->mtd->offset;
+   instr->addr += instr->mtd->offset;
+   }
 }
 EXPORT_SYMBOL_GPL(mtd_erase_callback);
 
-- 
2.32.0



[PATCH u-boot-spi v2 6/9] mtd: spi-nor-core: Call mtd_erase_callback() from spi_nor_erase()

2021-09-25 Thread Marek Behún
From: Marek Behún 

The spi_nor_erase() function does not call mtd_erase_callback() as it
should.

The mtdpart code currently implements the subtraction of partition
offset in mtd_erase_callback().

This results in partition offset being added prior calling
spi_nor_erase(), but not subtracted back on return. The result is that
the `mtd erase` command does not erase the whole partition, only some of
it's blocks:

  => mtd erase "Rescue system"
  Erasing 0x ... 0x006f (1792 eraseblock(s))
  jedec_spi_nor spi-nor@0: at 0x10, len 4096
  jedec_spi_nor spi-nor@0: at 0x201000, len 4096
  jedec_spi_nor spi-nor@0: at 0x302000, len 4096
  jedec_spi_nor spi-nor@0: at 0x403000, len 4096
  jedec_spi_nor spi-nor@0: at 0x504000, len 4096
  jedec_spi_nor spi-nor@0: at 0x605000, len 4096
  jedec_spi_nor spi-nor@0: at 0x706000, len 4096

This is obviously wrong.

Add proper calling of mtd_erase_callback() into the spi_nor_erase()
function.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Reported-by: Masami Hiramatsu 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 211eea22a4..f3e08ed412 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -906,6 +906,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   bool addr_known = false;
u32 addr, len, rem;
int ret, err;
 
@@ -913,12 +914,17 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
(long long)instr->len);
 
div_u64_rem(instr->len, mtd->erasesize, );
-   if (rem)
-   return -EINVAL;
+   if (rem) {
+   ret = -EINVAL;
+   goto erase_err_callback;
+   }
 
addr = instr->addr;
len = instr->len;
 
+   instr->state = MTD_ERASING;
+   addr_known = true;
+
while (len) {
WATCHDOG_RESET();
 #ifdef CONFIG_SPI_FLASH_BAR
@@ -942,6 +948,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
goto erase_err;
}
 
+   addr_known = false;
 erase_err:
 #ifdef CONFIG_SPI_FLASH_BAR
err = clean_bar(nor);
@@ -952,6 +959,15 @@ erase_err:
if (!ret)
ret = err;
 
+erase_err_callback:
+   if (ret) {
+   instr->fail_addr = addr_known ? addr : MTD_FAIL_ADDR_UNKNOWN;
+   instr->state = MTD_ERASE_FAILED;
+   } else {
+   instr->state = MTD_ERASE_DONE;
+   }
+   mtd_erase_callback(instr);
+
return ret;
 }
 
-- 
2.32.0



[PATCH u-boot-spi v2 3/9] mtd: spi-nor-core: Don't overwrite return value if it is non-zero

2021-09-25 Thread Marek Behún
From: Marek Behún 

The cleanup code of the spi_nor_erase() function overwrites the ret
variable with return value of clean_bar(), even if the ret variable is
already set. Fix this.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index d2018ab702..30c0afc08c 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -907,7 +907,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
u32 addr, len, rem;
-   int ret;
+   int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
(long long)instr->len);
@@ -947,7 +947,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 
 erase_err:
 #ifdef CONFIG_SPI_FLASH_BAR
-   ret = clean_bar(nor);
+   err = clean_bar(nor);
+   if (!ret)
+   ret = err;
 #endif
write_disable(nor);
 
-- 
2.32.0



[PATCH u-boot-spi v2 5/9] mtd: spi-nor-core: Don't check for zero length in spi_nor_erase()

2021-09-25 Thread Marek Behún
From: Marek Behún 

This check is already done in mtdcore's mtd_erase(), no reason to do
this here as well.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9e936cbe1a..211eea22a4 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -912,9 +912,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
(long long)instr->len);
 
-   if (!instr->len)
-   return 0;
-
div_u64_rem(instr->len, mtd->erasesize, );
if (rem)
return -EINVAL;
-- 
2.32.0



[PATCH u-boot-spi v2 7/9] mtd: spi-nor-core: Check for ctrlc() in spi_nor_erase()

2021-09-25 Thread Marek Behún
From: Marek Behún 

May it possible to interrupt the spi_nor_erase() function.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index f3e08ed412..124594f0cd 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -927,6 +927,11 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 
while (len) {
WATCHDOG_RESET();
+   if (ctrlc()) {
+   addr_known = false;
+   ret = -EINTR;
+   goto erase_err;
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
-- 
2.32.0



[PATCH u-boot-spi v2 4/9] mtd: spi-nor-core: Check return value of write_disable() in spi_nor_erase()

2021-09-25 Thread Marek Behún
From: Marek Behún 

The cleanup code of spi_nor_erase() function calls write_disable(), but
does not return it's return value even in case of failure. Fix this.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 30c0afc08c..9e936cbe1a 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -951,7 +951,9 @@ erase_err:
if (!ret)
ret = err;
 #endif
-   write_disable(nor);
+   err = write_disable(nor);
+   if (!ret)
+   ret = err;
 
return ret;
 }
-- 
2.32.0



[PATCH u-boot-spi v2 1/9] mtd: spi-nor-core: Try cleaning up in case writing BAR failed

2021-09-25 Thread Marek Behún
From: Marek Behún 

Use the cleanup codepath of spi_nor_erase() also in the event of failure
of writing the BAR register.

Signed-off-by: Marek Behún 
Reviewed-by: Simon Glass 
Reviewed-by: Jagan Teki 
Tested-by: Masami Hiramatsu 
---
 drivers/mtd/spi/spi-nor-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index d5d905fa5a..529e7e9178 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -927,7 +927,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
-   return ret;
+   goto erase_err;
 #endif
write_enable(nor);
 
-- 
2.32.0



[PATCH u-boot-spi v2 0/9] Fix `mtd erase` when used with mtdpart

2021-09-25 Thread Marek Behún
From: Marek Behún 

The original cover letter said:

this patch series fixes the `mtd erase` command when used with mtdpart
with a partition of non-zero offset.

Currently when the `mtd erase` command is used for such a partition,
it does not erase all blocks. Instead after a block is erased, the next
block address not current block address + block size, but current block
address + block size + partition offset, due to spi_nor_erase() not
calling mtd_erase_callback():
  => mtd erase "Rescue system"  
  Erasing 0x ... 0x006f (1792 eraseblock(s))
  jedec_spi_nor spi-nor@0: at 0x10, len 4096
  jedec_spi_nor spi-nor@0: at 0x201000, len 4096
  jedec_spi_nor spi-nor@0: at 0x302000, len 4096
  jedec_spi_nor spi-nor@0: at 0x403000, len 4096
  jedec_spi_nor spi-nor@0: at 0x504000, len 4096
  jedec_spi_nor spi-nor@0: at 0x605000, len 4096
  jedec_spi_nor spi-nor@0: at 0x706000, len 4096

This series adds some fixes to spi_nor_erase() function, then adds
calling of mtd_erase_callback() to fix this bug.

The series also contains an improvement - adding the posibility to
interrupt spi_nor_erase() with Ctrl+C; and another one - making mtdpart's
_erase() method more sane so that the above mentioned bug will not occur
even if underlying driver does not call mtd_erase_callback().

Finally the last patch removes mtd_erase_callback() entirely, since:
- all provided callbacks across U-Boot are no-ops
- mtd_erase_callback() is abused for completely different purpose
  than the original one (as explained in last commit message)

Marek

Changes since v1:
- fixed CI bugs (by removing mtd_erase_callback() entirely)

Marek Behún (9):
  mtd: spi-nor-core: Try cleaning up in case writing BAR failed
  mtd: spi-nor-core: Check return value of write_enable() in
spi_nor_erase()
  mtd: spi-nor-core: Don't overwrite return value if it is non-zero
  mtd: spi-nor-core: Check return value of write_disable() in
spi_nor_erase()
  mtd: spi-nor-core: Don't check for zero length in spi_nor_erase()
  mtd: spi-nor-core: Call mtd_erase_callback() from spi_nor_erase()
  mtd: spi-nor-core: Check for ctrlc() in spi_nor_erase()
  mtd: mtdpart: Make mtdpart's _erase method sane
  mtd: Remove mtd_erase_callback() entirely

 cmd/onenand.c  |  9 ++-
 drivers/mtd/altera_qspi.c  |  3 ---
 drivers/mtd/cfi_mtd.c  |  1 -
 drivers/mtd/mtdconcat.c| 11 
 drivers/mtd/mtdcore.c  |  8 --
 drivers/mtd/mtdpart.c  | 23 +---
 drivers/mtd/nand/raw/nand_base.c   |  4 ---
 drivers/mtd/onenand/onenand_base.c |  3 ---
 drivers/mtd/spi/sf_mtd.c   |  1 -
 drivers/mtd/spi/spi-nor-core.c | 43 +++---
 drivers/mtd/ubi/io.c   | 13 -
 env/onenand.c  |  4 +--
 fs/yaffs2/yaffs_mtdif.c|  1 -
 include/linux/mtd/mtd.h| 11 
 include/nand.h |  1 -
 15 files changed, 42 insertions(+), 94 deletions(-)

-- 
2.32.0



[PATCH u-boot-marvell 6/6] arm: a37xx: pci: Update private structure documentation

2021-09-25 Thread Marek Behún
From: Marek Behún 

There were several changes for this structure but the documentation was
not changed at the time. Fix this.

Signed-off-by: Marek Behún 
---
 drivers/pci/pci-aardvark.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index b4f350ca2c..76cb2098e8 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -186,14 +186,15 @@
 /**
  * struct pcie_advk - Advk PCIe controller state
  *
- * @reg_base:The base address of the register space.
- * @first_busno: This driver supports multiple PCIe controllers.
- *   first_busno stores the bus number of the PCIe root-port
- *   number which may vary depending on the PCIe setup
- *   (PEX switches etc).
- * @sec_busno:   sec_busno stores the bus number for the device behind
- *   the PCIe root-port
- * @device:  The pointer to PCI uclass device.
+ * @base:The base address of the register space.
+ * @first_busno: Bus number for the device behind the PCIe root-port.
+ *   This may vary depending on the PCIe setup.
+ * @sec_busno:   Bus number for the device behind the PCIe root-port.
+ * @dev: The pointer to PCI uclass device.
+ * @reset_gpio:  GPIO descriptor for PERST.
+ * @cfgcache:Buffer for emulation of PCIe Root Port's PCI Bridge registers
+ *   that are not available on Aardvark.
+ * @cfgcrssve:   For CRSSVE emulation.
  */
 struct pcie_advk {
void*base;
-- 
2.32.0



[PATCH u-boot-spi v2 9/9] mtd: Remove mtd_erase_callback() entirely

2021-09-25 Thread Marek Behún
From: Marek Behún 

The original purpose of mtd_erase_callback() in Linux at the time it was
imported to U-Boot, was to inform the caller that erasing is done (since
it was an asynchronous operation).

All supplied callback methods in U-Boot do nothing, but the
mtd_erase_callback() function was (until previous patch) grossly abused
in U-Boot's mtdpart implementation for completely different purpose.

Since we got rid of the abusement, remove the mtd_erase_callback()
function and the .callback member from struct erase_info entirely, in
order to avoid such problems in the future.

Signed-off-by: Marek Behún 
---
 cmd/onenand.c  |  9 ++---
 drivers/mtd/altera_qspi.c  |  3 ---
 drivers/mtd/cfi_mtd.c  |  1 -
 drivers/mtd/mtdconcat.c| 11 ---
 drivers/mtd/mtdcore.c  |  8 
 drivers/mtd/mtdpart.c  | 21 -
 drivers/mtd/nand/raw/nand_base.c   |  4 
 drivers/mtd/onenand/onenand_base.c |  3 ---
 drivers/mtd/spi/sf_mtd.c   |  1 -
 drivers/mtd/spi/spi-nor-core.c |  5 ++---
 drivers/mtd/ubi/io.c   | 13 -
 env/onenand.c  |  4 +---
 fs/yaffs2/yaffs_mtdif.c|  1 -
 include/linux/mtd/mtd.h| 11 ---
 include/nand.h |  1 -
 15 files changed, 5 insertions(+), 91 deletions(-)

diff --git a/cmd/onenand.c b/cmd/onenand.c
index 852ed5c7b2..592985a7ee 100644
--- a/cmd/onenand.c
+++ b/cmd/onenand.c
@@ -186,9 +186,7 @@ next:
 static int onenand_block_erase(u32 start, u32 size, int force)
 {
struct onenand_chip *this = mtd->priv;
-   struct erase_info instr = {
-   .callback   = NULL,
-   };
+   struct erase_info instr = {};
loff_t ofs;
int ret;
int blocksize = 1 << this->erase_shift;
@@ -219,10 +217,7 @@ static int onenand_block_erase(u32 start, u32 size, int 
force)
 static int onenand_block_test(u32 start, u32 size)
 {
struct onenand_chip *this = mtd->priv;
-   struct erase_info instr = {
-   .callback   = NULL,
-   .priv   = 0,
-   };
+   struct erase_info instr = {};
 
int blocks;
loff_t ofs;
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index 7bac599a54..d31391f36a 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -153,7 +153,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct 
erase_info *instr)
putc('\n');
instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
instr->state = MTD_ERASE_FAILED;
-   mtd_erase_callback(instr);
return -EIO;
}
flash = pdata->base + addr;
@@ -177,7 +176,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct 
erase_info *instr)
writel(stat, >isr); /* clear isr */
instr->fail_addr = addr;
instr->state = MTD_ERASE_FAILED;
-   mtd_erase_callback(instr);
return -EIO;
}
if (flash_verbose)
@@ -189,7 +187,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct 
erase_info *instr)
addr += mtd->erasesize;
}
instr->state = MTD_ERASE_DONE;
-   mtd_erase_callback(instr);
 
return 0;
 }
diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c
index 78293caa2f..2295bb7220 100644
--- a/drivers/mtd/cfi_mtd.c
+++ b/drivers/mtd/cfi_mtd.c
@@ -58,7 +58,6 @@ static int cfi_mtd_erase(struct mtd_info *mtd, struct 
erase_info *instr)
}
 
instr->state = MTD_ERASE_DONE;
-   mtd_erase_callback(instr);
return 0;
}
 
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 684bc94998..af3c4765c4 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -338,14 +338,6 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct 
mtd_oob_ops *ops)
return -EINVAL;
 }
 
-static void concat_erase_callback(struct erase_info *instr)
-{
-   /* Nothing to do here in U-Boot */
-#ifndef __UBOOT__
-   wake_up((wait_queue_head_t *) instr->priv);
-#endif
-}
-
 static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
 {
int err;
@@ -358,7 +350,6 @@ static int concat_dev_erase(struct mtd_info *mtd, struct 
erase_info *erase)
init_waitqueue_head();
 
erase->mtd = mtd;
-   erase->callback = concat_erase_callback;
erase->priv = (unsigned long) 
 
/*
@@ -498,8 +489,6 @@ static int concat_erase(struct mtd_info *mtd, struct 
erase_info *instr)
if (err)
return err;
 
-   if (instr->callback)

[PATCH u-boot-marvell 12/12] arm: mvebu: turris_omnia: Move CONFIG_SPL_DRIVERS_MISC to Kconfig

2021-10-09 Thread Marek Behún
From: Marek Behún 

Instead of declaring CONFIG_SPL_DRIVERS_MISC in board config header,
select it in Kconfig.

Signed-off-by: Marek Behún 
---
 arch/arm/mach-mvebu/Kconfig| 1 +
 include/configs/turris_omnia.h | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 8365305733..c66dab6012 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -127,6 +127,7 @@ config TARGET_TURRIS_OMNIA
select DM_I2C
select I2C_MUX
select I2C_MUX_PCA954x
+   select SPL_DRIVERS_MISC
select SPL_I2C_MUX
select SPL_SYS_MALLOC_SIMPLE
select SYS_I2C_MVTWSI
diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
index 562b49327f..3af62ef48c 100644
--- a/include/configs/turris_omnia.h
+++ b/include/configs/turris_omnia.h
@@ -38,7 +38,6 @@
 
 #define CONFIG_SPL_STACK   (0x4000 + ((192 - 16) << 10))
 #define CONFIG_SPL_BOOTROM_SAVE(CONFIG_SPL_STACK + 4)
-#define CONFIG_SPL_DRIVERS_MISC
 
 #ifdef CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC
 /* SPL related MMC defines */
-- 
2.32.0



[PATCH 4/4] Convert CONFIG_USB_EHCI_IS_TDI to Kconfig

2021-10-09 Thread Marek Behún
From: Marek Behún 

On mvebu this is defined if and only if !ARM64.

Otherwise it is defined for boards with ARCH_MX23, ARCH_TEGRA and
ARCH_ZYNQ, and also for SOC_AR934X (tplink_wdr4300).

Signed-off-by: Marek Behún 
---
 arch/arm/mach-kirkwood/include/mach/config.h | 7 ---
 arch/mips/mach-ath79/Kconfig | 1 +
 drivers/usb/host/Kconfig | 7 +++
 include/configs/clearfog.h   | 3 ---
 include/configs/controlcenterdc.h| 3 ---
 include/configs/crs3xx-98dx3236.h| 3 ---
 include/configs/db-88f6720.h | 1 -
 include/configs/db-88f6820-amc.h | 3 ---
 include/configs/db-88f6820-gp.h  | 3 ---
 include/configs/db-mv784mp-gp.h  | 1 -
 include/configs/db-xc3-24g4xg.h  | 3 ---
 include/configs/ds414.h  | 3 ---
 include/configs/helios4.h| 3 ---
 include/configs/mxs.h| 5 -
 include/configs/nas220.h | 7 ---
 include/configs/tegra114-common.h| 1 -
 include/configs/tegra124-common.h| 1 -
 include/configs/tegra20-common.h | 1 -
 include/configs/tegra210-common.h| 1 -
 include/configs/tegra30-common.h | 1 -
 include/configs/theadorable.h| 1 -
 include/configs/tplink_wdr4300.h | 1 -
 include/configs/turris_omnia.h   | 3 ---
 include/configs/x530.h   | 3 ---
 include/configs/zynq-common.h| 2 --
 scripts/config_whitelist.txt | 1 -
 26 files changed, 8 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-kirkwood/include/mach/config.h 
b/arch/arm/mach-kirkwood/include/mach/config.h
index f262d70b14..cf6b1b9b63 100644
--- a/arch/arm/mach-kirkwood/include/mach/config.h
+++ b/arch/arm/mach-kirkwood/include/mach/config.h
@@ -62,13 +62,6 @@
 #define CONFIG_RESET_PHY_R /* use reset_phy() to init mv8831116 PHY */
 #endif /* CONFIG_CMD_NET */
 
-/*
- * USB/EHCI
- */
-#ifdef CONFIG_CMD_USB
-#define CONFIG_USB_EHCI_IS_TDI
-#endif /* CONFIG_CMD_USB */
-
 /*
  * IDE Support on SATA ports
  */
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index bdb23b5765..cd85d1b6c3 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -20,6 +20,7 @@ config SOC_AR934X
select SUPPORTS_BIG_ENDIAN
select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2
+   select USB_EHCI_IS_TDI if USB_EHCI_HCD
help
  This supports QCA/Atheros ar934x family SOCs.
 
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index be5e4b994d..ccecb5a3b0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -139,6 +139,9 @@ config USB_EHCI_HCD
 
 if USB_EHCI_HCD
 
+config USB_EHCI_IS_TDI
+   bool
+
 config USB_EHCI_ATMEL
bool  "Support for Atmel on-chip EHCI USB controller"
depends on ARCH_AT91
@@ -150,6 +153,7 @@ config USB_EHCI_MARVELL
bool "Support for Marvell on-chip EHCI USB controller"
depends on ARCH_MVEBU || ARCH_KIRKWOOD || ARCH_ORION5X
default y
+   select USB_EHCI_IS_TDI if !ARM64
---help---
  Enables support for the on-chip EHCI controller on MVEBU SoCs.
 
@@ -179,6 +183,7 @@ config USB_EHCI_MXS
bool "Support for i.MX23 EHCI USB controller"
depends on ARCH_MX23
default y
+   select USB_EHCI_IS_TDI
help
  Enables support for the on-chip EHCI controller on i.MX23 SoCs.
 
@@ -258,12 +263,14 @@ config USB_EHCI_PCI
 config USB_EHCI_TEGRA
bool "Support for NVIDIA Tegra on-chip EHCI USB controller"
depends on ARCH_TEGRA
+   select USB_EHCI_IS_TDI
---help---
  Enable support for Tegra on-chip EHCI USB controller
 
 config USB_EHCI_ZYNQ
bool "Support for Xilinx Zynq on-chip EHCI USB controller"
default y if ARCH_ZYNQ
+   select USB_EHCI_IS_TDI
---help---
  Enable support for Zynq on-chip EHCI USB controller
 
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
index a12e1582d6..a30bca5147 100644
--- a/include/configs/clearfog.h
+++ b/include/configs/clearfog.h
@@ -18,9 +18,6 @@
  * U-Boot into it.
  */
 
-/* USB/EHCI configuration */
-#define CONFIG_USB_EHCI_IS_TDI
-
 #define CONFIG_ENV_MIN_ENTRIES 128
 
 /* Environment in MMC */
diff --git a/include/configs/controlcenterdc.h 
b/include/configs/controlcenterdc.h
index 12e9b8d06d..21e61e5e8f 100644
--- a/include/configs/controlcenterdc.h
+++ b/include/configs/controlcenterdc.h
@@ -27,9 +27,6 @@
 #define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
 CONFIG_SYS_SCSI_MAX_LUN)
 
-/* USB/EHCI configuration */
-#define CONFIG_USB_EHCI_IS_TDI
-
 /* Environment in SPI NOR flash */
 
 #define PHY_ANEG_TIMEOUT

[PATCH 1/4] Rename CONFIG_EHCI_IS_TDI to CONFIG_USB_EHCI_IS_TDI

2021-10-09 Thread Marek Behún
From: Marek Behún 

In preparation for moving this option to Kconfig, rename it to be
consistent with other USB EHCI Kconfig options.

Signed-off-by: Marek Behún 
---
 arch/arm/mach-kirkwood/include/mach/config.h | 2 +-
 drivers/usb/host/ehci-hcd.c  | 2 +-
 include/configs/clearfog.h   | 2 +-
 include/configs/controlcenterdc.h| 2 +-
 include/configs/crs3xx-98dx3236.h| 2 +-
 include/configs/db-88f6720.h | 2 +-
 include/configs/db-88f6820-amc.h | 2 +-
 include/configs/db-88f6820-gp.h  | 2 +-
 include/configs/db-mv784mp-gp.h  | 2 +-
 include/configs/db-xc3-24g4xg.h  | 2 +-
 include/configs/ds414.h  | 2 +-
 include/configs/helios4.h| 2 +-
 include/configs/mxs.h| 2 +-
 include/configs/nas220.h | 2 +-
 include/configs/tegra114-common.h| 2 +-
 include/configs/tegra124-common.h| 2 +-
 include/configs/tegra20-common.h | 2 +-
 include/configs/tegra210-common.h| 2 +-
 include/configs/tegra30-common.h | 2 +-
 include/configs/theadorable.h| 2 +-
 include/configs/tplink_wdr4300.h | 2 +-
 include/configs/turris_omnia.h   | 2 +-
 include/configs/x530.h   | 2 +-
 include/configs/zynq-common.h| 2 +-
 scripts/config_whitelist.txt | 2 +-
 25 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-kirkwood/include/mach/config.h 
b/arch/arm/mach-kirkwood/include/mach/config.h
index 9002e26d75..f262d70b14 100644
--- a/arch/arm/mach-kirkwood/include/mach/config.h
+++ b/arch/arm/mach-kirkwood/include/mach/config.h
@@ -66,7 +66,7 @@
  * USB/EHCI
  */
 #ifdef CONFIG_CMD_USB
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 #endif /* CONFIG_CMD_USB */
 
 /*
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ba75c27d04..e6355263cb 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -108,7 +108,7 @@ static struct descriptor {
},
 };
 
-#if defined(CONFIG_EHCI_IS_TDI)
+#if defined(CONFIG_USB_EHCI_IS_TDI)
 #define ehci_is_TDI()  (1)
 #else
 #define ehci_is_TDI()  (0)
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
index 705217067b..a12e1582d6 100644
--- a/include/configs/clearfog.h
+++ b/include/configs/clearfog.h
@@ -19,7 +19,7 @@
  */
 
 /* USB/EHCI configuration */
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 
 #define CONFIG_ENV_MIN_ENTRIES 128
 
diff --git a/include/configs/controlcenterdc.h 
b/include/configs/controlcenterdc.h
index efd04c6fb8..12e9b8d06d 100644
--- a/include/configs/controlcenterdc.h
+++ b/include/configs/controlcenterdc.h
@@ -28,7 +28,7 @@
 CONFIG_SYS_SCSI_MAX_LUN)
 
 /* USB/EHCI configuration */
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 
 /* Environment in SPI NOR flash */
 
diff --git a/include/configs/crs3xx-98dx3236.h 
b/include/configs/crs3xx-98dx3236.h
index 3feaa60eda..5300467a76 100644
--- a/include/configs/crs3xx-98dx3236.h
+++ b/include/configs/crs3xx-98dx3236.h
@@ -14,7 +14,7 @@
 #define CONFIG_SYS_KWD_CONFIG  $(CONFIG_BOARDDIR)/kwbimage.cfg
 
 /* USB/EHCI configuration */
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 
 /* Environment in SPI NOR flash */
 
diff --git a/include/configs/db-88f6720.h b/include/configs/db-88f6720.h
index 95f5cf0056..76c02f6656 100644
--- a/include/configs/db-88f6720.h
+++ b/include/configs/db-88f6720.h
@@ -20,7 +20,7 @@
 #define CONFIG_I2C_MVTWSI_BASE0MVEBU_TWSI_BASE
 
 /* USB/EHCI configuration */
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 3
 
 /* Environment in SPI NOR flash */
diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h
index 41216b8b4f..c5f0a1d2e0 100644
--- a/include/configs/db-88f6820-amc.h
+++ b/include/configs/db-88f6820-amc.h
@@ -11,7 +11,7 @@
  */
 
 /* USB/EHCI configuration */
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 
 /* Environment in SPI NOR flash */
 
diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h
index 6bae063ae4..ecda30bab5 100644
--- a/include/configs/db-88f6820-gp.h
+++ b/include/configs/db-88f6820-gp.h
@@ -23,7 +23,7 @@
 CONFIG_SYS_SCSI_MAX_LUN)
 
 /* USB/EHCI configuration */
-#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_IS_TDI
 
 /* Environment in SPI NOR flash */
 
diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
index 48471993b8..defe480613 100644
--- a/include/configs/db-mv784mp-gp.h
+++ b/include/configs/db-mv784mp-gp.h
@@ -21,7 +21,7 @@
 #define CONFIG_I2C_MVTWSI_BASE0MVEBU_TWSI_BASE
 
 /* USB/EHCI configuration */
-#define

[PATCH 2/4] Convert CONFIG_USB_EHCI_MXS to Kconfig

2021-10-09 Thread Marek Behún
From: Marek Behún 

This option is only used for
  mx23evk_defconfig
  mx23_olinuxino_defconfig
which are the only i.MX23 boards.

Add depend on ARCH_MX23 and default to y.

Signed-off-by: Marek Behún 
---
 drivers/usb/host/Kconfig | 7 +++
 include/configs/mxs.h| 1 -
 scripts/config_whitelist.txt | 1 -
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 10b0479a8a..be5e4b994d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -175,6 +175,13 @@ config USB_EHCI_MX7
---help---
  Enables support for the on-chip EHCI controller on i.MX7 SoCs.
 
+config USB_EHCI_MXS
+   bool "Support for i.MX23 EHCI USB controller"
+   depends on ARCH_MX23
+   default y
+   help
+ Enables support for the on-chip EHCI controller on i.MX23 SoCs.
+
 config USB_EHCI_OMAP
bool "Support for OMAP3+ on-chip EHCI USB controller"
depends on ARCH_OMAP2PLUS
diff --git a/include/configs/mxs.h b/include/configs/mxs.h
index 330ac42402..4473d5177a 100644
--- a/include/configs/mxs.h
+++ b/include/configs/mxs.h
@@ -128,7 +128,6 @@
 
 /* USB */
 #ifdef CONFIG_CMD_USB
-#define CONFIG_USB_EHCI_MXS
 #define CONFIG_USB_EHCI_IS_TDI
 #endif
 
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 682f597f37..7610739021 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3037,7 +3037,6 @@ CONFIG_USB_EHCI_EXYNOS
 CONFIG_USB_EHCI_FARADAY
 CONFIG_USB_EHCI_IS_TDI
 CONFIG_USB_EHCI_KIRKWOOD
-CONFIG_USB_EHCI_MXS
 CONFIG_USB_EHCI_TXFIFO_THRESH
 CONFIG_USB_ETH_QMULT
 CONFIG_USB_ETH_SUBSET
-- 
2.32.0



[PATCH 3/4] Drop CONFIG_USB_EHCI_KIRKWOOD

2021-10-09 Thread Marek Behún
From: Marek Behún 

This config option doesn't do anything.

nas220 uses USB_EHCI_MARVELL.

Signed-off-by: Marek Behún 
---
 include/configs/nas220.h | 1 -
 scripts/config_whitelist.txt | 1 -
 2 files changed, 2 deletions(-)

diff --git a/include/configs/nas220.h b/include/configs/nas220.h
index f071ee6e1c..52c55be061 100644
--- a/include/configs/nas220.h
+++ b/include/configs/nas220.h
@@ -64,7 +64,6 @@
  * USB/EHCI
  */
 #ifdef CONFIG_CMD_USB
-#define CONFIG_USB_EHCI_KIRKWOOD   /* on Kirkwood platform */
 #define CONFIG_USB_EHCI_IS_TDI
 #endif /* CONFIG_CMD_USB */
 
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 7610739021..bf5f7cae74 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3036,7 +3036,6 @@ CONFIG_USB_EHCI_BASE_LIST
 CONFIG_USB_EHCI_EXYNOS
 CONFIG_USB_EHCI_FARADAY
 CONFIG_USB_EHCI_IS_TDI
-CONFIG_USB_EHCI_KIRKWOOD
 CONFIG_USB_EHCI_TXFIFO_THRESH
 CONFIG_USB_ETH_QMULT
 CONFIG_USB_ETH_SUBSET
-- 
2.32.0



Re: [PATCH 1/2] arm: mvebu: Implement the mac command (Marvell hw_info)

2021-10-09 Thread Marek Behún
> > > > +config MVEBU_MAC_HW_INFO_OFFSET
> > > > + hex "Marvell hw_info (mac) SPI flash offset"
> > > > + depends on MVEBU_MAC_HW_INFO
> > > > + default 0x3E
> > > > + help
> > > > +   This option defines the SPI flash offset of the Marvell
> > > > +   hw_info area. This defaults to 0x3E on most Armada
> > > > +   A3720 platforms.  
> > >
> > > Have you tried to specify this offset directly into DTS file? Because
> > > in DTS file is already specified this hw info partition and it seems
> > > like that this kind of information belongs to DTS.  
> > 
> > I haven't encountered a board, which has a different offset so far.
> > This can be treated as a nicer way of defining this offset, rather
> > than just hard-coding it in the source code itself.
> > 
> > In case there are more boards with this partition, a way of defining
> > the offset in the DTS can be added later and this value can then
> > be used as a default.  
> 
> +Marek
> 
> My understanding is that all these definitions, like memory address
> spaces, partitions, etc... belong to DTS file (or plat structures for
> boards which do not use DT) and not into source code or config options
> as they are describing hw layout.
> 
> There is ongoing process to move / convert SPI partitions from source
> files and config defines into DTS files, so for me this looks like a
> step backward...
> 
> But I would like to hear opinion also from other people.

This should be done in device tree. Device tree has bindings for such
things. You should be able to do something like this:

spi-flash@1 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

board_info: board-info@3E {
compatible = "nvmem-cells";
label = "board-info";
reg = <0x3E 0x1000>;
read-only;
#address-cells = <1>;
#size-cells = <1>;

mac_addr_eth0: mac-addr1@0 {
reg = <0x0 0x6>;
};

mac_addr_eth1: mac-addr2@1 {
reg = <0x6 0x6>;
};
};
};
};

ethernet@3 {
nvmem-cells = <_addr_eth0>;
nvmem-cell-names = "mac-address";
};

Look at
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml

Also we need to add nvmem API into U-Boot and get rid of the ad-hoc
efuse/mac/hw_mac nonsense.

Marek


[PATCH u-boot-marvell 09/12] arm: mvebu: turris_omnia: Overwrite ethaddr only if invalid

2021-10-09 Thread Marek Behún
From: Marek Behún 

Currently we always overwrite ethaddrs with those from EEPROM.

In order to allow user to use a cloned MAC address in U-Boot, change the
code so that it sets ethaddr variables only if they aren't set or are
invalid.

Signed-off-by: Marek Behún 
---
 board/CZ.NIC/turris_omnia/turris_omnia.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c 
b/board/CZ.NIC/turris_omnia/turris_omnia.c
index a48e1f5c30..7a86111890 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -518,6 +518,15 @@ static void increment_mac(u8 *mac)
}
 }
 
+static void set_mac_if_invalid(int i, u8 *mac)
+{
+   u8 oldmac[6];
+
+   if (is_valid_ethaddr(mac) &&
+   !eth_env_get_enetaddr_by_index("eth", i, oldmac))
+   eth_env_set_enetaddr_by_index("eth", i, mac);
+}
+
 int misc_init_r(void)
 {
int err;
@@ -550,18 +559,11 @@ int misc_init_r(void)
mac[4] = mac1[2];
mac[5] = mac1[3];
 
-   if (is_valid_ethaddr(mac))
-   eth_env_set_enetaddr("eth1addr", mac);
-
+   set_mac_if_invalid(1, mac);
increment_mac(mac);
-
-   if (is_valid_ethaddr(mac))
-   eth_env_set_enetaddr("eth2addr", mac);
-
+   set_mac_if_invalid(2, mac);
increment_mac(mac);
-
-   if (is_valid_ethaddr(mac))
-   eth_env_set_enetaddr("ethaddr", mac);
+   set_mac_if_invalid(0, mac);
 
 out:
return 0;
-- 
2.32.0



[PATCH u-boot-marvell 11/12] arm: mvebu: turris_omnia: Move SPL's SYS_MALLOC_SIMPLE to Kconfig

2021-10-09 Thread Marek Behún
From: Marek Behún 

Instead of declaring CONFIG_SYS_MALLOC_SIMPLE dependant on
CONFIG_SPL_BUILD in board config header, select
CONFIG_SPL_SYS_MALLOC_SIMPLE in Kconfig.

Signed-off-by: Marek Behún 
---
 arch/arm/mach-mvebu/Kconfig| 1 +
 include/configs/turris_omnia.h | 4 
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 54dff9986b..8365305733 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -128,6 +128,7 @@ config TARGET_TURRIS_OMNIA
select I2C_MUX
select I2C_MUX_PCA954x
select SPL_I2C_MUX
+   select SPL_SYS_MALLOC_SIMPLE
select SYS_I2C_MVTWSI
select ATSHA204A
 
diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
index 8646633ea4..562b49327f 100644
--- a/include/configs/turris_omnia.h
+++ b/include/configs/turris_omnia.h
@@ -36,10 +36,6 @@
 #define CONFIG_SPL_BSS_START_ADDR  (0x4000 + CONFIG_SPL_SIZE)
 #define CONFIG_SPL_BSS_MAX_SIZE(16 << 10)
 
-#ifdef CONFIG_SPL_BUILD
-#define CONFIG_SYS_MALLOC_SIMPLE
-#endif
-
 #define CONFIG_SPL_STACK   (0x4000 + ((192 - 16) << 10))
 #define CONFIG_SPL_BOOTROM_SAVE(CONFIG_SPL_STACK + 4)
 #define CONFIG_SPL_DRIVERS_MISC
-- 
2.32.0



[PATCH u-boot-marvell 06/12] arm: mvebu: turris_mox: Use show_board_info()

2021-10-09 Thread Marek Behún
From: Marek Behún 

We are printing board information in last_stage_init(), but U-Boot has
dedicated function, show_board_info(), for this.

Move code which prints board information (board version, serial number,
module topology, ...) to show_board_info().

Signed-off-by: Marek Behún 
---
 board/CZ.NIC/turris_mox/turris_mox.c | 67 ++--
 1 file changed, 33 insertions(+), 34 deletions(-)

diff --git a/board/CZ.NIC/turris_mox/turris_mox.c 
b/board/CZ.NIC/turris_mox/turris_mox.c
index 428cd23a19..ff0ed28045 100644
--- a/board/CZ.NIC/turris_mox/turris_mox.c
+++ b/board/CZ.NIC/turris_mox/turris_mox.c
@@ -485,44 +485,34 @@ static void handle_reset_button(void)
}
 }
 
-static void mox_print_info(void)
+int show_board_info(void)
 {
-   int ret, board_version, ram_size;
-   u64 serial_number;
+   int i, ret, board_version, ram_size, is_sd;
const char *pub_key;
+   const u8 *topology;
+   u64 serial_number;
+
+   printf("Model: CZ.NIC Turris Mox Board\n");
 
ret = mbox_sp_get_board_info(_number, NULL, NULL, _version,
 _size);
-   if (ret < 0)
-   return;
-
-   printf("Turris Mox:\n");
-   printf("  Board version: %i\n", board_version);
-   printf("  RAM size: %i MiB\n", ram_size);
-   printf("  Serial Number: %016llX\n", serial_number);
+   if (ret < 0) {
+   printf("  Cannot read board info: %i\n", ret);
+   } else {
+   printf("  Board version: %i\n", board_version);
+   printf("  RAM size: %i MiB\n", ram_size);
+   printf("  Serial Number: %016llX\n", serial_number);
+   }
 
pub_key = mox_sp_get_ecdsa_public_key();
if (pub_key)
printf("  ECDSA Public Key: %s\n", pub_key);
else
-   printf("Cannot read ECDSA Public Key\n");
-}
-
-int last_stage_init(void)
-{
-   int ret, i;
-   const u8 *topology;
-   int is_sd;
-   struct mii_dev *bus;
-   struct gpio_desc reset_gpio = {};
-
-   mox_print_info();
+   printf("  Cannot read ECDSA Public Key\n");
 
ret = mox_get_topology(, _count, _sd);
-   if (ret) {
+   if (ret)
printf("Cannot read module topology!\n");
-   return 0;
-   }
 
printf("  SD/eMMC version: %s\n", is_sd ? "SD" : "eMMC");
 
@@ -554,8 +544,7 @@ int last_stage_init(void)
}
}
 
-   /* now check if modules are connected in supported mode */
-
+   /* check if modules are connected in supported mode */
for (i = 0; i < module_count; ++i) {
switch (topology[i]) {
case MOX_MODULE_SFP:
@@ -616,8 +605,17 @@ int last_stage_init(void)
}
}
 
-   /* now configure modules */
+   if (module_count)
+   printf("\n");
+
+   return 0;
+}
+
+int last_stage_init(void)
+{
+   struct gpio_desc reset_gpio = {};
 
+   /* configure modules */
if (get_reset_gpio(_gpio) < 0)
return 0;
 
@@ -633,16 +631,19 @@ int last_stage_init(void)
mdelay(50);
}
 
+   /*
+* check if the addresses are set by reading Scratch & Misc register
+* 0x70 of Peridot (and potentially Topaz) modules
+*/
if (peridot || topaz) {
-   /*
-* now check if the addresses are set by reading Scratch & Misc
-* register 0x70 of Peridot (and potentially Topaz) modules
-*/
+   struct mii_dev *bus;
 
bus = miiphy_get_dev_by_name("neta@3");
if (!bus) {
printf("Cannot get MDIO bus device!\n");
} else {
+   int i;
+
for (i = 0; i < peridot; ++i)
check_switch_address(bus, 0x10 + i);
 
@@ -653,8 +654,6 @@ int last_stage_init(void)
}
}
 
-   printf("\n");
-
handle_reset_button();
 
return 0;
-- 
2.32.0



[PATCH u-boot-marvell 08/12] arm: mvebu: turris_mox: Better check for valid ethernet addresses in env

2021-10-09 Thread Marek Behún
From: Marek Behún 

Currently we overwrite ethaddr and eth1addr only if these variables
don't exist.

Better overwrite them even if the env variable exists, but is invalid -
eth_env_get_enetaddr_by_index() checks for validity.

Refactor the code to use a for cycle.

Signed-off-by: Marek Behún 
---
 board/CZ.NIC/turris_mox/turris_mox.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/board/CZ.NIC/turris_mox/turris_mox.c 
b/board/CZ.NIC/turris_mox/turris_mox.c
index 7c5acfd1d9..2202eb8cfb 100644
--- a/board/CZ.NIC/turris_mox/turris_mox.c
+++ b/board/CZ.NIC/turris_mox/turris_mox.c
@@ -359,20 +359,22 @@ static int get_reset_gpio(struct gpio_desc *reset_gpio)
 
 int misc_init_r(void)
 {
-   int ret;
-   u8 mac1[6], mac2[6];
+   u8 mac[2][6];
+   int i, ret;
 
-   ret = mbox_sp_get_board_info(NULL, mac1, mac2, NULL, NULL);
+   ret = mbox_sp_get_board_info(NULL, mac[0], mac[1], NULL, NULL);
if (ret < 0) {
printf("Cannot read data from OTP!\n");
return 0;
}
 
-   if (is_valid_ethaddr(mac1) && !env_get("ethaddr"))
-   eth_env_set_enetaddr("ethaddr", mac1);
+   for (i = 0; i < 2; ++i) {
+   u8 oldmac[6];
 
-   if (is_valid_ethaddr(mac2) && !env_get("eth1addr"))
-   eth_env_set_enetaddr("eth1addr", mac2);
+   if (is_valid_ethaddr(mac[i]) &&
+   !eth_env_get_enetaddr_by_index("eth", i, oldmac))
+   eth_env_set_enetaddr_by_index("eth", i, mac[i]);
+   }
 
return 0;
 }
-- 
2.32.0



[PATCH u-boot-marvell 10/12] arm: mvebu: turris_omnia: Use show_board_info()

2021-10-09 Thread Marek Behún
From: Marek Behún 

We are printing board information in checkboard() function, which is
called from the default weak implementation of show_board_info().

Rename checkboard() to show_board_info(). This throws away the weak
implementation of show_board_info().

Signed-off-by: Marek Behún 
---
 board/CZ.NIC/turris_omnia/turris_omnia.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c 
b/board/CZ.NIC/turris_omnia/turris_omnia.c
index 7a86111890..39051a803a 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -468,7 +468,7 @@ static struct udevice *get_atsha204a_dev(void)
return dev;
 }
 
-int checkboard(void)
+int show_board_info(void)
 {
u32 version_num, serial_num;
int err = 1;
@@ -496,7 +496,7 @@ int checkboard(void)
}
 
 out:
-   printf("Turris Omnia:\n");
+   printf("Model: Turris Omnia\n");
printf("  RAM size: %i MiB\n", omnia_get_ram_size_gb() * 1024);
if (err)
printf("  Serial Number: unknown\n");
-- 
2.32.0



[PATCH u-boot-marvell 07/12] arm: mvebu: turris_mox: Always handle reset button

2021-10-09 Thread Marek Behún
From: Marek Behún 

Handle reset button even if we can't configure modules.

This happens if we fail retrieving reset GPIO with which we can reset
the modules.

(Note that this GPIO is different from reset button GPIO.)

Signed-off-by: Marek Behún 
---
 board/CZ.NIC/turris_mox/turris_mox.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/board/CZ.NIC/turris_mox/turris_mox.c 
b/board/CZ.NIC/turris_mox/turris_mox.c
index ff0ed28045..7c5acfd1d9 100644
--- a/board/CZ.NIC/turris_mox/turris_mox.c
+++ b/board/CZ.NIC/turris_mox/turris_mox.c
@@ -617,7 +617,7 @@ int last_stage_init(void)
 
/* configure modules */
if (get_reset_gpio(_gpio) < 0)
-   return 0;
+   goto handle_reset_btn;
 
if (peridot > 0) {
if (configure_peridots(_gpio) < 0) {
@@ -654,6 +654,7 @@ int last_stage_init(void)
}
}
 
+handle_reset_btn:
handle_reset_button();
 
return 0;
-- 
2.32.0



[PATCH u-boot-marvell 05/12] arm: mvebu: turris_mox: Cosmetic update for board config header

2021-10-09 Thread Marek Behún
From: Marek Behún 

Reorder the definitions in Turris MOX' board config header, drop the
comment relics from when this file was copied, fix indentation.

Signed-off-by: Marek Behún 
---
 include/configs/turris_mox.h | 61 +---
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h
index 070abe38db..3cfad7cca9 100644
--- a/include/configs/turris_mox.h
+++ b/include/configs/turris_mox.h
@@ -8,13 +8,11 @@
 #ifndef _CONFIG_TURRIS_MOX_H
 #define _CONFIG_TURRIS_MOX_H
 
-#define CONFIG_SYS_BOOTM_LEN (64 << 20)
-
-/* additions for new ARM relocation support */
-#define CONFIG_SYS_SDRAM_BASE  0x
-
-/* auto boot */
-
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)
+#define CONFIG_SYS_SDRAM_BASE  0x
+#define CONFIG_SYS_INIT_SP_ADDR(CONFIG_SYS_TEXT_BASE + 
0xFF)
+#define CONFIG_SYS_CBSIZE  1024
+#define CONFIG_SYS_MAXARGS 32
 #define CONFIG_SYS_BAUDRATE_TABLE  { 300, 600, 1200, 1800, 2400, 4800, \
  9600, 19200, 38400, 57600, 115200, \
  230400, 460800, 50, 576000, \
@@ -23,25 +21,10 @@
  400, 450, 500, 550, \
  600 }
 
-#defineCONFIG_SYS_CBSIZE   1024/* Console I/O Buff Size */
-
-/*
- * Other required minimal configurations
- */
-#define CONFIG_SYS_MAXARGS 32  /* max number of command args */
-
-/* End of 16M scrubbed by training in bootrom */
-#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0xFF)
-
-/* Environment in SPI NOR flash */
-
-/*
- * Ethernet Driver configuration
- */
-#define CONFIG_ARP_TIMEOUT 200
-#define CONFIG_NET_RETRY_COUNT 50
+#define CONFIG_ARP_TIMEOUT 200
+#define CONFIG_NET_RETRY_COUNT 50
 
-#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3)
+#define CONFIG_USB_MAX_CONTROLLER_COUNT6
 
 #define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 0) \
@@ -51,22 +34,22 @@
 
 #include 
 
-#define TURRIS_MOX_BOOTCMD_RESCUE \
-   "setenv bootargs \"console=ttyMV0,115200 " \
- "earlycon=ar3700_uart,0xd0012000\" && " \
-   "sf probe && " \
-   "sf read 0x500 0x19 && " \
-   "lzmadec 0x500 0x580 && " \
+#define TURRIS_MOX_BOOTCMD_RESCUE  \
+   "setenv bootargs \"console=ttyMV0,115200 "  \
+ "earlycon=ar3700_uart,0xd0012000\" && "   \
+   "sf probe && "  \
+   "sf read 0x500 0x19 && "\
+   "lzmadec 0x500 0x580 && "   \
"bootm 0x580"
 
-#define CONFIG_EXTRA_ENV_SETTINGS  \
-   "scriptaddr=0x4d0\0"\
-   "pxefile_addr_r=0x4e0\0"\
-   "fdt_addr_r=0x4f0\0"\
-   "kernel_addr_r=0x500\0" \
-   "ramdisk_addr_r=0x800\0"\
-   "fdtfile=marvell/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
-   "bootcmd_rescue=" TURRIS_MOX_BOOTCMD_RESCUE "\0" \
+#define CONFIG_EXTRA_ENV_SETTINGS  \
+   "scriptaddr=0x4d0\0"\
+   "pxefile_addr_r=0x4e0\0"\
+   "fdt_addr_r=0x4f0\0"\
+   "kernel_addr_r=0x500\0" \
+   "ramdisk_addr_r=0x800\0"\
+   "fdtfile=marvell/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0"  \
+   "bootcmd_rescue=" TURRIS_MOX_BOOTCMD_RESCUE "\0"\
BOOTENV
 
 #endif /* _CONFIG_TURRIS_MOX_H */
-- 
2.32.0



[PATCH u-boot-marvell 03/12] arm: mvebu: a3720: Create Kconfig option for I2C_MV

2021-10-09 Thread Marek Behún
From: Marek Behún 

Move the config option CONFIG_I2C_MV to a Kconfig option
CONFIG_SYS_I2C_MV and move the default definition from config header
files into defconfigs.

Signed-off-by: Marek Behún 
---
 configs/mvebu_db-88f3720_defconfig  | 1 +
 configs/mvebu_espressobin-88f3720_defconfig | 1 +
 configs/turris_mox_defconfig| 1 +
 configs/uDPU_defconfig  | 1 +
 drivers/i2c/Kconfig | 6 ++
 drivers/i2c/Makefile| 2 +-
 include/configs/mvebu_armada-37xx.h | 5 -
 include/configs/turris_mox.h| 5 -
 scripts/config_whitelist.txt| 1 -
 9 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/configs/mvebu_db-88f3720_defconfig 
b/configs/mvebu_db-88f3720_defconfig
index d401f4765f..6c2a2180a4 100644
--- a/configs/mvebu_db-88f3720_defconfig
+++ b/configs/mvebu_db-88f3720_defconfig
@@ -45,6 +45,7 @@ CONFIG_CLK=y
 CONFIG_CLK_MVEBU=y
 # CONFIG_MVEBU_GPIO is not set
 CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MV=y
 CONFIG_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig 
b/configs/mvebu_espressobin-88f3720_defconfig
index 01cf24aec9..b783246562 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -54,6 +54,7 @@ CONFIG_AHCI_MVEBU=y
 CONFIG_CLK=y
 CONFIG_CLK_MVEBU=y
 CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MV=y
 CONFIG_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
index e494aebecc..3cae32f69b 100644
--- a/configs/turris_mox_defconfig
+++ b/configs/turris_mox_defconfig
@@ -61,6 +61,7 @@ CONFIG_CLK=y
 CONFIG_CLK_MVEBU=y
 # CONFIG_MVEBU_GPIO is not set
 CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MV=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_MISC=y
diff --git a/configs/uDPU_defconfig b/configs/uDPU_defconfig
index a06a25378e..6a222f3d6c 100644
--- a/configs/uDPU_defconfig
+++ b/configs/uDPU_defconfig
@@ -54,6 +54,7 @@ CONFIG_CLK=y
 CONFIG_CLK_MVEBU=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_MV=y
 CONFIG_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 57cac4483f..b1c3a96dc0 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -611,6 +611,12 @@ config SYS_I2C_VERSATILE
  Add support for the Arm Ltd Versatile Express I2C driver. The I2C host
  controller is present in the development boards manufactured by Arm 
Ltd.
 
+config SYS_I2C_MV
+   bool "Marvell PXA (Armada 3720) I2C driver"
+   help
+ Support for PXA based I2C controller used on Armada 3720 SoC.
+ In Linux, this driver is called i2c-pxa.
+
 config SYS_I2C_MVTWSI
bool "Marvell I2C driver"
help
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 67841bf3e0..7cfb3b9043 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_$(SPL_)DM_I2C_GPIO) += i2c-gpio.o
 obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
 obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o
 
-obj-$(CONFIG_I2C_MV) += mv_i2c.o
 obj-$(CONFIG_$(SPL_)SYS_I2C_LEGACY) += i2c_core.o
 obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o
 obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
@@ -29,6 +28,7 @@ obj-$(CONFIG_SYS_I2C_IPROC) += iproc_i2c.o
 obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o
 obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o
 obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o
+obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
 obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
 obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
 obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
diff --git a/include/configs/mvebu_armada-37xx.h 
b/include/configs/mvebu_armada-37xx.h
index 755f59eee9..8c315eb563 100644
--- a/include/configs/mvebu_armada-37xx.h
+++ b/include/configs/mvebu_armada-37xx.h
@@ -36,11 +36,6 @@
 /* End of 16M scrubbed by training in bootrom */
 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0xFF)
 
-/*
- * I2C
- */
-#define CONFIG_I2C_MV
-
 /*
  * Environment
  */
diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h
index 0fcf216eb1..ab7931d35b 100644
--- a/include/configs/turris_mox.h
+++ b/include/configs/turris_mox.h
@@ -34,11 +34,6 @@
 /* End of 16M scrubbed by training in bootrom */
 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0xFF)
 
-/*
- * I2C
- */
-#define CONFIG_I2C_MV
-
 /* Environment in SPI NOR flash */
 
 /*
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 02d86d79cf..3475d0bc6d 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -601,7 +601,6 @@ CONFIG_I2C_ENV_EEPROM_BUS
 CONFIG_I2C_GSC
 CONFIG_I2C_MBB_TIMEOUT
 CONFIG_I2C_MULTI_BUS
-CONFIG_I2C_MV
 CONFIG_I2C_MVTWSI
 CONFIG_I2C_MVTWSI_BASE
 CONFIG_I2C_MVTWSI_BASE0
-- 
2.32.0



[PATCH u-boot-marvell 04/12] arm: kirkwood, mvebu: Remove CONFIG_SYS_RESET_ADDRESS option

2021-10-09 Thread Marek Behún
From: Marek Behún 

This option is not used anywhere.

Signed-off-by: Marek Behún 
---
 include/configs/SBx81LIFKW.h| 5 -
 include/configs/SBx81LIFXCAT.h  | 5 -
 include/configs/edminiv2.h  | 6 --
 include/configs/mv-common.h | 1 -
 include/configs/mvebu_armada-37xx.h | 1 -
 include/configs/mvebu_armada-8k.h   | 1 -
 include/configs/turris_mox.h| 1 -
 include/configs/x530.h  | 5 -
 8 files changed, 25 deletions(-)

diff --git a/include/configs/SBx81LIFKW.h b/include/configs/SBx81LIFKW.h
index fc6167cf96..462619ff69 100644
--- a/include/configs/SBx81LIFKW.h
+++ b/include/configs/SBx81LIFKW.h
@@ -59,11 +59,6 @@
 /* There is no PHY directly connected so don't ask it for link status */
 #undef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
 
-/*
- * Other required minimal configurations
- */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
-
 /*
  * Ethernet Driver configuration
  */
diff --git a/include/configs/SBx81LIFXCAT.h b/include/configs/SBx81LIFXCAT.h
index 06be63e242..a271567f85 100644
--- a/include/configs/SBx81LIFXCAT.h
+++ b/include/configs/SBx81LIFXCAT.h
@@ -64,11 +64,6 @@
 /* There is no PHY directly connected so don't ask it for link status */
 #undef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
 
-/*
- * Other required minimal configurations
- */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
-
 /*
  * Ethernet Driver configuration
  */
diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h
index fbe468010b..664d6d1f34 100644
--- a/include/configs/edminiv2.h
+++ b/include/configs/edminiv2.h
@@ -151,12 +151,6 @@
  *  Environment variables configurations
  */
 
-/*
- * Other required minimal configurations
- */
-
-#define CONFIG_SYS_RESET_ADDRESS   0x
-
 /* Enable command line editing */
 
 /* provide extensive help */
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index e460f69a08..cc3b597f28 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -55,7 +55,6 @@
 /*
  * Other required minimal configurations
  */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
 #define CONFIG_SYS_MAXARGS 32  /* max number of command args */
 
 /* > Include platform Common Definitions */
diff --git a/include/configs/mvebu_armada-37xx.h 
b/include/configs/mvebu_armada-37xx.h
index 8c315eb563..e7f7e772fc 100644
--- a/include/configs/mvebu_armada-37xx.h
+++ b/include/configs/mvebu_armada-37xx.h
@@ -30,7 +30,6 @@
 /*
  * Other required minimal configurations
  */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
 #define CONFIG_SYS_MAXARGS 32  /* max number of command args */
 
 /* End of 16M scrubbed by training in bootrom */
diff --git a/include/configs/mvebu_armada-8k.h 
b/include/configs/mvebu_armada-8k.h
index 2f8be2ee49..886f44c903 100644
--- a/include/configs/mvebu_armada-8k.h
+++ b/include/configs/mvebu_armada-8k.h
@@ -24,7 +24,6 @@
 /*
  * Other required minimal configurations
  */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
 #define CONFIG_SYS_MAXARGS 32  /* max number of command args */
 
 /* End of 16M scrubbed by training in bootrom */
diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h
index ab7931d35b..070abe38db 100644
--- a/include/configs/turris_mox.h
+++ b/include/configs/turris_mox.h
@@ -28,7 +28,6 @@
 /*
  * Other required minimal configurations
  */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
 #define CONFIG_SYS_MAXARGS 32  /* max number of command args */
 
 /* End of 16M scrubbed by training in bootrom */
diff --git a/include/configs/x530.h b/include/configs/x530.h
index d6aec6d7f2..699deffbe0 100644
--- a/include/configs/x530.h
+++ b/include/configs/x530.h
@@ -61,11 +61,6 @@
 
 #include 
 
-/*
- * Other required minimal configurations
- */
-#define CONFIG_SYS_RESET_ADDRESS 0x/* Rst Vector Adr */
-
 /* Keep device tree and initrd in low memory so the kernel can access them */
 #define CONFIG_EXTRA_ENV_SETTINGS  \
"fdt_high=0x1000\0" \
-- 
2.32.0



[PATCH u-boot-marvell 00/12] Small Turris MOX and Omnia changes

2021-10-09 Thread Marek Behún
From: Marek Behún 

Hi Stefan,

these are some small changes for Turris Omnia and MOX, mainly moving
options from board config header to Kconfig, but also some other.

Two patchs are touching other mvebu boards.

Marek

Marek Behún (12):
  arm: mvebu: turris_mox: Drop SF_DEFAULT_MODE from defconfig
  arm: mvebu: turris_mox: Move options to defconfig
  arm: mvebu: a3720: Create Kconfig option for I2C_MV
  arm: kirkwood, mvebu: Remove CONFIG_SYS_RESET_ADDRESS option
  arm: mvebu: turris_mox: Cosmetic update for board config header
  arm: mvebu: turris_mox: Use show_board_info()
  arm: mvebu: turris_mox: Always handle reset button
  arm: mvebu: turris_mox: Better check for valid ethernet addresses in
env
  arm: mvebu: turris_omnia: Overwrite ethaddr only if invalid
  arm: mvebu: turris_omnia: Use show_board_info()
  arm: mvebu: turris_omnia: Move SPL's SYS_MALLOC_SIMPLE to Kconfig
  arm: mvebu: turris_omnia: Move CONFIG_SPL_DRIVERS_MISC to Kconfig

 arch/arm/mach-mvebu/Kconfig |  2 +
 board/CZ.NIC/turris_mox/turris_mox.c| 86 +++--
 board/CZ.NIC/turris_omnia/turris_omnia.c| 26 ---
 configs/mvebu_db-88f3720_defconfig  |  1 +
 configs/mvebu_espressobin-88f3720_defconfig |  1 +
 configs/turris_mox_defconfig|  4 +-
 configs/uDPU_defconfig  |  1 +
 drivers/i2c/Kconfig |  6 ++
 drivers/i2c/Makefile|  2 +-
 include/configs/SBx81LIFKW.h|  5 --
 include/configs/SBx81LIFXCAT.h  |  5 --
 include/configs/edminiv2.h  |  6 --
 include/configs/mv-common.h |  1 -
 include/configs/mvebu_armada-37xx.h |  6 --
 include/configs/mvebu_armada-8k.h   |  1 -
 include/configs/turris_mox.h| 74 ++
 include/configs/turris_omnia.h  |  5 --
 include/configs/x530.h  |  5 --
 scripts/config_whitelist.txt|  1 -
 19 files changed, 95 insertions(+), 143 deletions(-)

-- 
2.32.0



[PATCH u-boot-marvell 02/12] arm: mvebu: turris_mox: Move options to defconfig

2021-10-09 Thread Marek Behún
From: Marek Behún 

Move config options CONFIG_LAST_STAGE_INIT and
CONFIG_DISPLAY_BOARDINFO_LATE to turris_mox_defconfig.

Signed-off-by: Marek Behún 
---
 configs/turris_mox_defconfig | 2 ++
 include/configs/turris_mox.h | 7 ---
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
index 6ff551e477..e494aebecc 100644
--- a/configs/turris_mox_defconfig
+++ b/configs/turris_mox_defconfig
@@ -24,7 +24,9 @@ CONFIG_USE_PREBOOT=y
 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_LAST_STAGE_INIT=y
 CONFIG_MISC_INIT_R=y
 CONFIG_CMD_SHA1SUM=y
 CONFIG_CMD_CLK=y
diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h
index 0bbc984753..0fcf216eb1 100644
--- a/include/configs/turris_mox.h
+++ b/include/configs/turris_mox.h
@@ -10,13 +10,6 @@
 
 #define CONFIG_SYS_BOOTM_LEN (64 << 20)
 
-#define CONFIG_LAST_STAGE_INIT
-
-/*
- * High Level Configuration Options (easy to change)
- */
-#define CONFIG_DISPLAY_BOARDINFO_LATE
-
 /* additions for new ARM relocation support */
 #define CONFIG_SYS_SDRAM_BASE  0x
 
-- 
2.32.0



[PATCH u-boot-marvell 01/12] arm: mvebu: turris_mox: Drop SF_DEFAULT_MODE from defconfig

2021-10-09 Thread Marek Behún
From: Marek Behún 

This config option defaults to 0, so it is redundant in defconfig.

Signed-off-by: Marek Behún 
---
 configs/turris_mox_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
index 82ad68b6a1..6ff551e477 100644
--- a/configs/turris_mox_defconfig
+++ b/configs/turris_mox_defconfig
@@ -67,7 +67,6 @@ CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
 CONFIG_MTD=y
 CONFIG_DM_MTD=y
-CONFIG_SF_DEFAULT_MODE=0
 CONFIG_SF_DEFAULT_SPEED=2000
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
-- 
2.32.0



[PATCH v2 13/13] env: Move non-cmd specific env functions to env/common.c

2021-10-13 Thread Marek Behún
From: Marek Behún 

Move the following functions from cmd/nvedit.c to env/common.c:
  env_set_ulong()
  env_set_hex()
  env_get_hex()
  eth_env_get_enetaddr()
  eth_env_set_enetaddr()
  env_get()
  from_env()
  env_get_f()
  env_get_ulong()
since these functions are not specific for U-Boot's CLI.

We leave env_set() in cmd/nvedit.c, since it calls _do_env_set(), which
is a static function in that file.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 185 -
 env/common.c | 190 +++
 2 files changed, 190 insertions(+), 185 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 7f094b3cd7..3bb6e764c0 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -30,7 +30,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -38,7 +37,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -320,69 +318,6 @@ int env_set(const char *varname, const char *varvalue)
return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
 }
 
-/**
- * Set an environment variable to an integer value
- *
- * @param varname  Environment variable to set
- * @param valueValue to set it to
- * @return 0 if ok, 1 on error
- */
-int env_set_ulong(const char *varname, ulong value)
-{
-   /* TODO: this should be unsigned */
-   char *str = simple_itoa(value);
-
-   return env_set(varname, str);
-}
-
-/**
- * Set an environment variable to an value in hex
- *
- * @param varname  Environment variable to set
- * @param valueValue to set it to
- * @return 0 if ok, 1 on error
- */
-int env_set_hex(const char *varname, ulong value)
-{
-   char str[17];
-
-   sprintf(str, "%lx", value);
-   return env_set(varname, str);
-}
-
-ulong env_get_hex(const char *varname, ulong default_val)
-{
-   const char *s;
-   ulong value;
-   char *endp;
-
-   s = env_get(varname);
-   if (s)
-   value = hextoul(s, );
-   if (!s || endp == s)
-   return default_val;
-
-   return value;
-}
-
-int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr)
-{
-   string_to_enetaddr(env_get(name), enetaddr);
-   return is_valid_ethaddr(enetaddr);
-}
-
-int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr)
-{
-   char buf[ARP_HLEN_ASCII + 1];
-
-   if (eth_env_get_enetaddr(name, (uint8_t *)buf))
-   return -EEXIST;
-
-   sprintf(buf, "%pM", enetaddr);
-
-   return env_set(name, buf);
-}
-
 #ifndef CONFIG_SPL_BUILD
 static int do_env_set(struct cmd_tbl *cmdtp, int flag, int argc,
  char *const argv[])
@@ -661,127 +596,7 @@ static int do_env_edit(struct cmd_tbl *cmdtp, int flag, 
int argc,
}
 }
 #endif /* CONFIG_CMD_EDITENV */
-#endif /* CONFIG_SPL_BUILD */
-
-/*
- * Look up variable from environment,
- * return address of storage for that variable,
- * or NULL if not found
- */
-char *env_get(const char *name)
-{
-   if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */
-   struct env_entry e, *ep;
-
-   WATCHDOG_RESET();
-
-   e.key   = name;
-   e.data  = NULL;
-   hsearch_r(e, ENV_FIND, , _htab, 0);
-
-   return ep ? ep->data : NULL;
-   }
-
-   /* restricted capabilities before import */
-   if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
-   return (char *)(gd->env_buf);
 
-   return NULL;
-}
-
-/*
- * Like env_get, but prints an error if envvar isn't defined in the
- * environment.  It always returns what env_get does, so it can be used in
- * place of env_get without changing error handling otherwise.
- */
-char *from_env(const char *envvar)
-{
-   char *ret;
-
-   ret = env_get(envvar);
-
-   if (!ret)
-   printf("missing environment variable: %s\n", envvar);
-
-   return ret;
-}
-
-static const char *matching_name_get_value(const char *p, const char *name)
-{
-   while (*name == *p++ && *name != '\0')
-   if (*name++ == '=')
-   return p;
-
-   /* We can look at p[-1] because p was incremented at least once. */
-   if (*name == '\0' && p[-1] == '=')
-   return p;
-
-   return NULL;
-}
-
-/*
- * Look up variable from environment for restricted C runtime env.
- */
-int env_get_f(const char *name, char *buf, unsigned len)
-{
-   const char *env, *p, *end;
-
-   if (name == NULL || *name == '\0')
-   return -1;
-
-   if (gd->env_valid == ENV_INVALID)
-   env = (const char *)default_environment;
-   else
-   env = (const char *)gd->env_addr;
-
-   for (p = env; *p != '\0'; p = end + 1) {
-   const char *value;
-  

[PATCH v2 11/13] env: Make return value of env_get_f() behave like sprintf() on success

2021-10-13 Thread Marek Behún
From: Marek Behún 

Currently the env_get_f() function's return value behaves weirdly: it
returns the number of bytes written into `buf`, but whether this is
excluding the terminating NULL-byte or including it depends on whether
there was enough space in `buf`.

Change the function to always return the actual length of the value of
the environment variable (excluding the terminating NULL-byte) on
success. This makes it behave like sprintf().

All users of this function in U-Boot are compatible with this change.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c  | 8 +---
 include/env.h | 6 ++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 08288fad10..8989c85d20 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -736,7 +736,7 @@ int env_get_f(const char *name, char *buf, unsigned len)
 
for (p = env; *p != '\0'; p = end + 1) {
const char *value;
-   int n;
+   int n, res;
 
for (end = p; *end != '\0'; ++end)
if (end - env >= CONFIG_ENV_SIZE)
@@ -746,11 +746,13 @@ int env_get_f(const char *name, char *buf, unsigned len)
if (value == NULL)
continue;
 
+   res = end - value;
+
/* found; copy out */
for (n = 0; n < len; ++n, ++buf) {
*buf = *value++;
if (*buf == '\0')
-   return n;
+   return res;
}
 
if (n)
@@ -759,7 +761,7 @@ int env_get_f(const char *name, char *buf, unsigned len)
printf("env_buf [%u bytes] too small for value of \"%s\"\n",
   len, name);
 
-   return n;
+   return res;
}
 
return -1;
diff --git a/include/env.h b/include/env.h
index 220ab979d9..ee5e30d036 100644
--- a/include/env.h
+++ b/include/env.h
@@ -120,10 +120,8 @@ char *from_env(const char *envvar);
  * support reading the value (slowly) and some will not.
  *
  * @varname:   Variable to look up
- * @return number of bytes written into @buf, excluding the terminating
- * NULL-byte if there was enough space in @buf, and including the
- * terminating NULL-byte if there wasn't enough space, or -1 if the
- * variable is not found
+ * @return actual length of the variable value excluding the terminating
+ * NULL-byte, or -1 if the variable is not found
  */
 int env_get_f(const char *name, char *buf, unsigned int len);
 
-- 
2.32.0



[PATCH v2 10/13] env: Use better name for variable in env_get_f()

2021-10-13 Thread Marek Behún
From: Marek Behún 

The `nxt` variable actually points to the terminating null-byte of the
current env var, and the next env var is at `nxt + 1`, not `nxt`. So a
better name for this variable is `end`.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 6eabd51209..08288fad10 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -724,7 +724,7 @@ static const char *matching_name_get_value(const char *p, 
const char *name)
  */
 int env_get_f(const char *name, char *buf, unsigned len)
 {
-   const char *env, *p, *nxt;
+   const char *env, *p, *end;
 
if (name == NULL || *name == '\0')
return -1;
@@ -734,12 +734,12 @@ int env_get_f(const char *name, char *buf, unsigned len)
else
env = (const char *)gd->env_addr;
 
-   for (p = env; *p != '\0'; p = nxt + 1) {
+   for (p = env; *p != '\0'; p = end + 1) {
const char *value;
int n;
 
-   for (nxt = p; *nxt != '\0'; ++nxt)
-   if (nxt - env >= CONFIG_ENV_SIZE)
+   for (end = p; *end != '\0'; ++end)
+   if (end - env >= CONFIG_ENV_SIZE)
return -1;
 
value = matching_name_get_value(p, name);
-- 
2.32.0



[PATCH v2 07/13] env: Inline env_get_char() into it's only user

2021-10-13 Thread Marek Behún
From: Marek Behún 

This function is a relic from the past when environment was read from
underlying device one character at a time.

It is used only in the case when getting an environemnt variable prior
relocation, and the function is simple enough to be inlined there.

Since env_get_char() is being changed to simple access to an array, we
can drop the failing cases and simplify the code (this could have been
done before, since env_get_char() did not fail even before).

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c  | 28 ++--
 env/env.c |  8 
 env/nowhere.c |  5 ++---
 include/env.h | 10 --
 4 files changed, 16 insertions(+), 35 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index a22445132b..9f0caceadf 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -706,16 +706,16 @@ char *from_env(const char *envvar)
return ret;
 }
 
-static int env_match(uchar *s1, int i2)
+static int env_match(const char *env, const char *s1, int i2)
 {
if (s1 == NULL || *s1 == '\0')
return -1;
 
-   while (*s1 == env_get_char(i2++) && *s1 != '\0')
+   while (*s1 == env[i2++] && *s1 != '\0')
if (*s1++ == '=')
return i2;
 
-   if (*s1 == '\0' && env_get_char(i2-1) == '=')
+   if (*s1 == '\0' && env[i2-1] == '=')
return i2;
 
return -1;
@@ -726,28 +726,28 @@ static int env_match(uchar *s1, int i2)
  */
 int env_get_f(const char *name, char *buf, unsigned len)
 {
-   int i, nxt, c;
+   const char *env;
+   int i, nxt;
 
-   for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+   if (gd->env_valid == ENV_INVALID)
+   env = (const char *)default_environment;
+   else
+   env = (const char *)gd->env_addr;
+
+   for (i = 0; env[i] != '\0'; i = nxt + 1) {
int val, n;
 
-   for (nxt = i; (c = env_get_char(nxt)) != '\0'; ++nxt) {
-   if (c < 0)
-   return c;
+   for (nxt = i; env[nxt] != '\0'; ++nxt)
if (nxt >= CONFIG_ENV_SIZE)
return -1;
-   }
 
-   val = env_match((uchar *)name, i);
+   val = env_match(env, name, i);
if (val < 0)
continue;
 
/* found; copy out */
for (n = 0; n < len; ++n, ++buf) {
-   c = env_get_char(val++);
-   if (c < 0)
-   return c;
-   *buf = c;
+   *buf = env[val++];
if (*buf == '\0')
return n;
}
diff --git a/env/env.c b/env/env.c
index 91d220c3dd..e4dfb92e15 100644
--- a/env/env.c
+++ b/env/env.c
@@ -166,14 +166,6 @@ static struct env_driver *env_driver_lookup(enum 
env_operation op, int prio)
return drv;
 }
 
-int env_get_char(int index)
-{
-   if (gd->env_valid == ENV_INVALID)
-   return default_environment[index];
-   else
-   return *(uchar *)(gd->env_addr + index);
-}
-
 int env_load(void)
 {
struct env_driver *drv;
diff --git a/env/nowhere.c b/env/nowhere.c
index 41557f5ce4..1fcf503453 100644
--- a/env/nowhere.c
+++ b/env/nowhere.c
@@ -31,9 +31,8 @@ static int env_nowhere_init(void)
 static int env_nowhere_load(void)
 {
/*
-* for SPL, set env_valid = ENV_INVALID is enough as env_get_char()
-* return the default env if env_get is used
-* and SPL don't used env_import to reduce its size
+* For SPL, setting env_valid = ENV_INVALID is enough, as env_get()
+* searches default_environment array in that case.
 * For U-Boot proper, import the default environment to allow reload.
 */
if (!IS_ENABLED(CONFIG_SPL_BUILD))
diff --git a/include/env.h b/include/env.h
index a9b2a4c8b2..220ab979d9 100644
--- a/include/env.h
+++ b/include/env.h
@@ -351,16 +351,6 @@ char *env_get_default(const char *name);
 /* [re]set to the default environment */
 void env_set_default(const char *s, int flags);
 
-/**
- * env_get_char() - Get a character from the early environment
- *
- * This reads from the pre-relocation environment
- *
- * @index: Index of character to read (0 = first)
- * @return character read, or -ve on error
- */
-int env_get_char(int index);
-
 /**
  * env_reloc() - Relocate the 'env' sub-commands
  *
-- 
2.32.0



[PATCH v2 09/13] env: Use string pointer instead of indexes in env_get_f()

2021-10-13 Thread Marek Behún
From: Marek Behún 

Since we no longer use env_get_char() to access n-th character of
linearized environment data, but rather access the arrays themselves, we
can convert the iteration to use string pointers instead of position
indexes.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 7c99a693ea..6eabd51209 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -706,17 +706,17 @@ char *from_env(const char *envvar)
return ret;
 }
 
-static int env_match(const char *env, const char *s1, int i2)
+static const char *matching_name_get_value(const char *p, const char *name)
 {
-   while (*s1 == env[i2++] && *s1 != '\0')
-   if (*s1++ == '=')
-   return i2;
+   while (*name == *p++ && *name != '\0')
+   if (*name++ == '=')
+   return p;
 
-   /* We can look at env[i2-1] because i2 was incremented at least once. */
-   if (*s1 == '\0' && env[i2-1] == '=')
-   return i2;
+   /* We can look at p[-1] because p was incremented at least once. */
+   if (*name == '\0' && p[-1] == '=')
+   return p;
 
-   return -1;
+   return NULL;
 }
 
 /*
@@ -724,8 +724,7 @@ static int env_match(const char *env, const char *s1, int 
i2)
  */
 int env_get_f(const char *name, char *buf, unsigned len)
 {
-   const char *env;
-   int i, nxt;
+   const char *env, *p, *nxt;
 
if (name == NULL || *name == '\0')
return -1;
@@ -735,20 +734,21 @@ int env_get_f(const char *name, char *buf, unsigned len)
else
env = (const char *)gd->env_addr;
 
-   for (i = 0; env[i] != '\0'; i = nxt + 1) {
-   int val, n;
+   for (p = env; *p != '\0'; p = nxt + 1) {
+   const char *value;
+   int n;
 
-   for (nxt = i; env[nxt] != '\0'; ++nxt)
-   if (nxt >= CONFIG_ENV_SIZE)
+   for (nxt = p; *nxt != '\0'; ++nxt)
+   if (nxt - env >= CONFIG_ENV_SIZE)
return -1;
 
-   val = env_match(env, name, i);
-   if (val < 0)
+   value = matching_name_get_value(p, name);
+   if (value == NULL)
continue;
 
/* found; copy out */
for (n = 0; n < len; ++n, ++buf) {
-   *buf = env[val++];
+   *buf = *value++;
if (*buf == '\0')
return n;
}
-- 
2.32.0



[PATCH v2 08/13] env: Early return from env_get_f() on NULL name

2021-10-13 Thread Marek Behún
From: Marek Behún 

Test non-NULL name immediately, not in env_match().

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 9f0caceadf..7c99a693ea 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -708,13 +708,11 @@ char *from_env(const char *envvar)
 
 static int env_match(const char *env, const char *s1, int i2)
 {
-   if (s1 == NULL || *s1 == '\0')
-   return -1;
-
while (*s1 == env[i2++] && *s1 != '\0')
if (*s1++ == '=')
return i2;
 
+   /* We can look at env[i2-1] because i2 was incremented at least once. */
if (*s1 == '\0' && env[i2-1] == '=')
return i2;
 
@@ -729,6 +727,9 @@ int env_get_f(const char *name, char *buf, unsigned len)
const char *env;
int i, nxt;
 
+   if (name == NULL || *name == '\0')
+   return -1;
+
if (gd->env_valid == ENV_INVALID)
env = (const char *)default_environment;
else
-- 
2.32.0



[PATCH v2 12/13] env: Use memcpy() instead of ad-hoc code to copy variable value

2021-10-13 Thread Marek Behún
From: Marek Behún 

Copy the value of the found variable into given buffer with memcpy()
instead of ad-hoc code.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 8989c85d20..7f094b3cd7 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -736,7 +736,7 @@ int env_get_f(const char *name, char *buf, unsigned len)
 
for (p = env; *p != '\0'; p = end + 1) {
const char *value;
-   int n, res;
+   unsigned res;
 
for (end = p; *end != '\0'; ++end)
if (end - env >= CONFIG_ENV_SIZE)
@@ -747,20 +747,14 @@ int env_get_f(const char *name, char *buf, unsigned len)
continue;
 
res = end - value;
+   memcpy(buf, value, min(len, res + 1));
 
-   /* found; copy out */
-   for (n = 0; n < len; ++n, ++buf) {
-   *buf = *value++;
-   if (*buf == '\0')
-   return res;
+   if (len <= res) {
+   buf[len - 1] = '\0';
+   printf("env_buf [%u bytes] too small for value of 
\"%s\"\n",
+  len, name);
}
 
-   if (n)
-   *--buf = '\0';
-
-   printf("env_buf [%u bytes] too small for value of \"%s\"\n",
-  len, name);
-
return res;
}
 
-- 
2.32.0



[PATCH v2 06/13] env: Check for terminating null-byte in env_match()

2021-10-13 Thread Marek Behún
From: Marek Behún 

There is a possible overflow in env_match(): if environment contains
a terminating null-byte before '=' character (i.e. environment is
broken), the env_match() function can access data after the terminating
null-byte from parameter pointer.

Example: if env_get_char() returns characters from string array
"abc\0def\0" and env_match("abc", 0) is called, the function will access
at least one byte after the end of the "abc" literal.

Fix this by checking for terminating null-byte in env_match().

Signed-off-by: Marek Behún 
---
Change since v1:
- check for '\0' only after incrementing i2
---
 cmd/nvedit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index e2e8a38b5d..a22445132b 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -711,7 +711,7 @@ static int env_match(uchar *s1, int i2)
if (s1 == NULL || *s1 == '\0')
return -1;
 
-   while (*s1 == env_get_char(i2++))
+   while (*s1 == env_get_char(i2++) && *s1 != '\0')
if (*s1++ == '=')
return i2;
 
-- 
2.32.0



[PATCH v2 04/13] env: Change env_match() to static and remove from header

2021-10-13 Thread Marek Behún
From: Marek Behún 

This function was used by other parts of U-Boot in the past when
environment was read from underlying device one character at a time.

This is not the case anymore.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c  | 30 +++---
 include/env.h | 11 ---
 2 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index ddc715b4f9..742e0924af 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -706,6 +706,21 @@ char *from_env(const char *envvar)
return ret;
 }
 
+static int env_match(uchar *s1, int i2)
+{
+   if (s1 == NULL)
+   return -1;
+
+   while (*s1 == env_get_char(i2++))
+   if (*s1++ == '=')
+   return i2;
+
+   if (*s1 == '\0' && env_get_char(i2-1) == '=')
+   return i2;
+
+   return -1;
+}
+
 /*
  * Look up variable from environment for restricted C runtime env.
  */
@@ -816,21 +831,6 @@ static int do_env_select(struct cmd_tbl *cmdtp, int flag, 
int argc,
 
 #endif /* CONFIG_SPL_BUILD */
 
-int env_match(uchar *s1, int i2)
-{
-   if (s1 == NULL)
-   return -1;
-
-   while (*s1 == env_get_char(i2++))
-   if (*s1++ == '=')
-   return i2;
-
-   if (*s1 == '\0' && env_get_char(i2-1) == '=')
-   return i2;
-
-   return -1;
-}
-
 #ifndef CONFIG_SPL_BUILD
 static int do_env_default(struct cmd_tbl *cmdtp, int flag,
  int argc, char *const argv[])
diff --git a/include/env.h b/include/env.h
index b1a4003681..a9b2a4c8b2 100644
--- a/include/env.h
+++ b/include/env.h
@@ -90,17 +90,6 @@ int env_init(void);
  */
 void env_relocate(void);
 
-/**
- * env_match() - Match a name / name=value pair
- *
- * This is used prior to relocation for finding envrionment variables
- *
- * @name: A simple 'name', or a 'name=value' pair.
- * @index: The environment index for a 'name2=value2' pair.
- * @return index for the value if the names match, else -1.
- */
-int env_match(unsigned char *name, int index);
-
 /**
  * env_get() - Look up the value of an environment variable
  *
-- 
2.32.0



[PATCH v2 02/13] env: Drop env_get_char_spec() and old, unused .get_char() implementations

2021-10-13 Thread Marek Behún
From: Marek Behún 

Commit b2cdef4861be ("env: restore old env_get_char() behaviour")
dropped the .get_char() method from struct env_driver, but left the two
existing implementations (eeprom and nvram) in case someone would use
them by overwriting weak function env_get_char_spec().

Since this was never done in the 3.5 years, let's drop these methods and
simplify the code.

Signed-off-by: Marek Behún 
---
 env/eeprom.c | 18 --
 env/env.c|  7 +--
 env/nvram.c  | 14 --
 3 files changed, 1 insertion(+), 38 deletions(-)

diff --git a/env/eeprom.c b/env/eeprom.c
index 253bdf1428..f8556a4721 100644
--- a/env/eeprom.c
+++ b/env/eeprom.c
@@ -64,24 +64,6 @@ static int eeprom_bus_write(unsigned dev_addr, unsigned 
offset,
return rcode;
 }
 
-/** Call this function from overridden env_get_char_spec() if you need
- * this functionality.
- */
-int env_eeprom_get_char(int index)
-{
-   uchar c;
-   unsigned int off = CONFIG_ENV_OFFSET;
-
-#ifdef CONFIG_ENV_OFFSET_REDUND
-   if (gd->env_valid == ENV_REDUND)
-   off = CONFIG_ENV_OFFSET_REDUND;
-#endif
-   eeprom_bus_read(CONFIG_SYS_I2C_EEPROM_ADDR,
-   off + index + offsetof(env_t, data), , 1);
-
-   return c;
-}
-
 static int env_eeprom_load(void)
 {
char buf_env[CONFIG_ENV_SIZE];
diff --git a/env/env.c b/env/env.c
index e534008006..91d220c3dd 100644
--- a/env/env.c
+++ b/env/env.c
@@ -166,17 +166,12 @@ static struct env_driver *env_driver_lookup(enum 
env_operation op, int prio)
return drv;
 }
 
-__weak int env_get_char_spec(int index)
-{
-   return *(uchar *)(gd->env_addr + index);
-}
-
 int env_get_char(int index)
 {
if (gd->env_valid == ENV_INVALID)
return default_environment[index];
else
-   return env_get_char_spec(index);
+   return *(uchar *)(gd->env_addr + index);
 }
 
 int env_load(void)
diff --git a/env/nvram.c b/env/nvram.c
index f4126858b5..261b31edfb 100644
--- a/env/nvram.c
+++ b/env/nvram.c
@@ -42,20 +42,6 @@ extern void nvram_write(long dest, const void *src, size_t 
count);
 static env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR;
 #endif
 
-#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
-/** Call this function from overridden env_get_char_spec() if you need
- * this functionality.
- */
-int env_nvram_get_char(int index)
-{
-   uchar c;
-
-   nvram_read(, CONFIG_ENV_ADDR + index, 1);
-
-   return c;
-}
-#endif
-
 static int env_nvram_load(void)
 {
char buf[CONFIG_ENV_SIZE];
-- 
2.32.0



[PATCH v2 03/13] examples: api: glue: Remove comment that does not apply anymore

2021-10-13 Thread Marek Behún
From: Marek Behún 

This comment is not true since commit 6215bd4c1fd6 ("api: Use hashtable
function for API_env_enum").

Signed-off-by: Marek Behún 
---
 examples/api/glue.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/examples/api/glue.c b/examples/api/glue.c
index 91d13157a1..075d307ae2 100644
--- a/examples/api/glue.c
+++ b/examples/api/glue.c
@@ -365,11 +365,6 @@ const char * ub_env_enum(const char *last)
 
env = NULL;
 
-   /*
-* It's OK to pass only the name piece as last (and not the whole
-* 'name=val' string), since the API_ENUM_ENV call uses env_match()
-* internally, which handles such case
-*/
if (!syscall(API_ENV_ENUM, NULL, last, ))
return NULL;
 
-- 
2.32.0



[PATCH v2 05/13] env: Don't match empty variable name in env_match()

2021-10-13 Thread Marek Behún
From: Marek Behún 

Do we really allow zero-length variable name? I guess not.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 742e0924af..e2e8a38b5d 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -708,7 +708,7 @@ char *from_env(const char *envvar)
 
 static int env_match(uchar *s1, int i2)
 {
-   if (s1 == NULL)
+   if (s1 == NULL || *s1 == '\0')
return -1;
 
while (*s1 == env_get_char(i2++))
-- 
2.32.0



Re: [PATCH 1/2] arm: mvebu: Implement the mac command (Marvell hw_info)

2021-10-13 Thread Marek Behún
On Mon, 11 Oct 2021 18:16:02 +0200
Luka Kovacic  wrote:

>> eth1_mac_addr: eth1addr {
>>   compatible = "mac-address-string";
>>   name = "eth1addr";
>> };  
>
> I don't see any better approach than just matching strings to retrieve
> values for specific keys (for MACs), so this looks good to me.

The `name` property can be omitted, the node name should be used, since
it is unique both in DT and in env.

MAC addresses will need a special compatible property so that the nvmem
driver knows to convert them from 'XX:XX:XX:XX:XX:XX' string to 6-byte
value.

> I agree, a real nvmem API would be much cleaner than the current
> U-Boot implementation, as there is currently no way to
> programmatically access these parameters and the implementations have
> different user interfaces.
> 
> As there is currently no nvmem framework, I recommend that the basic,
> futureproof DT bindings are defined and DT parsing is temporarily
> implemented in the hw_info mac command. What do you think?

Yes, that is acceptable.

> Is anyone already working on a nvmem framework to support nvmem
> providers in U-Boot?

AFAIK no, but I am planning to look into this.

In the meantime implement the hw_info mac command.

I will send proposal for dt-binding.

Marek


Re: [PATCH 05/10] env: Check for terminating null-byte in env_match()

2021-10-13 Thread Marek Behún
On Tue, 12 Oct 2021 13:04:56 +0200
Marek Behún  wrote:

> - while (*s1 == env_get_char(i2++))
> + while (*s1 != '\0' && *s1 == env_get_char(i2++))

This check has to be done in the other order:
  while (*s1 == env_get_char(i2++) && *s1 != '\0')

so that i2 gets incremented even if *s1 == '\0'.

Will be fixed in v2.


[PATCH v2 01/13] env: Fix documentation for env_get_f()

2021-10-13 Thread Marek Behún
From: Marek Behún 

This function actually returns:
- the number of bytes written into @buf excluding the terminating
  NULL-byte, if there was enough space in @buf
- the number of bytes written into @buf including the terminating
  NULL-byte, if there wasn't enough space in @buf
- -1 if the variable is not found

Signed-off-by: Marek Behún 
---
 include/env.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/env.h b/include/env.h
index d5e2bcb530..b1a4003681 100644
--- a/include/env.h
+++ b/include/env.h
@@ -131,7 +131,10 @@ char *from_env(const char *envvar);
  * support reading the value (slowly) and some will not.
  *
  * @varname:   Variable to look up
- * @return value of variable, or NULL if not found
+ * @return number of bytes written into @buf, excluding the terminating
+ * NULL-byte if there was enough space in @buf, and including the
+ * terminating NULL-byte if there wasn't enough space, or -1 if the
+ * variable is not found
  */
 int env_get_f(const char *name, char *buf, unsigned int len);
 
-- 
2.32.0



[PATCH v2 00/13] env_get_char() removal and env_get_f() refactor

2021-10-13 Thread Marek Behún
From: Marek Behún 

Hi Simon, Tom,

env_get_char() is a relic from the past when env was read char-by-char
from underlying device. Currently it only accesses in-memory arrays.
We can remove it and access the arrays directly. This simplifies the old
code of env_get_f().

Changes since v1:
- use memcpy() instead of strncpy() when copying value to buffer
- fixed a bug in patch adding check to terminating NULL-byte
- added patch fixing documentation for env_get_f()
- added patch changing behaviour of return value of env_get_f()
- some other cosmetic changes

Marek

Marek Behún (13):
  env: Fix documentation for env_get_f()
  env: Drop env_get_char_spec() and old, unused .get_char()
implementations
  examples: api: glue: Remove comment that does not apply anymore
  env: Change env_match() to static and remove from header
  env: Don't match empty variable name in env_match()
  env: Check for terminating null-byte in env_match()
  env: Inline env_get_char() into it's only user
  env: Early return from env_get_f() on NULL name
  env: Use string pointer instead of indexes in env_get_f()
  env: Use better name for variable in env_get_f()
  env: Make return value of env_get_f() behave like sprintf() on success
  env: Use memcpy() instead of ad-hoc code to copy variable value
  env: Move non-cmd specific env functions to env/common.c

 cmd/nvedit.c| 188 ---
 env/common.c| 190 
 env/eeprom.c|  18 -
 env/env.c   |  13 ---
 env/nowhere.c   |   5 +-
 env/nvram.c |  14 
 examples/api/glue.c |   5 --
 include/env.h   |  24 +-
 8 files changed, 194 insertions(+), 263 deletions(-)

-- 
2.32.0



[PATCH RFC linux] dt-bindings: nvmem: Add binding for U-Boot environment NVMEM provider

2021-10-13 Thread Marek Behún
Add device tree bindings for U-Boot environment NVMEM provider.

U-Boot environment can be stored at a specific offset of a MTD device,
EEPROM, MMC, NAND or SATA device, on an UBI volume, or in a file on a
filesystem.

The environment can contain information such as device's MAC address,
which should be used by the ethernet controller node.

Signed-off-by: Marek Behún 
---
 .../bindings/nvmem/denx,u-boot-env.yaml   | 88 +++
 include/dt-bindings/nvmem/u-boot-env.h| 18 
 2 files changed, 106 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/denx,u-boot-env.yaml
 create mode 100644 include/dt-bindings/nvmem/u-boot-env.h

diff --git a/Documentation/devicetree/bindings/nvmem/denx,u-boot-env.yaml 
b/Documentation/devicetree/bindings/nvmem/denx,u-boot-env.yaml
new file mode 100644
index ..56505c08e622
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/denx,u-boot-env.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/denx,u-boot-env.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: U-Boot environment NVMEM Device Tree Bindings
+
+maintainers:
+  - Marek Behún 
+
+description:
+  This binding represents U-Boot's environment NVMEM settings which can be
+  stored on a specific offset of an EEPROM, MMC, NAND or SATA device, or
+  an UBI volume, or in a file on a filesystem.
+
+properties:
+  compatible:
+const: denx,u-boot-env
+
+  path:
+description:
+  The path to the file containing the environment if on a filesystem.
+$ref: /schemas/types.yaml#/definitions/string
+
+patternProperties:
+  "^[^=]+$":
+type: object
+
+description:
+  This node represents one U-Boot environment variable, which is also one
+  NVMEM data cell.
+
+properties:
+  name:
+description:
+  If the variable name contains characters not allowed in device tree 
node
+  name, use this property to specify the name, otherwise the variable 
name
+  is equal to node name.
+$ref: /schemas/types.yaml#/definitions/string
+
+  type:
+description:
+  Type of the variable. Since variables, even integers and MAC 
addresses,
+  are stored as strings in U-Boot environment, for proper conversion 
the
+  type needs to be specified. Use one of the U_BOOT_ENV_TYPE_* prefixed
+  definitions from include/dt-bindings/nvmem/u-boot-env.h.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 5
+
+required:
+  - type
+
+required:
+  - compatible
+
+additionalProperties: true
+
+examples:
+  - |
+
+#include 
+
+spi-flash {
+partitions {
+compatible = "fixed-partitions";
+#address-cells = <1>;
+#size-cells = <1>;
+
+partition@18 {
+compatible = "denx,u-boot-env";
+label = "u-boot-env";
+reg = <0x18 0x1>;
+
+eth0_addr: ethaddr {
+type = ;
+};
+};
+};
+};
+
+ethernet-controller {
+nvmem-cells = <_addr>;
+nvmem-cell-names = "mac-address";
+};
+
+...
diff --git a/include/dt-bindings/nvmem/u-boot-env.h 
b/include/dt-bindings/nvmem/u-boot-env.h
new file mode 100644
index ..760e5b240619
--- /dev/null
+++ b/include/dt-bindings/nvmem/u-boot-env.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Macros for U-Boot environment NVMEM device tree bindings.
+ *
+ * Copyright (C) 2021 Marek Behún 
+ */
+
+#ifndef __DT_BINDINGS_NVMEM_U_BOOT_ENV_H
+#define __DT_BINDINGS_NVMEM_U_BOOT_ENV_H
+
+#define U_BOOT_ENV_TYPE_STRING 0
+#define U_BOOT_ENV_TYPE_ULONG  1
+#define U_BOOT_ENV_TYPE_BOOL   2
+#define U_BOOT_ENV_TYPE_MAC_ADDRESS3
+#define U_BOOT_ENV_TYPE_ULONG_HEX  4
+#define U_BOOT_ENV_TYPE_ULONG_DEC  5
+
+#endif /* __DT_BINDINGS_NVMEM_U_BOOT_ENV_H */
-- 
2.32.0



[PATCH 10/10] env: Move non-cmd specific env functions to env/common.c

2021-10-12 Thread Marek Behún
From: Marek Behún 

Move the following functions from cmd/nvedit.c to env/common.c:
  env_set_ulong()
  env_set_hex()
  env_get_hex()
  eth_env_get_enetaddr()
  eth_env_set_enetaddr()
  env_get()
  from_env()
  env_get_f()
  env_get_ulong()
since these functions are not specific for U-Boot's CLI.

We leave env_set() in cmd/nvedit.c, since it calls _do_env_set(), which
is a static function in this file.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 182 ---
 env/common.c | 180 ++
 2 files changed, 180 insertions(+), 182 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 455783dccc..3bb6e764c0 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -30,7 +30,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -38,7 +37,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -320,69 +318,6 @@ int env_set(const char *varname, const char *varvalue)
return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
 }
 
-/**
- * Set an environment variable to an integer value
- *
- * @param varname  Environment variable to set
- * @param valueValue to set it to
- * @return 0 if ok, 1 on error
- */
-int env_set_ulong(const char *varname, ulong value)
-{
-   /* TODO: this should be unsigned */
-   char *str = simple_itoa(value);
-
-   return env_set(varname, str);
-}
-
-/**
- * Set an environment variable to an value in hex
- *
- * @param varname  Environment variable to set
- * @param valueValue to set it to
- * @return 0 if ok, 1 on error
- */
-int env_set_hex(const char *varname, ulong value)
-{
-   char str[17];
-
-   sprintf(str, "%lx", value);
-   return env_set(varname, str);
-}
-
-ulong env_get_hex(const char *varname, ulong default_val)
-{
-   const char *s;
-   ulong value;
-   char *endp;
-
-   s = env_get(varname);
-   if (s)
-   value = hextoul(s, );
-   if (!s || endp == s)
-   return default_val;
-
-   return value;
-}
-
-int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr)
-{
-   string_to_enetaddr(env_get(name), enetaddr);
-   return is_valid_ethaddr(enetaddr);
-}
-
-int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr)
-{
-   char buf[ARP_HLEN_ASCII + 1];
-
-   if (eth_env_get_enetaddr(name, (uint8_t *)buf))
-   return -EEXIST;
-
-   sprintf(buf, "%pM", enetaddr);
-
-   return env_set(name, buf);
-}
-
 #ifndef CONFIG_SPL_BUILD
 static int do_env_set(struct cmd_tbl *cmdtp, int flag, int argc,
  char *const argv[])
@@ -661,124 +596,7 @@ static int do_env_edit(struct cmd_tbl *cmdtp, int flag, 
int argc,
}
 }
 #endif /* CONFIG_CMD_EDITENV */
-#endif /* CONFIG_SPL_BUILD */
-
-/*
- * Look up variable from environment,
- * return address of storage for that variable,
- * or NULL if not found
- */
-char *env_get(const char *name)
-{
-   if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */
-   struct env_entry e, *ep;
-
-   WATCHDOG_RESET();
-
-   e.key   = name;
-   e.data  = NULL;
-   hsearch_r(e, ENV_FIND, , _htab, 0);
-
-   return ep ? ep->data : NULL;
-   }
-
-   /* restricted capabilities before import */
-   if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
-   return (char *)(gd->env_buf);
-
-   return NULL;
-}
 
-/*
- * Like env_get, but prints an error if envvar isn't defined in the
- * environment.  It always returns what env_get does, so it can be used in
- * place of env_get without changing error handling otherwise.
- */
-char *from_env(const char *envvar)
-{
-   char *ret;
-
-   ret = env_get(envvar);
-
-   if (!ret)
-   printf("missing environment variable: %s\n", envvar);
-
-   return ret;
-}
-
-static const char *matching_name_get_value(const char *p, const char *name)
-{
-   while (*name != '\0' && *name == *p++)
-   if (*name++ == '=')
-   return p;
-
-   if (*name == '\0' && p[-1] == '=')
-   return p;
-
-   return NULL;
-}
-
-/*
- * Look up variable from environment for restricted C runtime env.
- */
-int env_get_f(const char *name, char *buf, unsigned len)
-{
-   const char *env, *p, *nxt;
-
-   if (name == NULL || *name == '\0')
-   return -1;
-
-   if (gd->env_valid == ENV_INVALID)
-   env = (const char *)default_environment;
-   else
-   env = (const char *)gd->env_addr;
-
-   for (p = env; *p != '\0'; p = nxt + 1) {
-   const char *value;
-   unsigned copied;
-
-   for (nxt = p; *nxt != '\0'; ++nxt)
-  

[PATCH 05/10] env: Check for terminating null-byte in env_match()

2021-10-12 Thread Marek Behún
From: Marek Behún 

There is a possible overflow in env_match(): if environment contains
a terminating null-byte before '=' character (i.e. environment is
broken), the env_match() function can access data after the terminating
null-byte from parameter pointer.

Example: if env_get_char() returns characters from string array
"abc\0def\0" and env_match("abc", 0) is called, the function will access
at least one byte after the end of the "abc" literal.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index e2e8a38b5d..a516491832 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -711,7 +711,7 @@ static int env_match(uchar *s1, int i2)
if (s1 == NULL || *s1 == '\0')
return -1;
 
-   while (*s1 == env_get_char(i2++))
+   while (*s1 != '\0' && *s1 == env_get_char(i2++))
if (*s1++ == '=')
return i2;
 
-- 
2.32.0



[PATCH 09/10] env: Use string pointer instead of indexes in env_get_f()

2021-10-12 Thread Marek Behún
From: Marek Behún 

Since we no longer use env_get_char() to access n-th character of
linearized environment data, but rather access the arrays themselves, we
can convert the iteration to use string pointers instead of position
indexes.

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 37 ++---
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 51b9e4ffa4..455783dccc 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -706,16 +706,16 @@ char *from_env(const char *envvar)
return ret;
 }
 
-static int env_match(const char *env, const char *s1, int i2)
+static const char *matching_name_get_value(const char *p, const char *name)
 {
-   while (*s1 != '\0' && *s1 == env[i2++])
-   if (*s1++ == '=')
-   return i2;
+   while (*name != '\0' && *name == *p++)
+   if (*name++ == '=')
+   return p;
 
-   if (*s1 == '\0' && env[i2-1] == '=')
-   return i2;
+   if (*name == '\0' && p[-1] == '=')
+   return p;
 
-   return -1;
+   return NULL;
 }
 
 /*
@@ -723,8 +723,7 @@ static int env_match(const char *env, const char *s1, int 
i2)
  */
 int env_get_f(const char *name, char *buf, unsigned len)
 {
-   const char *env;
-   int i, nxt;
+   const char *env, *p, *nxt;
 
if (name == NULL || *name == '\0')
return -1;
@@ -734,26 +733,26 @@ int env_get_f(const char *name, char *buf, unsigned len)
else
env = (const char *)gd->env_addr;
 
-   for (i = 0; env[i] != '\0'; i = nxt + 1) {
-   int val, n;
+   for (p = env; *p != '\0'; p = nxt + 1) {
+   const char *value;
+   unsigned copied;
 
-   for (nxt = i; env[nxt] != '\0'; ++nxt)
-   if (nxt >= CONFIG_ENV_SIZE)
+   for (nxt = p; *nxt != '\0'; ++nxt)
+   if (p - env >= CONFIG_ENV_SIZE)
return -1;
 
-   val = env_match(env, name, i);
-   if (val < 0)
+   value = matching_name_get_value(p, name);
+   if (value == NULL)
continue;
 
-   /* found; copy out */
-   n = strncpy(buf, [val], len) - buf;
-   if (len && n == len) {
+   copied = strncpy(buf, value, len) - buf;
+   if (len && copied == len) {
buf[len - 1] = '\0';
printf("env_buf [%u bytes] too small for value of 
\"%s\"\n",
   len, name);
}
 
-   return n;
+   return copied;
}
 
return -1;
-- 
2.32.0



[PATCH 02/10] examples: api: glue: Remove comment that does not apply anymore

2021-10-12 Thread Marek Behún
From: Marek Behún 

This comment is not true since commit 6215bd4c1fd6 ("api: Use hashtable
function for API_env_enum").

Signed-off-by: Marek Behún 
---
 examples/api/glue.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/examples/api/glue.c b/examples/api/glue.c
index 91d13157a1..075d307ae2 100644
--- a/examples/api/glue.c
+++ b/examples/api/glue.c
@@ -365,11 +365,6 @@ const char * ub_env_enum(const char *last)
 
env = NULL;
 
-   /*
-* It's OK to pass only the name piece as last (and not the whole
-* 'name=val' string), since the API_ENUM_ENV call uses env_match()
-* internally, which handles such case
-*/
if (!syscall(API_ENV_ENUM, NULL, last, ))
return NULL;
 
-- 
2.32.0



[PATCH 07/10] env: Early return from env_get_f() on NULL name

2021-10-12 Thread Marek Behún
From: Marek Behún 

Test non-NULL name immediately, not in env_match().

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 4664b7b872..412918a000 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -708,9 +708,6 @@ char *from_env(const char *envvar)
 
 static int env_match(const char *env, const char *s1, int i2)
 {
-   if (s1 == NULL || *s1 == '\0')
-   return -1;
-
while (*s1 != '\0' && *s1 == env[i2++])
if (*s1++ == '=')
return i2;
@@ -729,6 +726,9 @@ int env_get_f(const char *name, char *buf, unsigned len)
const char *env;
int i, nxt;
 
+   if (name == NULL || *name == '\0')
+   return -1;
+
if (gd->env_valid == ENV_INVALID)
env = (const char *)default_environment;
else
-- 
2.32.0



[PATCH 06/10] env: Inline env_get_char() into it's only user

2021-10-12 Thread Marek Behún
From: Marek Behún 

This function is a relic from the past when environment was read from
underlying device one character at a time.

It is used only in the case when getting an environemnt variable prior
relocation, and the function is simple enough to be inlined there.

Since env_get_char() is being changed to simple access to an array, we
can drop the failing cases and simplify the code (this could have been
done before, since env_get_char() did not fail even before).

Signed-off-by: Marek Behún 
---
 cmd/nvedit.c  | 28 ++--
 env/env.c |  8 
 env/nowhere.c |  5 ++---
 include/env.h | 10 --
 4 files changed, 16 insertions(+), 35 deletions(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index a516491832..4664b7b872 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -706,16 +706,16 @@ char *from_env(const char *envvar)
return ret;
 }
 
-static int env_match(uchar *s1, int i2)
+static int env_match(const char *env, const char *s1, int i2)
 {
if (s1 == NULL || *s1 == '\0')
return -1;
 
-   while (*s1 != '\0' && *s1 == env_get_char(i2++))
+   while (*s1 != '\0' && *s1 == env[i2++])
if (*s1++ == '=')
return i2;
 
-   if (*s1 == '\0' && env_get_char(i2-1) == '=')
+   if (*s1 == '\0' && env[i2-1] == '=')
return i2;
 
return -1;
@@ -726,28 +726,28 @@ static int env_match(uchar *s1, int i2)
  */
 int env_get_f(const char *name, char *buf, unsigned len)
 {
-   int i, nxt, c;
+   const char *env;
+   int i, nxt;
 
-   for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+   if (gd->env_valid == ENV_INVALID)
+   env = (const char *)default_environment;
+   else
+   env = (const char *)gd->env_addr;
+
+   for (i = 0; env[i] != '\0'; i = nxt + 1) {
int val, n;
 
-   for (nxt = i; (c = env_get_char(nxt)) != '\0'; ++nxt) {
-   if (c < 0)
-   return c;
+   for (nxt = i; env[nxt] != '\0'; ++nxt)
if (nxt >= CONFIG_ENV_SIZE)
return -1;
-   }
 
-   val = env_match((uchar *)name, i);
+   val = env_match(env, name, i);
if (val < 0)
continue;
 
/* found; copy out */
for (n = 0; n < len; ++n, ++buf) {
-   c = env_get_char(val++);
-   if (c < 0)
-   return c;
-   *buf = c;
+   *buf = env[val++];
if (*buf == '\0')
return n;
}
diff --git a/env/env.c b/env/env.c
index 91d220c3dd..e4dfb92e15 100644
--- a/env/env.c
+++ b/env/env.c
@@ -166,14 +166,6 @@ static struct env_driver *env_driver_lookup(enum 
env_operation op, int prio)
return drv;
 }
 
-int env_get_char(int index)
-{
-   if (gd->env_valid == ENV_INVALID)
-   return default_environment[index];
-   else
-   return *(uchar *)(gd->env_addr + index);
-}
-
 int env_load(void)
 {
struct env_driver *drv;
diff --git a/env/nowhere.c b/env/nowhere.c
index 41557f5ce4..1fcf503453 100644
--- a/env/nowhere.c
+++ b/env/nowhere.c
@@ -31,9 +31,8 @@ static int env_nowhere_init(void)
 static int env_nowhere_load(void)
 {
/*
-* for SPL, set env_valid = ENV_INVALID is enough as env_get_char()
-* return the default env if env_get is used
-* and SPL don't used env_import to reduce its size
+* For SPL, setting env_valid = ENV_INVALID is enough, as env_get()
+* searches default_environment array in that case.
 * For U-Boot proper, import the default environment to allow reload.
 */
if (!IS_ENABLED(CONFIG_SPL_BUILD))
diff --git a/include/env.h b/include/env.h
index 6b774ae078..412b2bf21b 100644
--- a/include/env.h
+++ b/include/env.h
@@ -348,16 +348,6 @@ char *env_get_default(const char *name);
 /* [re]set to the default environment */
 void env_set_default(const char *s, int flags);
 
-/**
- * env_get_char() - Get a character from the early environment
- *
- * This reads from the pre-relocation environment
- *
- * @index: Index of character to read (0 = first)
- * @return character read, or -ve on error
- */
-int env_get_char(int index);
-
 /**
  * env_reloc() - Relocate the 'env' sub-commands
  *
-- 
2.32.0



<    4   5   6   7   8   9   10   11   12   13   >