// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
 */
#define pr_fmt(fmt) "hw-breakpoint: " fmt

#include <linux/hw_breakpoint.h>
#include <linux/kprobes.h>
#include <linux/perf_event.h>

#include <asm/hw_breakpoint.h>

/* Breakpoint currently in use for each BRP. */
static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[LOONGARCH_MAX_BRP]);

/* Watchpoint currently in use for each WRP. */
static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[LOONGARCH_MAX_WRP]);

int hw_breakpoint_slots(int type)
{
	/*
	 * We can be called early, so don't rely on
	 * our static variables being initialised.
	 */
	switch (type) {
	case TYPE_INST:
		return get_num_brps();
	case TYPE_DATA:
		return get_num_wrps();
	default:
		pr_warn("unknown slot type: %d\n", type);
		return 0;
	}
}

#define READ_WB_REG_CASE(OFF, N, REG, T, VAL)		\
	case (OFF + N):					\
		LOONGARCH_CSR_WATCH_READ(N, REG, T, VAL);	\
		break

#define WRITE_WB_REG_CASE(OFF, N, REG, T, VAL)		\
	case (OFF + N):					\
		LOONGARCH_CSR_WATCH_WRITE(N, REG, T, VAL);	\
		break

#define GEN_READ_WB_REG_CASES(OFF, REG, T, VAL)		\
	READ_WB_REG_CASE(OFF, 0, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 1, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 2, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 3, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 4, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 5, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 6, REG, T, VAL);		\
	READ_WB_REG_CASE(OFF, 7, REG, T, VAL);

#define GEN_WRITE_WB_REG_CASES(OFF, REG, T, VAL)	\
	WRITE_WB_REG_CASE(OFF, 0, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 1, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 2, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 3, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 4, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 5, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 6, REG, T, VAL);		\
	WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL);

static u64 read_wb_reg(int reg, int n, int t)
{
	u64 val = 0;

	switch (reg + n) {
	GEN_READ_WB_REG_CASES(CSR_CFG_ADDR, ADDR, t, val);
	GEN_READ_WB_REG_CASES(CSR_CFG_MASK, MASK, t, val);
	GEN_READ_WB_REG_CASES(CSR_CFG_CTRL, CTRL, t, val);
	GEN_READ_WB_REG_CASES(CSR_CFG_ASID, ASID, t, val);
	default:
		pr_warn("Attempt to read from unknown breakpoint register %d\n", n);
	}

	return val;
}
NOKPROBE_SYMBOL(read_wb_reg);

static void write_wb_reg(int reg, int n, int t, u64 val)
{
	switch (reg + n) {
	GEN_WRITE_WB_REG_CASES(CSR_CFG_ADDR, ADDR, t, val);
	GEN_WRITE_WB_REG_CASES(CSR_CFG_MASK, MASK, t, val);
	GEN_WRITE_WB_REG_CASES(CSR_CFG_CTRL, CTRL, t, val);
	GEN_WRITE_WB_REG_CASES(CSR_CFG_ASID, ASID, t, val);
	default:
		pr_warn("Attempt to write to unknown breakpoint register %d\n", n);
	}
}
NOKPROBE_SYMBOL(write_wb_reg);

enum hw_breakpoint_ops {
	HW_BREAKPOINT_INSTALL,
	HW_BREAKPOINT_UNINSTALL,
};

/*
 * hw_breakpoint_slot_setup - Find and setup a perf slot according to operations
 *
 * @slots: pointer to array of slots
 * @max_slots: max number of slots
 * @bp: perf_event to setup
 * @ops: operation to be carried out on the slot
 *
 * Return:
 *	slot index on success
 *	-ENOSPC if no slot is available/matches
 *	-EINVAL on wrong operations parameter
 */

static int hw_breakpoint_slot_setup(struct perf_event **slots, int max_slots,
				    struct perf_event *bp, enum hw_breakpoint_ops ops)
{
	int i;
	struct perf_event **slot;

	for (i = 0; i < max_slots; ++i) {
		slot = &slots[i];
		switch (ops) {
		case HW_BREAKPOINT_INSTALL:
			if (!*slot) {
				*slot = bp;
				return i;
			}
			break;
		case HW_BREAKPOINT_UNINSTALL:
			if (*slot == bp) {
				*slot = NULL;
				return i;
			}
			break;
		default:
			pr_warn_once("Unhandled hw breakpoint ops %d\n", ops);
			return -EINVAL;
		}
	}

	return -ENOSPC;
}

void ptrace_hw_copy_thread(struct task_struct *tsk)
{
	memset(tsk->thread.hbp_break, 0, sizeof(tsk->thread.hbp_break));
	memset(tsk->thread.hbp_watch, 0, sizeof(tsk->thread.hbp_watch));
}

/*
 * Unregister breakpoints from this task and reset the pointers in the thread_struct.
 */
void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
{
	int i;
	struct thread_struct *t = &tsk->thread;

	for (i = 0; i < LOONGARCH_MAX_BRP; i++) {
		if (t->hbp_break[i]) {
			unregister_hw_breakpoint(t->hbp_break[i]);
			t->hbp_break[i] = NULL;
		}
	}

	for (i = 0; i < LOONGARCH_MAX_WRP; i++) {
		if (t->hbp_watch[i]) {
			unregister_hw_breakpoint(t->hbp_watch[i]);
			t->hbp_watch[i] = NULL;
		}
	}
}

static int hw_breakpoint_control(struct perf_event *bp,
				 enum hw_breakpoint_ops ops)
{
	u32 ctrl;
	int i, max_slots, enable;
	struct perf_event **slots;
	struct arch_hw_breakpoint *info = counter_arch_bp(bp);

	if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
		/* Breakpoint */
		slots = this_cpu_ptr(bp_on_reg);
		max_slots = boot_cpu_data.watch_ireg_count;
	} else {
		/* Watchpoint */
		slots = this_cpu_ptr(wp_on_reg);
		max_slots = boot_cpu_data.watch_dreg_count;
	}

	i = hw_breakpoint_slot_setup(slots, max_slots, bp, ops);

	if (WARN_ONCE(i < 0, "Can't find any breakpoint slot"))
		return i;

	switch (ops) {
	case HW_BREAKPOINT_INSTALL:
		/* Set the FWPnCFG/MWPnCFG 1~4 register. */
		write_wb_reg(CSR_CFG_ADDR, i, 0, info->address);
		write_wb_reg(CSR_CFG_ADDR, i, 1, info->address);
		write_wb_reg(CSR_CFG_MASK, i, 0, info->mask);
		write_wb_reg(CSR_CFG_MASK, i, 1, info->mask);
		write_wb_reg(CSR_CFG_ASID, i, 0, 0);
		write_wb_reg(CSR_CFG_ASID, i, 1, 0);
		if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
			write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE);
		} else {
			ctrl = encode_ctrl_reg(info->ctrl);
			write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | CTRL_PLV_ENABLE);
		}
		enable = csr_read64(LOONGARCH_CSR_CRMD);
		csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD);
		break;
	case HW_BREAKPOINT_UNINSTALL:
		/* Reset the FWPnCFG/MWPnCFG 1~4 register. */
		write_wb_reg(CSR_CFG_ADDR, i, 0, 0);
		write_wb_reg(CSR_CFG_ADDR, i, 1, 0);
		write_wb_reg(CSR_CFG_MASK, i, 0, 0);
		write_wb_reg(CSR_CFG_MASK, i, 1, 0);
		write_wb_reg(CSR_CFG_CTRL, i, 0, 0);
		write_wb_reg(CSR_CFG_CTRL, i, 1, 0);
		write_wb_reg(CSR_CFG_ASID, i, 0, 0);
		write_wb_reg(CSR_CFG_ASID, i, 1, 0);
		break;
	}

	return 0;
}

/*
 * Install a perf counter breakpoint.
 */
int arch_install_hw_breakpoint(struct perf_event *bp)
{
	return hw_breakpoint_control(bp, HW_BREAKPOINT_INSTALL);
}

void arch_uninstall_hw_breakpoint(struct perf_event *bp)
{
	hw_breakpoint_control(bp, HW_BREAKPOINT_UNINSTALL);
}

static int get_hbp_len(u8 hbp_len)
{
	unsigned int len_in_bytes = 0;

	switch (hbp_len) {
	case LOONGARCH_BREAKPOINT_LEN_1:
		len_in_bytes = 1;
		break;
	case LOONGARCH_BREAKPOINT_LEN_2:
		len_in_bytes = 2;
		break;
	case LOONGARCH_BREAKPOINT_LEN_4:
		len_in_bytes = 4;
		break;
	case LOONGARCH_BREAKPOINT_LEN_8:
		len_in_bytes = 8;
		break;
	}

	return len_in_bytes;
}

/*
 * Check whether bp virtual address is in kernel space.
 */
int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
{
	unsigned int len;
	unsigned long va;

	va = hw->address;
	len = get_hbp_len(hw->ctrl.len);

	return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
}

/*
 * Extract generic type and length encodings from an arch_hw_breakpoint_ctrl.
 * Hopefully this will disappear when ptrace can bypass the conversion
 * to generic breakpoint descriptions.
 */
int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
			   int *gen_len, int *gen_type, int *offset)
{
	/* Type */
	switch (ctrl.type) {
	case LOONGARCH_BREAKPOINT_EXECUTE:
		*gen_type = HW_BREAKPOINT_X;
		break;
	case LOONGARCH_BREAKPOINT_LOAD:
		*gen_type = HW_BREAKPOINT_R;
		break;
	case LOONGARCH_BREAKPOINT_STORE:
		*gen_type = HW_BREAKPOINT_W;
		break;
	case LOONGARCH_BREAKPOINT_LOAD | LOONGARCH_BREAKPOINT_STORE:
		*gen_type = HW_BREAKPOINT_RW;
		break;
	default:
		return -EINVAL;
	}

	if (!ctrl.len)
		return -EINVAL;

	*offset = __ffs(ctrl.len);

	/* Len */
	switch (ctrl.len) {
	case LOONGARCH_BREAKPOINT_LEN_1:
		*gen_len = HW_BREAKPOINT_LEN_1;
		break;
	case LOONGARCH_BREAKPOINT_LEN_2:
		*gen_len = HW_BREAKPOINT_LEN_2;
		break;
	case LOONGARCH_BREAKPOINT_LEN_4:
		*gen_len = HW_BREAKPOINT_LEN_4;
		break;
	case LOONGARCH_BREAKPOINT_LEN_8:
		*gen_len = HW_BREAKPOINT_LEN_8;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/*
 * Construct an arch_hw_breakpoint from a perf_event.
 */
static int arch_build_bp_info(struct perf_event *bp,
			      const struct perf_event_attr *attr,
			      struct arch_hw_breakpoint *hw)
{
	/* Type */
	switch (attr->bp_type) {
	case HW_BREAKPOINT_X:
		hw->ctrl.type = LOONGARCH_BREAKPOINT_EXECUTE;
		break;
	case HW_BREAKPOINT_R:
		hw->ctrl.type = LOONGARCH_BREAKPOINT_LOAD;
		break;
	case HW_BREAKPOINT_W:
		hw->ctrl.type = LOONGARCH_BREAKPOINT_STORE;
		break;
	case HW_BREAKPOINT_RW:
		hw->ctrl.type = LOONGARCH_BREAKPOINT_LOAD | LOONGARCH_BREAKPOINT_STORE;
		break;
	default:
		return -EINVAL;
	}

	/* Len */
	switch (attr->bp_len) {
	case HW_BREAKPOINT_LEN_1:
		hw->ctrl.len = LOONGARCH_BREAKPOINT_LEN_1;
		break;
	case HW_BREAKPOINT_LEN_2:
		hw->ctrl.len = LOONGARCH_BREAKPOINT_LEN_2;
		break;
	case HW_BREAKPOINT_LEN_4:
		hw->ctrl.len = LOONGARCH_BREAKPOINT_LEN_4;
		break;
	case HW_BREAKPOINT_LEN_8:
		hw->ctrl.len = LOONGARCH_BREAKPOINT_LEN_8;
		break;
	default:
		return -EINVAL;
	}

	/* Address */
	hw->address = attr->bp_addr;

	return 0;
}

/*
 * Validate the arch-specific HW Breakpoint register settings.
 */
int hw_breakpoint_arch_parse(struct perf_event *bp,
			     const struct perf_event_attr *attr,
			     struct arch_hw_breakpoint *hw)
{
	int ret;
	u64 alignment_mask, offset;

	/* Build the arch_hw_breakpoint. */
	ret = arch_build_bp_info(bp, attr, hw);
	if (ret)
		return ret;

	if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE)
		alignment_mask = 0x7;
	else
		alignment_mask = 0x3;
	offset = hw->address & alignment_mask;

	hw->address &= ~alignment_mask;
	hw->ctrl.len <<= offset;

	return 0;
}

static void update_bp_registers(struct pt_regs *regs, int enable, int type)
{
	u32 ctrl;
	int i, max_slots;
	struct perf_event **slots;
	struct arch_hw_breakpoint *info;

	switch (type) {
	case 0:
		slots = this_cpu_ptr(bp_on_reg);
		max_slots = boot_cpu_data.watch_ireg_count;
		break;
	case 1:
		slots = this_cpu_ptr(wp_on_reg);
		max_slots = boot_cpu_data.watch_dreg_count;
		break;
	default:
		return;
	}

	for (i = 0; i < max_slots; ++i) {
		if (!slots[i])
			continue;

		info = counter_arch_bp(slots[i]);
		if (enable) {
			if ((info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) && (type == 0)) {
				write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE);
				write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE);
			} else {
				ctrl = read_wb_reg(CSR_CFG_CTRL, i, 1);
				if (info->ctrl.type == LOONGARCH_BREAKPOINT_LOAD)
					ctrl |= 0x1 << MWPnCFG3_LoadEn;
				if (info->ctrl.type == LOONGARCH_BREAKPOINT_STORE)
					ctrl |= 0x1 << MWPnCFG3_StoreEn;
				write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl);
			}
			regs->csr_prmd |= CSR_PRMD_PWE;
		} else {
			if ((info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) && (type == 0)) {
				write_wb_reg(CSR_CFG_CTRL, i, 0, 0);
			} else {
				ctrl = read_wb_reg(CSR_CFG_CTRL, i, 1);
				if (info->ctrl.type == LOONGARCH_BREAKPOINT_LOAD)
					ctrl &= ~0x1 << MWPnCFG3_LoadEn;
				if (info->ctrl.type == LOONGARCH_BREAKPOINT_STORE)
					ctrl &= ~0x1 << MWPnCFG3_StoreEn;
				write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl);
			}
			regs->csr_prmd &= ~CSR_PRMD_PWE;
		}
	}
}
NOKPROBE_SYMBOL(update_bp_registers);

/*
 * Debug exception handlers.
 */
void breakpoint_handler(struct pt_regs *regs)
{
	int i;
	struct perf_event *bp, **slots;

	slots = this_cpu_ptr(bp_on_reg);

	for (i = 0; i < boot_cpu_data.watch_ireg_count; ++i) {
		bp = slots[i];
		if (bp == NULL)
			continue;
		perf_bp_event(bp, regs);
	}
	update_bp_registers(regs, 0, 0);
}
NOKPROBE_SYMBOL(breakpoint_handler);

void watchpoint_handler(struct pt_regs *regs)
{
	int i;
	struct perf_event *wp, **slots;

	slots = this_cpu_ptr(wp_on_reg);

	for (i = 0; i < boot_cpu_data.watch_dreg_count; ++i) {
		wp = slots[i];
		if (wp == NULL)
			continue;
		perf_bp_event(wp, regs);
	}
	update_bp_registers(regs, 0, 1);
}
NOKPROBE_SYMBOL(watchpoint_handler);

static int __init arch_hw_breakpoint_init(void)
{
	int cpu;

	boot_cpu_data.watch_ireg_count = get_num_brps();
	boot_cpu_data.watch_dreg_count = get_num_wrps();

	pr_info("Found %d breakpoint and %d watchpoint registers.\n",
		boot_cpu_data.watch_ireg_count, boot_cpu_data.watch_dreg_count);

	for (cpu = 1; cpu < NR_CPUS; cpu++) {
		cpu_data[cpu].watch_ireg_count = boot_cpu_data.watch_ireg_count;
		cpu_data[cpu].watch_dreg_count = boot_cpu_data.watch_dreg_count;
	}

	return 0;
}
arch_initcall(arch_hw_breakpoint_init);

void hw_breakpoint_thread_switch(struct task_struct *next)
{
	u64 addr, mask;
	struct pt_regs *regs = task_pt_regs(next);

	if (test_tsk_thread_flag(next, TIF_SINGLESTEP)) {
		addr = read_wb_reg(CSR_CFG_ADDR, 0, 0);
		mask = read_wb_reg(CSR_CFG_MASK, 0, 0);
		if (!((regs->csr_era ^ addr) & ~mask))
			csr_write32(CSR_FWPC_SKIP, LOONGARCH_CSR_FWPS);
		regs->csr_prmd |= CSR_PRMD_PWE;
	} else {
		/* Update breakpoints */
		update_bp_registers(regs, 1, 0);
		/* Update watchpoints */
		update_bp_registers(regs, 1, 1);
	}
}

void hw_breakpoint_pmu_read(struct perf_event *bp)
{
}

/*
 * Dummy function to register with die_notifier.
 */
int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
				    unsigned long val, void *data)
{
	return NOTIFY_DONE;
}
