* [PATCH] sparc64: remove byteshifting from out* helpers
@ 2008-10-22 18:50 Harvey Harrison
2008-10-23 21:08 ` David Miller
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Harvey Harrison @ 2008-10-22 18:50 UTC (permalink / raw)
To: sparclinux
__raw_write avoids the need to byteswap twice, as we are reading from a
host-endian (big) area, just deref the pointers directly, taking care
of alignment.
As before, outsw must still be called with a 2-byte aligned pointer.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
---
arch/sparc64/lib/PeeCeeI.c | 138 +++++++++++++++----------------------------
1 files changed, 48 insertions(+), 90 deletions(-)
diff --git a/arch/sparc64/lib/PeeCeeI.c b/arch/sparc64/lib/PeeCeeI.c
index 8b313f1..a4b6246 100644
--- a/arch/sparc64/lib/PeeCeeI.c
+++ b/arch/sparc64/lib/PeeCeeI.c
@@ -20,30 +20,9 @@ void outsw(unsigned long __addr, const void *src, unsigned long count)
{
void __iomem *addr = (void __iomem *) __addr;
- if (count) {
- u16 *ps = (u16 *)src;
- u32 *pi;
-
- if (((u64)src) & 0x2) {
- u16 val = le16_to_cpup(ps);
- outw(val, addr);
- ps++;
- count--;
- }
- pi = (u32 *)ps;
- while (count >= 2) {
- u32 w = le32_to_cpup(pi);
-
- pi++;
- outw(w >> 0, addr);
- outw(w >> 16, addr);
- count -= 2;
- }
- ps = (u16 *)pi;
- if (count) {
- u16 val = le16_to_cpup(ps);
- outw(val, addr);
- }
+ while (count--) {
+ __raw_writew(*(u16 *)src, addr);
+ src += sizeof(u16);
}
}
@@ -51,76 +30,55 @@ void outsl(unsigned long __addr, const void *src, unsigned long count)
{
void __iomem *addr = (void __iomem *) __addr;
- if (count) {
- if ((((u64)src) & 0x3) = 0) {
- u32 *p = (u32 *)src;
- while (count--) {
- u32 val = cpu_to_le32p(p);
- outl(val, addr);
- p++;
- }
- } else {
- u8 *pb;
- u16 *ps = (u16 *)src;
- u32 l = 0, l2;
- u32 *pi;
-
- switch (((u64)src) & 0x3) {
- case 0x2:
- count -= 1;
- l = cpu_to_le16p(ps) << 16;
- ps++;
- pi = (u32 *)ps;
- while (count--) {
- l2 = cpu_to_le32p(pi);
- pi++;
- outl(((l >> 16) | (l2 << 16)), addr);
- l = l2;
- }
- ps = (u16 *)pi;
- l2 = cpu_to_le16p(ps);
- outl(((l >> 16) | (l2 << 16)), addr);
- break;
-
- case 0x1:
- count -= 1;
- pb = (u8 *)src;
- l = (*pb++ << 8);
- ps = (u16 *)pb;
- l2 = cpu_to_le16p(ps);
- ps++;
- l |= (l2 << 16);
- pi = (u32 *)ps;
- while (count--) {
- l2 = cpu_to_le32p(pi);
- pi++;
- outl(((l >> 8) | (l2 << 24)), addr);
- l = l2;
- }
- pb = (u8 *)pi;
- outl(((l >> 8) | (*pb << 24)), addr);
- break;
+ if (!count)
+ return;
- case 0x3:
- count -= 1;
- pb = (u8 *)src;
- l = (*pb++ << 24);
- pi = (u32 *)pb;
- while (count--) {
- l2 = cpu_to_le32p(pi);
- pi++;
- outl(((l >> 24) | (l2 << 8)), addr);
- l = l2;
- }
- ps = (u16 *)pi;
- l2 = cpu_to_le16p(ps);
- ps++;
- pb = (u8 *)ps;
- l2 |= (*pb << 16);
- outl(((l >> 24) | (l2 << 8)), addr);
- break;
- }
+ switch (((unsigned long)src) & 0x3) {
+ case 0x0:
+ /* src is naturally aligned */
+ while (count--) {
+ __raw_writel(*(u32 *)src, addr);
+ src += sizeof(u32);
+ }
+ break;
+ case 0x2:
+ /* 2-byte alignment */
+ while (count--) {
+ u32 l = (*(u16 *)src) << 16;
+ l |= *(u16 *)(src + sizeof(u16));
+ __raw_writel(l, addr);
+ src += sizeof(u32);
+ }
+ break;
+ case 0x1:
+ /* Hold three bytes in l each time, grab a byte from l2 */
+ u32 l, l2;
+
+ l = (*(u8 *)src) << 24;
+ l |= (*(u16 *)(src + sizeof(u8))) << 8;
+ src += sizeof(u8) + sizeof(u16);
+ while (count--) {
+ l2 = *(u32 *)src;
+ l |= (l2 >> 24);
+ __raw_writel(l, addr);
+ l = l2 << 8;
+ src += sizeof(u32);
+ }
+ break;
+ case 0x3:
+ /* Hold a byte in l each time, grab 3 bytes from l2 */
+ u32 l, l2;
+
+ l = (*(u8 *)src) << 24;
+ src += sizeof(u8);
+ while (count--) {
+ l2 = *(u32 *)src;
+ l |= (l2 >> 8);
+ __raw_writel(l, addr);
+ l = l2 << 24;
+ src += sizeof(u32);
}
+ break;
}
}
--
1.6.0.2.824.geb4d2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] sparc64: remove byteshifting from out* helpers
2008-10-22 18:50 [PATCH] sparc64: remove byteshifting from out* helpers Harvey Harrison
@ 2008-10-23 21:08 ` David Miller
2008-10-23 21:19 ` David Miller
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2008-10-23 21:08 UTC (permalink / raw)
To: sparclinux
From: Harvey Harrison <harvey.harrison@gmail.com>
Date: Wed, 22 Oct 2008 11:50:24 -0700
> __raw_write avoids the need to byteswap twice, as we are reading from a
> host-endian (big) area, just deref the pointers directly, taking care
> of alignment.
>
> As before, outsw must still be called with a 2-byte aligned pointer.
>
> Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Applied, thanks Harvey.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] sparc64: remove byteshifting from out* helpers
2008-10-22 18:50 [PATCH] sparc64: remove byteshifting from out* helpers Harvey Harrison
2008-10-23 21:08 ` David Miller
@ 2008-10-23 21:19 ` David Miller
2008-10-24 3:48 ` Harvey Harrison
2008-10-29 22:33 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2008-10-23 21:19 UTC (permalink / raw)
To: sparclinux
From: David Miller <davem@davemloft.net>
Date: Thu, 23 Oct 2008 14:08:19 -0700 (PDT)
> From: Harvey Harrison <harvey.harrison@gmail.com>
> Date: Wed, 22 Oct 2008 11:50:24 -0700
>
> > __raw_write avoids the need to byteswap twice, as we are reading from a
> > host-endian (big) area, just deref the pointers directly, taking care
> > of alignment.
> >
> > As before, outsw must still be called with a 2-byte aligned pointer.
> >
> > Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
>
> Applied, thanks Harvey.
Sorry, I had to revert this, it doesn't even build.
arch/sparc64/lib/PeeCeeI.c: In function ‘outsl’:
arch/sparc64/lib/PeeCeeI.c:57: error: expected expression before ‘u32’
arch/sparc64/lib/PeeCeeI.c:59: error: ‘l’ undeclared (first use in this function)
arch/sparc64/lib/PeeCeeI.c:59: error: (Each undeclared identifier is reported only once
arch/sparc64/lib/PeeCeeI.c:59: error: for each function it appears in.)
arch/sparc64/lib/PeeCeeI.c:63: error: ‘l2’ undeclared (first use in this function)
arch/sparc64/lib/PeeCeeI.c:72: error: expected expression before ‘u32’
make[1]: *** [arch/sparc64/lib/PeeCeeI.o] Error 1
ÿôèº{.nÇ+‰·Ÿ®‰†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¬¥ªÜ–)îÇø§¶\x17›¡Ü¨}©ž²Æ zÚ&j:+v‰¨þø\x1e¯ù\x1e®w¥þŠà2ŠÞ™¨èÚ&¢)ß¡«a¶Úÿÿûàz¿äz¹Þ—ú+ƒùšŽŠÝ¢jÿŠwèþ^[f
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] sparc64: remove byteshifting from out* helpers
2008-10-22 18:50 [PATCH] sparc64: remove byteshifting from out* helpers Harvey Harrison
2008-10-23 21:08 ` David Miller
2008-10-23 21:19 ` David Miller
@ 2008-10-24 3:48 ` Harvey Harrison
2008-10-29 22:33 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Harvey Harrison @ 2008-10-24 3:48 UTC (permalink / raw)
To: sparclinux
__raw_write avoids the need to byteswap, as we are reading from a
host-endian area, just deref the pointers directly, taking care
of alignment.
As before, outsw must be called with a 2-byte aligned pointer.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
---
Sorry about the build breakage, I did a last-minute move of the variable
declarations into the individual case statements where they were used. Should
have retested.
This is a build-tested version.
arch/sparc64/lib/PeeCeeI.c | 139 +++++++++++++++-----------------------------
1 files changed, 47 insertions(+), 92 deletions(-)
diff --git a/arch/sparc64/lib/PeeCeeI.c b/arch/sparc64/lib/PeeCeeI.c
index 8b313f1..46053e6 100644
--- a/arch/sparc64/lib/PeeCeeI.c
+++ b/arch/sparc64/lib/PeeCeeI.c
@@ -20,107 +20,62 @@ void outsw(unsigned long __addr, const void *src, unsigned long count)
{
void __iomem *addr = (void __iomem *) __addr;
- if (count) {
- u16 *ps = (u16 *)src;
- u32 *pi;
-
- if (((u64)src) & 0x2) {
- u16 val = le16_to_cpup(ps);
- outw(val, addr);
- ps++;
- count--;
- }
- pi = (u32 *)ps;
- while (count >= 2) {
- u32 w = le32_to_cpup(pi);
-
- pi++;
- outw(w >> 0, addr);
- outw(w >> 16, addr);
- count -= 2;
- }
- ps = (u16 *)pi;
- if (count) {
- u16 val = le16_to_cpup(ps);
- outw(val, addr);
- }
+ while (count--) {
+ __raw_writew(*(u16 *)src, addr);
+ src += sizeof(u16);
}
}
void outsl(unsigned long __addr, const void *src, unsigned long count)
{
void __iomem *addr = (void __iomem *) __addr;
+ u32 l, l2;
- if (count) {
- if ((((u64)src) & 0x3) = 0) {
- u32 *p = (u32 *)src;
- while (count--) {
- u32 val = cpu_to_le32p(p);
- outl(val, addr);
- p++;
- }
- } else {
- u8 *pb;
- u16 *ps = (u16 *)src;
- u32 l = 0, l2;
- u32 *pi;
-
- switch (((u64)src) & 0x3) {
- case 0x2:
- count -= 1;
- l = cpu_to_le16p(ps) << 16;
- ps++;
- pi = (u32 *)ps;
- while (count--) {
- l2 = cpu_to_le32p(pi);
- pi++;
- outl(((l >> 16) | (l2 << 16)), addr);
- l = l2;
- }
- ps = (u16 *)pi;
- l2 = cpu_to_le16p(ps);
- outl(((l >> 16) | (l2 << 16)), addr);
- break;
-
- case 0x1:
- count -= 1;
- pb = (u8 *)src;
- l = (*pb++ << 8);
- ps = (u16 *)pb;
- l2 = cpu_to_le16p(ps);
- ps++;
- l |= (l2 << 16);
- pi = (u32 *)ps;
- while (count--) {
- l2 = cpu_to_le32p(pi);
- pi++;
- outl(((l >> 8) | (l2 << 24)), addr);
- l = l2;
- }
- pb = (u8 *)pi;
- outl(((l >> 8) | (*pb << 24)), addr);
- break;
+ if (!count)
+ return;
- case 0x3:
- count -= 1;
- pb = (u8 *)src;
- l = (*pb++ << 24);
- pi = (u32 *)pb;
- while (count--) {
- l2 = cpu_to_le32p(pi);
- pi++;
- outl(((l >> 24) | (l2 << 8)), addr);
- l = l2;
- }
- ps = (u16 *)pi;
- l2 = cpu_to_le16p(ps);
- ps++;
- pb = (u8 *)ps;
- l2 |= (*pb << 16);
- outl(((l >> 24) | (l2 << 8)), addr);
- break;
- }
+ switch (((unsigned long)src) & 0x3) {
+ case 0x0:
+ /* src is naturally aligned */
+ while (count--) {
+ __raw_writel(*(u32 *)src, addr);
+ src += sizeof(u32);
+ }
+ break;
+ case 0x2:
+ /* 2-byte alignment */
+ while (count--) {
+ l = (*(u16 *)src) << 16;
+ l |= *(u16 *)(src + sizeof(u16));
+ __raw_writel(l, addr);
+ src += sizeof(u32);
+ }
+ break;
+ case 0x1:
+ /* Hold three bytes in l each time, grab a byte from l2 */
+ l = (*(u8 *)src) << 24;
+ l |= (*(u16 *)(src + sizeof(u8))) << 8;
+ src += sizeof(u8) + sizeof(u16);
+ while (count--) {
+ l2 = *(u32 *)src;
+ l |= (l2 >> 24);
+ __raw_writel(l, addr);
+ l = l2 << 8;
+ src += sizeof(u32);
+ }
+ break;
+ case 0x3:
+ /* Hold a byte in l each time, grab 3 bytes from l2 */
+ l = (*(u8 *)src) << 24;
+ src += sizeof(u8);
+ while (count--) {
+ l2 = *(u32 *)src;
+ l |= (l2 >> 8);
+ __raw_writel(l, addr);
+ l = l2 << 24;
+ src += sizeof(u32);
}
+ break;
}
}
--
1.6.0.3.723.g757e
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] sparc64: remove byteshifting from out* helpers
2008-10-22 18:50 [PATCH] sparc64: remove byteshifting from out* helpers Harvey Harrison
` (2 preceding siblings ...)
2008-10-24 3:48 ` Harvey Harrison
@ 2008-10-29 22:33 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2008-10-29 22:33 UTC (permalink / raw)
To: sparclinux
From: Harvey Harrison <harvey.harrison@gmail.com>
Date: Thu, 23 Oct 2008 20:48:59 -0700
> __raw_write avoids the need to byteswap, as we are reading from a
> host-endian area, just deref the pointers directly, taking care
> of alignment.
>
> As before, outsw must be called with a 2-byte aligned pointer.
>
> Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Applied, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-10-29 22:33 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-22 18:50 [PATCH] sparc64: remove byteshifting from out* helpers Harvey Harrison
2008-10-23 21:08 ` David Miller
2008-10-23 21:19 ` David Miller
2008-10-24 3:48 ` Harvey Harrison
2008-10-29 22:33 ` David Miller
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.