xref: /openbmc/u-boot/test/compression.c (revision e8f80a5a)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2013, The Chromium Authors
4  */
5 
6 #include <common.h>
7 #include <bootm.h>
8 #include <command.h>
9 #include <malloc.h>
10 #include <mapmem.h>
11 #include <asm/io.h>
12 
13 #include <u-boot/zlib.h>
14 #include <bzlib.h>
15 
16 #include <lzma/LzmaTypes.h>
17 #include <lzma/LzmaDec.h>
18 #include <lzma/LzmaTools.h>
19 
20 #include <linux/lzo.h>
21 #include <test/compression.h>
22 #include <test/suites.h>
23 #include <test/ut.h>
24 
25 static const char plain[] =
26 	"I am a highly compressable bit of text.\n"
27 	"I am a highly compressable bit of text.\n"
28 	"I am a highly compressable bit of text.\n"
29 	"There are many like me, but this one is mine.\n"
30 	"If I were any shorter, there wouldn't be much sense in\n"
31 	"compressing me in the first place. At least with lzo, anyway,\n"
32 	"which appears to behave poorly in the face of short text\n"
33 	"messages.\n";
34 
35 /* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
36 static const char bzip2_compressed[] =
37 	"\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
38 	"\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
39 	"\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
40 	"\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
41 	"\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
42 	"\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
43 	"\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
44 	"\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
45 	"\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
46 	"\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
47 	"\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
48 	"\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
49 	"\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
50 	"\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
51 	"\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
52 static const unsigned long bzip2_compressed_size = 240;
53 
54 /* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
55 static const char lzma_compressed[] =
56 	"\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
57 	"\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
58 	"\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
59 	"\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
60 	"\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
61 	"\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
62 	"\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
63 	"\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
64 	"\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
65 	"\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
66 	"\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
67 	"\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
68 	"\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
69 	"\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
70 	"\xfd\xf5\x50\x8d\xca";
71 static const unsigned long lzma_compressed_size = 229;
72 
73 /* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
74 static const char lzo_compressed[] =
75 	"\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
76 	"\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
77 	"\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
78 	"\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
79 	"\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
80 	"\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
81 	"\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
82 	"\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
83 	"\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
84 	"\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
85 	"\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
86 	"\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
87 	"\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
88 	"\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
89 	"\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
90 	"\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
91 	"\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
92 	"\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
93 	"\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
94 	"\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
95 	"\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
96 static const unsigned long lzo_compressed_size = 334;
97 
98 /* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */
99 static const char lz4_compressed[] =
100 	"\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61"
101 	"\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
102 	"\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
103 	"\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20"
104 	"\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65"
105 	"\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69"
106 	"\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00"
107 	"\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00"
108 	"\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75"
109 	"\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69"
110 	"\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73"
111 	"\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
112 	"\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77"
113 	"\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
114 	"\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
115 	"\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01"
116 	"\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00"
117 	"\x9d\x12\x8c\x9d";
118 static const unsigned long lz4_compressed_size = 276;
119 
120 
121 #define TEST_BUFFER_SIZE	512
122 
123 typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long,
124 			   void *, unsigned long, unsigned long *);
125 
compress_using_gzip(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)126 static int compress_using_gzip(struct unit_test_state *uts,
127 			       void *in, unsigned long in_size,
128 			       void *out, unsigned long out_max,
129 			       unsigned long *out_size)
130 {
131 	int ret;
132 	unsigned long inout_size = out_max;
133 
134 	ret = gzip(out, &inout_size, in, in_size);
135 	if (out_size)
136 		*out_size = inout_size;
137 
138 	return ret;
139 }
140 
uncompress_using_gzip(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)141 static int uncompress_using_gzip(struct unit_test_state *uts,
142 				 void *in, unsigned long in_size,
143 				 void *out, unsigned long out_max,
144 				 unsigned long *out_size)
145 {
146 	int ret;
147 	unsigned long inout_size = in_size;
148 
149 	ret = gunzip(out, out_max, in, &inout_size);
150 	if (out_size)
151 		*out_size = inout_size;
152 
153 	return ret;
154 }
155 
compress_using_bzip2(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)156 static int compress_using_bzip2(struct unit_test_state *uts,
157 				void *in, unsigned long in_size,
158 				void *out, unsigned long out_max,
159 				unsigned long *out_size)
160 {
161 	/* There is no bzip2 compression in u-boot, so fake it. */
162 	ut_asserteq(in_size, strlen(plain));
163 	ut_asserteq(0, memcmp(plain, in, in_size));
164 
165 	if (bzip2_compressed_size > out_max)
166 		return -1;
167 
168 	memcpy(out, bzip2_compressed, bzip2_compressed_size);
169 	if (out_size)
170 		*out_size = bzip2_compressed_size;
171 
172 	return 0;
173 }
174 
uncompress_using_bzip2(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)175 static int uncompress_using_bzip2(struct unit_test_state *uts,
176 				  void *in, unsigned long in_size,
177 				  void *out, unsigned long out_max,
178 				  unsigned long *out_size)
179 {
180 	int ret;
181 	unsigned int inout_size = out_max;
182 
183 	ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
184 			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
185 	if (out_size)
186 		*out_size = inout_size;
187 
188 	return (ret != BZ_OK);
189 }
190 
compress_using_lzma(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)191 static int compress_using_lzma(struct unit_test_state *uts,
192 			       void *in, unsigned long in_size,
193 			       void *out, unsigned long out_max,
194 			       unsigned long *out_size)
195 {
196 	/* There is no lzma compression in u-boot, so fake it. */
197 	ut_asserteq(in_size,  strlen(plain));
198 	ut_asserteq(0, memcmp(plain, in, in_size));
199 
200 	if (lzma_compressed_size > out_max)
201 		return -1;
202 
203 	memcpy(out, lzma_compressed, lzma_compressed_size);
204 	if (out_size)
205 		*out_size = lzma_compressed_size;
206 
207 	return 0;
208 }
209 
uncompress_using_lzma(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)210 static int uncompress_using_lzma(struct unit_test_state *uts,
211 				 void *in, unsigned long in_size,
212 				 void *out, unsigned long out_max,
213 				 unsigned long *out_size)
214 {
215 	int ret;
216 	SizeT inout_size = out_max;
217 
218 	ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
219 	if (out_size)
220 		*out_size = inout_size;
221 
222 	return (ret != SZ_OK);
223 }
224 
compress_using_lzo(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)225 static int compress_using_lzo(struct unit_test_state *uts,
226 			      void *in, unsigned long in_size,
227 			      void *out, unsigned long out_max,
228 			      unsigned long *out_size)
229 {
230 	/* There is no lzo compression in u-boot, so fake it. */
231 	ut_asserteq(in_size,  strlen(plain));
232 	ut_asserteq(0, memcmp(plain, in, in_size));
233 
234 	if (lzo_compressed_size > out_max)
235 		return -1;
236 
237 	memcpy(out, lzo_compressed, lzo_compressed_size);
238 	if (out_size)
239 		*out_size = lzo_compressed_size;
240 
241 	return 0;
242 }
243 
uncompress_using_lzo(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)244 static int uncompress_using_lzo(struct unit_test_state *uts,
245 				void *in, unsigned long in_size,
246 				void *out, unsigned long out_max,
247 				unsigned long *out_size)
248 {
249 	int ret;
250 	size_t input_size = in_size;
251 	size_t output_size = out_max;
252 
253 	ret = lzop_decompress(in, input_size, out, &output_size);
254 	if (out_size)
255 		*out_size = output_size;
256 
257 	return (ret != LZO_E_OK);
258 }
259 
compress_using_lz4(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)260 static int compress_using_lz4(struct unit_test_state *uts,
261 			      void *in, unsigned long in_size,
262 			      void *out, unsigned long out_max,
263 			      unsigned long *out_size)
264 {
265 	/* There is no lz4 compression in u-boot, so fake it. */
266 	ut_asserteq(in_size,  strlen(plain));
267 	ut_asserteq(0, memcmp(plain, in, in_size));
268 
269 	if (lz4_compressed_size > out_max)
270 		return -1;
271 
272 	memcpy(out, lz4_compressed, lz4_compressed_size);
273 	if (out_size)
274 		*out_size = lz4_compressed_size;
275 
276 	return 0;
277 }
278 
uncompress_using_lz4(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)279 static int uncompress_using_lz4(struct unit_test_state *uts,
280 				void *in, unsigned long in_size,
281 				void *out, unsigned long out_max,
282 				unsigned long *out_size)
283 {
284 	int ret;
285 	size_t input_size = in_size;
286 	size_t output_size = out_max;
287 
288 	ret = ulz4fn(in, input_size, out, &output_size);
289 	if (out_size)
290 		*out_size = output_size;
291 
292 	return (ret != 0);
293 }
294 
295 #define errcheck(statement) if (!(statement)) { \
296 	fprintf(stderr, "\tFailed: %s\n", #statement); \
297 	ret = 1; \
298 	goto out; \
299 }
300 
301 struct buf_state {
302 	ulong orig_size;
303 	ulong compressed_size;
304 	ulong uncompressed_size;
305 	void *orig_buf;
306 	void *compressed_buf;
307 	void *uncompressed_buf;
308 	void *compare_buf;
309 };
310 
run_test_internal(struct unit_test_state * uts,char * name,mutate_func compress,mutate_func uncompress,struct buf_state * buf)311 static int run_test_internal(struct unit_test_state *uts, char *name,
312 			     mutate_func compress, mutate_func uncompress,
313 			     struct buf_state *buf)
314 {
315 	int ret;
316 
317 	/* Compress works as expected. */
318 	printf("\torig_size:%lu\n", buf->orig_size);
319 	memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
320 	errcheck(compress(uts, buf->orig_buf, buf->orig_size,
321 			  buf->compressed_buf, buf->compressed_size,
322 			  &buf->compressed_size) == 0);
323 	printf("\tcompressed_size:%lu\n", buf->compressed_size);
324 	errcheck(buf->compressed_size > 0);
325 	errcheck(buf->compressed_size < buf->orig_size);
326 	errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] !=
327 			'A');
328 	errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A');
329 
330 	/* Uncompresses with space remaining. */
331 	errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
332 			    buf->uncompressed_buf, buf->uncompressed_size,
333 			    &buf->uncompressed_size) == 0);
334 	printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
335 	errcheck(buf->uncompressed_size == buf->orig_size);
336 	errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
337 			buf->orig_size) == 0);
338 
339 	/* Uncompresses with exactly the right size output buffer. */
340 	memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
341 	errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
342 			    buf->uncompressed_buf, buf->orig_size,
343 			    &buf->uncompressed_size) == 0);
344 	errcheck(buf->uncompressed_size == buf->orig_size);
345 	errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
346 			buf->orig_size) == 0);
347 	errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
348 
349 	/* Make sure compression does not over-run. */
350 	memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
351 	ret = compress(uts, buf->orig_buf, buf->orig_size,
352 		       buf->compare_buf, buf->compressed_size - 1,
353 		       NULL);
354 	errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A');
355 	errcheck(ret != 0);
356 	printf("\tcompress does not overrun\n");
357 
358 	/* Make sure decompression does not over-run. */
359 	memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
360 	ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
361 			 buf->compare_buf, buf->uncompressed_size - 1,
362 			 NULL);
363 	errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A');
364 	errcheck(ret != 0);
365 	printf("\tuncompress does not overrun\n");
366 
367 	/* Got here, everything is fine. */
368 	ret = 0;
369 
370 out:
371 	return ret;
372 }
373 
run_test(struct unit_test_state * uts,char * name,mutate_func compress,mutate_func uncompress)374 static int run_test(struct unit_test_state *uts, char *name,
375 		    mutate_func compress, mutate_func uncompress)
376 {
377 	struct buf_state sbuf, *buf = &sbuf;
378 	int ret;
379 
380 	printf(" testing %s ...\n", name);
381 
382 	buf->orig_buf = (void *)plain;
383 	buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */
384 	errcheck(buf->orig_size > 0);
385 
386 	buf->compressed_size = TEST_BUFFER_SIZE;
387 	buf->uncompressed_size = TEST_BUFFER_SIZE;
388 	buf->compressed_buf = malloc(buf->compressed_size);
389 	errcheck(buf->compressed_buf);
390 	buf->uncompressed_buf = malloc(buf->uncompressed_size);
391 	errcheck(buf->uncompressed_buf);
392 	buf->compare_buf = malloc(buf->uncompressed_size);
393 	errcheck(buf->compare_buf);
394 
395 	ret = run_test_internal(uts, name, compress, uncompress, buf);
396 out:
397 	printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
398 
399 	free(buf->compare_buf);
400 	free(buf->uncompressed_buf);
401 	free(buf->compressed_buf);
402 
403 	return ret;
404 }
405 
compression_test_gzip(struct unit_test_state * uts)406 static int compression_test_gzip(struct unit_test_state *uts)
407 {
408 	return run_test(uts, "gzip", compress_using_gzip,
409 			uncompress_using_gzip);
410 }
411 COMPRESSION_TEST(compression_test_gzip, 0);
412 
compression_test_bzip2(struct unit_test_state * uts)413 static int compression_test_bzip2(struct unit_test_state *uts)
414 {
415 	return run_test(uts, "bzip2", compress_using_bzip2,
416 			uncompress_using_bzip2);
417 }
418 COMPRESSION_TEST(compression_test_bzip2, 0);
419 
compression_test_lzma(struct unit_test_state * uts)420 static int compression_test_lzma(struct unit_test_state *uts)
421 {
422 	return run_test(uts, "lzma", compress_using_lzma,
423 			uncompress_using_lzma);
424 }
425 COMPRESSION_TEST(compression_test_lzma, 0);
426 
compression_test_lzo(struct unit_test_state * uts)427 static int compression_test_lzo(struct unit_test_state *uts)
428 {
429 	return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
430 }
431 COMPRESSION_TEST(compression_test_lzo, 0);
432 
compression_test_lz4(struct unit_test_state * uts)433 static int compression_test_lz4(struct unit_test_state *uts)
434 {
435 	return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
436 }
437 COMPRESSION_TEST(compression_test_lz4, 0);
438 
compress_using_none(struct unit_test_state * uts,void * in,unsigned long in_size,void * out,unsigned long out_max,unsigned long * out_size)439 static int compress_using_none(struct unit_test_state *uts,
440 			       void *in, unsigned long in_size,
441 			       void *out, unsigned long out_max,
442 			       unsigned long *out_size)
443 {
444 	/* Here we just copy */
445 	memcpy(out, in, in_size);
446 	*out_size = in_size;
447 
448 	return 0;
449 }
450 
451 /**
452  * run_bootm_test() - Run tests on the bootm decopmression function
453  *
454  * @comp_type:	Compression type to test
455  * @compress:	Our function to compress data
456  * @return 0 if OK, non-zero on failure
457  */
run_bootm_test(struct unit_test_state * uts,int comp_type,mutate_func compress)458 static int run_bootm_test(struct unit_test_state *uts, int comp_type,
459 			  mutate_func compress)
460 {
461 	ulong compress_size = 1024;
462 	void *compress_buff;
463 	int unc_len;
464 	int err = 0;
465 	const ulong image_start = 0;
466 	const ulong load_addr = 0x1000;
467 	ulong load_end;
468 
469 	printf("Testing: %s\n", genimg_get_comp_name(comp_type));
470 	compress_buff = map_sysmem(image_start, 0);
471 	unc_len = strlen(plain);
472 	compress(uts, (void *)plain, unc_len, compress_buff, compress_size,
473 		 &compress_size);
474 	err = bootm_decomp_image(comp_type, load_addr, image_start,
475 				 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
476 				 compress_buff, compress_size, unc_len,
477 				 &load_end);
478 	ut_assertok(err);
479 	err = bootm_decomp_image(comp_type, load_addr, image_start,
480 				 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
481 				 compress_buff, compress_size, unc_len - 1,
482 				 &load_end);
483 	ut_assert(err);
484 
485 	/* We can't detect corruption when not decompressing */
486 	if (comp_type == IH_COMP_NONE)
487 		return 0;
488 	memset(compress_buff + compress_size / 2, '\x49',
489 	       compress_size / 2);
490 	err = bootm_decomp_image(comp_type, load_addr, image_start,
491 				 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
492 				 compress_buff, compress_size, 0x10000,
493 				 &load_end);
494 	ut_assert(err);
495 
496 	return 0;
497 }
498 
compression_test_bootm_gzip(struct unit_test_state * uts)499 static int compression_test_bootm_gzip(struct unit_test_state *uts)
500 {
501 	return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
502 }
503 COMPRESSION_TEST(compression_test_bootm_gzip, 0);
504 
compression_test_bootm_bzip2(struct unit_test_state * uts)505 static int compression_test_bootm_bzip2(struct unit_test_state *uts)
506 {
507 	return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
508 }
509 COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
510 
compression_test_bootm_lzma(struct unit_test_state * uts)511 static int compression_test_bootm_lzma(struct unit_test_state *uts)
512 {
513 	return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
514 }
515 COMPRESSION_TEST(compression_test_bootm_lzma, 0);
516 
compression_test_bootm_lzo(struct unit_test_state * uts)517 static int compression_test_bootm_lzo(struct unit_test_state *uts)
518 {
519 	return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
520 }
521 COMPRESSION_TEST(compression_test_bootm_lzo, 0);
522 
compression_test_bootm_lz4(struct unit_test_state * uts)523 static int compression_test_bootm_lz4(struct unit_test_state *uts)
524 {
525 	return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
526 }
527 COMPRESSION_TEST(compression_test_bootm_lz4, 0);
528 
compression_test_bootm_none(struct unit_test_state * uts)529 static int compression_test_bootm_none(struct unit_test_state *uts)
530 {
531 	return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
532 }
533 COMPRESSION_TEST(compression_test_bootm_none, 0);
534 
do_ut_compression(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])535 int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
536 {
537 	struct unit_test *tests = ll_entry_start(struct unit_test,
538 						 compression_test);
539 	const int n_ents = ll_entry_count(struct unit_test, compression_test);
540 
541 	return cmd_ut_category("compression", tests, n_ents, argc, argv);
542 }
543