All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frieder Schrempf <frieder.schrempf@kontron.de>
To: Michael Walle <michael@walle.cc>, Frieder Schrempf <frieder@fris.de>
Cc: u-boot@lists.denx.de, Heiko Thiery <heiko.thiery@gmail.com>,
	Bin Meng <bmeng.cn@gmail.com>,
	Jagan Teki <jagan@amarulasolutions.com>,
	Pratyush Yadav <p.yadav@ti.com>,
	Sean Anderson <seanga2@gmail.com>, Simon Glass <sjg@chromium.org>
Subject: Re: [PATCH] cmd: sf: Support unaligned flash updates with 'sf update'
Date: Mon, 4 Oct 2021 12:41:44 +0200	[thread overview]
Message-ID: <eb5c0cca-3a4d-cc34-16d2-d88d2595c916@kontron.de> (raw)
In-Reply-To: <23600cdcfd4bf7f6b925efea28b2db1a@walle.cc>

On 30.09.21 23:21, Michael Walle wrote:
> Am 2021-09-30 18:19, schrieb Frieder Schrempf:
>> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>>
>> Currently 'sf update' supports only offsets that are aligned to the
>> erase block size of the serial flash. Unaligned offsets result in
>> something like:
>>
>> => sf update ${kernel_addr_r} 0x400 ${filesize}
>> device 0 offset 0x400, size 0x11f758
>> SPI flash failed in erase step
>>
>> In order to support unaligned updates, we simply read the first full
>> block and check only the requested part of the block for changes. If
>> necessary, the block is erased, the first (unchanged) part of the block
>> is written back together with the second part of the block (updated
>> data).
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> ---
>>  cmd/sf.c | 17 +++++++++++------
>>  1 file changed, 11 insertions(+), 6 deletions(-)
>>
>> diff --git a/cmd/sf.c b/cmd/sf.c
>> index eac27ed2d7..c54b4b10bb 100644
>> --- a/cmd/sf.c
>> +++ b/cmd/sf.c
>> @@ -171,30 +171,32 @@ static int do_spi_flash_probe(int argc, char
>> *const argv[])
>>  static const char *spi_flash_update_block(struct spi_flash *flash,
>> u32 offset,
>>          size_t len, const char *buf, char *cmp_buf, size_t *skipped)
>>  {
>> +    u32 offset_aligned = ALIGN_DOWN(offset, flash->sector_size);
>> +    u32 sector_offset = offset - offset_aligned;
>>      char *ptr = (char *)buf;
>>
>>      debug("offset=%#x, sector_size=%#x, len=%#zx\n",
>>            offset, flash->sector_size, len);
>>      /* Read the entire sector so to allow for rewriting */
>> -    if (spi_flash_read(flash, offset, flash->sector_size, cmp_buf))
>> +    if (spi_flash_read(flash, offset_aligned, flash->sector_size,
>> cmp_buf))
>>          return "read";
>>      /* Compare only what is meaningful (len) */
>> -    if (memcmp(cmp_buf, buf, len) == 0) {
>> +    if (memcmp(cmp_buf + sector_offset, buf, len) == 0) {
>>          debug("Skip region %x size %zx: no change\n",
>>                offset, len);
>>          *skipped += len;
>>          return NULL;
>>      }
>>      /* Erase the entire sector */
>> -    if (spi_flash_erase(flash, offset, flash->sector_size))
>> +    if (spi_flash_erase(flash, offset_aligned, flash->sector_size))
>>          return "erase";
>>      /* If it's a partial sector, copy the data into the temp-buffer */
>>      if (len != flash->sector_size) {
>> -        memcpy(cmp_buf, buf, len);
>> +        memcpy(cmp_buf + sector_offset, buf, len);
>>          ptr = cmp_buf;
>>      }
>>      /* Write one complete sector */
>> -    if (spi_flash_write(flash, offset, flash->sector_size, ptr))
>> +    if (spi_flash_write(flash, offset_aligned, flash->sector_size, ptr))
>>          return "write";
>>
>>      return NULL;
>> @@ -230,7 +232,10 @@ static int spi_flash_update(struct spi_flash
>> *flash, u32 offset,
>>          ulong last_update = get_timer(0);
>>
>>          for (; buf < end && !err_oper; buf += todo, offset += todo) {
>> -            todo = min_t(size_t, end - buf, flash->sector_size);
>> +            if (offset % flash->sector_size)
> 
> do_div() to avoid linking errors on some archs, I guess.

Ok, will fix it.

> 
>> +                todo = flash->sector_size - (offset %
>> flash->sector_size);
> 
> This is missing the end-buf calculation, no? I.e. if you update just one
> sector at an offset and the data you write is smaller than "sector_size
> - offset".

Indeed, thanks for catching this.

> 
>> +            else
>> +                todo = min_t(size_t, end - buf, flash->sector_size);
>>              if (get_timer(last_update) > 100) {
>>                  printf("   \rUpdating, %zu%% %lu B/s",
>>                         100 - (end - buf) / scale,
> 
> -michael

  reply	other threads:[~2021-10-04 10:41 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-30 16:19 [PATCH] cmd: sf: Support unaligned flash updates with 'sf update' Frieder Schrempf
2021-09-30 16:35 ` Michael Walle
2021-09-30 17:17   ` Frieder Schrempf
2021-09-30 21:08     ` Michael Walle
2021-10-04 10:31       ` Frieder Schrempf
2021-10-04 11:21         ` Michael Walle
2021-09-30 21:21 ` Michael Walle
2021-10-04 10:41   ` Frieder Schrempf [this message]
2021-10-01  5:03 ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eb5c0cca-3a4d-cc34-16d2-d88d2595c916@kontron.de \
    --to=frieder.schrempf@kontron.de \
    --cc=bmeng.cn@gmail.com \
    --cc=frieder@fris.de \
    --cc=heiko.thiery@gmail.com \
    --cc=jagan@amarulasolutions.com \
    --cc=michael@walle.cc \
    --cc=p.yadav@ti.com \
    --cc=seanga2@gmail.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.