1*88d52c6aSLei Wen /* 2*88d52c6aSLei Wen * (C) Copyright 2012 3*88d52c6aSLei Wen * Lei Wen <leiwen@marvell.com>, Marvell Inc. 4*88d52c6aSLei Wen * 5*88d52c6aSLei Wen * See file CREDITS for list of people who contributed to this 6*88d52c6aSLei Wen * project. 7*88d52c6aSLei Wen * 8*88d52c6aSLei Wen * This program is free software; you can redistribute it and/or 9*88d52c6aSLei Wen * modify it under the terms of the GNU General Public License as 10*88d52c6aSLei Wen * published by the Free Software Foundation; either version 2 of 11*88d52c6aSLei Wen * the License, or (at your option) any later version. 12*88d52c6aSLei Wen * 13*88d52c6aSLei Wen * This program is distributed in the hope that it will be useful, 14*88d52c6aSLei Wen * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*88d52c6aSLei Wen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*88d52c6aSLei Wen * GNU General Public License for more details. 17*88d52c6aSLei Wen * 18*88d52c6aSLei Wen * You should have received a copy of the GNU General Public License 19*88d52c6aSLei Wen * along with this program; if not, write to the Free Software 20*88d52c6aSLei Wen * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*88d52c6aSLei Wen * MA 02111-1307 USA 22*88d52c6aSLei Wen */ 23*88d52c6aSLei Wen 24*88d52c6aSLei Wen #include <common.h> 25*88d52c6aSLei Wen #include <watchdog.h> 26*88d52c6aSLei Wen #include <command.h> 27*88d52c6aSLei Wen #include <image.h> 28*88d52c6aSLei Wen #include <malloc.h> 29*88d52c6aSLei Wen #include <u-boot/zlib.h> 30*88d52c6aSLei Wen #include "zlib/zutil.h" 31*88d52c6aSLei Wen 32*88d52c6aSLei Wen #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ 33*88d52c6aSLei Wen #define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200 34*88d52c6aSLei Wen #endif 35*88d52c6aSLei Wen #define ZALLOC_ALIGNMENT 16 36*88d52c6aSLei Wen 37*88d52c6aSLei Wen static void *zalloc(void *x, unsigned items, unsigned size) 38*88d52c6aSLei Wen { 39*88d52c6aSLei Wen void *p; 40*88d52c6aSLei Wen 41*88d52c6aSLei Wen size *= items; 42*88d52c6aSLei Wen size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); 43*88d52c6aSLei Wen 44*88d52c6aSLei Wen p = malloc (size); 45*88d52c6aSLei Wen 46*88d52c6aSLei Wen return (p); 47*88d52c6aSLei Wen } 48*88d52c6aSLei Wen 49*88d52c6aSLei Wen static void zfree(void *x, void *addr, unsigned nb) 50*88d52c6aSLei Wen { 51*88d52c6aSLei Wen free (addr); 52*88d52c6aSLei Wen } 53*88d52c6aSLei Wen 54*88d52c6aSLei Wen int gzip(void *dst, unsigned long *lenp, 55*88d52c6aSLei Wen unsigned char *src, unsigned long srclen) 56*88d52c6aSLei Wen { 57*88d52c6aSLei Wen return zzip(dst, lenp, src, srclen, 1, NULL); 58*88d52c6aSLei Wen } 59*88d52c6aSLei Wen 60*88d52c6aSLei Wen /* 61*88d52c6aSLei Wen * Compress blocks with zlib 62*88d52c6aSLei Wen */ 63*88d52c6aSLei Wen int zzip(void *dst, unsigned long *lenp, unsigned char *src, 64*88d52c6aSLei Wen unsigned long srclen, int stoponerr, 65*88d52c6aSLei Wen int (*func)(unsigned long, unsigned long)) 66*88d52c6aSLei Wen { 67*88d52c6aSLei Wen z_stream s; 68*88d52c6aSLei Wen int r, flush, orig, window; 69*88d52c6aSLei Wen unsigned long comp_len, left_len; 70*88d52c6aSLei Wen 71*88d52c6aSLei Wen if (!srclen) 72*88d52c6aSLei Wen return 0; 73*88d52c6aSLei Wen 74*88d52c6aSLei Wen #ifndef CONFIG_GZIP 75*88d52c6aSLei Wen window = MAX_WBITS; 76*88d52c6aSLei Wen #else 77*88d52c6aSLei Wen window = 2 * MAX_WBITS; 78*88d52c6aSLei Wen #endif 79*88d52c6aSLei Wen orig = *lenp; 80*88d52c6aSLei Wen s.zalloc = zalloc; 81*88d52c6aSLei Wen s.zfree = zfree; 82*88d52c6aSLei Wen s.opaque = Z_NULL; 83*88d52c6aSLei Wen 84*88d52c6aSLei Wen r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window, 85*88d52c6aSLei Wen DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 86*88d52c6aSLei Wen ZLIB_VERSION, sizeof(z_stream)); 87*88d52c6aSLei Wen if (r != Z_OK) { 88*88d52c6aSLei Wen printf ("Error: deflateInit2_() returned %d\n", r); 89*88d52c6aSLei Wen return -1; 90*88d52c6aSLei Wen } 91*88d52c6aSLei Wen 92*88d52c6aSLei Wen while (srclen > 0) { 93*88d52c6aSLei Wen comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ? 94*88d52c6aSLei Wen CONFIG_GZIP_COMPRESS_DEF_SZ : srclen; 95*88d52c6aSLei Wen 96*88d52c6aSLei Wen s.next_in = src; 97*88d52c6aSLei Wen s.avail_in = comp_len; 98*88d52c6aSLei Wen flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)? 99*88d52c6aSLei Wen Z_NO_FLUSH : Z_FINISH; 100*88d52c6aSLei Wen 101*88d52c6aSLei Wen do { 102*88d52c6aSLei Wen left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ? 103*88d52c6aSLei Wen CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp; 104*88d52c6aSLei Wen s.next_out = dst; 105*88d52c6aSLei Wen s.avail_out = left_len; 106*88d52c6aSLei Wen r = deflate(&s, flush); 107*88d52c6aSLei Wen if (r == Z_STREAM_ERROR && stoponerr == 1) { 108*88d52c6aSLei Wen printf("Error: deflate() returned %d\n", r); 109*88d52c6aSLei Wen r = -1; 110*88d52c6aSLei Wen goto bail; 111*88d52c6aSLei Wen } 112*88d52c6aSLei Wen if (!func) { 113*88d52c6aSLei Wen dst += (left_len - s.avail_out); 114*88d52c6aSLei Wen *lenp -= (left_len - s.avail_out); 115*88d52c6aSLei Wen } else if (left_len - s.avail_out > 0) { 116*88d52c6aSLei Wen r = func((unsigned long)dst, 117*88d52c6aSLei Wen left_len - s.avail_out); 118*88d52c6aSLei Wen if (r < 0) 119*88d52c6aSLei Wen goto bail; 120*88d52c6aSLei Wen } 121*88d52c6aSLei Wen } while (s.avail_out == 0 && (*lenp > 0)); 122*88d52c6aSLei Wen if (s.avail_in) { 123*88d52c6aSLei Wen printf("Deflate failed to consume %u bytes", s.avail_in); 124*88d52c6aSLei Wen r = -1; 125*88d52c6aSLei Wen goto bail; 126*88d52c6aSLei Wen } 127*88d52c6aSLei Wen if (*lenp == 0) { 128*88d52c6aSLei Wen printf("Deflate need more space to compress " 129*88d52c6aSLei Wen "left %lu bytes\n", srclen); 130*88d52c6aSLei Wen r = -1; 131*88d52c6aSLei Wen goto bail; 132*88d52c6aSLei Wen } 133*88d52c6aSLei Wen srclen -= comp_len; 134*88d52c6aSLei Wen src += comp_len; 135*88d52c6aSLei Wen } 136*88d52c6aSLei Wen 137*88d52c6aSLei Wen r = 0; 138*88d52c6aSLei Wen bail: 139*88d52c6aSLei Wen deflateEnd(&s); 140*88d52c6aSLei Wen *lenp = orig - *lenp; 141*88d52c6aSLei Wen return r; 142*88d52c6aSLei Wen } 143