xref: /openbmc/u-boot/test/lib/string.c (revision 2e8560797fc69a34c330a875da4f5d2992452f1e)
1*2dd0111aSHeinrich Schuchardt // SPDX-License-Identifier: GPL-2.0+
2*2dd0111aSHeinrich Schuchardt /*
3*2dd0111aSHeinrich Schuchardt  * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
4*2dd0111aSHeinrich Schuchardt  *
5*2dd0111aSHeinrich Schuchardt  * Unit tests for memory functions
6*2dd0111aSHeinrich Schuchardt  *
7*2dd0111aSHeinrich Schuchardt  * The architecture dependent implementations run through different lines of
8*2dd0111aSHeinrich Schuchardt  * code depending on the alignment and length of memory regions copied or set.
9*2dd0111aSHeinrich Schuchardt  * This has to be considered in testing.
10*2dd0111aSHeinrich Schuchardt  */
11*2dd0111aSHeinrich Schuchardt 
12*2dd0111aSHeinrich Schuchardt #include <common.h>
13*2dd0111aSHeinrich Schuchardt #include <command.h>
14*2dd0111aSHeinrich Schuchardt #include <test/lib.h>
15*2dd0111aSHeinrich Schuchardt #include <test/test.h>
16*2dd0111aSHeinrich Schuchardt #include <test/ut.h>
17*2dd0111aSHeinrich Schuchardt 
18*2dd0111aSHeinrich Schuchardt /* Xor mask used for marking memory regions */
19*2dd0111aSHeinrich Schuchardt #define MASK 0xA5
20*2dd0111aSHeinrich Schuchardt /* Number of different alignment values */
21*2dd0111aSHeinrich Schuchardt #define SWEEP 16
22*2dd0111aSHeinrich Schuchardt /* Allow for copying up to 32 bytes */
23*2dd0111aSHeinrich Schuchardt #define BUFLEN (SWEEP + 33)
24*2dd0111aSHeinrich Schuchardt 
25*2dd0111aSHeinrich Schuchardt /**
26*2dd0111aSHeinrich Schuchardt  * init_buffer() - initialize buffer
27*2dd0111aSHeinrich Schuchardt  *
28*2dd0111aSHeinrich Schuchardt  * The buffer is filled with incrementing values xor'ed with the mask.
29*2dd0111aSHeinrich Schuchardt  *
30*2dd0111aSHeinrich Schuchardt  * @buf:	buffer
31*2dd0111aSHeinrich Schuchardt  * @mask:	xor mask
32*2dd0111aSHeinrich Schuchardt  */
init_buffer(u8 buf[],u8 mask)33*2dd0111aSHeinrich Schuchardt static void init_buffer(u8 buf[], u8 mask)
34*2dd0111aSHeinrich Schuchardt {
35*2dd0111aSHeinrich Schuchardt 	int i;
36*2dd0111aSHeinrich Schuchardt 
37*2dd0111aSHeinrich Schuchardt 	for (i = 0; i < BUFLEN; ++i)
38*2dd0111aSHeinrich Schuchardt 		buf[i] = i ^ mask;
39*2dd0111aSHeinrich Schuchardt }
40*2dd0111aSHeinrich Schuchardt 
41*2dd0111aSHeinrich Schuchardt /**
42*2dd0111aSHeinrich Schuchardt  * test_memset() - test result of memset()
43*2dd0111aSHeinrich Schuchardt  *
44*2dd0111aSHeinrich Schuchardt  * @uts:	unit test state
45*2dd0111aSHeinrich Schuchardt  * @buf:	buffer
46*2dd0111aSHeinrich Schuchardt  * @mask:	value set by memset()
47*2dd0111aSHeinrich Schuchardt  * @offset:	relative start of region changed by memset() in buffer
48*2dd0111aSHeinrich Schuchardt  * @len:	length of region changed by memset()
49*2dd0111aSHeinrich Schuchardt  * Return:	0 = success, 1 = failure
50*2dd0111aSHeinrich Schuchardt  */
test_memset(struct unit_test_state * uts,u8 buf[],u8 mask,int offset,int len)51*2dd0111aSHeinrich Schuchardt static int test_memset(struct unit_test_state *uts, u8 buf[], u8 mask,
52*2dd0111aSHeinrich Schuchardt 		       int offset, int len)
53*2dd0111aSHeinrich Schuchardt {
54*2dd0111aSHeinrich Schuchardt 	int i;
55*2dd0111aSHeinrich Schuchardt 
56*2dd0111aSHeinrich Schuchardt 	for (i = 0; i < BUFLEN; ++i) {
57*2dd0111aSHeinrich Schuchardt 		if (i < offset || i >= offset + len) {
58*2dd0111aSHeinrich Schuchardt 			ut_asserteq(i, buf[i]);
59*2dd0111aSHeinrich Schuchardt 		} else {
60*2dd0111aSHeinrich Schuchardt 			ut_asserteq(mask, buf[i]);
61*2dd0111aSHeinrich Schuchardt 		}
62*2dd0111aSHeinrich Schuchardt 	}
63*2dd0111aSHeinrich Schuchardt 	return 0;
64*2dd0111aSHeinrich Schuchardt }
65*2dd0111aSHeinrich Schuchardt 
66*2dd0111aSHeinrich Schuchardt /**
67*2dd0111aSHeinrich Schuchardt  * lib_memset() - unit test for memset()
68*2dd0111aSHeinrich Schuchardt  *
69*2dd0111aSHeinrich Schuchardt  * Test memset() with varied alignment and length of the changed buffer.
70*2dd0111aSHeinrich Schuchardt  *
71*2dd0111aSHeinrich Schuchardt  * @uts:	unit test state
72*2dd0111aSHeinrich Schuchardt  * Return:	0 = success, 1 = failure
73*2dd0111aSHeinrich Schuchardt  */
lib_memset(struct unit_test_state * uts)74*2dd0111aSHeinrich Schuchardt static int lib_memset(struct unit_test_state *uts)
75*2dd0111aSHeinrich Schuchardt {
76*2dd0111aSHeinrich Schuchardt 	u8 buf[BUFLEN];
77*2dd0111aSHeinrich Schuchardt 	int offset, len;
78*2dd0111aSHeinrich Schuchardt 	void *ptr;
79*2dd0111aSHeinrich Schuchardt 
80*2dd0111aSHeinrich Schuchardt 	for (offset = 0; offset <= SWEEP; ++offset) {
81*2dd0111aSHeinrich Schuchardt 		for (len = 1; len < BUFLEN - SWEEP; ++len) {
82*2dd0111aSHeinrich Schuchardt 			init_buffer(buf, 0);
83*2dd0111aSHeinrich Schuchardt 			ptr = memset(buf + offset, MASK, len);
84*2dd0111aSHeinrich Schuchardt 			ut_asserteq_ptr(buf + offset, (u8 *)ptr);
85*2dd0111aSHeinrich Schuchardt 			if (test_memset(uts, buf, MASK, offset, len)) {
86*2dd0111aSHeinrich Schuchardt 				debug("%s: failure %d, %d\n",
87*2dd0111aSHeinrich Schuchardt 				      __func__, offset, len);
88*2dd0111aSHeinrich Schuchardt 				return CMD_RET_FAILURE;
89*2dd0111aSHeinrich Schuchardt 			}
90*2dd0111aSHeinrich Schuchardt 		}
91*2dd0111aSHeinrich Schuchardt 	}
92*2dd0111aSHeinrich Schuchardt 	return 0;
93*2dd0111aSHeinrich Schuchardt }
94*2dd0111aSHeinrich Schuchardt 
95*2dd0111aSHeinrich Schuchardt LIB_TEST(lib_memset, 0);
96*2dd0111aSHeinrich Schuchardt 
97*2dd0111aSHeinrich Schuchardt /**
98*2dd0111aSHeinrich Schuchardt  * test_memmove() - test result of memcpy() or memmove()
99*2dd0111aSHeinrich Schuchardt  *
100*2dd0111aSHeinrich Schuchardt  * @uts:	unit test state
101*2dd0111aSHeinrich Schuchardt  * @buf:	buffer
102*2dd0111aSHeinrich Schuchardt  * @mask:	xor mask used to initialize source buffer
103*2dd0111aSHeinrich Schuchardt  * @offset1:	relative start of copied region in source buffer
104*2dd0111aSHeinrich Schuchardt  * @offset2:	relative start of copied region in destination buffer
105*2dd0111aSHeinrich Schuchardt  * @len:	length of region changed by memset()
106*2dd0111aSHeinrich Schuchardt  * Return:	0 = success, 1 = failure
107*2dd0111aSHeinrich Schuchardt  */
test_memmove(struct unit_test_state * uts,u8 buf[],u8 mask,int offset1,int offset2,int len)108*2dd0111aSHeinrich Schuchardt static int test_memmove(struct unit_test_state *uts, u8 buf[], u8 mask,
109*2dd0111aSHeinrich Schuchardt 			int offset1, int offset2, int len)
110*2dd0111aSHeinrich Schuchardt {
111*2dd0111aSHeinrich Schuchardt 	int i;
112*2dd0111aSHeinrich Schuchardt 
113*2dd0111aSHeinrich Schuchardt 	for (i = 0; i < BUFLEN; ++i) {
114*2dd0111aSHeinrich Schuchardt 		if (i < offset2 || i >= offset2 + len) {
115*2dd0111aSHeinrich Schuchardt 			ut_asserteq(i, buf[i]);
116*2dd0111aSHeinrich Schuchardt 		} else {
117*2dd0111aSHeinrich Schuchardt 			ut_asserteq((i + offset1 - offset2) ^ mask, buf[i]);
118*2dd0111aSHeinrich Schuchardt 		}
119*2dd0111aSHeinrich Schuchardt 	}
120*2dd0111aSHeinrich Schuchardt 	return 0;
121*2dd0111aSHeinrich Schuchardt }
122*2dd0111aSHeinrich Schuchardt 
123*2dd0111aSHeinrich Schuchardt /**
124*2dd0111aSHeinrich Schuchardt  * lib_memcpy() - unit test for memcpy()
125*2dd0111aSHeinrich Schuchardt  *
126*2dd0111aSHeinrich Schuchardt  * Test memcpy() with varied alignment and length of the copied buffer.
127*2dd0111aSHeinrich Schuchardt  *
128*2dd0111aSHeinrich Schuchardt  * @uts:	unit test state
129*2dd0111aSHeinrich Schuchardt  * Return:	0 = success, 1 = failure
130*2dd0111aSHeinrich Schuchardt  */
lib_memcpy(struct unit_test_state * uts)131*2dd0111aSHeinrich Schuchardt static int lib_memcpy(struct unit_test_state *uts)
132*2dd0111aSHeinrich Schuchardt {
133*2dd0111aSHeinrich Schuchardt 	u8 buf1[BUFLEN];
134*2dd0111aSHeinrich Schuchardt 	u8 buf2[BUFLEN];
135*2dd0111aSHeinrich Schuchardt 	int offset1, offset2, len;
136*2dd0111aSHeinrich Schuchardt 	void *ptr;
137*2dd0111aSHeinrich Schuchardt 
138*2dd0111aSHeinrich Schuchardt 	init_buffer(buf1, MASK);
139*2dd0111aSHeinrich Schuchardt 
140*2dd0111aSHeinrich Schuchardt 	for (offset1 = 0; offset1 <= SWEEP; ++offset1) {
141*2dd0111aSHeinrich Schuchardt 		for (offset2 = 0; offset2 <= SWEEP; ++offset2) {
142*2dd0111aSHeinrich Schuchardt 			for (len = 1; len < BUFLEN - SWEEP; ++len) {
143*2dd0111aSHeinrich Schuchardt 				init_buffer(buf2, 0);
144*2dd0111aSHeinrich Schuchardt 				ptr = memcpy(buf2 + offset2, buf1 + offset1,
145*2dd0111aSHeinrich Schuchardt 					     len);
146*2dd0111aSHeinrich Schuchardt 				ut_asserteq_ptr(buf2 + offset2, (u8 *)ptr);
147*2dd0111aSHeinrich Schuchardt 				if (test_memmove(uts, buf2, MASK, offset1,
148*2dd0111aSHeinrich Schuchardt 						 offset2, len)) {
149*2dd0111aSHeinrich Schuchardt 					debug("%s: failure %d, %d, %d\n",
150*2dd0111aSHeinrich Schuchardt 					      __func__, offset1, offset2, len);
151*2dd0111aSHeinrich Schuchardt 					return CMD_RET_FAILURE;
152*2dd0111aSHeinrich Schuchardt 				}
153*2dd0111aSHeinrich Schuchardt 			}
154*2dd0111aSHeinrich Schuchardt 		}
155*2dd0111aSHeinrich Schuchardt 	}
156*2dd0111aSHeinrich Schuchardt 	return 0;
157*2dd0111aSHeinrich Schuchardt }
158*2dd0111aSHeinrich Schuchardt 
159*2dd0111aSHeinrich Schuchardt LIB_TEST(lib_memcpy, 0);
160*2dd0111aSHeinrich Schuchardt 
161*2dd0111aSHeinrich Schuchardt /**
162*2dd0111aSHeinrich Schuchardt  * lib_memmove() - unit test for memmove()
163*2dd0111aSHeinrich Schuchardt  *
164*2dd0111aSHeinrich Schuchardt  * Test memmove() with varied alignment and length of the copied buffer.
165*2dd0111aSHeinrich Schuchardt  *
166*2dd0111aSHeinrich Schuchardt  * @uts:	unit test state
167*2dd0111aSHeinrich Schuchardt  * Return:	0 = success, 1 = failure
168*2dd0111aSHeinrich Schuchardt  */
lib_memmove(struct unit_test_state * uts)169*2dd0111aSHeinrich Schuchardt static int lib_memmove(struct unit_test_state *uts)
170*2dd0111aSHeinrich Schuchardt {
171*2dd0111aSHeinrich Schuchardt 	u8 buf[BUFLEN];
172*2dd0111aSHeinrich Schuchardt 	int offset1, offset2, len;
173*2dd0111aSHeinrich Schuchardt 	void *ptr;
174*2dd0111aSHeinrich Schuchardt 
175*2dd0111aSHeinrich Schuchardt 	for (offset1 = 0; offset1 <= SWEEP; ++offset1) {
176*2dd0111aSHeinrich Schuchardt 		for (offset2 = 0; offset2 <= SWEEP; ++offset2) {
177*2dd0111aSHeinrich Schuchardt 			for (len = 1; len < BUFLEN - SWEEP; ++len) {
178*2dd0111aSHeinrich Schuchardt 				init_buffer(buf, 0);
179*2dd0111aSHeinrich Schuchardt 				ptr = memmove(buf + offset2, buf + offset1,
180*2dd0111aSHeinrich Schuchardt 					      len);
181*2dd0111aSHeinrich Schuchardt 				ut_asserteq_ptr(buf + offset2, (u8 *)ptr);
182*2dd0111aSHeinrich Schuchardt 				if (test_memmove(uts, buf, 0, offset1, offset2,
183*2dd0111aSHeinrich Schuchardt 						 len)) {
184*2dd0111aSHeinrich Schuchardt 					debug("%s: failure %d, %d, %d\n",
185*2dd0111aSHeinrich Schuchardt 					      __func__, offset1, offset2, len);
186*2dd0111aSHeinrich Schuchardt 					return CMD_RET_FAILURE;
187*2dd0111aSHeinrich Schuchardt 				}
188*2dd0111aSHeinrich Schuchardt 			}
189*2dd0111aSHeinrich Schuchardt 		}
190*2dd0111aSHeinrich Schuchardt 	}
191*2dd0111aSHeinrich Schuchardt 	return 0;
192*2dd0111aSHeinrich Schuchardt }
193*2dd0111aSHeinrich Schuchardt 
194*2dd0111aSHeinrich Schuchardt LIB_TEST(lib_memmove, 0);
195