mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-25 06:51:49 +00:00
hv: refine memcpy_s
Use enhanced rep fast-string operation to refine memcpy_s. And assume that the destination and the source would not overlap. Tracked-On: #861 Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
2d1b3dd98d
commit
10c49ae6fd
@ -28,7 +28,7 @@ char *strncpy_s(char *d_arg, size_t dmax, const char *s_arg, size_t slen_arg);
|
|||||||
char *strchr(char *s_arg, char ch);
|
char *strchr(char *s_arg, char ch);
|
||||||
size_t strnlen_s(const char *str_arg, size_t maxlen_arg);
|
size_t strnlen_s(const char *str_arg, size_t maxlen_arg);
|
||||||
void *memset(void *base, uint8_t v, size_t n);
|
void *memset(void *base, uint8_t v, size_t n);
|
||||||
void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen_arg);
|
void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen);
|
||||||
int32_t atoi(const char *str);
|
int32_t atoi(const char *str);
|
||||||
long strtol_deci(const char *nptr);
|
long strtol_deci(const char *nptr);
|
||||||
uint64_t strtoul_hex(const char *nptr);
|
uint64_t strtoul_hex(const char *nptr);
|
||||||
|
@ -274,96 +274,36 @@ void *memchr(const void *void_s, int32_t c, size_t n)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static inline void memcpy_erms(void *d, const void *s, size_t slen)
|
||||||
*
|
{
|
||||||
* FUNCTION
|
asm volatile ("rep; movsb"
|
||||||
*
|
: "=&D"(d), "=&S"(s)
|
||||||
* memcpy_s
|
: "c"(slen), "0" (d), "1" (s)
|
||||||
*
|
: "memory");
|
||||||
* DESCRIPTION
|
}
|
||||||
*
|
|
||||||
* Copies at most slen bytes from src address to dest address,
|
/*
|
||||||
* up to dmax.
|
* @brief Copies at most slen bytes from src address to dest address, up to dmax.
|
||||||
*
|
*
|
||||||
* INPUTS
|
* INPUTS
|
||||||
*
|
*
|
||||||
* d pointer to Destination address
|
* @param[in] d pointer to Destination address
|
||||||
* dmax maximum length of dest
|
* @param[in] dmax maximum length of dest
|
||||||
* s pointer to Source address
|
* @param[in] s pointer to Source address
|
||||||
* slen maximum number of bytes of src to copy
|
* @param[in] slen maximum number of bytes of src to copy
|
||||||
*
|
*
|
||||||
* OUTPUTS
|
* @return pointer to destination address.
|
||||||
*
|
*
|
||||||
* void * pointer to destination address if successful,
|
* @pre d and s will not overlap.
|
||||||
* or else return null.
|
*/
|
||||||
*
|
void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen)
|
||||||
***********************************************************************/
|
|
||||||
void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen_arg)
|
|
||||||
{
|
{
|
||||||
uint8_t *dest8;
|
if ((slen != 0U) && (dmax != 0U) && (dmax >= slen)) {
|
||||||
uint8_t *src8;
|
/* same memory block, no need to copy */
|
||||||
size_t slen = slen_arg;
|
if (d != s) {
|
||||||
|
memcpy_erms(d, s, slen);
|
||||||
if ((slen == 0U) || (dmax == 0U) || (dmax < slen)) {
|
|
||||||
ASSERT(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((((d) > (s)) && ((d) <= ((s + slen) - 1U)))
|
|
||||||
|| (((d) < (s)) && ((s) <= ((d + dmax) - 1U)))) {
|
|
||||||
ASSERT(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* same memory block, no need to copy */
|
|
||||||
if (d == s) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest8 = (uint8_t *)d;
|
|
||||||
src8 = (uint8_t *)s;
|
|
||||||
|
|
||||||
/* small data block */
|
|
||||||
if (slen < 8U) {
|
|
||||||
while (slen != 0U) {
|
|
||||||
*dest8 = *src8;
|
|
||||||
dest8++;
|
|
||||||
src8++;
|
|
||||||
slen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure 8bytes-aligned for at least one addr. */
|
|
||||||
if ((!mem_aligned_check((uint64_t)src8, 8UL)) &&
|
|
||||||
(!mem_aligned_check((uint64_t)dest8, 8UL))) {
|
|
||||||
for (; (slen != 0U) && ((((uint64_t)src8) & 7UL) != 0UL);
|
|
||||||
slen--) {
|
|
||||||
*dest8 = *src8;
|
|
||||||
dest8++;
|
|
||||||
src8++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy main data blocks, with rep prefix */
|
|
||||||
if (slen > 8U) {
|
|
||||||
uint32_t ecx;
|
|
||||||
|
|
||||||
asm volatile ("cld; rep; movsq"
|
|
||||||
: "=&c"(ecx), "=&D"(dest8), "=&S"(src8)
|
|
||||||
: "0" (slen >> 3), "1" (dest8), "2" (src8)
|
|
||||||
: "memory");
|
|
||||||
|
|
||||||
slen = slen & 0x7U;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tail bytes */
|
|
||||||
while (slen != 0U) {
|
|
||||||
*dest8 = *src8;
|
|
||||||
dest8++;
|
|
||||||
src8++;
|
|
||||||
slen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user