/*
 * Definitions and wrapper functions for kernel decompressor
 *
 *   (C) 2017 Helge Deller <deller@gmx.de>
 */

#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <asm/page.h>
#include "sizes.h"

/*
 * gzip declarations
 */
#define STATIC static

#undef memmove
#define memmove memmove
#define memzero(s, n) memset((s), 0, (n))

#define malloc	malloc_gzip
#define free	free_gzip

/* Symbols defined by linker scripts */
extern char input_data[];
extern int input_len;
extern __le32 output_len;	/* at unaligned address, little-endian */
extern char _text, _end;
extern char _bss, _ebss;
extern char _startcode_end;
extern void startup_continue(void *entry, unsigned long cmdline,
	unsigned long rd_start, unsigned long rd_end) __noreturn;

void error(char *m) __noreturn;

static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;

#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif

#ifdef CONFIG_KERNEL_BZIP2
#include "../../../../lib/decompress_bunzip2.c"
#endif

#ifdef CONFIG_KERNEL_LZ4
#include "../../../../lib/decompress_unlz4.c"
#endif

#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif

#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif

#ifdef CONFIG_KERNEL_XZ
#include "../../../../lib/decompress_unxz.c"
#endif

void *memmove(void *dest, const void *src, size_t n)
{
	const char *s = src;
	char *d = dest;

	if (d <= s) {
		while (n--)
			*d++ = *s++;
	} else {
		d += n;
		s += n;
		while (n--)
			*--d = *--s;
	}
	return dest;
}

void *memset(void *s, int c, size_t count)
{
	char *xs = (char *)s;

	while (count--)
		*xs++ = c;
	return s;
}

void *memcpy(void *d, const void *s, size_t len)
{
	char *dest = (char *)d;
	const char *source = (const char *)s;

	while (len--)
		*dest++ = *source++;
	return d;
}

size_t strlen(const char *s)
{
	const char *sc;

	for (sc = s; *sc != '\0'; ++sc)
		;
	return sc - s;
}

char *strchr(const char *s, int c)
{
	while (*s) {
		if (*s == (char)c)
			return (char *)s;
		++s;
	}
	return NULL;
}

int puts(const char *s)
{
	const char *nuline = s;

	while ((nuline = strchr(s, '\n')) != NULL) {
		if (nuline != s)
			pdc_iodc_print(s, nuline - s);
			pdc_iodc_print("\r\n", 2);
			s = nuline + 1;
	}
	if (*s != '\0')
		pdc_iodc_print(s, strlen(s));

	return 0;
}

static int putchar(int c)
{
	char buf[2];

	buf[0] = c;
	buf[1] = '\0';
	puts(buf);
	return c;
}

void __noreturn error(char *x)
{
	puts("\n\n");
	puts(x);
	puts("\n\n -- System halted");
	while (1)	/* wait forever */
		;
}

static int print_hex(unsigned long num)
{
	const char hex[] = "0123456789abcdef";
	char str[40];
	int i = sizeof(str)-1;

	str[i--] = '\0';
	do {
		str[i--] = hex[num & 0x0f];
		num >>= 4;
	} while (num);

	str[i--] = 'x';
	str[i] = '0';
	puts(&str[i]);

	return 0;
}

int printf(const char *fmt, ...)
{
	va_list args;
	int i = 0;

	va_start(args, fmt);

	while (fmt[i]) {
		if (fmt[i] != '%') {
put:
			putchar(fmt[i++]);
			continue;
		}

		if (fmt[++i] == '%')
			goto put;
		++i;
		print_hex(va_arg(args, unsigned long));
	}

	va_end(args);
	return 0;
}

/* helper functions for libgcc */
void abort(void)
{
	error("aborted.");
}

#undef malloc
void *malloc(size_t size)
{
	return malloc_gzip(size);
}

#undef free
void free(void *ptr)
{
	return free_gzip(ptr);
}


static void flush_data_cache(char *start, unsigned long length)
{
	char *end = start + length;

	do {
		asm volatile("fdc 0(%0)" : : "r" (start));
		asm volatile("fic 0(%%sr0,%0)" : : "r" (start));
		start += 16;
	} while (start < end);
	asm volatile("fdc 0(%0)" : : "r" (end));

	asm ("sync");
}

unsigned long decompress_kernel(unsigned int started_wide,
		unsigned int command_line,
		const unsigned int rd_start,
		const unsigned int rd_end)
{
	char *output;
	unsigned long len, len_all;

#ifdef CONFIG_64BIT
	parisc_narrow_firmware = 0;
#endif

	set_firmware_width_unlocked();

	putchar('U');	/* if you get this p and no more, string storage */
			/* in $GLOBAL$ is wrong or %dp is wrong */
	puts("ncompressing ...\n");

	output = (char *) KERNEL_BINARY_TEXT_START;
	len_all = __pa(SZ_end) - __pa(SZparisc_kernel_start);

	if ((unsigned long) &_startcode_end > (unsigned long) output)
		error("Bootcode overlaps kernel code");

	len = get_unaligned_le32(&output_len);
	if (len > len_all)
		error("Output len too big.");
	else
		memset(&output[len], 0, len_all - len);

	/*
	 * Initialize free_mem_ptr and free_mem_end_ptr.
	 */
	free_mem_ptr = (unsigned long) &_ebss;
	free_mem_ptr += 2*1024*1024;	/* leave 2 MB for stack */

	/* Limit memory for bootoader to 1GB */
	#define ARTIFICIAL_LIMIT (1*1024*1024*1024)
	free_mem_end_ptr = PAGE0->imm_max_mem;
	if (free_mem_end_ptr > ARTIFICIAL_LIMIT)
		free_mem_end_ptr = ARTIFICIAL_LIMIT;

#ifdef CONFIG_BLK_DEV_INITRD
	/* if we have ramdisk this is at end of memory */
	if (rd_start && rd_start < free_mem_end_ptr)
		free_mem_end_ptr = rd_start;
#endif

#ifdef DEBUG
	printf("startcode_end = %x\n", &_startcode_end);
	printf("commandline   = %x\n", command_line);
	printf("rd_start      = %x\n", rd_start);
	printf("rd_end        = %x\n", rd_end);

	printf("free_ptr      = %x\n", free_mem_ptr);
	printf("free_ptr_end  = %x\n", free_mem_end_ptr);

	printf("input_data    = %x\n", input_data);
	printf("input_len     = %x\n", input_len);
	printf("output        = %x\n", output);
	printf("output_len    = %x\n", len);
	printf("output_max    = %x\n", len_all);
#endif

	__decompress(input_data, input_len, NULL, NULL,
			output, 0, NULL, error);

	flush_data_cache(output, len);

	printf("Booting kernel ...\n\n");

	return (unsigned long) output;
}
