* [PATCH] Inline ioremap() magic for 32-bit constant addresses
@ 2005-06-29 10:55 Maciej W. Rozycki
2005-06-29 13:14 ` Ralf Baechle
0 siblings, 1 reply; 3+ messages in thread
From: Maciej W. Rozycki @ 2005-06-29 10:55 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Ralf,
I'd like to get rid of CKSEG1ADDR() wherever possible from code I am
looking after as the macro is unportable and has already proven to cause
maintenance hassle. I don't want to get rid of its advantages though, so
here's an update for ioremap() that makes it be expanded inline when
constant arguments are used and the resulting mapping fits in KSEG1.
Likewise for iounmap().
Apparently the generic version is used for all platforms but the Au1000.
I have only implemented the bare minimum required for the platform to keep
working. The platform seems to be maintained though, so I'm leaving the
decision as to whether to inline the platform-specific variation or not up
to the maintainer.
OK to apply?
Maciej
patch-mips-2.6.12-rc4-20050526-ioremap-constant-1
diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/arch/mips/au1000/common/setup.c linux-mips-2.6.12-rc4-20050526/arch/mips/au1000/common/setup.c
--- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/au1000/common/setup.c 2005-04-04 04:56:03.000000000 +0000
+++ linux-mips-2.6.12-rc4-20050526/arch/mips/au1000/common/setup.c 2005-06-25 23:45:43.000000000 +0000
@@ -159,7 +159,7 @@ early_initcall(au1x00_setup);
#if defined(CONFIG_64BIT_PHYS_ADDR)
/* This routine should be valid for all Au1x based boards */
-phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
{
u32 start, end;
diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/ioremap.c linux-mips-2.6.12-rc4-20050526/arch/mips/mm/ioremap.c
--- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/ioremap.c 2005-02-11 05:56:05.000000000 +0000
+++ linux-mips-2.6.12-rc4-20050526/arch/mips/mm/ioremap.c 2005-06-26 00:00:51.000000000 +0000
@@ -102,15 +102,6 @@ static int remap_area_pages(unsigned lon
}
/*
- * Allow physical addresses to be fixed up to help 36 bit peripherals.
- */
-phys_t __attribute__ ((weak))
-fixup_bigphys_addr(phys_t phys_addr, phys_t size)
-{
- return phys_addr;
-}
-
-/*
* Generic mapping function (not visible outside):
*/
diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/io.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/io.h
--- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/io.h 2005-04-19 04:57:17.000000000 +0000
+++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/io.h 2005-06-26 00:27:00.000000000 +0000
@@ -26,6 +26,7 @@
#include <asm/pgtable-bits.h>
#include <asm/processor.h>
+#include <ioremap.h>
#include <mangle-port.h>
/*
@@ -208,6 +209,8 @@ extern void __iounmap(volatile void __io
static inline void * __ioremap_mode(phys_t offset, unsigned long size,
unsigned long flags)
{
+#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+
if (cpu_has_64bit_addresses) {
u64 base = UNCAC_BASE;
@@ -218,9 +221,30 @@ static inline void * __ioremap_mode(phys
if (flags == _CACHE_UNCACHED)
base = (u64) IO_BASE;
return (void *) (unsigned long) (base + offset);
+ } else if (__builtin_constant_p(offset) &&
+ __builtin_constant_p(size) && __builtin_constant_p(flags)) {
+ phys_t phys_addr, last_addr;
+
+ phys_addr = fixup_bigphys_addr(offset, size);
+
+ /* Don't allow wraparound or zero size. */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ /*
+ * Map uncached objects in the low 512MB of address
+ * space using KSEG1.
+ */
+ if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
+ flags == _CACHE_UNCACHED)
+ return (void *)CKSEG1ADDR(phys_addr);
+
}
return __ioremap(offset, size, flags);
+
+#undef __IS_LOW512
}
/*
@@ -272,12 +296,16 @@ static inline void * __ioremap_mode(phys
static inline void iounmap(volatile void __iomem *addr)
{
- if (cpu_has_64bit_addresses)
+#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+
+ if (cpu_has_64bit_addresses ||
+ (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
return;
__iounmap(addr);
-}
+#undef __IS_KSEG1
+}
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
\
diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-au1x00/ioremap.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-au1x00/ioremap.h
--- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-au1x00/ioremap.h 1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-au1x00/ioremap.h 2005-06-26 00:16:26.000000000 +0000
@@ -0,0 +1,29 @@
+/*
+ * include/asm-mips/mach-au1x00/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_AU1X00_IOREMAP_H
+#define __ASM_MACH_AU1X00_IOREMAP_H
+
+#include <linux/types.h>
+
+#ifndef CONFIG_64BIT_PHYS_ADDR
+static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+#endif
+
+/*
+ * Allow physical addresses to be fixed up to help 36-bit peripherals.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return __fixup_bigphys_addr(phys_addr, size);
+}
+
+#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-generic/ioremap.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-generic/ioremap.h
--- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-generic/ioremap.h 1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-generic/ioremap.h 2005-06-26 00:05:42.000000000 +0000
@@ -0,0 +1,23 @@
+/*
+ * include/asm-mips/mach-generic/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_GENERIC_IOREMAP_H
+#define __ASM_MACH_GENERIC_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Inline ioremap() magic for 32-bit constant addresses
2005-06-29 10:55 [PATCH] Inline ioremap() magic for 32-bit constant addresses Maciej W. Rozycki
@ 2005-06-29 13:14 ` Ralf Baechle
2005-06-29 17:07 ` Maciej W. Rozycki
0 siblings, 1 reply; 3+ messages in thread
From: Ralf Baechle @ 2005-06-29 13:14 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Wed, Jun 29, 2005 at 11:55:55AM +0100, Maciej W. Rozycki wrote:
> I'd like to get rid of CKSEG1ADDR() wherever possible from code I am
> looking after as the macro is unportable and has already proven to cause
> maintenance hassle. I don't want to get rid of its advantages though, so
> here's an update for ioremap() that makes it be expanded inline when
> constant arguments are used and the resulting mapping fits in KSEG1.
> Likewise for iounmap().
I don't think I'd complain about taking the whole thing out off line. Last
I checked we had no driver that did substancially benefit from being
initialized a few nanoseconds faster.
> Apparently the generic version is used for all platforms but the Au1000.
> I have only implemented the bare minimum required for the platform to keep
> working. The platform seems to be maintained though, so I'm leaving the
> decision as to whether to inline the platform-specific variation or not up
> to the maintainer.
So I guess your patch leaves getting rid of that indirection of
fixup_bigphys_addr calling into __fixup_bigphys_addr to Pete :-)
> OK to apply?
Fee free.
Ralf
> patch-mips-2.6.12-rc4-20050526-ioremap-constant-1
> diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/arch/mips/au1000/common/setup.c linux-mips-2.6.12-rc4-20050526/arch/mips/au1000/common/setup.c
> --- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/au1000/common/setup.c 2005-04-04 04:56:03.000000000 +0000
> +++ linux-mips-2.6.12-rc4-20050526/arch/mips/au1000/common/setup.c 2005-06-25 23:45:43.000000000 +0000
> @@ -159,7 +159,7 @@ early_initcall(au1x00_setup);
>
> #if defined(CONFIG_64BIT_PHYS_ADDR)
> /* This routine should be valid for all Au1x based boards */
> -phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
> +phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
> {
> u32 start, end;
>
> diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/ioremap.c linux-mips-2.6.12-rc4-20050526/arch/mips/mm/ioremap.c
> --- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/ioremap.c 2005-02-11 05:56:05.000000000 +0000
> +++ linux-mips-2.6.12-rc4-20050526/arch/mips/mm/ioremap.c 2005-06-26 00:00:51.000000000 +0000
> @@ -102,15 +102,6 @@ static int remap_area_pages(unsigned lon
> }
>
> /*
> - * Allow physical addresses to be fixed up to help 36 bit peripherals.
> - */
> -phys_t __attribute__ ((weak))
> -fixup_bigphys_addr(phys_t phys_addr, phys_t size)
> -{
> - return phys_addr;
> -}
> -
> -/*
> * Generic mapping function (not visible outside):
> */
>
> diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/io.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/io.h
> --- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/io.h 2005-04-19 04:57:17.000000000 +0000
> +++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/io.h 2005-06-26 00:27:00.000000000 +0000
> @@ -26,6 +26,7 @@
> #include <asm/pgtable-bits.h>
> #include <asm/processor.h>
>
> +#include <ioremap.h>
> #include <mangle-port.h>
>
> /*
> @@ -208,6 +209,8 @@ extern void __iounmap(volatile void __io
> static inline void * __ioremap_mode(phys_t offset, unsigned long size,
> unsigned long flags)
> {
> +#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
> +
> if (cpu_has_64bit_addresses) {
> u64 base = UNCAC_BASE;
>
> @@ -218,9 +221,30 @@ static inline void * __ioremap_mode(phys
> if (flags == _CACHE_UNCACHED)
> base = (u64) IO_BASE;
> return (void *) (unsigned long) (base + offset);
> + } else if (__builtin_constant_p(offset) &&
> + __builtin_constant_p(size) && __builtin_constant_p(flags)) {
> + phys_t phys_addr, last_addr;
> +
> + phys_addr = fixup_bigphys_addr(offset, size);
> +
> + /* Don't allow wraparound or zero size. */
> + last_addr = phys_addr + size - 1;
> + if (!size || last_addr < phys_addr)
> + return NULL;
> +
> + /*
> + * Map uncached objects in the low 512MB of address
> + * space using KSEG1.
> + */
> + if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
> + flags == _CACHE_UNCACHED)
> + return (void *)CKSEG1ADDR(phys_addr);
> +
> }
>
> return __ioremap(offset, size, flags);
> +
> +#undef __IS_LOW512
> }
>
> /*
> @@ -272,12 +296,16 @@ static inline void * __ioremap_mode(phys
>
> static inline void iounmap(volatile void __iomem *addr)
> {
> - if (cpu_has_64bit_addresses)
> +#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
> +
> + if (cpu_has_64bit_addresses ||
> + (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
> return;
>
> __iounmap(addr);
> -}
>
> +#undef __IS_KSEG1
> +}
>
> #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
> \
> diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-au1x00/ioremap.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-au1x00/ioremap.h
> --- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-au1x00/ioremap.h 1970-01-01 00:00:00.000000000 +0000
> +++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-au1x00/ioremap.h 2005-06-26 00:16:26.000000000 +0000
> @@ -0,0 +1,29 @@
> +/*
> + * include/asm-mips/mach-au1x00/ioremap.h
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +#ifndef __ASM_MACH_AU1X00_IOREMAP_H
> +#define __ASM_MACH_AU1X00_IOREMAP_H
> +
> +#include <linux/types.h>
> +
> +#ifndef CONFIG_64BIT_PHYS_ADDR
> +static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
> +{
> + return phys_addr;
> +}
> +#endif
> +
> +/*
> + * Allow physical addresses to be fixed up to help 36-bit peripherals.
> + */
> +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
> +{
> + return __fixup_bigphys_addr(phys_addr, size);
> +}
> +
> +#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
> diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-generic/ioremap.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-generic/ioremap.h
> --- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-generic/ioremap.h 1970-01-01 00:00:00.000000000 +0000
> +++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-generic/ioremap.h 2005-06-26 00:05:42.000000000 +0000
> @@ -0,0 +1,23 @@
> +/*
> + * include/asm-mips/mach-generic/ioremap.h
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +#ifndef __ASM_MACH_GENERIC_IOREMAP_H
> +#define __ASM_MACH_GENERIC_IOREMAP_H
> +
> +#include <linux/types.h>
> +
> +/*
> + * Allow physical addresses to be fixed up to help peripherals located
> + * outside the low 32-bit range -- generic pass-through version.
> + */
> +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
> +{
> + return phys_addr;
> +}
> +
> +#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Inline ioremap() magic for 32-bit constant addresses
2005-06-29 13:14 ` Ralf Baechle
@ 2005-06-29 17:07 ` Maciej W. Rozycki
0 siblings, 0 replies; 3+ messages in thread
From: Maciej W. Rozycki @ 2005-06-29 17:07 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
On Wed, 29 Jun 2005, Ralf Baechle wrote:
> > I'd like to get rid of CKSEG1ADDR() wherever possible from code I am
> > looking after as the macro is unportable and has already proven to cause
> > maintenance hassle. I don't want to get rid of its advantages though, so
> > here's an update for ioremap() that makes it be expanded inline when
> > constant arguments are used and the resulting mapping fits in KSEG1.
> > Likewise for iounmap().
>
> I don't think I'd complain about taking the whole thing out off line. Last
> I checked we had no driver that did substancially benefit from being
> initialized a few nanoseconds faster.
I haven't checked it yet, but it may be possible for my updates to add
calls to ioremap() from interrupt handlers, which may not necessarily be
so neutral to performance if calculations are done out of line. With this
inline implementation ioremap() expands to at most two instructions for
qualifying calls and iounmap() expands to nothing. With an out of line
version not only the address calculations are done at the run time, but
you need to add an overhead of two function calls.
I like the MIPS64 version best, though. ;-)
> > Apparently the generic version is used for all platforms but the Au1000.
> > I have only implemented the bare minimum required for the platform to keep
> > working. The platform seems to be maintained though, so I'm leaving the
> > decision as to whether to inline the platform-specific variation or not up
> > to the maintainer.
>
> So I guess your patch leaves getting rid of that indirection of
> fixup_bigphys_addr calling into __fixup_bigphys_addr to Pete :-)
Yes, formally. Technically, I can probably get convinced to do the dirty
cut & paste work if asked to appropriately. ;-)
Maciej
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-06-29 17:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-29 10:55 [PATCH] Inline ioremap() magic for 32-bit constant addresses Maciej W. Rozycki
2005-06-29 13:14 ` Ralf Baechle
2005-06-29 17:07 ` Maciej W. Rozycki
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.