// SPDX-License-Identifier: GPL-2.0+
/*
 * MIPS Relocation
 *
 * Copyright (c) 2017 Imagination Technologies Ltd.
 *
 * Relocation data, found in the .rel section, is generated by the mips-relocs
 * tool & contains a record of all locations in the U-Boot binary that need to
 * be fixed up during relocation.
 *
 * The data is a sequence of unsigned integers, which are of somewhat arbitrary
 * size. This is achieved by encoding integers as a sequence of bytes, each of
 * which contains 7 bits of data with the most significant bit indicating
 * whether any further bytes need to be read. The least significant bits of the
 * integer are found in the first byte - ie. it somewhat resembles little
 * endian.
 *
 * Each pair of two integers represents a relocation that must be applied. The
 * first integer represents the type of relocation as a standard ELF relocation
 * type (ie. R_MIPS_*). The second integer represents the offset at which to
 * apply the relocation, relative to the previous relocation or for the first
 * relocation the start of the relocated .text section.
 *
 * The end of the relocation data is indicated when type R_MIPS_NONE (0) is
 * read, at which point no further integers should be read. That is, the
 * terminating R_MIPS_NONE reloc includes no offset.
 */

#include <cpu_func.h>
#include <init.h>
#include <asm/relocs.h>
#include <asm/sections.h>
#include <linux/bitops.h>

/**
 * read_uint() - Read an unsigned integer from the buffer
 * @buf: pointer to a pointer to the reloc buffer
 *
 * Read one whole unsigned integer from the relocation data pointed to by @buf,
 * advancing @buf past the bytes encoding the integer.
 *
 * Returns: the integer read from @buf
 */
static unsigned long read_uint(uint8_t **buf)
{
	unsigned long val = 0;
	unsigned int shift = 0;
	uint8_t new;

	do {
		new = *(*buf)++;
		val |= (new & 0x7f) << shift;
		shift += 7;
	} while (new & 0x80);

	return val;
}

/**
 * apply_reloc() - Apply a single relocation
 * @type: the type of reloc (R_MIPS_*)
 * @addr: the address that the reloc should be applied to
 * @off: the relocation offset, ie. number of bytes we're moving U-Boot by
 *
 * Apply a single relocation of type @type at @addr. This function is
 * intentionally simple, and does the bare minimum needed to fixup the
 * relocated U-Boot - in particular, it does not check for overflows.
 */
static void apply_reloc(unsigned int type, void *addr, long off, uint8_t *buf)
{
	uint32_t u32;

	switch (type) {
	case R_MIPS_26:
		u32 = *(uint32_t *)addr;
		u32 = (u32 & GENMASK(31, 26)) |
		      ((u32 + (off >> 2)) & GENMASK(25, 0));
		*(uint32_t *)addr = u32;
		break;

	case R_MIPS_32:
		*(uint32_t *)addr += off;
		break;

	case R_MIPS_64:
		*(uint64_t *)addr += off;
		break;

	case R_MIPS_HI16:
		*(uint32_t *)addr += off >> 16;
		break;

	default:
		panic("Unhandled reloc type %u (@ %p), bss used before relocation?\n",
		      type, buf);
	}
}

/**
 * relocate_code() - Relocate U-Boot, generally from flash to DDR
 * @start_addr_sp: new stack pointer
 * @new_gd: pointer to relocated global data
 * @relocaddr: the address to relocate to
 *
 * Relocate U-Boot from its current location (generally in flash) to a new one
 * (generally in DDR). This function will copy the U-Boot binary & apply
 * relocations as necessary, then jump to board_init_r in the new build of
 * U-Boot. As such, this function does not return.
 */
void relocate_code(ulong start_addr_sp, gd_t *new_gd, ulong relocaddr)
{
	unsigned long addr, length, bss_len;
	uint8_t *buf, *bss_start;
	unsigned int type;
	long off;

	/*
	 * Ensure that we're relocating by an offset which is a multiple of
	 * 64KiB, ie. doesn't change the least significant 16 bits of any
	 * addresses. This allows us to discard R_MIPS_LO16 relocs, saving
	 * space in the U-Boot binary & complexity in handling them.
	 */
	off = relocaddr - (unsigned long)__text_start;
	if (off & 0xffff)
		panic("Mis-aligned relocation\n");

	/* Copy U-Boot to RAM */
	length = __image_copy_end - __text_start;
	memcpy((void *)relocaddr, __text_start, length);

	/* Now apply relocations to the copy in RAM */
	buf = __rel_start;
	addr = relocaddr;
	while (true) {
		type = read_uint(&buf);
		if (type == R_MIPS_NONE)
			break;

		addr += read_uint(&buf) << 2;
		apply_reloc(type, (void *)addr, off, buf);
	}

	/* Ensure the icache is coherent */
	flush_cache(relocaddr, length);

	/* Clear the .bss section */
	bss_start = (uint8_t *)((unsigned long)__bss_start + off);
	bss_len = (unsigned long)__bss_end - (unsigned long)__bss_start;
	memset(bss_start, 0, bss_len);

	/* Jump to the relocated U-Boot */
	asm volatile(
		       "move	$29, %0\n"
		"	move	$4, %1\n"
		"	move	$5, %2\n"
		"	move	$31, $0\n"
		"	jr	%3"
		: /* no outputs */
		: "r"(start_addr_sp),
		  "r"(new_gd),
		  "r"(relocaddr),
		  "r"((unsigned long)board_init_r + off));

	/* Since we jumped to the new U-Boot above, we won't get here */
	unreachable();
}
