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
This commit is contained in:
commit
9447dc4394
@ -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;
|
||||
@ -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_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);
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "../string.h"
|
||||
|
||||
/* WARNING!!
|
||||
* This code is compiled with -fPIC and it is relocated dynamically
|
||||
@ -97,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))
|
||||
|
||||
|
||||
@ -109,9 +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);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
memptr free_mem_ptr;
|
||||
memptr free_mem_end_ptr;
|
||||
|
||||
@ -216,45 +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;
|
||||
}
|
||||
#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)
|
||||
{
|
||||
error_putstr("\n\n");
|
||||
|
@ -1,11 +1,45 @@
|
||||
#include "misc.h"
|
||||
|
||||
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 */
|
||||
#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
|
||||
|
||||
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 @@
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/required-features.h>
|
||||
#include <asm/msr-index.h>
|
||||
#include "string.h"
|
||||
|
||||
static u32 err_flags[NCAPINTS];
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "boot.h"
|
||||
#include <linux/edd.h>
|
||||
#include "string.h"
|
||||
|
||||
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
#include "string.h"
|
||||
|
||||
struct boot_params boot_params __attribute__((aligned(16)));
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
#include "string.h"
|
||||
|
||||
void initregs(struct biosregs *reg)
|
||||
{
|
||||
|
@ -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;
|
||||
|
21
arch/x86/boot/string.h
Normal file
21
arch/x86/boot/string.h
Normal file
@ -0,0 +1,21 @@
|
||||
#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 @@
|
||||
#include "boot.h"
|
||||
#include "video.h"
|
||||
#include "vesa.h"
|
||||
#include "string.h"
|
||||
|
||||
/* VESA information */
|
||||
static struct vesa_general_info vginfo;
|
||||
|
Loading…
Reference in New Issue
Block a user