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