From patchwork Wed Sep 28 16:45:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 1683966 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=denx.de header.i=@denx.de header.a=rsa-sha256 header.s=phobos-20191101 header.b=nxoPW2B4; dkim=pass (2048-bit key) header.d=denx.de header.i=@denx.de header.a=rsa-sha256 header.s=phobos-20191101 header.b=j5y+Dklt; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Md2RK0Nnlz1yqJ for ; Thu, 29 Sep 2022 02:45:17 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 269F684BDA; Wed, 28 Sep 2022 18:45:10 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1664383510; bh=l9/S+d0wRPTh9SpHNTC9OseMG6RjiQP/z6xhyMI0ac4=; h=From:To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=nxoPW2B44X3qUpldwWB2c3LqN/fmZgrwGMfSrmowhrDJQgnW9FP9+P0os+xxMAKfL AnrMsEtWVTWDsgCMyH+Yvb51zhBQtPeyt3kFVWOolWxoO/4Uz1XNSLHo90H1blFGkd BZsdTjZQvNXlodDd6SRcHKHBpa+U7TjgaKLQrW4Wzi6eNdJR2S/N9vzFK7LKtJPSL6 iX/xz/USQZuc7kyl+zirDPW+VO5pp5bc2GLaf6H72b4KJFivd1T4UFKX1zaDI3c+fF NK1dT+LFxHxT8UfG4ufHVZ4U5BfJPPGORVkhgCcefcIsddAhwBsZewGMLXlOxKZaO8 pHsVMaHhpjOyA== Received: from tr.lan (ip-86-49-12-201.bb.vodafone.cz [86.49.12.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 3687184BA7; Wed, 28 Sep 2022 18:45:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1664383507; bh=l9/S+d0wRPTh9SpHNTC9OseMG6RjiQP/z6xhyMI0ac4=; h=From:To:Cc:Subject:Date:From; b=j5y+DkltNsM3xISNH1dWULV+wDZPObRQZdj+63LwRSPSAZs/yKFRM5xA4vU6oI8jZ K/MTFkSc+4HY8vpuaUqZS+GjyLMzsVX2m1RszfBCYj0LKIcjqXW1Bh44Vb7dr+haXG 6usLyvjnUvDSrzb+hEKQSXJsPe75YWW8OY16vjbmqUWXYGJhK2+P2b/mXhDcDbOySM 8M5kH7Gt+Sede7O3UV1dhPP7Nd49bqW6li5yirr7H2Av6X7beZfcyvkPb8w1xmAJCQ fa05Qrhnt6nChnATg9FsDzY91yjvElryFkKhhkSYNA57WDVEdHPxsDJvH4DDuwg1V0 wvW0RwaTS+AQA== From: Marek Vasut To: u-boot@lists.denx.de Cc: Marek Vasut , Bin Meng , Jagan Teki , Jan Kiszka , Pratyush Yadav , Sean Anderson Subject: [PATCH] cmd: sf: Handle unaligned 'update' start offset Date: Wed, 28 Sep 2022 18:45:04 +0200 Message-Id: <20220928164504.181734-1-marex@denx.de> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean Currently the 'sf update' command fails in case the 'start' offset is not aligned to SPI NOR erase block size. Add the missing alignment calculation. In case the start offset is in the middle of erase block, round start address down to the nearest aligned one, compare only the updated data between what is in the SPI NOR and what is being written, copy new data at offset of the compare buffer, and write back the entire erase block. This is useful e.g. on i.MX6Q where the u-boot-with-spl.imx is at offset 0x400 in the SPI NOR, while the SPI NOR may have erase block size e.g. 0x1000 bytes. Signed-off-by: Marek Vasut Reviewed-by: Jagan Teki --- Cc: Bin Meng Cc: Jagan Teki Cc: Jan Kiszka Cc: Pratyush Yadav Cc: Sean Anderson --- cmd/sf.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/cmd/sf.c b/cmd/sf.c index bd102f5af9d..f9b2d9a47a7 100644 --- a/cmd/sf.c +++ b/cmd/sf.c @@ -179,16 +179,18 @@ 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) { char *ptr = (char *)buf; + u32 start_offset = offset % flash->sector_size; + u32 read_offset = offset - start_offset; - debug("offset=%#x, sector_size=%#x, len=%#zx\n", - offset, flash->sector_size, len); + debug("offset=%#x+%#x, sector_size=%#x, len=%#zx\n", + read_offset, start_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, read_offset, flash->sector_size, cmp_buf)) return "read"; /* Compare only what is meaningful (len) */ - if (memcmp(cmp_buf, buf, len) == 0) { - debug("Skip region %x size %zx: no change\n", - offset, len); + if (memcmp(cmp_buf + start_offset, buf, len) == 0) { + debug("Skip region %x+%x size %zx: no change\n", + start_offset, read_offset, len); *skipped += len; return NULL; } @@ -197,7 +199,7 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset, 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 + start_offset, buf, len); ptr = cmp_buf; } /* Write one complete sector */ @@ -238,6 +240,8 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset, for (; buf < end && !err_oper; buf += todo, offset += todo) { todo = min_t(size_t, end - buf, flash->sector_size); + todo = min_t(size_t, end - buf, + flash->sector_size - (offset % flash->sector_size)); if (get_timer(last_update) > 100) { printf(" \rUpdating, %zu%% %lu B/s", 100 - (end - buf) / scale,