mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 02/12] ARM: io: read 32 bits at once for aligned I/O memcpy/memset
Date: Wed, 13 Mar 2024 11:56:21 +0100	[thread overview]
Message-ID: <20240313105631.686778-3-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20240313105631.686778-1-a.fatoum@pengutronix.de>

The barebox arm32 implementation for I/O memcpy/memset uses single
byte accesses exclusively. This is different from the barebox arm64
implementation, which accesses 64 bits at once if the buffer is aligned
and the Linux arm32 implementation, which is the optimized assembly
version that doesn't use single byte accesses for aligned buffers
either.

The current implementation is slower than need be and breaks code ported
from Linux. e.g. the OMAP RNG driver uses memcpy_fromio and expects it
to perform 32-bit accesses as any smaller access leads to a data abort
on the hardware. In Linux this works, but in barebox it crashes.

Avoid these issues by using 32-bit accesses if possible.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/lib32/io.c | 73 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 16 deletions(-)

diff --git a/arch/arm/lib32/io.c b/arch/arm/lib32/io.c
index a12da49c0ab2..780b1083a641 100644
--- a/arch/arm/lib32/io.c
+++ b/arch/arm/lib32/io.c
@@ -2,48 +2,89 @@
 
 #include <module.h>
 #include <linux/types.h>
+#include <asm/unaligned.h>
 #include <io.h>
 
 /*
  * Copy data from IO memory space to "real" memory space.
- * This needs to be optimized.
  */
 void memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
 {
-	unsigned char *t = to;
-	while (count) {
-		count--;
-		*t = readb(from);
-		t++;
+	while (count && !PTR_IS_ALIGNED(from, 4)) {
+		*(u8 *)to = __raw_readb(from);
 		from++;
+		to++;
+		count--;
+	}
+
+	while (count >= 4) {
+		put_unaligned(__raw_readl(from), (u32 *)to);
+		from += 4;
+		to += 4;
+		count -= 4;
+	}
+
+	while (count) {
+		*(u8 *)to = __raw_readb(from);
+		from++;
+		to++;
+		count--;
 	}
 }
 
 /*
  * Copy data from "real" memory space to IO memory space.
- * This needs to be optimized.
  */
 void memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
 {
-	const unsigned char *f = from;
-	while (count) {
-		count--;
-		writeb(*f, to);
-		f++;
+	while (count && !IS_ALIGNED((unsigned long)to, 4)) {
+		__raw_writeb(*(u8 *)from, to);
+		from++;
 		to++;
+		count--;
+	}
+
+	while (count >= 4) {
+		__raw_writel(get_unaligned((u32 *)from), to);
+		from += 4;
+		to += 4;
+		count -= 4;
+	}
+
+	while (count) {
+		__raw_writeb(*(u8 *)from, to);
+		from++;
+		to++;
+		count--;
 	}
 }
 
 /*
  * "memset" on IO memory space.
- * This needs to be optimized.
  */
 void memset_io(volatile void __iomem *dst, int c, size_t count)
 {
-	while (count) {
-		count--;
-		writeb(c, dst);
+	u32 qc = (u8)c;
+
+	qc |= qc << 8;
+	qc |= qc << 16;
+
+	while (count && !PTR_IS_ALIGNED(dst, 4)) {
+		__raw_writeb(c, dst);
 		dst++;
+		count--;
+	}
+
+	while (count >= 4) {
+		__raw_writel(qc, dst);
+		dst += 4;
+		count -= 4;
+	}
+
+	while (count) {
+		__raw_writeb(c, dst);
+		dst++;
+		count--;
 	}
 }
 
-- 
2.39.2




  parent reply	other threads:[~2024-03-13 10:57 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-13 10:56 [PATCH 00/12] hw_random: add 6 more RNG drivers Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 01/12] hw_random: support ctrlc() Ahmad Fatoum
2024-03-13 10:56 ` Ahmad Fatoum [this message]
2024-03-13 10:56 ` [PATCH 03/12] driver: implement dev_platform_get_and_ioremap_resource Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 04/12] hw_random: add struct hwrng::priv member Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 05/12] hw_random: remove confusing left-overs from kernel help texts Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 06/12] hw_random: remove reference to undefined CONFIG_HW_RANDOM Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 07/12] hw_random: add Atmel RNG driver Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 08/12] hw_random: add BCM2835 " Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 09/12] hw_random: add IPROC RNG200 driver for BCM2711 Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 10/12] hw_random: add Rockchip RNG support Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 11/12] hw_random: add timeriomem_rng driver Ahmad Fatoum
2024-03-13 10:56 ` [PATCH 12/12] hw_random: add OMAP RNG driver Ahmad Fatoum
2024-03-15  7:07 ` [PATCH 00/12] hw_random: add 6 more RNG drivers Sascha Hauer

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=20240313105631.686778-3-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox