// 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>

/**
 * 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)
{
	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\n", type);
	}
}

/**
 * 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);
	}

	/* 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();
}
