1b2441318SGreg Kroah-Hartman// SPDX-License-Identifier: GPL-2.0
21844c9bcSMartin Schwidefsky/*
31844c9bcSMartin Schwidefsky * Definitions and wrapper functions for kernel decompressor
41844c9bcSMartin Schwidefsky *
51844c9bcSMartin Schwidefsky * Copyright IBM Corp. 2010
61844c9bcSMartin Schwidefsky *
71844c9bcSMartin Schwidefsky * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
81844c9bcSMartin Schwidefsky */
91844c9bcSMartin Schwidefsky
107516fc11SVasily Gorbik#include <linux/kernel.h>
117516fc11SVasily Gorbik#include <linux/string.h>
121844c9bcSMartin Schwidefsky#include <asm/page.h>
138f75582aSVasily Gorbik#include "decompressor.h"
141844c9bcSMartin Schwidefsky
151844c9bcSMartin Schwidefsky/*
161844c9bcSMartin Schwidefsky * gzip declarations
171844c9bcSMartin Schwidefsky */
181844c9bcSMartin Schwidefsky#define STATIC static
191844c9bcSMartin Schwidefsky
201844c9bcSMartin Schwidefsky#undef memset
211844c9bcSMartin Schwidefsky#undef memcpy
221844c9bcSMartin Schwidefsky#undef memmove
23d7b081acSHeiko Carstens#define memmove memmove
241844c9bcSMartin Schwidefsky#define memzero(s, n) memset((s), 0, (n))
251844c9bcSMartin Schwidefsky
2654f45214SVasily Gorbik#ifdef CONFIG_KERNEL_BZIP2
271b3e3fafSMikhail Zaslonko#define BOOT_HEAP_SIZE	0x400000
287b034d9cSDimitri John Ledkov#elif CONFIG_KERNEL_ZSTD
297b034d9cSDimitri John Ledkov#define BOOT_HEAP_SIZE	0x30000
301844c9bcSMartin Schwidefsky#else
311b3e3fafSMikhail Zaslonko#define BOOT_HEAP_SIZE	0x10000
321844c9bcSMartin Schwidefsky#endif
331844c9bcSMartin Schwidefsky
34a2ac1bb1SVasily Gorbikstatic unsigned long free_mem_ptr = (unsigned long) _end;
351b3e3fafSMikhail Zaslonkostatic unsigned long free_mem_end_ptr = (unsigned long) _end + BOOT_HEAP_SIZE;
36a2ac1bb1SVasily Gorbik
371844c9bcSMartin Schwidefsky#ifdef CONFIG_KERNEL_GZIP
381844c9bcSMartin Schwidefsky#include "../../../../lib/decompress_inflate.c"
391844c9bcSMartin Schwidefsky#endif
401844c9bcSMartin Schwidefsky
411844c9bcSMartin Schwidefsky#ifdef CONFIG_KERNEL_BZIP2
421844c9bcSMartin Schwidefsky#include "../../../../lib/decompress_bunzip2.c"
431844c9bcSMartin Schwidefsky#endif
441844c9bcSMartin Schwidefsky
458e2872ceSHeiko Carstens#ifdef CONFIG_KERNEL_LZ4
468e2872ceSHeiko Carstens#include "../../../../lib/decompress_unlz4.c"
478e2872ceSHeiko Carstens#endif
488e2872ceSHeiko Carstens
491844c9bcSMartin Schwidefsky#ifdef CONFIG_KERNEL_LZMA
501844c9bcSMartin Schwidefsky#include "../../../../lib/decompress_unlzma.c"
511844c9bcSMartin Schwidefsky#endif
521844c9bcSMartin Schwidefsky
53cdf56649SHeiko Carstens#ifdef CONFIG_KERNEL_LZO
54cdf56649SHeiko Carstens#include "../../../../lib/decompress_unlzo.c"
55cdf56649SHeiko Carstens#endif
56cdf56649SHeiko Carstens
57d7b081acSHeiko Carstens#ifdef CONFIG_KERNEL_XZ
58d7b081acSHeiko Carstens#include "../../../../lib/decompress_unxz.c"
59d7b081acSHeiko Carstens#endif
60d7b081acSHeiko Carstens
617b034d9cSDimitri John Ledkov#ifdef CONFIG_KERNEL_ZSTD
627b034d9cSDimitri John Ledkov#include "../../../../lib/decompress_unzstd.c"
637b034d9cSDimitri John Ledkov#endif
647b034d9cSDimitri John Ledkov
651b3e3fafSMikhail Zaslonko#define decompress_offset ALIGN((unsigned long)_end + BOOT_HEAP_SIZE, PAGE_SIZE)
661844c9bcSMartin Schwidefsky
6715426ca4SVasily Gorbikunsigned long mem_safe_offset(void)
6815426ca4SVasily Gorbik{
691844c9bcSMartin Schwidefsky	/*
7015426ca4SVasily Gorbik	 * due to 4MB HEAD_SIZE for bzip2
7115426ca4SVasily Gorbik	 * 'decompress_offset + vmlinux.image_size' could be larger than
7215426ca4SVasily Gorbik	 * kernel at final position + its .bss, so take the larger of two
731844c9bcSMartin Schwidefsky	 */
7415426ca4SVasily Gorbik	return max(decompress_offset + vmlinux.image_size,
7515426ca4SVasily Gorbik		   vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size);
7615426ca4SVasily Gorbik}
7715426ca4SVasily Gorbik
7815426ca4SVasily Gorbikvoid *decompress_kernel(void)
7915426ca4SVasily Gorbik{
8015426ca4SVasily Gorbik	void *output = (void *)decompress_offset;
811844c9bcSMartin Schwidefsky
82369f91c3SVasily Gorbik	__decompress(_compressed_start, _compressed_end - _compressed_start,
83369f91c3SVasily Gorbik		     NULL, NULL, output, 0, NULL, error);
848f75582aSVasily Gorbik	return output;
851844c9bcSMartin Schwidefsky}
86