Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 Arm Limited
3 : : */
4 : :
5 : : #include "test.h"
6 : : #include <stdint.h>
7 : : #include <string.h>
8 : :
9 : : #include <rte_ptr_compress.h>
10 : :
11 : : #define MAX_ALIGN_EXPONENT 3
12 : : #define MAX_PTRS 16
13 : : #define NUM_BASES 2
14 : : #define NUM_REGIONS 4
15 : : #define MAX_32BIT_REGION ((uint64_t)UINT32_MAX + 1)
16 : : #define MAX_16BIT_REGION (UINT16_MAX + 1)
17 : :
18 : : static int
19 : 240 : test_ptr_compress_params(
20 : : void *base,
21 : : uint64_t mem_sz,
22 : : unsigned int align_exp,
23 : : unsigned int num_ptrs,
24 : : bool use_32_bit)
25 : : {
26 : : unsigned int i;
27 : : unsigned int align = 1 << align_exp;
28 : 240 : void *ptrs[MAX_PTRS] = {0};
29 : 240 : void *ptrs_out[MAX_PTRS] = {0};
30 : 240 : uint32_t offsets32[MAX_PTRS] = {0};
31 : 240 : uint16_t offsets16[MAX_PTRS] = {0};
32 : :
33 [ + + ]: 2160 : for (i = 0; i < num_ptrs; i++) {
34 : : /* make pointers point at memory in steps of align */
35 : : /* alternate steps from the start and end of memory region */
36 [ + + ]: 1920 : if ((i & 1) == 1)
37 : 896 : ptrs[i] = (char *)base + mem_sz - i * align;
38 : : else
39 : 1024 : ptrs[i] = (char *)base + i * align;
40 : : }
41 : :
42 [ + + ]: 240 : if (use_32_bit) {
43 : 120 : rte_ptr_compress_32_shift(
44 : : base, ptrs, offsets32, num_ptrs, align_exp);
45 : : rte_ptr_decompress_32_shift(base, offsets32, ptrs_out, num_ptrs,
46 : : align_exp);
47 : : } else {
48 : 120 : rte_ptr_compress_16_shift(
49 : : base, ptrs, offsets16, num_ptrs, align_exp);
50 : : rte_ptr_decompress_16_shift(base, offsets16, ptrs_out, num_ptrs,
51 : : align_exp);
52 : : }
53 : :
54 [ - + - - ]: 240 : TEST_ASSERT_BUFFERS_ARE_EQUAL(ptrs, ptrs_out, sizeof(void *) * num_ptrs,
55 : : "Decompressed pointers corrupted\nbase pointer: %p, "
56 : : "memory region size: %" PRIu64 ", alignment exponent: %u, "
57 : : "num of pointers: %u, using %s offsets",
58 : : base, mem_sz, align_exp, num_ptrs,
59 : : use_32_bit ? "32-bit" : "16-bit");
60 : :
61 : : return 0;
62 : : }
63 : :
64 : : static int
65 : 1 : test_ptr_compress(void)
66 : : {
67 : : unsigned int j, k, n;
68 : : int ret = 0;
69 : : /* the test is run with multiple memory regions and base addresses */
70 : 1 : void * const bases[NUM_BASES] = { (void *)0, (void *)UINT16_MAX };
71 : : /* maximum size for pointers aligned by consecutive powers of 2 */
72 : 1 : const uint64_t region_sizes_16[NUM_REGIONS] = {
73 : : MAX_16BIT_REGION,
74 : : MAX_16BIT_REGION * 2,
75 : : MAX_16BIT_REGION * 4,
76 : : MAX_16BIT_REGION * 8,
77 : : };
78 : 1 : const uint64_t region_sizes_32[NUM_REGIONS] = {
79 : : MAX_32BIT_REGION,
80 : : MAX_32BIT_REGION * 2,
81 : : MAX_32BIT_REGION * 4,
82 : : MAX_32BIT_REGION * 8,
83 : : };
84 : :
85 : : /* main test compresses and decompresses arrays of pointers
86 : : * and compares the array before and after to verify that
87 : : * pointers are successfully decompressed
88 : : */
89 : :
90 [ + + ]: 5 : for (j = 0; j < NUM_REGIONS; j++) {
91 [ + + ]: 12 : for (k = 0; k < NUM_BASES; k++) {
92 [ + + ]: 128 : for (n = 1; n < MAX_PTRS; n++) {
93 : 240 : ret |= test_ptr_compress_params(
94 : 120 : bases[k],
95 : 120 : region_sizes_16[j],
96 : : j /* exponent of alignment */,
97 : : n,
98 : : false
99 : : );
100 : 240 : ret |= test_ptr_compress_params(
101 : : bases[k],
102 : 120 : region_sizes_32[j],
103 : : j /* exponent of alignment */,
104 : : n,
105 : : true
106 : : );
107 [ - + ]: 120 : if (ret != 0)
108 : 0 : return ret;
109 : : }
110 : : }
111 : : }
112 : :
113 : : /* verify helper macro computations */
114 : :
115 : : n = RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE(0);
116 : : TEST_ASSERT_EQUAL(n, 1,
117 : : "RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE "
118 : : "macro computation incorrect\n");
119 : :
120 : : n = RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE(1);
121 : : TEST_ASSERT_EQUAL(n, 1,
122 : : "RTE_PTR_COMPREtopSS_BITS_REQUIRED_TO_STORE_VALUE "
123 : : "macro computation incorrect\n");
124 : :
125 : : n = RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE(MAX_16BIT_REGION);
126 : : TEST_ASSERT_EQUAL(n, 16,
127 : : "RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE "
128 : : "macro computation incorrect\n");
129 : :
130 : : n = RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE(MAX_32BIT_REGION);
131 : : TEST_ASSERT_EQUAL(n, 32,
132 : : "RTE_PTR_COMPRESS_BITS_NEEDED_FOR_POINTER_WITHIN_RANGE "
133 : : "macro computation incorrect\n");
134 : :
135 : : n = RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT(0);
136 : : TEST_ASSERT_EQUAL(n, 0,
137 : : "RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT "
138 : : "macro computation incorrect\n");
139 : :
140 : : n = RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT(1);
141 : : TEST_ASSERT_EQUAL(n, 0,
142 : : "RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT "
143 : : "macro computation incorrect\n");
144 : :
145 : : n = RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT(2);
146 : : TEST_ASSERT_EQUAL(n, 1,
147 : : "RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT "
148 : : "macro computation incorrect\n");
149 : :
150 : : n = RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT(3);
151 : : TEST_ASSERT_EQUAL(n, 0,
152 : : "RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT "
153 : : "macro computation incorrect\n");
154 : :
155 : : n = RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT(4);
156 : : TEST_ASSERT_EQUAL(n, 2,
157 : : "RTE_PTR_COMPRESS_BIT_SHIFT_FROM_ALIGNMENT "
158 : : "macro computation incorrect\n");
159 : :
160 : : ret = RTE_PTR_COMPRESS_CAN_COMPRESS_16_SHIFT(MAX_16BIT_REGION, 1);
161 : : TEST_ASSERT_EQUAL(ret, 1,
162 : : "RTE_PTR_COMPRESS_CAN_COMPRESS_16_SHIFT "
163 : : "macro computation incorrect\n");
164 : :
165 : : ret = RTE_PTR_COMPRESS_CAN_COMPRESS_16_SHIFT(MAX_16BIT_REGION + 1, 1);
166 : : TEST_ASSERT_EQUAL(ret, 0,
167 : : "RTE_PTR_COMPRESS_CAN_COMPRESS_16_SHIFT "
168 : : "macro computation incorrect\n");
169 : :
170 : : ret = RTE_PTR_COMPRESS_CAN_COMPRESS_16_SHIFT(MAX_16BIT_REGION + 1, 2);
171 : : TEST_ASSERT_EQUAL(ret, 1,
172 : : "RTE_PTR_COMPRESS_CAN_COMPRESS_16_SHIFT "
173 : : "macro computation incorrect\n");
174 : :
175 : : ret = RTE_PTR_COMPRESS_CAN_COMPRESS_32_SHIFT(MAX_32BIT_REGION, 1);
176 : : TEST_ASSERT_EQUAL(ret, 1,
177 : : "RTE_PTR_COMPRESS_CAN_COMPRESS_32_SHIFT "
178 : : "macro computation incorrect\n");
179 : :
180 : : ret = RTE_PTR_COMPRESS_CAN_COMPRESS_32_SHIFT(MAX_32BIT_REGION + 1, 1);
181 : : TEST_ASSERT_EQUAL(ret, 0,
182 : : "RTE_PTR_COMPRESS_CAN_COMPRESS_32_SHIFT "
183 : : "macro computation incorrect\n");
184 : :
185 : : ret = RTE_PTR_COMPRESS_CAN_COMPRESS_32_SHIFT(MAX_32BIT_REGION + 1, 2);
186 : : TEST_ASSERT_EQUAL(ret, 1,
187 : : "RTE_PTR_COMPRESS_CAN_COMPRESS_32_SHIFT "
188 : : "macro computation incorrect\n");
189 : :
190 : : return 0;
191 : : }
192 : :
193 : 252 : REGISTER_FAST_TEST(ptr_compress_autotest, true, true, test_ptr_compress);
|