Commit 9447dc43 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86/boot' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot changes from Peter Anvin:
 "This patchset is a set of cleanups aiming at librarize some of the
  common code from the boot environments.  We currently have three
  different "little environments" (boot, boot/compressed, and
  realmode/rm) in x86, and we are likely to soon get a fourth one
  (kexec/purgatory, which will have to be integrated in the kernel to
  support secure kexec).  This is primarily a cleanup in the
  anticipation of the latter.

  While Vivek implemented this, he ran into some bugs, in particular the
  memcmp implementation for when gcc punts from using the builtin would
  have a misnamed symbol, causing compilation errors if we were ever
  unlucky enough that gcc didn't want to inline the test"

* 'x86/boot' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, boot: Move memset() definition in compressed/string.c
  x86, boot: Move memcmp() into string.h and string.c
  x86, boot: Move optimized memcpy() 32/64 bit versions to compressed/string.c
  x86, boot: Create a separate string.h file to provide standard string functions
  x86, boot: Undef memcmp before providing a new definition
parents bb1775c9 04999550
...@@ -177,14 +177,6 @@ static inline void wrgs32(u32 v, addr_t addr) ...@@ -177,14 +177,6 @@ static inline void wrgs32(u32 v, addr_t addr)
} }
/* Note: these only return true/false, not a signed return value! */ /* 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) static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
{ {
u8 diff; u8 diff;
...@@ -228,11 +220,6 @@ void copy_to_fs(addr_t dst, void *src, size_t len); ...@@ -228,11 +220,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_from_fs(void *dst, addr_t src, size_t len);
void copy_to_gs(addr_t dst, void *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 *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 */ /* a20.c */
int enable_a20(void); int enable_a20(void);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include "misc.h" #include "misc.h"
#include "../string.h"
/* WARNING!! /* WARNING!!
* This code is compiled with -fPIC and it is relocated dynamically * This code is compiled with -fPIC and it is relocated dynamically
...@@ -97,8 +98,14 @@ ...@@ -97,8 +98,14 @@
*/ */
#define STATIC static #define STATIC static
#undef memset
#undef memcpy #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)) #define memzero(s, n) memset((s), 0, (n))
...@@ -109,9 +116,6 @@ static void error(char *m); ...@@ -109,9 +116,6 @@ static void error(char *m);
*/ */
struct boot_params *real_mode; /* Pointer to real-mode data */ 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_ptr;
memptr free_mem_end_ptr; memptr free_mem_end_ptr;
...@@ -216,45 +220,6 @@ void __putstr(const char *s) ...@@ -216,45 +220,6 @@ void __putstr(const char *s)
outb(0xff & (pos >> 1), vidport+1); 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) static void error(char *x)
{ {
error_putstr("\n\n"); error_putstr("\n\n");
......
#include "misc.h" #include "misc.h"
#include "../string.c"
/* misc.h might pull in string_32.h which has a macro for memcpy. undef that */
#undef memcpy
int memcmp(const void *s1, const void *s2, size_t len) #ifdef CONFIG_X86_32
void *memcpy(void *dest, const void *src, size_t n)
{ {
u8 diff; int d0, d1, d2;
asm("repe; cmpsb; setnz %0" asm volatile(
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); "rep ; movsl\n\t"
return diff; "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");
#include "../string.c" 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;
}
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/processor-flags.h> #include <asm/processor-flags.h>
#include <asm/required-features.h> #include <asm/required-features.h>
#include <asm/msr-index.h> #include <asm/msr-index.h>
#include "string.h"
static u32 err_flags[NCAPINTS]; static u32 err_flags[NCAPINTS];
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "boot.h" #include "boot.h"
#include <linux/edd.h> #include <linux/edd.h>
#include "string.h"
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
*/ */
#include "boot.h" #include "boot.h"
#include "string.h"
struct boot_params boot_params __attribute__((aligned(16))); struct boot_params boot_params __attribute__((aligned(16)));
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include "boot.h" #include "boot.h"
#include "string.h"
void initregs(struct biosregs *reg) void initregs(struct biosregs *reg)
{ {
......
...@@ -14,6 +14,20 @@ ...@@ -14,6 +14,20 @@
#include "boot.h" #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) int strcmp(const char *str1, const char *str2)
{ {
const unsigned char *s1 = (const unsigned char *)str1; const unsigned char *s1 = (const unsigned char *)str1;
......
#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);
int memcmp(const void *s1, const void *s2, 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)
#define memcmp __builtin_memcmp
#endif /* BOOT_STRING_H */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "boot.h" #include "boot.h"
#include "video.h" #include "video.h"
#include "vesa.h" #include "vesa.h"
#include "string.h"
/* VESA information */ /* VESA information */
static struct vesa_general_info vginfo; static struct vesa_general_info vginfo;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment