// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
 */
#include <linux/sizes.h>
#include <linux/uaccess.h>
#include <linux/set_memory.h>
#include <linux/stop_machine.h>

#include <asm/cacheflush.h>
#include <asm/inst.h>

static DEFINE_RAW_SPINLOCK(patch_lock);

void simu_pc(struct pt_regs *regs, union loongarch_instruction insn)
{
	unsigned long pc = regs->csr_era;
	unsigned int rd = insn.reg1i20_format.rd;
	unsigned int imm = insn.reg1i20_format.immediate;

	if (pc & 3) {
		pr_warn("%s: invalid pc 0x%lx\n", __func__, pc);
		return;
	}

	switch (insn.reg1i20_format.opcode) {
	case pcaddi_op:
		regs->regs[rd] = pc + sign_extend64(imm << 2, 21);
		break;
	case pcaddu12i_op:
		regs->regs[rd] = pc + sign_extend64(imm << 12, 31);
		break;
	case pcaddu18i_op:
		regs->regs[rd] = pc + sign_extend64(imm << 18, 37);
		break;
	case pcalau12i_op:
		regs->regs[rd] = pc + sign_extend64(imm << 12, 31);
		regs->regs[rd] &= ~((1 << 12) - 1);
		break;
	default:
		pr_info("%s: unknown opcode\n", __func__);
		return;
	}

	regs->csr_era += LOONGARCH_INSN_SIZE;
}

void simu_branch(struct pt_regs *regs, union loongarch_instruction insn)
{
	unsigned int imm, imm_l, imm_h, rd, rj;
	unsigned long pc = regs->csr_era;

	if (pc & 3) {
		pr_warn("%s: invalid pc 0x%lx\n", __func__, pc);
		return;
	}

	imm_l = insn.reg0i26_format.immediate_l;
	imm_h = insn.reg0i26_format.immediate_h;
	switch (insn.reg0i26_format.opcode) {
	case b_op:
		regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 27);
		return;
	case bl_op:
		regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 27);
		regs->regs[1] = pc + LOONGARCH_INSN_SIZE;
		return;
	}

	imm_l = insn.reg1i21_format.immediate_l;
	imm_h = insn.reg1i21_format.immediate_h;
	rj = insn.reg1i21_format.rj;
	switch (insn.reg1i21_format.opcode) {
	case beqz_op:
		if (regs->regs[rj] == 0)
			regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 22);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		return;
	case bnez_op:
		if (regs->regs[rj] != 0)
			regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 22);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		return;
	}

	imm = insn.reg2i16_format.immediate;
	rj = insn.reg2i16_format.rj;
	rd = insn.reg2i16_format.rd;
	switch (insn.reg2i16_format.opcode) {
	case beq_op:
		if (regs->regs[rj] == regs->regs[rd])
			regs->csr_era = pc + sign_extend64(imm << 2, 17);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		break;
	case bne_op:
		if (regs->regs[rj] != regs->regs[rd])
			regs->csr_era = pc + sign_extend64(imm << 2, 17);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		break;
	case blt_op:
		if ((long)regs->regs[rj] < (long)regs->regs[rd])
			regs->csr_era = pc + sign_extend64(imm << 2, 17);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		break;
	case bge_op:
		if ((long)regs->regs[rj] >= (long)regs->regs[rd])
			regs->csr_era = pc + sign_extend64(imm << 2, 17);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		break;
	case bltu_op:
		if (regs->regs[rj] < regs->regs[rd])
			regs->csr_era = pc + sign_extend64(imm << 2, 17);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		break;
	case bgeu_op:
		if (regs->regs[rj] >= regs->regs[rd])
			regs->csr_era = pc + sign_extend64(imm << 2, 17);
		else
			regs->csr_era = pc + LOONGARCH_INSN_SIZE;
		break;
	case jirl_op:
		regs->csr_era = regs->regs[rj] + sign_extend64(imm << 2, 17);
		regs->regs[rd] = pc + LOONGARCH_INSN_SIZE;
		break;
	default:
		pr_info("%s: unknown opcode\n", __func__);
		return;
	}
}

bool insns_not_supported(union loongarch_instruction insn)
{
	switch (insn.reg3_format.opcode) {
	case amswapw_op ... ammindbdu_op:
		pr_notice("atomic memory access instructions are not supported\n");
		return true;
	case scq_op:
		pr_notice("sc.q instruction is not supported\n");
		return true;
	}

	switch (insn.reg2i14_format.opcode) {
	case llw_op:
	case lld_op:
	case scw_op:
	case scd_op:
		pr_notice("ll and sc instructions are not supported\n");
		return true;
	}

	switch (insn.reg2_format.opcode) {
	case llacqw_op:
	case llacqd_op:
	case screlw_op:
	case screld_op:
		pr_notice("llacq and screl instructions are not supported\n");
		return true;
	}

	switch (insn.reg1i21_format.opcode) {
	case bceqz_op:
		pr_notice("bceqz and bcnez instructions are not supported\n");
		return true;
	}

	return false;
}

bool insns_need_simulation(union loongarch_instruction insn)
{
	if (is_pc_ins(&insn))
		return true;

	if (is_branch_ins(&insn))
		return true;

	return false;
}

void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs)
{
	if (is_pc_ins(&insn))
		simu_pc(regs, insn);
	else if (is_branch_ins(&insn))
		simu_branch(regs, insn);
}

int larch_insn_read(void *addr, u32 *insnp)
{
	int ret;
	u32 val;

	ret = copy_from_kernel_nofault(&val, addr, LOONGARCH_INSN_SIZE);
	if (!ret)
		*insnp = val;

	return ret;
}

int larch_insn_write(void *addr, u32 insn)
{
	int ret;
	unsigned long flags = 0;

	raw_spin_lock_irqsave(&patch_lock, flags);
	ret = copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE);
	raw_spin_unlock_irqrestore(&patch_lock, flags);

	return ret;
}

int larch_insn_patch_text(void *addr, u32 insn)
{
	int ret;
	u32 *tp = addr;

	if ((unsigned long)tp & 3)
		return -EINVAL;

	ret = larch_insn_write(tp, insn);
	if (!ret)
		flush_icache_range((unsigned long)tp,
				   (unsigned long)tp + LOONGARCH_INSN_SIZE);

	return ret;
}

struct insn_copy {
	void *dst;
	void *src;
	size_t len;
	unsigned int cpu;
};

static int text_copy_cb(void *data)
{
	int ret = 0;
	struct insn_copy *copy = data;

	if (smp_processor_id() == copy->cpu) {
		ret = copy_to_kernel_nofault(copy->dst, copy->src, copy->len);
		if (ret) {
			pr_err("%s: operation failed\n", __func__);
			return ret;
		}
	}

	flush_icache_range((unsigned long)copy->dst, (unsigned long)copy->dst + copy->len);

	return 0;
}

int larch_insn_text_copy(void *dst, void *src, size_t len)
{
	int ret = 0;
	int err = 0;
	size_t start, end;
	struct insn_copy copy = {
		.dst = dst,
		.src = src,
		.len = len,
		.cpu = raw_smp_processor_id(),
	};

	/*
	 * Ensure copy.cpu won't be hot removed before stop_machine.
	 * If it is removed nobody will really update the text.
	 */
	lockdep_assert_cpus_held();

	start = round_down((size_t)dst, PAGE_SIZE);
	end   = round_up((size_t)dst + len, PAGE_SIZE);

	err = set_memory_rw(start, (end - start) / PAGE_SIZE);
	if (err) {
		pr_info("%s: set_memory_rw() failed\n", __func__);
		return err;
	}

	ret = stop_machine_cpuslocked(text_copy_cb, &copy, cpu_online_mask);

	err = set_memory_rox(start, (end - start) / PAGE_SIZE);
	if (err) {
		pr_info("%s: set_memory_rox() failed\n", __func__);
		return err;
	}

	return ret;
}

u32 larch_insn_gen_nop(void)
{
	return INSN_NOP;
}

u32 larch_insn_gen_b(unsigned long pc, unsigned long dest)
{
	long offset = dest - pc;
	union loongarch_instruction insn;

	if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) {
		pr_warn("The generated b instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_b(&insn, offset >> 2);

	return insn.word;
}

u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest)
{
	long offset = dest - pc;
	union loongarch_instruction insn;

	if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) {
		pr_warn("The generated bl instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_bl(&insn, offset >> 2);

	return insn.word;
}

u32 larch_insn_gen_break(int imm)
{
	union loongarch_instruction insn;

	if (imm < 0 || imm >= SZ_32K) {
		pr_warn("The generated break instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_break(&insn, imm);

	return insn.word;
}

u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk)
{
	union loongarch_instruction insn;

	emit_or(&insn, rd, rj, rk);

	return insn.word;
}

u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj)
{
	return larch_insn_gen_or(rd, rj, 0);
}

u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm)
{
	union loongarch_instruction insn;

	if (imm < -SZ_512K || imm >= SZ_512K) {
		pr_warn("The generated lu12i.w instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_lu12iw(&insn, rd, imm);

	return insn.word;
}

u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm)
{
	union loongarch_instruction insn;

	if (imm < -SZ_512K || imm >= SZ_512K) {
		pr_warn("The generated lu32i.d instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_lu32id(&insn, rd, imm);

	return insn.word;
}

u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
{
	union loongarch_instruction insn;

	if (imm < -SZ_2K || imm >= SZ_2K) {
		pr_warn("The generated lu52i.d instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_lu52id(&insn, rd, rj, imm);

	return insn.word;
}

u32 larch_insn_gen_beq(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
{
	union loongarch_instruction insn;

	if ((imm & 3) || imm < -SZ_128K || imm >= SZ_128K) {
		pr_warn("The generated beq instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_beq(&insn, rj, rd, imm >> 2);

	return insn.word;
}

u32 larch_insn_gen_bne(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
{
	union loongarch_instruction insn;

	if ((imm & 3) || imm < -SZ_128K || imm >= SZ_128K) {
		pr_warn("The generated bne instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_bne(&insn, rj, rd, imm >> 2);

	return insn.word;
}

u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
{
	union loongarch_instruction insn;

	if ((imm & 3) || imm < -SZ_128K || imm >= SZ_128K) {
		pr_warn("The generated jirl instruction is out of range.\n");
		return INSN_BREAK;
	}

	emit_jirl(&insn, rd, rj, imm >> 2);

	return insn.word;
}
