Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bd46782 authored by Russell King's avatar Russell King
Browse files

ARM: avoid unwanted GCC memset()/memcpy() optimisations for IO variants



We don't want GCC optimising our memset_io(), memcpy_fromio() or
memcpy_toio() variants, so we must not call one of the standard
functions.  Provide a separate name for our assembly memcpy() and
memset() functions, and use that instead, thereby bypassing GCC's
ability to optimise these operations.

GCCs optimisation may introduce unaligned accesses which are invalid
for device mappings.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9ab79bb2
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -316,21 +316,24 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
static inline void memset_io(volatile void __iomem *dst, unsigned c,
static inline void memset_io(volatile void __iomem *dst, unsigned c,
	size_t count)
	size_t count)
{
{
	memset((void __force *)dst, c, count);
	extern void mmioset(void *, unsigned int, size_t);
	mmioset((void __force *)dst, c, count);
}
}
#define memset_io(dst,c,count) memset_io(dst,c,count)
#define memset_io(dst,c,count) memset_io(dst,c,count)


static inline void memcpy_fromio(void *to, const volatile void __iomem *from,
static inline void memcpy_fromio(void *to, const volatile void __iomem *from,
	size_t count)
	size_t count)
{
{
	memcpy(to, (const void __force *)from, count);
	extern void mmiocpy(void *, const void *, size_t);
	mmiocpy(to, (const void __force *)from, count);
}
}
#define memcpy_fromio(to,from,count) memcpy_fromio(to,from,count)
#define memcpy_fromio(to,from,count) memcpy_fromio(to,from,count)


static inline void memcpy_toio(volatile void __iomem *to, const void *from,
static inline void memcpy_toio(volatile void __iomem *to, const void *from,
	size_t count)
	size_t count)
{
{
	memcpy((void __force *)to, from, count);
	extern void mmiocpy(void *, const void *, size_t);
	mmiocpy((void __force *)to, from, count);
}
}
#define memcpy_toio(to,from,count) memcpy_toio(to,from,count)
#define memcpy_toio(to,from,count) memcpy_toio(to,from,count)


+6 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,9 @@ extern void __aeabi_ulcmp(void);


extern void fpundefinstr(void);
extern void fpundefinstr(void);


void mmioset(void *, unsigned int, size_t);
void mmiocpy(void *, const void *, size_t);

	/* platform dependent support */
	/* platform dependent support */
EXPORT_SYMBOL(arm_delay_ops);
EXPORT_SYMBOL(arm_delay_ops);


@@ -88,6 +91,9 @@ EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(memchr);
EXPORT_SYMBOL(memchr);
EXPORT_SYMBOL(__memzero);
EXPORT_SYMBOL(__memzero);


EXPORT_SYMBOL(mmioset);
EXPORT_SYMBOL(mmiocpy);

#ifdef CONFIG_MMU
#ifdef CONFIG_MMU
EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(copy_page);


+2 −0
Original line number Original line Diff line number Diff line
@@ -61,8 +61,10 @@


/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */


ENTRY(mmiocpy)
ENTRY(memcpy)
ENTRY(memcpy)


#include "copy_template.S"
#include "copy_template.S"


ENDPROC(memcpy)
ENDPROC(memcpy)
ENDPROC(mmiocpy)
+2 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@
	.text
	.text
	.align	5
	.align	5


ENTRY(mmioset)
ENTRY(memset)
ENTRY(memset)
UNWIND( .fnstart         )
UNWIND( .fnstart         )
	ands	r3, r0, #3		@ 1 unaligned?
	ands	r3, r0, #3		@ 1 unaligned?
@@ -133,3 +134,4 @@ UNWIND( .fnstart )
	b	1b
	b	1b
UNWIND( .fnend   )
UNWIND( .fnend   )
ENDPROC(memset)
ENDPROC(memset)
ENDPROC(mmioset)