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