// SPDX-License-Identifier: GPL-2.0+
/*
 * DAWR infrastructure
 *
 * Copyright 2019, Michael Neuling, IBM Corporation.
 */

#include <linux/types.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <asm/machdep.h>
#include <asm/hvcall.h>
#include <asm/firmware.h>

bool dawr_force_enable;
EXPORT_SYMBOL_GPL(dawr_force_enable);

int set_dawr(int nr, struct arch_hw_breakpoint *brk)
{
	unsigned long dawr, dawrx, mrd;

	dawr = brk->address;

	dawrx  = (brk->type & (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE))
		<< (63 - 58);
	dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE)) >> 2) << (63 - 59);
	dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) >> 3;
	/*
	 * DAWR length is stored in field MDR bits 48:53.  Matches range in
	 * doublewords (64 bits) biased by -1 eg. 0b000000=1DW and
	 * 0b111111=64DW.
	 * brk->hw_len is in bytes.
	 * This aligns up to double word size, shifts and does the bias.
	 */
	mrd = ((brk->hw_len + 7) >> 3) - 1;
	dawrx |= (mrd & 0x3f) << (63 - 53);

	if (ppc_md.set_dawr)
		return ppc_md.set_dawr(nr, dawr, dawrx);

	if (nr == 0) {
		mtspr(SPRN_DAWR0, dawr);
		mtspr(SPRN_DAWRX0, dawrx);
	} else {
		mtspr(SPRN_DAWR1, dawr);
		mtspr(SPRN_DAWRX1, dawrx);
	}

	return 0;
}

static void disable_dawrs_cb(void *info)
{
	struct arch_hw_breakpoint null_brk = {0};
	int i;

	for (i = 0; i < nr_wp_slots(); i++)
		set_dawr(i, &null_brk);
}

static ssize_t dawr_write_file_bool(struct file *file,
				    const char __user *user_buf,
				    size_t count, loff_t *ppos)
{
	struct arch_hw_breakpoint null_brk = {0};
	size_t rc;

	/* Send error to user if they hypervisor won't allow us to write DAWR */
	if (!dawr_force_enable &&
	    firmware_has_feature(FW_FEATURE_LPAR) &&
	    set_dawr(0, &null_brk) != H_SUCCESS)
		return -ENODEV;

	rc = debugfs_write_file_bool(file, user_buf, count, ppos);
	if (rc)
		return rc;

	/* If we are clearing, make sure all CPUs have the DAWR cleared */
	if (!dawr_force_enable)
		smp_call_function(disable_dawrs_cb, NULL, 0);

	return rc;
}

static const struct file_operations dawr_enable_fops = {
	.read =		debugfs_read_file_bool,
	.write =	dawr_write_file_bool,
	.open =		simple_open,
	.llseek =	default_llseek,
};

static int __init dawr_force_setup(void)
{
	if (cpu_has_feature(CPU_FTR_DAWR)) {
		/* Don't setup sysfs file for user control on P8 */
		dawr_force_enable = true;
		return 0;
	}

	if (PVR_VER(mfspr(SPRN_PVR)) == PVR_POWER9) {
		/* Turn DAWR off by default, but allow admin to turn it on */
		debugfs_create_file_unsafe("dawr_enable_dangerous", 0600,
					   arch_debugfs_dir,
					   &dawr_force_enable,
					   &dawr_enable_fops);
	}
	return 0;
}
arch_initcall(dawr_force_setup);
