1 /*
2 * Copyright (C) 2018-2022 Intel Corporation.
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5 #include <types.h>
6
memset_erms(void * base,uint8_t v,size_t n)7 static inline void memset_erms(void *base, uint8_t v, size_t n)
8 {
9 asm volatile("rep ; stosb"
10 : "+D"(base)
11 : "a" (v), "c"(n));
12 }
13
memset(void * base,uint8_t v,size_t n)14 void *memset(void *base, uint8_t v, size_t n)
15 {
16 /*
17 * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
18 * to use it when possible.
19 */
20 if ((base != NULL) && (n != 0U)) {
21 memset_erms(base, v, n);
22 }
23
24 return base;
25 }
26
memcpy_erms(void * d,const void * s,size_t slen)27 void memcpy_erms(void *d, const void *s, size_t slen)
28 {
29 asm volatile ("rep; movsb"
30 : "=&D"(d), "=&S"(s)
31 : "c"(slen), "0" (d), "1" (s)
32 : "memory");
33 }
34
35 /* copy data from tail to head (backwards) with ERMS (Enhanced REP MOVSB/STOSB) */
memcpy_erms_backwards(void * d,const void * s,size_t slen)36 void memcpy_erms_backwards(void *d, const void *s, size_t slen)
37 {
38 asm volatile ("std; rep; movsb; cld"
39 : "=&D"(d), "=&S"(s)
40 : "c"(slen), "0" (d), "1" (s)
41 : "memory");
42 }
43
44 /*
45 * @brief Copies at most slen bytes from src address to dest address, up to dmax.
46 *
47 * INPUTS
48 *
49 * @param[in] d pointer to Destination address
50 * @param[in] dmax maximum length of dest
51 * @param[in] s pointer to Source address
52 * @param[in] slen maximum number of bytes of src to copy
53 *
54 * @return 0 for success and -1 for runtime-constraint violation.
55 */
memcpy_s(void * d,size_t dmax,const void * s,size_t slen)56 int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen)
57 {
58 int32_t ret = -1;
59
60 if ((d != NULL) && (s != NULL) && (dmax >= slen) && ((d > (s + slen)) || (s > (d + dmax)))) {
61 if (slen != 0U) {
62 memcpy_erms(d, s, slen);
63 }
64 ret = 0;
65 } else {
66 (void)memset(d, 0U, dmax);
67 }
68
69 return ret;
70 }
71