// 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 <common.h>
#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();
}
