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