aboutsummaryrefslogtreecommitdiff
path: root/lib/zlib
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2018-01-26 11:42:01 +0900
committerMasahiro Yamada <yamada.masahiro@socionext.com>2018-02-02 00:18:54 +0900
commitc43d68510e309b8e8d152c158ec46450f14d72a6 (patch)
tree3c8f200dcc9ec93b069c2f84ae831f4eeb75612d /lib/zlib
parent221b1638aed1bedd7b17802d66c3288c07a60c85 (diff)
downloadtrusted-firmware-a-c43d68510e309b8e8d152c158ec46450f14d72a6.tar.gz
zlib: add gunzip() support
This commit adds some more files to use zlib from TF. To use zlib, ->zalloc and ->zfree hooks are needed. The implementation depends on the system. For user-space, the libc provides malloc() and friends. Unfortunately, ARM Trusted Firmware does not provide malloc() or any concept of dynamic memory allocation. I implemented very simple calloc() and free() for this. Stupidly, zfree() never frees memory, but it works enough for this. The purpose of using zlib is to implement gunzip() - this function takes compressed data from in_buf, then dumps the decompressed data to oub_buf. The work_buf is used for memory allocation during the decompress. Upon exit, it updates in_buf and out_buf. If successful, in_buf points to the end of input data, out_buf to the end of the decompressed data. To use this feature, you need to do: - include lib/zlib/zlib.mk from your platform.mk - add $(ZLIB_SOURCES) to your BL*_SOURCES Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'lib/zlib')
-rw-r--r--lib/zlib/tf_gunzip.c101
-rw-r--r--lib/zlib/zlib.mk25
2 files changed, 126 insertions, 0 deletions
diff --git a/lib/zlib/tf_gunzip.c b/lib/zlib/tf_gunzip.c
new file mode 100644
index 0000000000..f07c380a1f
--- /dev/null
+++ b/lib/zlib/tf_gunzip.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <string.h>
+#include <tf_gunzip.h>
+#include <utils.h>
+
+#include "zutil.h"
+
+/*
+ * memory allocated by malloc() is supposed to be aligned for any built-in type
+ */
+#define ZALLOC_ALIGNMENT sizeof(void *)
+
+static uintptr_t zalloc_start;
+static uintptr_t zalloc_end;
+static uintptr_t zalloc_current;
+
+static void * ZLIB_INTERNAL zcalloc(void *opaque, unsigned int items,
+ unsigned int size)
+{
+ uintptr_t p, p_end;
+
+ size *= items;
+
+ p = round_up(zalloc_current, ZALLOC_ALIGNMENT);
+ p_end = p + size;
+
+ if (p_end > zalloc_end)
+ return NULL;
+
+ memset((void *)p, 0, size);
+
+ zalloc_current = p_end;
+
+ return (void *)p;
+}
+
+static void ZLIB_INTERNAL zfree(void *opaque, void *ptr)
+{
+}
+
+/*
+ * gunzip - decompress gzip data
+ * @in_buf: source of compressed input. Upon exit, the end of input.
+ * @in_len: length of in_buf
+ * @out_buf: destination of decompressed output. Upon exit, the end of output.
+ * @out_len: length of out_buf
+ * @work_buf: workspace
+ * @work_len: length of workspace
+ */
+int gunzip(uintptr_t *in_buf, size_t in_len, uintptr_t *out_buf,
+ size_t out_len, uintptr_t work_buf, size_t work_len)
+{
+ z_stream stream;
+ int zret, ret;
+
+ zalloc_start = work_buf;
+ zalloc_end = work_buf + work_len;
+ zalloc_current = zalloc_start;
+
+ stream.next_in = (typeof(stream.next_in))*in_buf;
+ stream.avail_in = in_len;
+ stream.next_out = (typeof(stream.next_out))*out_buf;
+ stream.avail_out = out_len;
+ stream.zalloc = zcalloc;
+ stream.zfree = zfree;
+ stream.opaque = (voidpf)0;
+
+ zret = inflateInit(&stream);
+ if (zret != Z_OK) {
+ ERROR("zlib: inflate init failed (ret = %d)\n", zret);
+ return (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
+ }
+
+ zret = inflate(&stream, Z_NO_FLUSH);
+ if (zret == Z_STREAM_END) {
+ ret = 0;
+ } else {
+ if (stream.msg)
+ ERROR("%s\n", stream.msg);
+ ERROR("zlib: inflate failed (ret = %d)\n", zret);
+ ret = (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
+ }
+
+ VERBOSE("zlib: %d byte input\n", stream.total_in);
+ VERBOSE("zlib: %d byte output\n", stream.total_out);
+
+ *in_buf = (uintptr_t)stream.next_in;
+ *out_buf = (uintptr_t)stream.next_out;
+
+ inflateEnd(&stream);
+
+ return ret;
+}
diff --git a/lib/zlib/zlib.mk b/lib/zlib/zlib.mk
new file mode 100644
index 0000000000..98d4efaa81
--- /dev/null
+++ b/lib/zlib/zlib.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ZLIB_PATH := lib/zlib
+
+# Imported from zlib 1.2.11 (do not modify them)
+ZLIB_SOURCES := $(addprefix $(ZLIB_PATH)/, \
+ adler32.c \
+ crc32.c \
+ inffast.c \
+ inflate.c \
+ inftrees.c \
+ zutil.c)
+
+# Implemented for TF
+ZLIB_SOURCES += $(addprefix $(ZLIB_PATH)/, \
+ tf_gunzip.c)
+
+INCLUDES += -Iinclude/lib/zlib
+
+# REVISIT: the following flags need not be given globally
+TF_CFLAGS += -DZ_SOLO -DDEF_WBITS=31