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