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