xref: /rk3399_ARM-atf/lib/zlib/tf_gunzip.c (revision 09d40e0e08283a249e7dce0e106c07c5141f9b7e)
1c43d6851SMasahiro Yamada /*
2c43d6851SMasahiro Yamada  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3c43d6851SMasahiro Yamada  *
4c43d6851SMasahiro Yamada  * SPDX-License-Identifier: BSD-3-Clause
5c43d6851SMasahiro Yamada  */
6c43d6851SMasahiro Yamada 
7c43d6851SMasahiro Yamada #include <assert.h>
8c43d6851SMasahiro Yamada #include <errno.h>
9c43d6851SMasahiro Yamada #include <string.h>
10*09d40e0eSAntonio Nino Diaz 
11*09d40e0eSAntonio Nino Diaz #include <common/debug.h>
12*09d40e0eSAntonio Nino Diaz #include <lib/utils.h>
13c43d6851SMasahiro Yamada #include <tf_gunzip.h>
14c43d6851SMasahiro Yamada 
15c43d6851SMasahiro Yamada #include "zutil.h"
16c43d6851SMasahiro Yamada 
17c43d6851SMasahiro Yamada /*
18c43d6851SMasahiro Yamada  * memory allocated by malloc() is supposed to be aligned for any built-in type
19c43d6851SMasahiro Yamada  */
20c43d6851SMasahiro Yamada #define ZALLOC_ALIGNMENT	sizeof(void *)
21c43d6851SMasahiro Yamada 
22c43d6851SMasahiro Yamada static uintptr_t zalloc_start;
23c43d6851SMasahiro Yamada static uintptr_t zalloc_end;
24c43d6851SMasahiro Yamada static uintptr_t zalloc_current;
25c43d6851SMasahiro Yamada 
26c43d6851SMasahiro Yamada static void * ZLIB_INTERNAL zcalloc(void *opaque, unsigned int items,
27c43d6851SMasahiro Yamada 				    unsigned int size)
28c43d6851SMasahiro Yamada {
29c43d6851SMasahiro Yamada 	uintptr_t p, p_end;
30c43d6851SMasahiro Yamada 
31c43d6851SMasahiro Yamada 	size *= items;
32c43d6851SMasahiro Yamada 
33c43d6851SMasahiro Yamada 	p = round_up(zalloc_current, ZALLOC_ALIGNMENT);
34c43d6851SMasahiro Yamada 	p_end = p + size;
35c43d6851SMasahiro Yamada 
36c43d6851SMasahiro Yamada 	if (p_end > zalloc_end)
37c43d6851SMasahiro Yamada 		return NULL;
38c43d6851SMasahiro Yamada 
39c43d6851SMasahiro Yamada 	memset((void *)p, 0, size);
40c43d6851SMasahiro Yamada 
41c43d6851SMasahiro Yamada 	zalloc_current = p_end;
42c43d6851SMasahiro Yamada 
43c43d6851SMasahiro Yamada 	return (void *)p;
44c43d6851SMasahiro Yamada }
45c43d6851SMasahiro Yamada 
46c43d6851SMasahiro Yamada static void ZLIB_INTERNAL zfree(void *opaque, void *ptr)
47c43d6851SMasahiro Yamada {
48c43d6851SMasahiro Yamada }
49c43d6851SMasahiro Yamada 
50c43d6851SMasahiro Yamada /*
51c43d6851SMasahiro Yamada  * gunzip - decompress gzip data
52c43d6851SMasahiro Yamada  * @in_buf: source of compressed input. Upon exit, the end of input.
53c43d6851SMasahiro Yamada  * @in_len: length of in_buf
54c43d6851SMasahiro Yamada  * @out_buf: destination of decompressed output. Upon exit, the end of output.
55c43d6851SMasahiro Yamada  * @out_len: length of out_buf
56c43d6851SMasahiro Yamada  * @work_buf: workspace
57c43d6851SMasahiro Yamada  * @work_len: length of workspace
58c43d6851SMasahiro Yamada  */
59c43d6851SMasahiro Yamada int gunzip(uintptr_t *in_buf, size_t in_len, uintptr_t *out_buf,
60c43d6851SMasahiro Yamada 	   size_t out_len, uintptr_t work_buf, size_t work_len)
61c43d6851SMasahiro Yamada {
62c43d6851SMasahiro Yamada 	z_stream stream;
63c43d6851SMasahiro Yamada 	int zret, ret;
64c43d6851SMasahiro Yamada 
65c43d6851SMasahiro Yamada 	zalloc_start = work_buf;
66c43d6851SMasahiro Yamada 	zalloc_end = work_buf + work_len;
67c43d6851SMasahiro Yamada 	zalloc_current = zalloc_start;
68c43d6851SMasahiro Yamada 
69c43d6851SMasahiro Yamada 	stream.next_in = (typeof(stream.next_in))*in_buf;
70c43d6851SMasahiro Yamada 	stream.avail_in = in_len;
71c43d6851SMasahiro Yamada 	stream.next_out = (typeof(stream.next_out))*out_buf;
72c43d6851SMasahiro Yamada 	stream.avail_out = out_len;
73c43d6851SMasahiro Yamada 	stream.zalloc = zcalloc;
74c43d6851SMasahiro Yamada 	stream.zfree = zfree;
75c43d6851SMasahiro Yamada 	stream.opaque = (voidpf)0;
76c43d6851SMasahiro Yamada 
77c43d6851SMasahiro Yamada 	zret = inflateInit(&stream);
78c43d6851SMasahiro Yamada 	if (zret != Z_OK) {
79c43d6851SMasahiro Yamada 		ERROR("zlib: inflate init failed (ret = %d)\n", zret);
80c43d6851SMasahiro Yamada 		return (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
81c43d6851SMasahiro Yamada 	}
82c43d6851SMasahiro Yamada 
83c43d6851SMasahiro Yamada 	zret = inflate(&stream, Z_NO_FLUSH);
84c43d6851SMasahiro Yamada 	if (zret == Z_STREAM_END) {
85c43d6851SMasahiro Yamada 		ret = 0;
86c43d6851SMasahiro Yamada 	} else {
87c43d6851SMasahiro Yamada 		if (stream.msg)
88c43d6851SMasahiro Yamada 			ERROR("%s\n", stream.msg);
89c43d6851SMasahiro Yamada 		ERROR("zlib: inflate failed (ret = %d)\n", zret);
90c43d6851SMasahiro Yamada 		ret = (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
91c43d6851SMasahiro Yamada 	}
92c43d6851SMasahiro Yamada 
9357546074SSandrine Bailleux 	VERBOSE("zlib: %lu byte input\n", stream.total_in);
9457546074SSandrine Bailleux 	VERBOSE("zlib: %lu byte output\n", stream.total_out);
95c43d6851SMasahiro Yamada 
96c43d6851SMasahiro Yamada 	*in_buf = (uintptr_t)stream.next_in;
97c43d6851SMasahiro Yamada 	*out_buf = (uintptr_t)stream.next_out;
98c43d6851SMasahiro Yamada 
99c43d6851SMasahiro Yamada 	inflateEnd(&stream);
100c43d6851SMasahiro Yamada 
101c43d6851SMasahiro Yamada 	return ret;
102c43d6851SMasahiro Yamada }
103