blob: 2595b2d04b42899e103e717bb5e9c071f76a2d78 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Lei Wen7592d1b2012-09-28 04:26:46 +00002/*
3 * (C) Copyright 2012
4 * Lei Wen <leiwen@marvell.com>, Marvell Inc.
Lei Wen7592d1b2012-09-28 04:26:46 +00005 */
6
7#include <common.h>
8#include <watchdog.h>
9#include <command.h>
Simon Glass1a974af2019-08-01 09:46:36 -060010#include <gzip.h>
Lei Wen7592d1b2012-09-28 04:26:46 +000011#include <image.h>
12#include <malloc.h>
Simon Glassa87fc0a2015-09-02 17:24:57 -060013#include <memalign.h>
Lei Wen7592d1b2012-09-28 04:26:46 +000014#include <u-boot/zlib.h>
15#include "zlib/zutil.h"
16
Tom Rini364d0022023-01-10 11:19:45 -050017#ifndef CFG_GZIP_COMPRESS_DEF_SZ
18#define CFG_GZIP_COMPRESS_DEF_SZ 0x200
Lei Wen7592d1b2012-09-28 04:26:46 +000019#endif
20#define ZALLOC_ALIGNMENT 16
21
22static void *zalloc(void *x, unsigned items, unsigned size)
23{
24 void *p;
25
26 size *= items;
27 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
28
Marcel Ziswilerabc574b2015-08-18 13:06:37 +020029 p = malloc_cache_aligned(size);
Lei Wen7592d1b2012-09-28 04:26:46 +000030
31 return (p);
32}
33
34static void zfree(void *x, void *addr, unsigned nb)
35{
36 free (addr);
37}
38
39int gzip(void *dst, unsigned long *lenp,
40 unsigned char *src, unsigned long srclen)
41{
42 return zzip(dst, lenp, src, srclen, 1, NULL);
43}
44
45/*
46 * Compress blocks with zlib
47 */
48int zzip(void *dst, unsigned long *lenp, unsigned char *src,
49 unsigned long srclen, int stoponerr,
50 int (*func)(unsigned long, unsigned long))
51{
52 z_stream s;
53 int r, flush, orig, window;
54 unsigned long comp_len, left_len;
55
56 if (!srclen)
57 return 0;
58
59#ifndef CONFIG_GZIP
60 window = MAX_WBITS;
61#else
62 window = 2 * MAX_WBITS;
63#endif
64 orig = *lenp;
65 s.zalloc = zalloc;
66 s.zfree = zfree;
67 s.opaque = Z_NULL;
68
69 r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window,
70 DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
71 ZLIB_VERSION, sizeof(z_stream));
72 if (r != Z_OK) {
73 printf ("Error: deflateInit2_() returned %d\n", r);
74 return -1;
75 }
76
77 while (srclen > 0) {
Tom Rini364d0022023-01-10 11:19:45 -050078 comp_len = (srclen > CFG_GZIP_COMPRESS_DEF_SZ) ?
79 CFG_GZIP_COMPRESS_DEF_SZ : srclen;
Lei Wen7592d1b2012-09-28 04:26:46 +000080
81 s.next_in = src;
82 s.avail_in = comp_len;
Tom Rini364d0022023-01-10 11:19:45 -050083 flush = (srclen > CFG_GZIP_COMPRESS_DEF_SZ)?
Lei Wen7592d1b2012-09-28 04:26:46 +000084 Z_NO_FLUSH : Z_FINISH;
85
86 do {
Tom Rini364d0022023-01-10 11:19:45 -050087 left_len = (*lenp > CFG_GZIP_COMPRESS_DEF_SZ) ?
88 CFG_GZIP_COMPRESS_DEF_SZ : *lenp;
Lei Wen7592d1b2012-09-28 04:26:46 +000089 s.next_out = dst;
90 s.avail_out = left_len;
91 r = deflate(&s, flush);
92 if (r == Z_STREAM_ERROR && stoponerr == 1) {
93 printf("Error: deflate() returned %d\n", r);
94 r = -1;
95 goto bail;
96 }
97 if (!func) {
98 dst += (left_len - s.avail_out);
99 *lenp -= (left_len - s.avail_out);
100 } else if (left_len - s.avail_out > 0) {
101 r = func((unsigned long)dst,
102 left_len - s.avail_out);
103 if (r < 0)
104 goto bail;
105 }
106 } while (s.avail_out == 0 && (*lenp > 0));
107 if (s.avail_in) {
108 printf("Deflate failed to consume %u bytes", s.avail_in);
109 r = -1;
110 goto bail;
111 }
112 if (*lenp == 0) {
113 printf("Deflate need more space to compress "
114 "left %lu bytes\n", srclen);
115 r = -1;
116 goto bail;
117 }
118 srclen -= comp_len;
119 src += comp_len;
120 }
121
122 r = 0;
123bail:
124 deflateEnd(&s);
125 *lenp = orig - *lenp;
126 return r;
127}