| // SPDX-License-Identifier: GPL-2.0-only |
| /* |
| * linux/arch/unicore32/boot/compressed/misc.c |
| * |
| * Code specific to PKUnity SoC and UniCore ISA |
| * |
| * Copyright (C) 2001-2010 GUAN Xue-tao |
| */ |
| |
| #include <asm/unaligned.h> |
| #include <mach/uncompress.h> |
| |
| /* |
| * gzip delarations |
| */ |
| unsigned char *output_data; |
| unsigned long output_ptr; |
| |
| unsigned int free_mem_ptr; |
| unsigned int free_mem_end_ptr; |
| |
| #define STATIC static |
| #define STATIC_RW_DATA /* non-static please */ |
| |
| /* |
| * arch-dependent implementations |
| */ |
| #ifndef ARCH_HAVE_DECOMP_ERROR |
| #define arch_decomp_error(x) |
| #endif |
| |
| #ifndef ARCH_HAVE_DECOMP_SETUP |
| #define arch_decomp_setup() |
| #endif |
| |
| #ifndef ARCH_HAVE_DECOMP_PUTS |
| #define arch_decomp_puts(p) |
| #endif |
| |
| void *memcpy(void *dest, const void *src, size_t n) |
| { |
| int i = 0; |
| unsigned char *d = (unsigned char *)dest, *s = (unsigned char *)src; |
| |
| for (i = n >> 3; i > 0; i--) { |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| } |
| |
| if (n & 1 << 2) { |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| *d++ = *s++; |
| } |
| |
| if (n & 1 << 1) { |
| *d++ = *s++; |
| *d++ = *s++; |
| } |
| |
| if (n & 1) |
| *d++ = *s++; |
| |
| return dest; |
| } |
| |
| void error(char *x) |
| { |
| arch_decomp_puts("\n\n"); |
| arch_decomp_puts(x); |
| arch_decomp_puts("\n\n -- System halted"); |
| |
| arch_decomp_error(x); |
| |
| for (;;) |
| ; /* Halt */ |
| } |
| |
| /* Heap size should be adjusted for different decompress method */ |
| #ifdef CONFIG_KERNEL_GZIP |
| #include "../../../../lib/decompress_inflate.c" |
| #endif |
| |
| #ifdef CONFIG_KERNEL_BZIP2 |
| #include "../../../../lib/decompress_bunzip2.c" |
| #endif |
| |
| #ifdef CONFIG_KERNEL_LZO |
| #include "../../../../lib/decompress_unlzo.c" |
| #endif |
| |
| #ifdef CONFIG_KERNEL_LZMA |
| #include "../../../../lib/decompress_unlzma.c" |
| #endif |
| |
| unsigned long decompress_kernel(unsigned long output_start, |
| unsigned long free_mem_ptr_p, |
| unsigned long free_mem_ptr_end_p) |
| { |
| unsigned char *tmp; |
| |
| output_data = (unsigned char *)output_start; |
| free_mem_ptr = free_mem_ptr_p; |
| free_mem_end_ptr = free_mem_ptr_end_p; |
| |
| arch_decomp_setup(); |
| |
| tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); |
| output_ptr = get_unaligned_le32(tmp); |
| |
| arch_decomp_puts("Uncompressing Linux..."); |
| __decompress(input_data, input_data_end - input_data, NULL, NULL, |
| output_data, 0, NULL, error); |
| arch_decomp_puts(" done, booting the kernel.\n"); |
| return output_ptr; |
| } |