1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson */
4a9de470cSBruce Richardson
5a9de470cSBruce Richardson #include <stdint.h>
6a9de470cSBruce Richardson #include <stdio.h>
7a9de470cSBruce Richardson #include <string.h>
8a9de470cSBruce Richardson #include <stdlib.h>
9a9de470cSBruce Richardson
10a9de470cSBruce Richardson #include <rte_common.h>
11a9de470cSBruce Richardson #include <rte_random.h>
12a9de470cSBruce Richardson #include <rte_memcpy.h>
13a9de470cSBruce Richardson
14a9de470cSBruce Richardson #include "test.h"
15a9de470cSBruce Richardson
16a9de470cSBruce Richardson /*
17a9de470cSBruce Richardson * Set this to the maximum buffer size you want to test. If it is 0, then the
18a9de470cSBruce Richardson * values in the buf_sizes[] array below will be used.
19a9de470cSBruce Richardson */
20a9de470cSBruce Richardson #define TEST_VALUE_RANGE 0
21a9de470cSBruce Richardson
22a9de470cSBruce Richardson /* List of buffer sizes to test */
23a9de470cSBruce Richardson #if TEST_VALUE_RANGE == 0
24a9de470cSBruce Richardson static size_t buf_sizes[] = {
25a9de470cSBruce Richardson 0, 1, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255,
26a9de470cSBruce Richardson 256, 257, 320, 384, 511, 512, 513, 1023, 1024, 1025, 1518, 1522, 1600,
27a9de470cSBruce Richardson 2048, 3072, 4096, 5120, 6144, 7168, 8192
28a9de470cSBruce Richardson };
29a9de470cSBruce Richardson /* MUST be as large as largest packet size above */
30a9de470cSBruce Richardson #define SMALL_BUFFER_SIZE 8192
31a9de470cSBruce Richardson #else /* TEST_VALUE_RANGE != 0 */
32a9de470cSBruce Richardson static size_t buf_sizes[TEST_VALUE_RANGE];
33a9de470cSBruce Richardson #define SMALL_BUFFER_SIZE TEST_VALUE_RANGE
34a9de470cSBruce Richardson #endif /* TEST_VALUE_RANGE == 0 */
35a9de470cSBruce Richardson
36a9de470cSBruce Richardson /* Data is aligned on this many bytes (power of 2) */
37a9de470cSBruce Richardson #define ALIGNMENT_UNIT 32
38a9de470cSBruce Richardson
39a9de470cSBruce Richardson
40a9de470cSBruce Richardson /*
41a9de470cSBruce Richardson * Create two buffers, and initialise one with random values. These are copied
42a9de470cSBruce Richardson * to the second buffer and then compared to see if the copy was successful.
43a9de470cSBruce Richardson * The bytes outside the copied area are also checked to make sure they were not
44a9de470cSBruce Richardson * changed.
45a9de470cSBruce Richardson */
46a9de470cSBruce Richardson static int
test_single_memcpy(unsigned int off_src,unsigned int off_dst,size_t size)47a9de470cSBruce Richardson test_single_memcpy(unsigned int off_src, unsigned int off_dst, size_t size)
48a9de470cSBruce Richardson {
49a9de470cSBruce Richardson unsigned int i;
50a9de470cSBruce Richardson uint8_t dest[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT];
51a9de470cSBruce Richardson uint8_t src[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT];
52a9de470cSBruce Richardson void * ret;
53a9de470cSBruce Richardson
54a9de470cSBruce Richardson /* Setup buffers */
55a9de470cSBruce Richardson for (i = 0; i < SMALL_BUFFER_SIZE + ALIGNMENT_UNIT; i++) {
56a9de470cSBruce Richardson dest[i] = 0;
57a9de470cSBruce Richardson src[i] = (uint8_t) rte_rand();
58a9de470cSBruce Richardson }
59a9de470cSBruce Richardson
60a9de470cSBruce Richardson /* Do the copy */
61a9de470cSBruce Richardson ret = rte_memcpy(dest + off_dst, src + off_src, size);
62a9de470cSBruce Richardson if (ret != (dest + off_dst)) {
63a9de470cSBruce Richardson printf("rte_memcpy() returned %p, not %p\n",
64a9de470cSBruce Richardson ret, dest + off_dst);
65a9de470cSBruce Richardson }
66a9de470cSBruce Richardson
67a9de470cSBruce Richardson /* Check nothing before offset is affected */
68a9de470cSBruce Richardson for (i = 0; i < off_dst; i++) {
69a9de470cSBruce Richardson if (dest[i] != 0) {
70a9de470cSBruce Richardson printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): "
71a9de470cSBruce Richardson "[modified before start of dst].\n",
72a9de470cSBruce Richardson (unsigned)size, off_src, off_dst);
73a9de470cSBruce Richardson return -1;
74a9de470cSBruce Richardson }
75a9de470cSBruce Richardson }
76a9de470cSBruce Richardson
77a9de470cSBruce Richardson /* Check everything was copied */
78a9de470cSBruce Richardson for (i = 0; i < size; i++) {
79a9de470cSBruce Richardson if (dest[i + off_dst] != src[i + off_src]) {
80a9de470cSBruce Richardson printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): "
81a9de470cSBruce Richardson "[didn't copy byte %u].\n",
82a9de470cSBruce Richardson (unsigned)size, off_src, off_dst, i);
83a9de470cSBruce Richardson return -1;
84a9de470cSBruce Richardson }
85a9de470cSBruce Richardson }
86a9de470cSBruce Richardson
87a9de470cSBruce Richardson /* Check nothing after copy was affected */
88a9de470cSBruce Richardson for (i = size; i < SMALL_BUFFER_SIZE; i++) {
89a9de470cSBruce Richardson if (dest[i + off_dst] != 0) {
90a9de470cSBruce Richardson printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): "
91a9de470cSBruce Richardson "[copied too many].\n",
92a9de470cSBruce Richardson (unsigned)size, off_src, off_dst);
93a9de470cSBruce Richardson return -1;
94a9de470cSBruce Richardson }
95a9de470cSBruce Richardson }
96a9de470cSBruce Richardson return 0;
97a9de470cSBruce Richardson }
98a9de470cSBruce Richardson
99a9de470cSBruce Richardson /*
100a9de470cSBruce Richardson * Check functionality for various buffer sizes and data offsets/alignments.
101a9de470cSBruce Richardson */
102a9de470cSBruce Richardson static int
func_test(void)103a9de470cSBruce Richardson func_test(void)
104a9de470cSBruce Richardson {
105a9de470cSBruce Richardson unsigned int off_src, off_dst, i;
106a9de470cSBruce Richardson int ret;
107a9de470cSBruce Richardson
108a9de470cSBruce Richardson for (off_src = 0; off_src < ALIGNMENT_UNIT; off_src++) {
109a9de470cSBruce Richardson for (off_dst = 0; off_dst < ALIGNMENT_UNIT; off_dst++) {
11071bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(buf_sizes); i++) {
111a9de470cSBruce Richardson ret = test_single_memcpy(off_src, off_dst,
112a9de470cSBruce Richardson buf_sizes[i]);
113a9de470cSBruce Richardson if (ret != 0)
114a9de470cSBruce Richardson return -1;
115a9de470cSBruce Richardson }
116a9de470cSBruce Richardson }
117a9de470cSBruce Richardson }
118a9de470cSBruce Richardson return 0;
119a9de470cSBruce Richardson }
120a9de470cSBruce Richardson
121a9de470cSBruce Richardson static int
test_memcpy(void)122a9de470cSBruce Richardson test_memcpy(void)
123a9de470cSBruce Richardson {
124a9de470cSBruce Richardson int ret;
125a9de470cSBruce Richardson
126a9de470cSBruce Richardson ret = func_test();
127a9de470cSBruce Richardson if (ret != 0)
128a9de470cSBruce Richardson return -1;
129a9de470cSBruce Richardson return 0;
130a9de470cSBruce Richardson }
131a9de470cSBruce Richardson
132*e0a8442cSBruce Richardson REGISTER_FAST_TEST(memcpy_autotest, true, true, test_memcpy);
133