diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index f41b38c..80a2219 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -9,6 +9,7 @@
extern unsigned long free_mem_ptr;
extern unsigned long free_mem_end_ptr;
extern void error(char *);
+extern int memcmp(const void *, const void *, size_t);
#define STATIC static
#define STATIC_RW_DATA /* non-static please */
@@ -45,8 +46,6 @@ extern void error(char *);
#endif
#ifdef CONFIG_KERNEL_XZ
-#define memmove memmove
-#define memcpy memcpy
#include "../../../../lib/decompress_unxz.c"
#endif
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c
index 36e53ef..269258d 100644
--- a/arch/arm/boot/compressed/string.c
+++ b/arch/arm/boot/compressed/string.c
@@ -6,6 +6,7 @@
#include <linux/string.h>
+#define __HAVE_PREBOOT_ARCH_MEMCPY
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i = 0;@@ -40,22 +41,6 @@ void *memcpy(void *__dest, __const void *__src, size_t __n)
return __dest;
}
-void *memmove(void *__dest, __const void *__src, size_t count)
-{
- unsigned char *d = __dest;
- const unsigned char *s = __src;
-
- if (__dest = __src)
- return __dest;
-
- if (__dest < __src)
- return memcpy(__dest, __src, count);
-
- while (count--)
- d[count] = s[count];
- return __dest;
-}
-
size_t strlen(const char *s)
{
const char *sc = s;@@ -65,19 +50,6 @@ size_t strlen(const char *s)
return sc - s;
}
-int memcmp(const void *cs, const void *ct, size_t count)
-{
- const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
- int res = 0;
-
- while (su1 < end) {
- res = *su1++ - *su2++;
- if (res)
- break;
- }
- return res;
-}
-
int strcmp(const char *cs, const char *ct)
{
unsigned char c1, c2;@@ -113,15 +85,10 @@ char *strchr(const char *s, int c)
#undef memset
-void *memset(void *s, int c, size_t count)
-{
- char *xs = s;
- while (count--)
- *xs++ = c;
- return s;
-}
-
void __memzero(void *s, size_t count)
{
memset(s, 0, count);
}
+
+#include "../../../../lib/boot/mem.c"
+diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
index 465eca7..7169232 100644
--- a/arch/s390/boot/compressed/misc.c
+++ b/arch/s390/boot/compressed/misc.c
@@ -67,6 +67,8 @@ static int puts(const char *s)
return 0;
}
+#define __HAVE_PREBOOT_ARCH_MEMSET
+
void *memset(void *s, int c, size_t n)
{
char *xs;@@ -82,25 +84,6 @@ void *memset(void *s, int c, size_t n)
return s;
}
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
- return __builtin_memcpy(__dest, __src, __n);
-}
-
-void *memmove(void *__dest, __const void *__src, size_t __n)
-{
- char *d;
- const char *s;
-
- if (__dest <= __src)
- return __builtin_memcpy(__dest, __src, __n);
- d = __dest + __n;
- s = __src + __n;
- while (__n--)
- *--d = *--s;
- return __dest;
-}
-
static void error(char *x)
{
unsigned long long psw = 0x000a0000deadbeefULL;@@ -166,3 +149,5 @@ unsigned long decompress_kernel(void)
return (unsigned long) output;
}
+#include "../../../../lib/boot/mem.c"
+
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
index 95470a4..b1dde68 100644
--- a/arch/sh/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc.c
@@ -75,14 +75,7 @@ int puts(const char *s)
return 0;
}
-void* memset(void* s, int c, size_t n)
-{
- int i;
- char *ss = (char*)s;
-
- for (i=0;i<n;i++) ss[i] = c;
- return s;
-}
+#define __HAVE_PREBOOT_ARCH_MEMCPY
void* memcpy(void* __dest, __const void* __src,
size_t __n)@@ -136,3 +129,5 @@ void decompress_kernel(void)
cache_control(CACHE_DISABLE);
puts("Ok, booting the kernel.\n");
}
+
+#include "../../../../lib/boot/mem.c"diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 7116dcb..ac07fbb 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -224,45 +224,6 @@ void __putstr(int error, const char *s)
outb(0xff & (pos >> 1), vidport+1);
}
-void *memset(void *s, int c, size_t n)
-{
- int i;
- char *ss = s;
-
- for (i = 0; i < n; i++)
- ss[i] = c;
- return s;
-}
-#ifdef CONFIG_X86_32
-void *memcpy(void *dest, const void *src, size_t n)
-{
- int d0, d1, d2;
- asm volatile(
- "rep ; movsl\n\t"
- "movl %4,%%ecx\n\t"
- "rep ; movsb\n\t"
- : "=&c" (d0), "=&D" (d1), "=&S" (d2)
- : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
- : "memory");
-
- return dest;
-}
-#else
-void *memcpy(void *dest, const void *src, size_t n)
-{
- long d0, d1, d2;
- asm volatile(
- "rep ; movsq\n\t"
- "movq %4,%%rcx\n\t"
- "rep ; movsb\n\t"
- : "=&c" (d0), "=&D" (d1), "=&S" (d2)
- : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
- : "memory");
-
- return dest;
-}
-#endif
-
static void error(char *x)
{
__putstr(1, "\n\n");diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c
index ffb9c5c..d6b8784 100644
--- a/arch/x86/boot/compressed/string.c
+++ b/arch/x86/boot/compressed/string.c
@@ -1,5 +1,7 @@
#include "misc.h"
+#define __HAVE_PREBOOT_ARCH_MEMCMP
+
int memcmp(const void *s1, const void *s2, size_t len)
{
u8 diff;@@ -8,4 +10,37 @@ int memcmp(const void *s1, const void *s2, size_t len)
return diff;
}
+#define __HAVE_PREBOOT_ARCH_MEMCPY
+
+#ifdef CONFIG_X86_32
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ int d0, d1, d2;
+ asm volatile(
+ "rep ; movsl\n\t"
+ "movl %4,%%ecx\n\t"
+ "rep ; movsb\n\t"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
+ : "memory");
+
+ return dest;
+}
+#else
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ long d0, d1, d2;
+ asm volatile(
+ "rep ; movsq\n\t"
+ "movq %4,%%rcx\n\t"
+ "rep ; movsb\n\t"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
+ : "memory");
+
+ return dest;
+}
+#endif
+
+#include "../../../../lib/boot/mem.c"
#include "../string.c"diff --git a/lib/boot/mem.c b/lib/boot/mem.c
new file mode 100644
index 0000000..a27381f
--- /dev/null
+++ b/lib/boot/mem.c
@@ -0,0 +1,58 @@
+/*
+ * Small subset of simple memory helper functions required by different
+ * compressors for preboot environment.
+ */
+
+#include <linux/string.h>
+
+#ifndef __HAVE_PREBOOT_ARCH_MEMCPY
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+ return __builtin_memcpy(__dest, __src, __n);
+}
+#endif
+
+#ifndef __HAVE_PREBOOT_ARCH_MEMMOVE
+void *memmove(void *__dest, __const void *__src, size_t count)
+{
+ unsigned char *d = __dest;
+ const unsigned char *s = __src;
+
+ if (__dest = __src)
+ return __dest;
+
+ if (__dest < __src)
+ return memcpy(__dest, __src, count);
+
+ while (count--)
+ d[count] = s[count];
+ return __dest;
+}
+#endif
+
+#ifndef __HAVE_PREBOOT_ARCH_MEMCMP
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+ const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
+ int res = 0;
+
+ while (su1 < end) {
+ res = *su1++ - *su2++;
+ if (res)
+ break;
+ }
+ return res;
+}
+#endif
+
+#ifndef __HAVE_PREBOOT_ARCH_MEMSET
+void *memset(void *s, int c, size_t count)
+{
+ char *xs = s;
+
+ while (count--)
+ *xs++ = c;
+ return s;
+}
+#endif
+diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
index 9f34eb5..97c9fb5 100644
--- a/lib/decompress_unxz.c
+++ b/lib/decompress_unxz.c
@@ -160,76 +160,10 @@
#define vfree(ptr) do { if (ptr != NULL) free(ptr); } while (0)
/*
- * FIXME: Not all basic memory functions are provided in architecture-specific
- * files (yet). We define our own versions here for now, but this should be
- * only a temporary solution.
- *
- * memeq and memzero are not used much and any remotely sane implementation
- * is fast enough. memcpy/memmove speed matters in multi-call mode, but
- * the kernel image is decompressed in single-call mode, in which only
- * memcpy speed can matter and only if there is a lot of uncompressible data
- * (LZMA2 stores uncompressible chunks in uncompressed form). Thus, the
- * functions below should just be kept small; it's probably not worth
- * optimizing for speed.
+ * To support XZ-decompressed file in preboot environment, include the file
+ * lib/boot/mem.c, to bring in all the required memory helper functions.
*/
-#ifndef memeq
-static bool memeq(const void *a, const void *b, size_t size)
-{
- const uint8_t *x = a;
- const uint8_t *y = b;
- size_t i;
-
- for (i = 0; i < size; ++i)
- if (x[i] != y[i])
- return false;
-
- return true;
-}
-#endif
-
-#ifndef memzero
-static void memzero(void *buf, size_t size)
-{
- uint8_t *b = buf;
- uint8_t *e = b + size;
-
- while (b != e)
- *b++ = '\0';
-}
-#endif
-
-#ifndef memmove
-/* Not static to avoid a conflict with the prototype in the Linux headers. */
-void *memmove(void *dest, const void *src, size_t size)
-{
- uint8_t *d = dest;
- const uint8_t *s = src;
- size_t i;
-
- if (d < s) {
- for (i = 0; i < size; ++i)
- d[i] = s[i];
- } else if (d > s) {
- i = size;
- while (i-- > 0)
- d[i] = s[i];
- }
-
- return dest;
-}
-#endif
-
-/*
- * Since we need memmove anyway, would use it as memcpy too.
- * Commented out for now to avoid breaking things.
- */
-/*
-#ifndef memcpy
-# define memcpy memmove
-#endif
-*/
-
#include "xz/xz_crc32.c"
#include "xz/xz_dec_stream.c"
#include "xz/xz_dec_lzma2.c"diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h
index 482b90f..a997dca 100644
--- a/lib/xz/xz_private.h
+++ b/lib/xz/xz_private.h
@@ -37,9 +37,12 @@
# ifdef CONFIG_XZ_DEC_SPARC
# define XZ_DEC_SPARC
# endif
-# define memeq(a, b, size) (memcmp(a, b, size) = 0)
-# define memzero(buf, size) memset(buf, 0, size)
# endif
+ /* Make all environments, including preboot, use memcmp for memeq */
+# define memeq(a, b, size) (memcmp(a, b, size) = 0)
+ /* To suppress redefine warning in some architecture's preboot */
+# undef memzero
+# define memzero(buf, size) memset(buf, 0, size)
# define get_le32(p) le32_to_cpup((const uint32_t *)(p))
#else
/*
--
1.7.1