From aad830938ed8ba175d8060751654f78d4115ea0a Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 18 Mar 2014 15:26:36 -0400 Subject: x86, boot: Undef memcmp before providing a new definition With CONFIG_X86_32=y, string_32.h gets pulled in compressed/string.c by "misch.h". string_32.h defines a macro to map memcmp to __builtin_memcmp(). And that macro in turn changes the name of memcmp() defined here and converts it to __builtin_memcmp(). I thought that's not the intention though. We probably want to provide our own optimized definition of memcmp(). If yes, then undef the memcmp before we define a new memcmp. Signed-off-by: Vivek Goyal Link: http://lkml.kernel.org/r/1395170800-11059-2-git-send-email-vgoyal@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/string.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/boot') diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c index ffb9c5c9d74..212004ec787 100644 --- a/arch/x86/boot/compressed/string.c +++ b/arch/x86/boot/compressed/string.c @@ -1,5 +1,7 @@ #include "misc.h" +/* Avoid intereference from any defines in string_32.h */ +#undef memcmp int memcmp(const void *s1, const void *s2, size_t len) { u8 diff; -- cgit v1.2.3-70-g09d2 From c041b5ad8640dd89ccf1411cd2636ef7c1cfee92 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 18 Mar 2014 15:26:37 -0400 Subject: x86, boot: Create a separate string.h file to provide standard string functions Create a separate arch/x86/boot/string.h file to provide declaration of some of the common string functions. By default memcpy, memset and memcmp functions will default to gcc builtin functions. If code wants to use an optimized version of any of these functions, they need to #undef the respective macro and link against a local file providing definition of undefed function. For example, arch/x86/boot/* code links against copy.S to get memcpy() and memcmp() definitions. arch/86/boot/compressed/* links against compressed/string.c. There are quite a few places in arch/x86/ where these functions are used. Idea is to try to consilidate their declaration and possibly definitions so that it can be reused. I am planning to reuse boot/string.h in arch/x86/purgatory/ and use gcc builtin functions for memcpy, memset and memcmp. Signed-off-by: Vivek Goyal Link: http://lkml.kernel.org/r/1395170800-11059-3-git-send-email-vgoyal@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/boot/boot.h | 5 ----- arch/x86/boot/cpucheck.c | 1 + arch/x86/boot/edd.c | 1 + arch/x86/boot/main.c | 1 + arch/x86/boot/regs.c | 1 + arch/x86/boot/string.h | 19 +++++++++++++++++++ arch/x86/boot/video-vesa.c | 1 + 7 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 arch/x86/boot/string.h (limited to 'arch/x86/boot') diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 50f8c5e0f37..bed9665cc7e 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -228,11 +228,6 @@ void copy_to_fs(addr_t dst, void *src, size_t len); void *copy_from_fs(void *dst, addr_t src, size_t len); void copy_to_gs(addr_t dst, void *src, size_t len); void *copy_from_gs(void *dst, addr_t src, size_t len); -void *memcpy(void *dst, void *src, size_t len); -void *memset(void *dst, int c, size_t len); - -#define memcpy(d,s,l) __builtin_memcpy(d,s,l) -#define memset(d,c,l) __builtin_memset(d,c,l) /* a20.c */ int enable_a20(void); diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c index 100a9a10076..086c4f4ff74 100644 --- a/arch/x86/boot/cpucheck.c +++ b/arch/x86/boot/cpucheck.c @@ -27,6 +27,7 @@ #include #include #include +#include "string.h" static u32 err_flags[NCAPINTS]; diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c index c501a5b466f..223e4252707 100644 --- a/arch/x86/boot/edd.c +++ b/arch/x86/boot/edd.c @@ -15,6 +15,7 @@ #include "boot.h" #include +#include "string.h" #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c index cf6083d444f..fd6c9f23699 100644 --- a/arch/x86/boot/main.c +++ b/arch/x86/boot/main.c @@ -14,6 +14,7 @@ */ #include "boot.h" +#include "string.h" struct boot_params boot_params __attribute__((aligned(16))); diff --git a/arch/x86/boot/regs.c b/arch/x86/boot/regs.c index 958019b1cfa..c0fb356a309 100644 --- a/arch/x86/boot/regs.c +++ b/arch/x86/boot/regs.c @@ -17,6 +17,7 @@ */ #include "boot.h" +#include "string.h" void initregs(struct biosregs *reg) { diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h new file mode 100644 index 00000000000..10939d8da2e --- /dev/null +++ b/arch/x86/boot/string.h @@ -0,0 +1,19 @@ +#ifndef BOOT_STRING_H +#define BOOT_STRING_H + +/* Undef any of these macros coming from string_32.h. */ +#undef memcpy +#undef memset +#undef memcmp + +void *memcpy(void *dst, const void *src, size_t len); +void *memset(void *dst, int c, size_t len); + +/* + * Access builtin version by default. If one needs to use optimized version, + * do "undef memcpy" in .c file and link against right string.c + */ +#define memcpy(d,s,l) __builtin_memcpy(d,s,l) +#define memset(d,c,l) __builtin_memset(d,c,l) + +#endif /* BOOT_STRING_H */ diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 11e8c6eb80a..ba3e100654d 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c @@ -16,6 +16,7 @@ #include "boot.h" #include "video.h" #include "vesa.h" +#include "string.h" /* VESA information */ static struct vesa_general_info vginfo; -- cgit v1.2.3-70-g09d2 From 820e8feca06ff744f60e5036c3178dde40b91afc Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 18 Mar 2014 15:26:38 -0400 Subject: x86, boot: Move optimized memcpy() 32/64 bit versions to compressed/string.c Move optimized versions of memcpy to compressed/string.c This will allow any other code to use these functions too if need be in future. Again trying to put definition in a common place instead of hiding it in misc.c Signed-off-by: Vivek Goyal Link: http://lkml.kernel.org/r/1395170800-11059-4-git-send-email-vgoyal@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/misc.c | 31 +------------------------------ arch/x86/boot/compressed/string.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 30 deletions(-) (limited to 'arch/x86/boot') diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 196eaf373a0..3100092b134 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -10,6 +10,7 @@ */ #include "misc.h" +#include "../string.h" /* WARNING!! * This code is compiled with -fPIC and it is relocated dynamically @@ -110,7 +111,6 @@ static void error(char *m); struct boot_params *real_mode; /* Pointer to real-mode data */ void *memset(void *s, int c, size_t n); -void *memcpy(void *dest, const void *src, size_t n); memptr free_mem_ptr; memptr free_mem_end_ptr; @@ -225,35 +225,6 @@ void *memset(void *s, int c, size_t n) 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) { diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c index 212004ec787..3b5a82fc6ad 100644 --- a/arch/x86/boot/compressed/string.c +++ b/arch/x86/boot/compressed/string.c @@ -11,3 +11,36 @@ int memcmp(const void *s1, const void *s2, size_t len) } #include "../string.c" + +/* misc.h might pull in string_32.h which has a macro for memcpy. undef that */ +#undef 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 -- cgit v1.2.3-70-g09d2 From fb4cac573ef6dce8d7543b68306566561c2e5725 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 18 Mar 2014 15:26:39 -0400 Subject: x86, boot: Move memcmp() into string.h and string.c Try to treat memcmp() in same way as memcpy() and memset(). Provide a declaration in boot/string.h and by default user gets a memcmp() which maps to builtin function. Move optimized definition of memcmp() in boot/string.c. Now a user can do #undef memcmp and link against string.c to use optimzied memcmp(). It also simplifies boot/compressed/string.c where we had to redefine memcmp(). That extra definition is gone now. Signed-off-by: Vivek Goyal Link: http://lkml.kernel.org/r/1395170800-11059-5-git-send-email-vgoyal@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/boot/boot.h | 8 -------- arch/x86/boot/compressed/string.c | 11 ----------- arch/x86/boot/string.c | 14 ++++++++++++++ arch/x86/boot/string.h | 2 ++ 4 files changed, 16 insertions(+), 19 deletions(-) (limited to 'arch/x86/boot') diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index bed9665cc7e..bd49ec61255 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -177,14 +177,6 @@ static inline void wrgs32(u32 v, addr_t addr) } /* Note: these only return true/false, not a signed return value! */ -static inline int memcmp(const void *s1, const void *s2, size_t len) -{ - u8 diff; - asm("repe; cmpsb; setnz %0" - : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); - return diff; -} - static inline int memcmp_fs(const void *s1, addr_t s2, size_t len) { u8 diff; diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c index 3b5a82fc6ad..920b55e3e24 100644 --- a/arch/x86/boot/compressed/string.c +++ b/arch/x86/boot/compressed/string.c @@ -1,15 +1,4 @@ #include "misc.h" - -/* Avoid intereference from any defines in string_32.h */ -#undef memcmp -int memcmp(const void *s1, const void *s2, size_t len) -{ - u8 diff; - asm("repe; cmpsb; setnz %0" - : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); - return diff; -} - #include "../string.c" /* misc.h might pull in string_32.h which has a macro for memcpy. undef that */ diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c index 574dedfe289..5339040ef86 100644 --- a/arch/x86/boot/string.c +++ b/arch/x86/boot/string.c @@ -14,6 +14,20 @@ #include "boot.h" +/* + * This file gets included in compressed/string.c which might pull in + * string_32.h and which in turn maps memcmp to __builtin_memcmp(). Undo + * that first. + */ +#undef memcmp +int memcmp(const void *s1, const void *s2, size_t len) +{ + u8 diff; + asm("repe; cmpsb; setnz %0" + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); + return diff; +} + int strcmp(const char *str1, const char *str2) { const unsigned char *s1 = (const unsigned char *)str1; diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h index 10939d8da2e..725e820602b 100644 --- a/arch/x86/boot/string.h +++ b/arch/x86/boot/string.h @@ -8,6 +8,7 @@ void *memcpy(void *dst, const void *src, size_t len); void *memset(void *dst, int c, size_t len); +int memcmp(const void *s1, const void *s2, size_t len); /* * Access builtin version by default. If one needs to use optimized version, @@ -15,5 +16,6 @@ void *memset(void *dst, int c, size_t len); */ #define memcpy(d,s,l) __builtin_memcpy(d,s,l) #define memset(d,c,l) __builtin_memset(d,c,l) +#define memcmp __builtin_memcmp #endif /* BOOT_STRING_H */ -- cgit v1.2.3-70-g09d2 From 04999550f93234bf05597a9b7d26e2bfe27ba883 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 18 Mar 2014 15:26:40 -0400 Subject: x86, boot: Move memset() definition in compressed/string.c Currently compressed/misc.c needs to link against memset(). I think one of the reasons of this need is inclusion of various header files which define static inline functions and use memset() inside these. For example, include/linux/bitmap.h I think trying to include "../string.h" and using builtin version of memset does not work because by the time "#define memset" shows up, it is too late. Some other header file has already used memset() and expects to find a definition during link phase. Currently we have a C definitoin of memset() in misc.c. Move it to compressed/string.c so that others can use it if need be. Signed-off-by: Vivek Goyal Link: http://lkml.kernel.org/r/1395170800-11059-6-git-send-email-vgoyal@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/misc.c | 20 +++++++------------- arch/x86/boot/compressed/string.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'arch/x86/boot') diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 3100092b134..17684615374 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -98,8 +98,14 @@ */ #define STATIC static -#undef memset #undef memcpy + +/* + * Use a normal definition of memset() from string.c. There are already + * included header files which expect a definition of memset() and by + * the time we define memset macro, it is too late. + */ +#undef memset #define memzero(s, n) memset((s), 0, (n)) @@ -110,8 +116,6 @@ static void error(char *m); */ struct boot_params *real_mode; /* Pointer to real-mode data */ -void *memset(void *s, int c, size_t n); - memptr free_mem_ptr; memptr free_mem_end_ptr; @@ -216,16 +220,6 @@ void __putstr(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; -} - static void error(char *x) { error_putstr("\n\n"); diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c index 920b55e3e24..f3c57e34140 100644 --- a/arch/x86/boot/compressed/string.c +++ b/arch/x86/boot/compressed/string.c @@ -33,3 +33,13 @@ void *memcpy(void *dest, const void *src, size_t n) return dest; } #endif + +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; +} -- cgit v1.2.3-70-g09d2