// SPDX-License-Identifier: GPL-2.0-only
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/alternative.h>
#include <asm/cacheflush.h>
#include <asm/inst.h>
#include <asm/sections.h>

int __read_mostly alternatives_patched;

EXPORT_SYMBOL_GPL(alternatives_patched);

#define MAX_PATCH_SIZE (((u8)(-1)) / LOONGARCH_INSN_SIZE)

static int __initdata_or_module debug_alternative;

static int __init debug_alt(char *str)
{
	debug_alternative = 1;
	return 1;
}
__setup("debug-alternative", debug_alt);

#define DPRINTK(fmt, args...)						\
do {									\
	if (debug_alternative)						\
		printk(KERN_DEBUG "%s: " fmt "\n", __func__, ##args);	\
} while (0)

#define DUMP_WORDS(buf, count, fmt, args...)				\
do {									\
	if (unlikely(debug_alternative)) {				\
		int _j;							\
		union loongarch_instruction *_buf = buf;		\
									\
		if (!(count))						\
			break;						\
									\
		printk(KERN_DEBUG fmt, ##args);				\
		for (_j = 0; _j < count - 1; _j++)			\
			printk(KERN_CONT "<%08x> ", _buf[_j].word);	\
		printk(KERN_CONT "<%08x>\n", _buf[_j].word);		\
	}								\
} while (0)

/* Use this to add nops to a buffer, then text_poke the whole buffer. */
static void __init_or_module add_nops(union loongarch_instruction *insn, int count)
{
	while (count--) {
		insn->word = INSN_NOP;
		insn++;
	}
}

/* Is the jump addr in local .altinstructions */
static inline bool in_alt_jump(unsigned long jump, void *start, void *end)
{
	return jump >= (unsigned long)start && jump < (unsigned long)end;
}

static void __init_or_module recompute_jump(union loongarch_instruction *buf,
		union loongarch_instruction *dest, union loongarch_instruction *src,
		void *start, void *end)
{
	unsigned int si, si_l, si_h;
	unsigned long cur_pc, jump_addr, pc;
	long offset;

	cur_pc = (unsigned long)src;
	pc = (unsigned long)dest;

	si_l = src->reg0i26_format.immediate_l;
	si_h = src->reg0i26_format.immediate_h;
	switch (src->reg0i26_format.opcode) {
	case b_op:
	case bl_op:
		jump_addr = cur_pc + sign_extend64((si_h << 16 | si_l) << 2, 27);
		if (in_alt_jump(jump_addr, start, end))
			return;
		offset = jump_addr - pc;
		BUG_ON(offset < -SZ_128M || offset >= SZ_128M);
		offset >>= 2;
		buf->reg0i26_format.immediate_h = offset >> 16;
		buf->reg0i26_format.immediate_l = offset;
		return;
	}

	si_l = src->reg1i21_format.immediate_l;
	si_h = src->reg1i21_format.immediate_h;
	switch (src->reg1i21_format.opcode) {
	case bceqz_op: /* bceqz_op = bcnez_op */
		BUG_ON(buf->reg1i21_format.rj & BIT(4));
		fallthrough;
	case beqz_op:
	case bnez_op:
		jump_addr = cur_pc + sign_extend64((si_h << 16 | si_l) << 2, 22);
		if (in_alt_jump(jump_addr, start, end))
			return;
		offset = jump_addr - pc;
		BUG_ON(offset < -SZ_4M || offset >= SZ_4M);
		offset >>= 2;
		buf->reg1i21_format.immediate_h = offset >> 16;
		buf->reg1i21_format.immediate_l = offset;
		return;
	}

	si = src->reg2i16_format.immediate;
	switch (src->reg2i16_format.opcode) {
	case beq_op:
	case bne_op:
	case blt_op:
	case bge_op:
	case bltu_op:
	case bgeu_op:
		jump_addr = cur_pc + sign_extend64(si << 2, 17);
		if (in_alt_jump(jump_addr, start, end))
			return;
		offset = jump_addr - pc;
		BUG_ON(offset < -SZ_128K || offset >= SZ_128K);
		offset >>= 2;
		buf->reg2i16_format.immediate = offset;
		return;
	}
}

static int __init_or_module copy_alt_insns(union loongarch_instruction *buf,
	union loongarch_instruction *dest, union loongarch_instruction *src, int nr)
{
	int i;

	for (i = 0; i < nr; i++) {
		buf[i].word = src[i].word;

		if (is_pc_ins(&src[i])) {
			pr_err("Not support pcrel instruction at present!");
			return -EINVAL;
		}

		if (is_branch_ins(&src[i]) &&
		    src[i].reg2i16_format.opcode != jirl_op) {
			recompute_jump(&buf[i], &dest[i], &src[i], src, src + nr);
		}
	}

	return 0;
}

/*
 * text_poke_early - Update instructions on a live kernel at boot time
 *
 * When you use this code to patch more than one byte of an instruction
 * you need to make sure that other CPUs cannot execute this code in parallel.
 * Also no thread must be currently preempted in the middle of these
 * instructions. And on the local CPU you need to be protected again NMI or MCE
 * handlers seeing an inconsistent instruction while you patch.
 */
static void *__init_or_module text_poke_early(union loongarch_instruction *insn,
			      union loongarch_instruction *buf, unsigned int nr)
{
	int i;
	unsigned long flags;

	local_irq_save(flags);

	for (i = 0; i < nr; i++)
		insn[i].word = buf[i].word;

	local_irq_restore(flags);

	wbflush();
	flush_icache_range((unsigned long)insn, (unsigned long)(insn + nr));

	return insn;
}

/*
 * Replace instructions with better alternatives for this CPU type. This runs
 * before SMP is initialized to avoid SMP problems with self modifying code.
 * This implies that asymmetric systems where APs have less capabilities than
 * the boot processor are not handled. Tough. Make sure you disable such
 * features by hand.
 */
void __init_or_module apply_alternatives(struct alt_instr *start, struct alt_instr *end)
{
	struct alt_instr *a;
	unsigned int nr_instr, nr_repl, nr_insnbuf;
	union loongarch_instruction *instr, *replacement;
	union loongarch_instruction insnbuf[MAX_PATCH_SIZE];

	DPRINTK("alt table %px, -> %px", start, end);
	/*
	 * The scan order should be from start to end. A later scanned
	 * alternative code can overwrite previously scanned alternative code.
	 * Some kernel functions (e.g. memcpy, memset, etc) use this order to
	 * patch code.
	 *
	 * So be careful if you want to change the scan order to any other
	 * order.
	 */
	for (a = start; a < end; a++) {
		nr_insnbuf = 0;

		instr = (void *)&a->instr_offset + a->instr_offset;
		replacement = (void *)&a->replace_offset + a->replace_offset;

		BUG_ON(a->instrlen > sizeof(insnbuf));
		BUG_ON(a->instrlen & 0x3);
		BUG_ON(a->replacementlen & 0x3);

		nr_instr = a->instrlen / LOONGARCH_INSN_SIZE;
		nr_repl = a->replacementlen / LOONGARCH_INSN_SIZE;

		if (!cpu_has(a->feature)) {
			DPRINTK("feat not exist: %d, old: (%px len: %d), repl: (%px, len: %d)",
				a->feature, instr, a->instrlen,
				replacement, a->replacementlen);

			continue;
		}

		DPRINTK("feat: %d, old: (%px len: %d), repl: (%px, len: %d)",
			a->feature, instr, a->instrlen,
			replacement, a->replacementlen);

		DUMP_WORDS(instr, nr_instr, "%px: old_insn: ", instr);
		DUMP_WORDS(replacement, nr_repl, "%px: rpl_insn: ", replacement);

		copy_alt_insns(insnbuf, instr, replacement, nr_repl);
		nr_insnbuf = nr_repl;

		if (nr_instr > nr_repl) {
			add_nops(insnbuf + nr_repl, nr_instr - nr_repl);
			nr_insnbuf += nr_instr - nr_repl;
		}
		DUMP_WORDS(insnbuf, nr_insnbuf, "%px: final_insn: ", instr);

		text_poke_early(instr, insnbuf, nr_insnbuf);
	}
}

void __init alternative_instructions(void)
{
	apply_alternatives(__alt_instructions, __alt_instructions_end);

	alternatives_patched = 1;
}
