blob: 3ac80bc5b962c20ba51546d359465596bcbb4631 [file] [log] [blame]
Masahiro Yamada55a040e2018-01-26 11:42:01 +09001/*
Manish V Badarkhe8ebcea32021-07-02 20:18:57 +01002 * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
Masahiro Yamada55a040e2018-01-26 11:42:01 +09003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Masahiro Yamada55a040e2018-01-26 11:42:01 +09008#include <errno.h>
9#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <common/debug.h>
Manish V Badarkhe8ebcea32021-07-02 20:18:57 +010012#include <common/tf_crc32.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <lib/utils.h>
Masahiro Yamada55a040e2018-01-26 11:42:01 +090014#include <tf_gunzip.h>
Masahiro Yamada55a040e2018-01-26 11:42:01 +090015
16#include "zutil.h"
17
18/*
19 * memory allocated by malloc() is supposed to be aligned for any built-in type
20 */
21#define ZALLOC_ALIGNMENT sizeof(void *)
22
23static uintptr_t zalloc_start;
24static uintptr_t zalloc_end;
25static uintptr_t zalloc_current;
26
27static void * ZLIB_INTERNAL zcalloc(void *opaque, unsigned int items,
28 unsigned int size)
29{
30 uintptr_t p, p_end;
31
32 size *= items;
33
34 p = round_up(zalloc_current, ZALLOC_ALIGNMENT);
35 p_end = p + size;
36
37 if (p_end > zalloc_end)
38 return NULL;
39
40 memset((void *)p, 0, size);
41
42 zalloc_current = p_end;
43
44 return (void *)p;
45}
46
47static void ZLIB_INTERNAL zfree(void *opaque, void *ptr)
48{
49}
50
51/*
52 * gunzip - decompress gzip data
53 * @in_buf: source of compressed input. Upon exit, the end of input.
54 * @in_len: length of in_buf
55 * @out_buf: destination of decompressed output. Upon exit, the end of output.
56 * @out_len: length of out_buf
57 * @work_buf: workspace
58 * @work_len: length of workspace
59 */
60int gunzip(uintptr_t *in_buf, size_t in_len, uintptr_t *out_buf,
61 size_t out_len, uintptr_t work_buf, size_t work_len)
62{
63 z_stream stream;
64 int zret, ret;
65
66 zalloc_start = work_buf;
67 zalloc_end = work_buf + work_len;
68 zalloc_current = zalloc_start;
69
70 stream.next_in = (typeof(stream.next_in))*in_buf;
71 stream.avail_in = in_len;
72 stream.next_out = (typeof(stream.next_out))*out_buf;
73 stream.avail_out = out_len;
74 stream.zalloc = zcalloc;
75 stream.zfree = zfree;
76 stream.opaque = (voidpf)0;
77
78 zret = inflateInit(&stream);
79 if (zret != Z_OK) {
80 ERROR("zlib: inflate init failed (ret = %d)\n", zret);
81 return (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
82 }
83
84 zret = inflate(&stream, Z_NO_FLUSH);
85 if (zret == Z_STREAM_END) {
86 ret = 0;
87 } else {
88 if (stream.msg)
89 ERROR("%s\n", stream.msg);
90 ERROR("zlib: inflate failed (ret = %d)\n", zret);
91 ret = (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
92 }
93
Sandrine Bailleux4d8938a2018-02-07 10:32:01 +010094 VERBOSE("zlib: %lu byte input\n", stream.total_in);
95 VERBOSE("zlib: %lu byte output\n", stream.total_out);
Masahiro Yamada55a040e2018-01-26 11:42:01 +090096
97 *in_buf = (uintptr_t)stream.next_in;
98 *out_buf = (uintptr_t)stream.next_out;
99
100 inflateEnd(&stream);
101
102 return ret;
103}
Manish V Badarkhe8ebcea32021-07-02 20:18:57 +0100104
105/* Wrapper function to calculate CRC
106 * @crc: previous accumulated CRC
107 * @buf: buffer base address
108 * @size: size of the buffer
109 *
110 * Return calculated CRC32 value
111 */
112uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size)
113{
114 return (uint32_t)crc32((unsigned long)crc, buf, size);
115}