diff --git a/include/lib/zlib/tf_gunzip.h b/include/lib/zlib/tf_gunzip.h new file mode 100644 index 0000000..46d20eb --- /dev/null +++ b/include/lib/zlib/tf_gunzip.h @@ -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 +#include + +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 index 0000000..f07c380 --- /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 +#include +#include +#include +#include +#include + +#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 0000000..98d4efa --- /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