// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2008-2011
 * Graeme Russ, <graeme.russ@gmail.com>
 *
 * (C) Copyright 2002
 * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
 *
 * (C) Copyright 2002
 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 */

#include <common.h>
#include <log.h>
#include <relocate.h>
#include <asm/global_data.h>
#include <asm/u-boot-x86.h>
#include <asm/sections.h>
#include <elf.h>

DECLARE_GLOBAL_DATA_PTR;

int copy_uboot_to_ram(void)
{
	size_t len = (uintptr_t)&__data_end - (uintptr_t)&__text_start;

	if (gd->flags & GD_FLG_SKIP_RELOC)
		return 0;
	memcpy((void *)gd->relocaddr, (void *)&__text_start, len);

	return 0;
}

int clear_bss(void)
{
	ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
	size_t len = (uintptr_t)&__bss_end - (uintptr_t)&__bss_start;

	if (gd->flags & GD_FLG_SKIP_RELOC)
		return 0;
	memset((void *)dst_addr, 0x00, len);

	return 0;
}

#if CONFIG_IS_ENABLED(X86_64)
static void do_elf_reloc_fixups64(unsigned int text_base, uintptr_t size,
				  Elf64_Rela *re_src, Elf64_Rela *re_end)
{
	Elf64_Addr *offset_ptr_rom, *last_offset = NULL;
	Elf64_Addr *offset_ptr_ram;

	do {
		unsigned long long type = ELF64_R_TYPE(re_src->r_info);

		if (type != R_X86_64_RELATIVE) {
			printf("%s: unsupported relocation type 0x%llx "
			       "at %p, ", __func__, type, re_src);
			printf("offset = 0x%llx\n", re_src->r_offset);
			continue;
		}

		/* Get the location from the relocation entry */
		offset_ptr_rom = (Elf64_Addr *)(uintptr_t)re_src->r_offset;

		/* Check that the location of the relocation is in .text */
		if (offset_ptr_rom >= (Elf64_Addr *)(uintptr_t)text_base &&
		    offset_ptr_rom > last_offset) {
			/* Switch to the in-RAM version */
			offset_ptr_ram = (Elf64_Addr *)((ulong)offset_ptr_rom +
							gd->reloc_off);

			/* Check that the target points into .text */
			if (*offset_ptr_ram >= text_base &&
			    *offset_ptr_ram <= text_base + size) {
				*offset_ptr_ram = gd->reloc_off +
							re_src->r_addend;
			} else {
				debug("   %p: %lx: rom reloc %lx, ram %p, value %lx, limit %lX\n",
				      re_src, (ulong)re_src->r_info,
				      (ulong)re_src->r_offset, offset_ptr_ram,
				      (ulong)*offset_ptr_ram, text_base + size);
			}
		} else {
			debug("   %p: %lx: rom reloc %lx, last %p\n", re_src,
			      (ulong)re_src->r_info, (ulong)re_src->r_offset,
			      last_offset);
		}
		last_offset = offset_ptr_rom;

	} while (++re_src < re_end);
}
#else
static void do_elf_reloc_fixups32(unsigned int text_base, uintptr_t size,
				  Elf32_Rel *re_src, Elf32_Rel *re_end)
{
	Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
	Elf32_Addr *offset_ptr_ram;

	do {
		unsigned int type = ELF32_R_TYPE(re_src->r_info);

		if (type != R_386_RELATIVE) {
			printf("%s: unsupported relocation type 0x%x "
			       "at %p, ", __func__, type, re_src);
			printf("offset = 0x%x\n", re_src->r_offset);
			continue;
		}

		/* Get the location from the relocation entry */
		offset_ptr_rom = (Elf32_Addr *)(uintptr_t)re_src->r_offset;

		/* Check that the location of the relocation is in .text */
		if (offset_ptr_rom >= (Elf32_Addr *)(uintptr_t)text_base &&
		    offset_ptr_rom > last_offset) {

			/* Switch to the in-RAM version */
			offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom +
							gd->reloc_off);

			/* Check that the target points into .text */
			if (*offset_ptr_ram >= text_base &&
			    *offset_ptr_ram <= text_base + size) {
				*offset_ptr_ram += gd->reloc_off;
			} else {
				debug("   %p: rom reloc %x, ram %p, value %x, limit %lX\n",
				      re_src, re_src->r_offset, offset_ptr_ram,
				      *offset_ptr_ram, text_base + size);
			}
		} else {
			debug("   %p: rom reloc %x, last %p\n", re_src,
			       re_src->r_offset, last_offset);
		}
		last_offset = offset_ptr_rom;

	} while (++re_src < re_end);
}
#endif

/*
 * This function has more error checking than you might expect. Please see
 * this commit message for more information:
 *    62f7970a x86: Add error checking to x86 relocation code
 */
int do_elf_reloc_fixups(void)
{
	void *re_src = (void *)(&__rel_dyn_start);
	void *re_end = (void *)(&__rel_dyn_end);
	uint text_base;

	/* The size of the region of u-boot that runs out of RAM. */
	uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;

	if (gd->flags & GD_FLG_SKIP_RELOC)
		return 0;
	if (re_src == re_end)
		panic("No relocation data");

#ifdef CONFIG_SYS_TEXT_BASE
	text_base = CONFIG_SYS_TEXT_BASE;
#else
	panic("No CONFIG_SYS_TEXT_BASE");
#endif
#if CONFIG_IS_ENABLED(X86_64)
	do_elf_reloc_fixups64(text_base, size, re_src, re_end);
#else
	do_elf_reloc_fixups32(text_base, size, re_src, re_end);
#endif

	return 0;
}
