kernel/x86_64: remove memset and memcpy from commpage
There is absolutely no reason for these functions to be in commpage, they don't do anything that involves the kernel in any way. Additionaly, this patch rewrites memset and memcpy to C++, current implementation is quite simple (though it may perform surprisingly well when dealing with large buffers on cpus with ermsb). Better versions are coming soon. Signed-off-by: Paweł Dziepak <[email protected]>
This commit is contained in:
@@ -9,11 +9,9 @@
|
||||
# error Must not be included directly. Include <commpage_defs.h> instead!
|
||||
#endif
|
||||
|
||||
#define COMMPAGE_ENTRY_X86_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
|
||||
#define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
|
||||
#define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2)
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
|
||||
#define COMMPAGE_ENTRY_X86_THREAD_EXIT \
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3)
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
|
||||
|
||||
#endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */
|
||||
|
||||
@@ -30,6 +30,10 @@ extern "C" void x86_sysenter();
|
||||
void (*gX86SetSyscallStack)(addr_t stackTop) = NULL;
|
||||
|
||||
|
||||
extern int memcpy_end;
|
||||
extern int memset_end;
|
||||
|
||||
|
||||
static bool
|
||||
all_cpus_have_feature(enum x86_feature_type type, int feature)
|
||||
{
|
||||
@@ -109,8 +113,20 @@ x86_initialize_syscall(void)
|
||||
addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SYSCALL,
|
||||
syscallCode, len);
|
||||
|
||||
// put the optimized functions into the commpage
|
||||
size_t memcpyLen = (addr_t)&memcpy_end - (addr_t)memcpy;
|
||||
addr_t memcpyPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY,
|
||||
(const void*)memcpy, memcpyLen);
|
||||
size_t memsetLen = (addr_t)&memset_end - (addr_t)memset;
|
||||
addr_t memsetPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET,
|
||||
(const void*)memset, memsetLen);
|
||||
|
||||
// add syscall to the commpage image
|
||||
image_id image = get_commpage_image();
|
||||
elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition,
|
||||
memcpyLen, B_SYMBOL_TYPE_TEXT);
|
||||
elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition,
|
||||
memsetLen, B_SYMBOL_TYPE_TEXT);
|
||||
elf_add_memory_image_symbol(image, "commpage_syscall", position, len,
|
||||
B_SYMBOL_TYPE_TEXT);
|
||||
}
|
||||
|
||||
@@ -105,9 +105,6 @@ static const size_t kDoubleFaultStackSize = 4096; // size per CPU
|
||||
static x86_cpu_module_info* sCpuModule;
|
||||
|
||||
|
||||
extern int memcpy_end;
|
||||
extern int memset_end;
|
||||
|
||||
/* CPU topology information */
|
||||
static uint32 (*sGetCPUTopologyID)(int currentCPU);
|
||||
static uint32 sHierarchyMask[CPU_TOPOLOGY_LEVELS];
|
||||
@@ -1154,13 +1151,6 @@ arch_cpu_init_post_modules(kernel_args* args)
|
||||
call_all_cpus(&init_mtrrs, NULL);
|
||||
}
|
||||
|
||||
// put the optimized functions into the commpage
|
||||
size_t memcpyLen = (addr_t)&memcpy_end - (addr_t)memcpy;
|
||||
addr_t memcpyPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY,
|
||||
(const void*)memcpy, memcpyLen);
|
||||
size_t memsetLen = (addr_t)&memset_end - (addr_t)memset;
|
||||
addr_t memsetPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET,
|
||||
(const void*)memset, memsetLen);
|
||||
size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit
|
||||
- (addr_t)x86_userspace_thread_exit;
|
||||
addr_t threadExitPosition = fill_commpage_entry(
|
||||
@@ -1169,10 +1159,7 @@ arch_cpu_init_post_modules(kernel_args* args)
|
||||
|
||||
// add the functions to the commpage image
|
||||
image_id image = get_commpage_image();
|
||||
elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition,
|
||||
memcpyLen, B_SYMBOL_TYPE_TEXT);
|
||||
elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition,
|
||||
memsetLen, B_SYMBOL_TYPE_TEXT);
|
||||
|
||||
elf_add_memory_image_symbol(image, "commpage_thread_exit",
|
||||
threadExitPosition, threadExitLen, B_SYMBOL_TYPE_TEXT);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
||||
;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(posixSources) arch $(TARGET_ARCH) ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(posixSources) string arch $(TARGET_ARCH) ] ;
|
||||
|
||||
KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o :
|
||||
siglongjmp.S
|
||||
@@ -28,12 +29,8 @@ KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o :
|
||||
kernel_longjmp_return.c
|
||||
kernel_setjmp_save_sigs.c
|
||||
|
||||
arch_string.S
|
||||
arch_string.cpp
|
||||
|
||||
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
||||
;
|
||||
|
||||
# Explicitly tell the build system that arch_string.S includes the generated
|
||||
# asm_offsets.h.
|
||||
Includes [ FGristFiles arch_string.S ]
|
||||
: <src!system!kernel!arch!x86>asm_offsets.h ;
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <asm_defs.h>
|
||||
|
||||
|
||||
.align 8
|
||||
FUNCTION(memcpy):
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
// Preserve original destination address for return value.
|
||||
movq %rdi, %rax
|
||||
|
||||
// size -> %rcx
|
||||
movq %rdx, %rcx
|
||||
|
||||
// For small copies, always do it bytewise, the additional overhead is
|
||||
// not worth it.
|
||||
cmp $24, %rcx
|
||||
jl .Lmemcpy_generic_byte_copy
|
||||
|
||||
// Do both source and dest have the same alignment?
|
||||
movq %rsi, %r8
|
||||
xorq %rdi, %r8
|
||||
test $7, %r8
|
||||
jnz .Lmemcpy_generic_byte_copy
|
||||
|
||||
// Align up to an 8-byte boundary.
|
||||
movq %rdi, %r8
|
||||
andq $7, %r8
|
||||
jz .Lmemcpy_generic_qword_copy
|
||||
movq $8, %rcx
|
||||
subq %r8, %rcx
|
||||
subq %rcx, %rdx // Subtract from the overall count.
|
||||
rep
|
||||
movsb
|
||||
|
||||
// Get back the original count value.
|
||||
movq %rdx, %rcx
|
||||
.Lmemcpy_generic_qword_copy:
|
||||
// Move by quadwords.
|
||||
shrq $3, %rcx
|
||||
rep
|
||||
movsq
|
||||
|
||||
// Get the remaining count.
|
||||
movq %rdx, %rcx
|
||||
andq $7, %rcx
|
||||
.Lmemcpy_generic_byte_copy:
|
||||
// Move any remaining data by bytes.
|
||||
rep
|
||||
movsb
|
||||
|
||||
pop %rbp
|
||||
ret
|
||||
FUNCTION_END(memcpy)
|
||||
SYMBOL(memcpy_end):
|
||||
|
||||
|
||||
.align 8
|
||||
FUNCTION(memset):
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
// Preserve original destination address for return value.
|
||||
movq %rdi, %r8
|
||||
|
||||
// size -> %rcx, value -> %al
|
||||
movq %rdx, %rcx
|
||||
movl %esi, %eax
|
||||
|
||||
// Move by bytes.
|
||||
rep
|
||||
stosb
|
||||
|
||||
movq %r8, %rax
|
||||
pop %rbp
|
||||
ret
|
||||
FUNCTION_END(memset)
|
||||
SYMBOL(memset_end):
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
SubDir HAIKU_TOP src system libroot posix string arch x86_64 ;
|
||||
|
||||
SubDirC++Flags -std=gnu++11 ;
|
||||
|
||||
local architectureObject ;
|
||||
for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
|
||||
on $(architectureObject) {
|
||||
@@ -8,7 +10,7 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
|
||||
UsePrivateSystemHeaders ;
|
||||
|
||||
MergeObject <$(architecture)>posix_string_arch_$(TARGET_ARCH).o :
|
||||
arch_string.S
|
||||
arch_string.cpp
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <asm_defs.h>
|
||||
#include <commpage_defs.h>
|
||||
|
||||
|
||||
FUNCTION(memcpy):
|
||||
movq __gCommPageAddress@GOTPCREL(%rip), %rax
|
||||
movq (%rax), %rax
|
||||
addq 8 * COMMPAGE_ENTRY_X86_MEMCPY(%rax), %rax
|
||||
jmp *%rax
|
||||
FUNCTION_END(memcpy)
|
||||
|
||||
FUNCTION(memset):
|
||||
movq __gCommPageAddress@GOTPCREL(%rip), %rax
|
||||
movq (%rax), %rax
|
||||
addq 8 * COMMPAGE_ENTRY_X86_MEMSET(%rax), %rax
|
||||
jmp *%rax
|
||||
FUNCTION_END(memset)
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2014, Paweł Dziepak, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
extern "C" void*
|
||||
memcpy(void* destination, const void* source, size_t length)
|
||||
{
|
||||
auto returnValue = destination;
|
||||
__asm__ __volatile__("rep movsb"
|
||||
: "+D" (destination), "+S" (source), "+c" (length)
|
||||
: : "memory");
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void*
|
||||
memset(void* destination, int value, size_t length)
|
||||
{
|
||||
auto returnValue = destination;
|
||||
__asm__ __volatile__("rep stosb"
|
||||
: "+D" (destination), "+c" (length)
|
||||
: "a" (value)
|
||||
: "memory");
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user