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