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