162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/sh/boot/compressed/misc.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * This is a collection of several routines from gzip-1.0.3
662306a36Sopenharmony_ci * adapted for Linux.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Adapted for SH by Stuart Menefy, Aug 1999
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/uaccess.h>
1662306a36Sopenharmony_ci#include <asm/addrspace.h>
1762306a36Sopenharmony_ci#include <asm/page.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*
2062306a36Sopenharmony_ci * gzip declarations
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define STATIC static
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#undef memset
2662306a36Sopenharmony_ci#undef memcpy
2762306a36Sopenharmony_ci#define memzero(s, n)     memset ((s), 0, (n))
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* cache.c */
3062306a36Sopenharmony_ci#define CACHE_ENABLE      0
3162306a36Sopenharmony_ci#define CACHE_DISABLE     1
3262306a36Sopenharmony_ciint cache_control(unsigned int command);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciextern char input_data[];
3562306a36Sopenharmony_ciextern int input_len;
3662306a36Sopenharmony_cistatic unsigned char *output;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic void error(char *m);
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciint puts(const char *);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciextern int _text;		/* Defined in vmlinux.lds.S */
4362306a36Sopenharmony_ciextern int _end;
4462306a36Sopenharmony_cistatic unsigned long free_mem_ptr;
4562306a36Sopenharmony_cistatic unsigned long free_mem_end_ptr;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#ifdef CONFIG_HAVE_KERNEL_BZIP2
4862306a36Sopenharmony_ci#define HEAP_SIZE	0x400000
4962306a36Sopenharmony_ci#else
5062306a36Sopenharmony_ci#define HEAP_SIZE	0x10000
5162306a36Sopenharmony_ci#endif
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#ifdef CONFIG_KERNEL_GZIP
5462306a36Sopenharmony_ci#include "../../../../lib/decompress_inflate.c"
5562306a36Sopenharmony_ci#endif
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#ifdef CONFIG_KERNEL_BZIP2
5862306a36Sopenharmony_ci#include "../../../../lib/decompress_bunzip2.c"
5962306a36Sopenharmony_ci#endif
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#ifdef CONFIG_KERNEL_LZMA
6262306a36Sopenharmony_ci#include "../../../../lib/decompress_unlzma.c"
6362306a36Sopenharmony_ci#endif
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#ifdef CONFIG_KERNEL_XZ
6662306a36Sopenharmony_ci#include "../../../../lib/decompress_unxz.c"
6762306a36Sopenharmony_ci#endif
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#ifdef CONFIG_KERNEL_LZO
7062306a36Sopenharmony_ci#include "../../../../lib/decompress_unlzo.c"
7162306a36Sopenharmony_ci#endif
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciint puts(const char *s)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	/* This should be updated to use the sh-sci routines */
7662306a36Sopenharmony_ci	return 0;
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_civoid* memset(void* s, int c, size_t n)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	int i;
8262306a36Sopenharmony_ci	char *ss = (char*)s;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	for (i=0;i<n;i++) ss[i] = c;
8562306a36Sopenharmony_ci	return s;
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_civoid* memcpy(void* __dest, __const void* __src,
8962306a36Sopenharmony_ci			    size_t __n)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	int i;
9262306a36Sopenharmony_ci	char *d = (char *)__dest, *s = (char *)__src;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	for (i=0;i<__n;i++) d[i] = s[i];
9562306a36Sopenharmony_ci	return __dest;
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic void error(char *x)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	puts("\n\n");
10162306a36Sopenharmony_ci	puts(x);
10262306a36Sopenharmony_ci	puts("\n\n -- System halted");
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	while(1);	/* Halt */
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciconst unsigned long __stack_chk_guard = 0x000a0dff;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_civoid __stack_chk_fail(void)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	error("stack-protector: Kernel stack is corrupted\n");
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/* Needed because vmlinux.lds.h references this */
11562306a36Sopenharmony_civoid ftrace_stub(void)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_civoid arch_ftrace_ops_list_func(void)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#define stackalign	4
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci#define STACK_SIZE (4096)
12562306a36Sopenharmony_cilong __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
12662306a36Sopenharmony_cilong *stack_start = &user_stack[STACK_SIZE];
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_civoid decompress_kernel(void)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	unsigned long output_addr;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
13362306a36Sopenharmony_ci#if defined(CONFIG_29BIT)
13462306a36Sopenharmony_ci	output_addr |= P2SEG;
13562306a36Sopenharmony_ci#endif
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	output = (unsigned char *)output_addr;
13862306a36Sopenharmony_ci	free_mem_ptr = (unsigned long)&_end;
13962306a36Sopenharmony_ci	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	puts("Uncompressing Linux... ");
14262306a36Sopenharmony_ci	cache_control(CACHE_ENABLE);
14362306a36Sopenharmony_ci	__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
14462306a36Sopenharmony_ci	cache_control(CACHE_DISABLE);
14562306a36Sopenharmony_ci	puts("Ok, booting the kernel.\n");
14662306a36Sopenharmony_ci}
147