188d52c6aSLei Wen /* 288d52c6aSLei Wen * (C) Copyright 2012 388d52c6aSLei Wen * Lei Wen <leiwen@marvell.com>, Marvell Inc. 488d52c6aSLei Wen * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 688d52c6aSLei Wen */ 788d52c6aSLei Wen 888d52c6aSLei Wen #include <common.h> 988d52c6aSLei Wen #include <watchdog.h> 1088d52c6aSLei Wen #include <command.h> 1188d52c6aSLei Wen #include <image.h> 1288d52c6aSLei Wen #include <malloc.h> 1388d52c6aSLei Wen #include <u-boot/zlib.h> 1488d52c6aSLei Wen #include "zlib/zutil.h" 1588d52c6aSLei Wen 1688d52c6aSLei Wen #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ 1788d52c6aSLei Wen #define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200 1888d52c6aSLei Wen #endif 1988d52c6aSLei Wen #define ZALLOC_ALIGNMENT 16 2088d52c6aSLei Wen 2188d52c6aSLei Wen static void *zalloc(void *x, unsigned items, unsigned size) 2288d52c6aSLei Wen { 2388d52c6aSLei Wen void *p; 2488d52c6aSLei Wen 2588d52c6aSLei Wen size *= items; 2688d52c6aSLei Wen size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); 2788d52c6aSLei Wen 28*4519668bSMarcel Ziswiler p = malloc_cache_aligned(size); 2988d52c6aSLei Wen 3088d52c6aSLei Wen return (p); 3188d52c6aSLei Wen } 3288d52c6aSLei Wen 3388d52c6aSLei Wen static void zfree(void *x, void *addr, unsigned nb) 3488d52c6aSLei Wen { 3588d52c6aSLei Wen free (addr); 3688d52c6aSLei Wen } 3788d52c6aSLei Wen 3888d52c6aSLei Wen int gzip(void *dst, unsigned long *lenp, 3988d52c6aSLei Wen unsigned char *src, unsigned long srclen) 4088d52c6aSLei Wen { 4188d52c6aSLei Wen return zzip(dst, lenp, src, srclen, 1, NULL); 4288d52c6aSLei Wen } 4388d52c6aSLei Wen 4488d52c6aSLei Wen /* 4588d52c6aSLei Wen * Compress blocks with zlib 4688d52c6aSLei Wen */ 4788d52c6aSLei Wen int zzip(void *dst, unsigned long *lenp, unsigned char *src, 4888d52c6aSLei Wen unsigned long srclen, int stoponerr, 4988d52c6aSLei Wen int (*func)(unsigned long, unsigned long)) 5088d52c6aSLei Wen { 5188d52c6aSLei Wen z_stream s; 5288d52c6aSLei Wen int r, flush, orig, window; 5388d52c6aSLei Wen unsigned long comp_len, left_len; 5488d52c6aSLei Wen 5588d52c6aSLei Wen if (!srclen) 5688d52c6aSLei Wen return 0; 5788d52c6aSLei Wen 5888d52c6aSLei Wen #ifndef CONFIG_GZIP 5988d52c6aSLei Wen window = MAX_WBITS; 6088d52c6aSLei Wen #else 6188d52c6aSLei Wen window = 2 * MAX_WBITS; 6288d52c6aSLei Wen #endif 6388d52c6aSLei Wen orig = *lenp; 6488d52c6aSLei Wen s.zalloc = zalloc; 6588d52c6aSLei Wen s.zfree = zfree; 6688d52c6aSLei Wen s.opaque = Z_NULL; 6788d52c6aSLei Wen 6888d52c6aSLei Wen r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window, 6988d52c6aSLei Wen DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 7088d52c6aSLei Wen ZLIB_VERSION, sizeof(z_stream)); 7188d52c6aSLei Wen if (r != Z_OK) { 7288d52c6aSLei Wen printf ("Error: deflateInit2_() returned %d\n", r); 7388d52c6aSLei Wen return -1; 7488d52c6aSLei Wen } 7588d52c6aSLei Wen 7688d52c6aSLei Wen while (srclen > 0) { 7788d52c6aSLei Wen comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ? 7888d52c6aSLei Wen CONFIG_GZIP_COMPRESS_DEF_SZ : srclen; 7988d52c6aSLei Wen 8088d52c6aSLei Wen s.next_in = src; 8188d52c6aSLei Wen s.avail_in = comp_len; 8288d52c6aSLei Wen flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)? 8388d52c6aSLei Wen Z_NO_FLUSH : Z_FINISH; 8488d52c6aSLei Wen 8588d52c6aSLei Wen do { 8688d52c6aSLei Wen left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ? 8788d52c6aSLei Wen CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp; 8888d52c6aSLei Wen s.next_out = dst; 8988d52c6aSLei Wen s.avail_out = left_len; 9088d52c6aSLei Wen r = deflate(&s, flush); 9188d52c6aSLei Wen if (r == Z_STREAM_ERROR && stoponerr == 1) { 9288d52c6aSLei Wen printf("Error: deflate() returned %d\n", r); 9388d52c6aSLei Wen r = -1; 9488d52c6aSLei Wen goto bail; 9588d52c6aSLei Wen } 9688d52c6aSLei Wen if (!func) { 9788d52c6aSLei Wen dst += (left_len - s.avail_out); 9888d52c6aSLei Wen *lenp -= (left_len - s.avail_out); 9988d52c6aSLei Wen } else if (left_len - s.avail_out > 0) { 10088d52c6aSLei Wen r = func((unsigned long)dst, 10188d52c6aSLei Wen left_len - s.avail_out); 10288d52c6aSLei Wen if (r < 0) 10388d52c6aSLei Wen goto bail; 10488d52c6aSLei Wen } 10588d52c6aSLei Wen } while (s.avail_out == 0 && (*lenp > 0)); 10688d52c6aSLei Wen if (s.avail_in) { 10788d52c6aSLei Wen printf("Deflate failed to consume %u bytes", s.avail_in); 10888d52c6aSLei Wen r = -1; 10988d52c6aSLei Wen goto bail; 11088d52c6aSLei Wen } 11188d52c6aSLei Wen if (*lenp == 0) { 11288d52c6aSLei Wen printf("Deflate need more space to compress " 11388d52c6aSLei Wen "left %lu bytes\n", srclen); 11488d52c6aSLei Wen r = -1; 11588d52c6aSLei Wen goto bail; 11688d52c6aSLei Wen } 11788d52c6aSLei Wen srclen -= comp_len; 11888d52c6aSLei Wen src += comp_len; 11988d52c6aSLei Wen } 12088d52c6aSLei Wen 12188d52c6aSLei Wen r = 0; 12288d52c6aSLei Wen bail: 12388d52c6aSLei Wen deflateEnd(&s); 12488d52c6aSLei Wen *lenp = orig - *lenp; 12588d52c6aSLei Wen return r; 12688d52c6aSLei Wen } 127