]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
zlib: add gunzip() support
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Fri, 26 Jan 2018 02:42:01 +0000 (11:42 +0900)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Thu, 1 Feb 2018 15:18:54 +0000 (00:18 +0900)
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>
include/lib/zlib/tf_gunzip.h [new file with mode: 0644]
lib/zlib/tf_gunzip.c [new file with mode: 0644]
lib/zlib/zlib.mk [new file with mode: 0644]

diff --git a/include/lib/zlib/tf_gunzip.h b/include/lib/zlib/tf_gunzip.h
new file mode 100644 (file)
index 0000000..46d20eb
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TF_GUNZIP_H__
+#define __TF_GUNZIP_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+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);
+
+#endif /* __TF_GUNZIP_H___ */
diff --git a/lib/zlib/tf_gunzip.c b/lib/zlib/tf_gunzip.c
new file mode 100644 (file)
index 0000000..f07c380
--- /dev/null
@@ -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 (file)
index 0000000..98d4efa
--- /dev/null
@@ -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