diff --git a/hypervisor/Makefile b/hypervisor/Makefile index dd286b2b9..7b6c5c8e2 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -149,6 +149,7 @@ endif # all the work. # COMMON_C_SRCS += common/notify.c +COMMON_C_SRCS += lib/memory.c ifeq ($(ARCH),x86) COMMON_C_SRCS += common/ticks.c diff --git a/hypervisor/arch/x86/lib/memory.c b/hypervisor/arch/x86/lib/memory.c index 65c1a6c14..198747a61 100644 --- a/hypervisor/arch/x86/lib/memory.c +++ b/hypervisor/arch/x86/lib/memory.c @@ -1,30 +1,18 @@ /* - * Copyright (C) 2018-2022 Intel Corporation. + * Copyright (C) 2018-2025 Intel Corporation. * SPDX-License-Identifier: BSD-3-Clause */ #include +#include -static inline void memset_erms(void *base, uint8_t v, size_t n) +static inline void x86_memset(void *base, uint8_t v, size_t n) { asm volatile("rep ; stosb" - : "+D"(base) - : "a" (v), "c"(n)); + : "+D"(base) + : "a" (v), "c"(n)); } -void *memset(void *base, uint8_t v, size_t n) -{ - /* - * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended - * to use it when possible. - */ - if ((base != NULL) && (n != 0U)) { - memset_erms(base, v, n); - } - - return base; -} - -void memcpy_erms(void *d, const void *s, size_t slen) +static inline void x86_memcpy(void *d, const void *s, size_t slen) { asm volatile ("rep; movsb" : "=&D"(d), "=&S"(s) @@ -32,8 +20,7 @@ void memcpy_erms(void *d, const void *s, size_t slen) : "memory"); } -/* copy data from tail to head (backwards) with ERMS (Enhanced REP MOVSB/STOSB) */ -void memcpy_erms_backwards(void *d, const void *s, size_t slen) +static inline void x86_memcpy_backwards(void *d, const void *s, size_t slen) { asm volatile ("std; rep; movsb; cld" : "=&D"(d), "=&S"(s) @@ -41,30 +28,29 @@ void memcpy_erms_backwards(void *d, const void *s, size_t slen) : "memory"); } -/* - * @brief Copies at most slen bytes from src address to dest address, up to dmax. - * - * INPUTS - * - * @param[in] d pointer to Destination address - * @param[in] dmax maximum length of dest - * @param[in] s pointer to Source address - * @param[in] slen maximum number of bytes of src to copy - * - * @return 0 for success and -1 for runtime-constraint violation. - */ -int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen) +void *arch_memset(void *base, uint8_t v, size_t n) { - int32_t ret = -1; - - if ((d != NULL) && (s != NULL) && (dmax >= slen) && ((d > (s + slen)) || (s > (d + dmax)))) { - if (slen != 0U) { - memcpy_erms(d, s, slen); - } - ret = 0; - } else { - (void)memset(d, 0U, dmax); + /* + * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended + * to use it when possible. + */ + if ((base != NULL) && (n != 0U)) { + x86_memset(base, v, n); } - return ret; + return base; +} + +void arch_memcpy(void *d, const void *s, size_t slen) +{ + if ((d != NULL) && (s != NULL) && (slen != 0U)) { + x86_memcpy(d, s, slen); + } +} + +void arch_memcpy_backwards(void *d, const void *s, size_t slen) +{ + if ((d != NULL) && (s != NULL) && (slen != 0U)) { + x86_memcpy_backwards(d, s, slen); + } } diff --git a/hypervisor/common/schedule.c b/hypervisor/common/schedule.c index 6ccd9c3c4..495a0b91c 100644 --- a/hypervisor/common/schedule.c +++ b/hypervisor/common/schedule.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2022 Intel Corporation. + * Copyright (C) 2018-2025 Intel Corporation. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -184,8 +184,8 @@ void schedule(void) /* If we picked different sched object, switch context */ if (prev != next) { if (prev != NULL) { - memcpy_erms(name, prev->name, 4); - memcpy_erms(name + 4, next->name, 4); + memcpy(name, prev->name, 4); + memcpy(name + 4, next->name, 4); memset(name + 8, 0, sizeof(name) - 8); TRACE_16STR(TRACE_SCHED_NEXT, name); if (prev->switch_out != NULL) { diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index cc3a7d5c6..fd0580e39 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -315,7 +315,7 @@ static void handle_delete_key(void) set_cursor_pos(delta); - memcpy_erms(p_shell->buffered_line[p_shell->input_line_active] + p_shell->cursor_offset, + memcpy(p_shell->buffered_line[p_shell->input_line_active] + p_shell->cursor_offset, p_shell->buffered_line[p_shell->input_line_active] + p_shell->cursor_offset + 1, delta); /* Null terminate the last character to erase it */ @@ -450,7 +450,7 @@ static void handle_backspace_key(void) shell_puts(" \b"); set_cursor_pos(delta); - memcpy_erms(p_shell->buffered_line[p_shell->input_line_active] + p_shell->cursor_offset - 1, + memcpy(p_shell->buffered_line[p_shell->input_line_active] + p_shell->cursor_offset - 1, p_shell->buffered_line[p_shell->input_line_active] + p_shell->cursor_offset, delta); } @@ -469,7 +469,7 @@ static void handle_input_char(char ch) /* move the input from cursor offset back first */ if (delta > 0) { - memcpy_erms_backwards(p_shell->buffered_line[p_shell->input_line_active] + p_shell->input_line_len, + memcpy_backwards(p_shell->buffered_line[p_shell->input_line_active] + p_shell->input_line_len, p_shell->buffered_line[p_shell->input_line_active] + p_shell->input_line_len - 1, delta); } diff --git a/hypervisor/include/arch/x86/asm/lib/memory.h b/hypervisor/include/arch/x86/asm/lib/memory.h new file mode 100644 index 000000000..417354ecc --- /dev/null +++ b/hypervisor/include/arch/x86/asm/lib/memory.h @@ -0,0 +1,10 @@ +/* + * Copyright (C) 2018-2025 Intel Corporation. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef X86_LIB_MEMORY_H +#define X86_LIB_MEMORY_H + +#define HAS_ARCH_MEMORY_LIB + +#endif /* X86_LIB_MEMORY_H */ diff --git a/hypervisor/include/lib/memory.h b/hypervisor/include/lib/memory.h new file mode 100644 index 000000000..8ba1985e9 --- /dev/null +++ b/hypervisor/include/lib/memory.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MEMORY_LIB_H +#define MEMORY_LIB_H +#include +#include + +#ifdef HAS_ARCH_MEMORY_LIB +void *arch_memset(void *base, uint8_t v, size_t n); +void arch_memcpy(void *d, const void *s, size_t slen); +void arch_memcpy_backwards(void *d, const void *s, size_t slen); + +static inline void *memset(void *base, uint8_t v, size_t n) { + return arch_memset(base, v, n); +} + +static inline void memcpy(void *d, const void *s, size_t slen) { + return arch_memcpy(d, s, slen); +} + +static inline void memcpy_backwards(void *d, const void *s, size_t slen) { + return arch_memcpy_backwards(d, s, slen); +} +#else +void *memset(void *base, uint8_t v, size_t n); +void memcpy(void *d, const void *s, size_t slen); +void memcpy_backwards(void *d, const void *s, size_t slen); +#endif + +int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen); + + +#endif /* MEMORY_LIB_H */ diff --git a/hypervisor/include/lib/rtl.h b/hypervisor/include/lib/rtl.h index 34695c58f..d56d5e53c 100644 --- a/hypervisor/include/lib/rtl.h +++ b/hypervisor/include/lib/rtl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2022 Intel Corporation. + * Copyright (C) 2018-2025 Intel Corporation. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,7 @@ #define RTL_H #include - +#include union u_qword { struct { uint32_t low; @@ -40,10 +40,6 @@ int32_t strncmp(const char *s1_arg, const char *s2_arg, size_t n_arg); int32_t strncpy_s(char *d, size_t dmax, const char *s, size_t slen); char *strchr(char *s_arg, char ch); size_t strnlen_s(const char *str_arg, size_t maxlen_arg); -void *memset(void *base, uint8_t v, size_t n); -int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen); -void memcpy_erms(void *d, const void *s, size_t slen); -void memcpy_erms_backwards(void *d, const void *s, size_t slen); int64_t strtol_deci(const char *nptr); uint64_t strtoul_hex(const char *nptr); char *strstr_s(const char *str1, size_t maxlen1, const char *str2, size_t maxlen2); diff --git a/hypervisor/lib/memory.c b/hypervisor/lib/memory.c new file mode 100644 index 000000000..6d88cb27d --- /dev/null +++ b/hypervisor/lib/memory.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023-2025 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Authors: + * Haicheng Li + */ +#include +#include + +#ifndef HAS_ARCH_MEMORY_LIB +void *memset(void *base, uint8_t v, size_t n) +{ + uint8_t *p = (uint8_t *)base; + + for (size_t i = 0U; i < n; i++) { + *p++ = v; + } + + return base; +} + +void *memset_s(void *base, uint8_t v, size_t n) +{ + if ((base != NULL) && (n != 0U)) { + (void)memset(base, v, n); + } + + return base; +} + +void memcpy(void *d, const void *s, size_t slen) +{ + uint8_t *dst = (uint8_t *)d; + const uint8_t *src = (const uint8_t *)s; + + for (size_t i = 0U; i < slen; i++) { + *dst++ = *src++; + } +} + +void memcpy_backwards(void *d, const void *s, size_t slen) +{ + uint8_t *dst = (uint8_t *)d + slen - 1; + const uint8_t *src = (const uint8_t *)s + slen - 1; + + for (size_t i = 0U; i < slen; i++) { + *dst-- = *src--; + } +} +#endif + +int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen) +{ + int32_t ret = -1; + + if ((d != NULL) && (s != NULL) && (dmax >= slen) && ((d > (s + slen)) || (s > (d + dmax)))) { + if (slen != 0U) { + memcpy(d, s, slen); + } + ret = 0; + } else { + (void)memset(d, 0U, dmax); + } + + return ret; +}